OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [or1ksim/] [sim-cmd.c] - Blame information for rev 557

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 jeremybenn
/* sim-cmd.c -- Simulator command parsing
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
5
   Copyright (C) 2008 Embecosm Limited
6 494 jeremybenn
   Copyright (C) 2011 Giuseppe Scrivano <gscrivano@gnu.org>
7 19 jeremybenn
 
8
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
9 494 jeremybenn
   contributor Giuseppe Scrivano <gscrivano@gnu.org>
10 19 jeremybenn
 
11
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
12
 
13
   This program is free software; you can redistribute it and/or modify it
14
   under the terms of the GNU General Public License as published by the Free
15
   Software Foundation; either version 3 of the License, or (at your option)
16
   any later version.
17
 
18
   This program is distributed in the hope that it will be useful, but WITHOUT
19
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
21
   more details.
22
 
23
   You should have received a copy of the GNU General Public License along
24
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
25
 
26
/* This program is commented throughout in a fashion suitable for processing
27
   with Doxygen. */
28
 
29
 
30
/* Autoconf and/or portability configuration */
31
#include "config.h"
32
 
33
/* System includes */
34
#include <stdlib.h>
35
#include <unistd.h>
36
#include <stdio.h>
37
 
38
#ifdef HAVE_LIBREADLINE
39
#include <readline/readline.h>
40
#include <readline/history.h>
41
#endif /* HAVE_LIBREADLINE */
42
 
43
/* Package includes */
44
#include "sim-cmd.h"
45
#include "sim-config.h"
46
#include "execute.h"
47
#include "labels.h"
48
#include "sched.h"
49
#include "toplevel-support.h"
50
#include "dumpverilog.h"
51
#include "profiler.h"
52
#include "mprofiler.h"
53
#include "trace.h"
54
#include "debug-unit.h"
55
#include "stats.h"
56
#include "sprs.h"
57
#include "dcache-model.h"
58
#include "branch-predict.h"
59
#include "debug.h"
60
#include "cuc.h"
61
#include "rsp-server.h"
62
 
63
 
64
/* The number of instructions to execute before droping into interactive mode */
65
static long long to_insn_num;
66
 
67
struct sim_stat
68
{
69
  void (*stat_func) (void *dat);
70
  void *dat;
71
  struct sim_stat *next;
72
};
73
 
74
static struct sim_stat *sim_stats = NULL;
75
 
76
/* Registers a status printing callback */
77
void
78
reg_sim_stat (void (*stat_func) (void *dat), void *dat)
79
{
80
  struct sim_stat *new = malloc (sizeof (struct sim_stat));
81
 
82
  if (!new)
83
    {
84
      fprintf (stderr, "reg_sim_stat: Out-of-memory\n");
85
      exit (1);
86
    }
87
 
88
  new->stat_func = stat_func;
89
  new->dat = dat;
90
  new->next = sim_stats;
91
  sim_stats = new;
92
}
93
 
94
/* Scheduler job that drops us back into interactive mode after the next
95
 * instruction has executed */
96
void
97
reenter_int (void *dat)
98
{
99
  if (!runtime.sim.hush)
100
    dumpreg ();
101
  handle_sim_command ();
102
}
103
 
104
static int
105
sim_cmd_quit (int argc, char **argv)    /* quit */
106
{
107
  PRINTF ("\n");
108
  sim_done ();
109
  return 0;
110
}
111
 
112
static int
113
sim_cmd_help (int argc, char **argv)    /* help */
114
{
115
  PRINTF ("q                              - quit simulator\n");
116
  PRINTF ("r                              - display all registers\n");
117
  PRINTF ("t                              - execute next instruction\n");
118
  PRINTF
119
    ("run <instructions> [<hush>]    - execute <instruction> instructions, no reg\n");
120
  PRINTF ("                                 dump if hush\n");
121
  PRINTF
122
    ("pr <r> <value>                 - patch register <r> with <value>\n");
123
  PRINTF
124
    ("dm <fromaddr> [<toaddr>]       - display memory from <fromaddr> to <toaddr>\n");
125
  PRINTF ("de <fromaddr> [<toaddr>]       - debug insn memory\n");
126
  PRINTF
127
    ("pm <addr> <value>              - patch memory location <addr> with <value>\n");
128
  PRINTF
129
    ("pc <value>                     - patch PC register with <value>\n");
130
  PRINTF ("cm <fromaddr> <toaddr> <size>  - copy memory\n");
131
  PRINTF
132
    ("break <addr>                   - toggle breakpoint at address <addr>\n");
133
  PRINTF ("breaks                         - print all set breakpoints\n");
134
  PRINTF ("reset                          - simulator reset\n");
135
  PRINTF ("hist                           - execution history\n");
136
  PRINTF
137
    ("stall                          - stalls the processor and gives control to\n");
138
  PRINTF ("                                 the debugger\n");
139
  PRINTF ("unstall                        - unstalls the processor\n");
140
  PRINTF
141
    ("stats <num|clear>              - execution statistics num or clear it.\n");
142
  PRINTF
143
    ("info                           - configuration info (caches etc.)\n");
144
  PRINTF
145
    ("dv <fromaddr> [<toaddr>] [<m>] - dumps memory as verilog module <m>\n");
146
  PRINTF ("                                 (use redirect to capture)\n");
147
  PRINTF
148
    ("dh <fromaddr> [<toaddr>]       - dumps memory as hex code (use redirect)\n");
149
  PRINTF ("setdbch                        - toggles debug channels on/off\n");
150
  PRINTF
151
    ("set <section> <item> = <param> - set configuration.  See sim.cfg for more\n");
152
  PRINTF ("                                 information.\n");
153
  PRINTF ("debug                          - toggles simulator debug mode\n");
154
  PRINTF
155
    ("cuc                            - enters Custom Unit Compiler command prompt\n");
156
  PRINTF
157
    ("help                           - available commands (this list)\n");
158
  PRINTF
159
    ("<cmd> > <filename>             - redirect simulator stdout to <filename>\n");
160
  PRINTF ("                                 (and not emulated PRINTF)\n\n");
161
  (void)main_mprofiler (0, NULL, 1);
162
  PRINTF ("\n");
163
  (void)main_profiler (0, NULL, 1);
164
  return 0;
165
}
166
 
167
static int
168
sim_cmd_trace (int argc, char **argv)   /* trace */
169
{
170
  runtime.sim.hush = 0;
171
  sched_next_insn (reenter_int, NULL);
172
  return 1;
173
}
174
 
175
static int
176
sim_cmd_dm (int argc, char **argv)      /* dump memory */
177
{
178
  static oraddr_t from = 0, to = 0;
179
 
180
  if (argc >= 2)
181
    {
182
      if (argv[1][0] == '_')
183
        from = eval_label (argv[1]);
184
      else
185
        from = strtoul (argv[1], NULL, 0);
186
      to = from + 0x40;
187
    }
188
  if (argc >= 3)
189
    to = strtoul (argv[2], NULL, 0);
190
  dump_memory (from, to);
191
  PRINTF ("\n");
192
  return 0;
193
}
194
 
195
static int
196
sim_cmd_dv (int argc, char **argv)      /* dump memory as verilog */
197
{
198
  static oraddr_t from = 0, to = 0;
199
 
200
  if (argc >= 2)
201
    {
202
      if (argv[1][0] == '_')
203
        from = eval_label (argv[1]);
204
      else
205
        from = strtoul (argv[1], NULL, 0);
206
      to = from + 0x40;
207
    }
208
  if (argc >= 3)
209
    to = strtoul (argv[2], NULL, 0);
210
 
211
  if (argc < 4)
212
    dumpverilog ("or1k_mem", from, to);
213
  else
214
    dumpverilog (argv[3], from, to);
215
 
216
  PRINTF ("\n");
217
  return 0;
218
}
219
 
220
static int
221
sim_cmd_dh (int argc, char **argv)      /* dump memory as hex */
222
{
223
  static oraddr_t from = 0, to = 0;
224
 
225
  if (argc >= 2)
226
    {
227
      if (argv[1][0] == '_')
228
        from = eval_label (argv[1]);
229
      else
230
        from = strtoul (argv[1], NULL, 0);
231
      to = from + 0x40;
232
    }
233
  if (argc >= 3)
234
    to = strtoul (argv[2], NULL, 0);
235
 
236
  dumphex (from, to);
237
  PRINTF ("\n");
238
  return 0;
239
}
240
 
241
static int
242
sim_cmd_pm (int argc, char **argv)      /* patch memory */
243
{
244
  static oraddr_t addr = 0;
245
  int breakpoint = 0;
246
 
247
  if (argc != 3)
248
    {
249
      PRINTF ("pm <address> <value>\n");
250
      return 0;
251
    }
252
 
253
  if (argc >= 2)
254
    {
255
      if (argv[1][0] == '_')
256
        addr = eval_label (argv[1]);
257
      else
258
        addr = strtoul (argv[1], NULL, 0);
259
    }
260
  set_mem32 (addr, strtoul (argv[2], NULL, 0), &breakpoint);
261
  return 0;
262
}
263
 
264
static int
265
sim_cmd_cm (int argc, char **argv)      /* copy memory 2004-01-20 hpanther */
266
{
267
  static oraddr_t from = 0, to = 0;
268
  static unsigned int size = 0;
269
  int i;
270
 
271
  if (argc >= 2)
272
    {
273
      if (argv[1][0] == '_')
274
        from = eval_label (argv[1]);
275
      else
276
        from = strtoul (argv[1], NULL, 0);
277
    }
278
 
279
  if (argc >= 3)
280
    {
281
      if (argv[2][0] == '_')
282
        to = eval_label (argv[2]);
283
      else
284
        to = strtoul (argv[2], NULL, 0);
285
    }
286
 
287
  if (argc >= 4)
288
    {
289
      if (argv[3][0] == '_')
290
        size = eval_label (argv[3]);
291
      else
292
        size = strtoul (argv[3], NULL, 0);
293
    }
294
 
295
  for (i = 0; i < size; i += 4)
296
    set_direct32 (to + i, eval_direct32 (from + i, 0, 0), 0, 0);
297
  return 0;
298
}
299
 
300
static int
301
sim_cmd_pr (int argc, char **argv)      /* patch regs */
302
{
303
  if (argc != 3)
304
    {
305
      PRINTF ("pr <register> <value>\n");
306
      return 0;
307
    }
308
  setsim_reg (strtoul (argv[1], NULL, 0), strtoul (argv[2], NULL, 0));
309
  return 0;
310
}
311
 
312
static int
313
sim_cmd_pc (int argc, char **argv)      /* patch PC */
314
{
315
  if (argc != 2)
316
    {
317
      PRINTF ("pc <value>\n");
318
      return 0;
319
    }
320
 
321
  cpu_state.pc = strtoul (argv[1], NULL, 0);
322
  pcnext = cpu_state.pc + 4;
323
  return 0;
324
}
325
 
326
static int
327
sim_cmd_breaks (int argc, char **argv)  /* print breakpoints */
328
{
329
  print_breakpoints ();
330
  return 0;
331
}
332
 
333
static int
334
sim_cmd_break (int argc, char **argv)   /* set/clear breakpoint */
335
{
336
  char *p;
337
  oraddr_t addr;
338
  struct label_entry *l;
339
 
340
  if (argc != 2)
341
    {
342
      PRINTF ("break <label or address>\n");
343
      return 0;
344
    }
345
 
346
  addr = strtoul (argv[1], &p, 0);
347
  if (*p)
348
    {
349
      l = find_label (argv[1]);
350
      if (l)
351
        set_insnbrkpoint (l->addr);
352
      else
353
        PRINTF ("Label `%s' does not exist\n", argv[1]);
354
    }
355
  else
356
    set_insnbrkpoint (addr);
357
  return 0;
358
}
359
 
360
static int
361
sim_cmd_r (int argc, char **argv)       /* dump regs */
362
{
363
  dumpreg ();
364
  return 0;
365
}
366
 
367
static int
368
sim_cmd_de (int argc, char **argv)      /* disassemble */
369
{
370
  static oraddr_t from = 0, to = 0;
371
 
372
  if (argc >= 2)
373
    {
374
      if (argv[1][0] == '_')
375
        from = eval_label (argv[1]);
376
      else
377
        from = strtoul (argv[1], NULL, 0);
378
      to = from + 0x40;
379
    }
380
 
381
  if (argc >= 3)
382
    to = strtoul (argv[2], NULL, 0);
383
 
384
  disassemble_memory (from, to, 1);
385
  PRINTF ("\n");
386
  return 0;
387
}
388
 
389
static int
390
sim_cmd_reset (int argc, char **argv)   /* reset simulator */
391
{
392
  sim_reset ();
393
  return 0;
394
}
395
 
396
static int
397
sim_cmd_hist (int argc, char **argv)    /* dump history */
398
{
399
  int i;
400
  struct hist_exec *cur;
401
  if (!config.sim.history)
402
    {
403
      PRINTF ("Simulation history disabled.\n");
404
      return 0;
405
    }
406
  for (i = HISTEXEC_LEN, cur = hist_exec_tail->next; i; i--, cur = cur->next)
407
    disassemble_memory (cur->addr, cur->addr + 4, 1);
408
  PRINTF ("\n");
409
  return 0;
410
}
411
 
412
/* Called when it is suspisous that runtime.sim.instructions has reached
413
 * to_insn_num */
414
void
415
check_insn_exec (void *dat)
416
{
417
  if (runtime.cpu.instructions < to_insn_num)
418
    {
419
      /* Instruction count has not yet been reached, reschedule */
420
      long long int delta = to_insn_num - runtime.cpu.instructions;
421
      SCHED_ADD (check_insn_exec, NULL,
422
                 (delta > INT32_MAX) ? INT32_MAX : delta);
423
      return;
424
    }
425
  handle_sim_command ();
426
}
427
 
428
void
429
print_insn_exec (void *dat)
430
{
431
  dumpreg ();
432
  if (runtime.cpu.instructions < to_insn_num)
433
    {
434
      /* Instruction count has not yet been reached, reschedule */
435
      sched_next_insn (print_insn_exec, NULL);
436
      return;
437
    }
438
  handle_sim_command ();
439
}
440
 
441
static int
442
sim_cmd_run (int argc, char **argv)     /* run */
443
{
444
  runtime.sim.hush = 0;
445
  if (argc >= 3)
446
    {
447
      if (!strcmp (argv[2], "hush"))
448
        runtime.sim.hush = 1;
449
    }
450
 
451
  if (argc >= 2)
452
    {
453
      if ((to_insn_num = strtoll (argv[1], NULL, 0)) != -1)
454
        {
455
          if (runtime.sim.hush)
456
            {
457
              /* Schedule a job to run in to_insn_num cycles time since an instruction
458
               * may execute in only 1 cycle.  check_insn_exec will check if the right
459
               * number of instructions have been executed.  If not it will
460
               * reschedule.  */
461
              SCHED_ADD (check_insn_exec, NULL,
462
                         (to_insn_num > INT32_MAX) ? INT32_MAX : to_insn_num);
463
            }
464
          else
465
            {
466
              /* The user wants to see the execution dumps.  Schedule a task to show
467
               * it to him after each cycle */
468
              sched_next_insn (print_insn_exec, NULL);
469
            }
470
          to_insn_num += runtime.cpu.instructions;
471
        }
472
      else
473
        {
474
          if (!runtime.sim.hush)
475
            sched_next_insn (print_insn_exec, NULL);
476
        }
477
    }
478
  else
479
    /* Run 0 instructions */
480
    return 0;
481
 
482
  return 1;
483
}
484
 
485
static int
486
sim_cmd_stall (int argc, char **argv)   /* Added by CZ 210801 */
487
{
488
  set_stall_state (1);
489
  runtime.sim.iprompt = 0;
490
  runtime.sim.hush = 1;
491
  return 1;
492
}
493
 
494
static int
495
sim_cmd_unstall (int argc, char **argv) /* Added by CZ 210801 */
496
{
497
  set_stall_state (0);
498
  return 0;
499
}
500
 
501
static int
502
sim_cmd_stats (int argc, char **argv)   /* stats */
503
{
504
  if (argc != 2)
505
    {
506
      PRINTF ("stats <stat no. or `clear'>\n");
507
      return 0;
508
    }
509
 
510
  if (strcmp (argv[1], "clear") == 0)
511
    {
512
      initstats ();
513
      PRINTF ("Cleared.\n");
514
    }
515
  else
516
    {
517
      printstats (strtoul (argv[1], NULL, 0));
518
    }
519
  return 0;
520
}
521
 
522
static int
523
sim_cmd_info (int argc, char **argv)    /* configuration info */
524
{
525
  struct sim_stat *cur_stat = sim_stats;
526
 
527
  /* Display info about various modules */
528
  sprs_status ();
529
  PRINTF ("\n");
530
  memory_table_status ();
531
  if (config.dc.enabled)
532
    dc_info ();
533
 
534
  if (config.bpb.enabled)
535
    bpb_info ();
536
  if (config.bpb.btic)
537
    btic_info ();
538
 
539
  while (cur_stat)
540
    {
541
      cur_stat->stat_func (cur_stat->dat);
542
      cur_stat = cur_stat->next;
543
    }
544
 
545
  return 0;
546
}
547
 
548
static int
549
sim_cmd_setdbch (int argc, char **argv) /* Toggle debug channel on/off */
550
{
551
  if (argc != 2)
552
    {
553
      PRINTF ("setdbch <channel>\n");
554
      return 0;
555
    }
556
  parse_dbchs (argv[1]);
557
  return 0;
558
}
559
 
560
static int
561
sim_cmd_debug (int argc, char **argv)   /* debug mode */
562
{
563
  config.sim.debug ^= 1;
564
  return 0;
565
}
566
 
567
static int
568
sim_cmd_profile (int argc, char **argv) /* run profiler utility */
569
{
570
  return  main_profiler (argc, argv, 0);
571
}
572
 
573
static int
574
sim_cmd_mprofile (int argc, char **argv)        /* run mprofiler utility */
575
{
576
  return  main_mprofiler (argc, argv, 0);
577
}
578
 
579
static int
580
sim_cmd_cuc (int argc, char **argv)     /* run Custom Unit Compiler */
581
{
582
  main_cuc (runtime.sim.filename);
583
  return 0;
584
}
585
 
586
static int
587
sim_cmd_set (int argc, char **argv)     /* configuration info */
588
{
589
  set_config_command (argc, argv);
590
  return 0;
591
}
592
 
593
static char *
594
strip_space (char *str)
595
{
596 240 julius
  while (isblank ((int)*str) && *str)
597 19 jeremybenn
    str++;
598
  return str;
599
}
600
 
601
struct sim_command
602
{
603
  const char *name;
604
  int (*cmd_handle) (int argc, char **argv);
605
};
606
 
607
static const struct sim_command sim_commands[] = {
608
  {"q", sim_cmd_quit},
609
  {"help", sim_cmd_help},
610
  {"t", sim_cmd_trace},
611
  {"dm", sim_cmd_dm},
612
  {"dv", sim_cmd_dv},
613
  {"dh", sim_cmd_dh},
614
  {"pm", sim_cmd_pm},
615
  {"cm", sim_cmd_cm},
616
  {"pr", sim_cmd_pr},
617
  {"pc", sim_cmd_pc},
618
  {"breaks", sim_cmd_breaks},
619
  {"break", sim_cmd_break},
620
  {"r", sim_cmd_r},
621
  {"de", sim_cmd_de},
622
  {"reset", sim_cmd_reset},
623
  {"hist", sim_cmd_hist},
624
  {"stall", sim_cmd_stall},
625
  {"unstall", sim_cmd_unstall},
626
  {"stats", sim_cmd_stats},
627
  {"info", sim_cmd_info},
628
  {"run", sim_cmd_run},
629
  {"setdbch", sim_cmd_setdbch},
630
  {"debug", sim_cmd_debug},
631
  {"profile", sim_cmd_profile},
632
  {"mprofile", sim_cmd_mprofile},
633
  {"cuc", sim_cmd_cuc},
634
  {"set", sim_cmd_set},
635
  {NULL, NULL}
636
};
637
 
638
#ifdef HAVE_LIBREADLINE
639
static void initialize_readline (void);
640
#endif
641
 
642
void
643
handle_sim_command (void)
644
{
645
  char *redirstr;
646
  int argc;
647
  char *argv[5];
648
  char *cur_arg;
649
  const struct sim_command *cur_cmd;
650
#ifdef HAVE_LIBREADLINE
651
  static char *prev_str = NULL;
652
#else
653
  char b2[500];
654
  static char prev_str[500] = { 0 };
655
#endif
656
 
657
  runtime.sim.iprompt_run = 1;
658
 
659
  /* Make sure that check_insn_exec is not left hanging in the scheduler (and
660
   * breaking the sim when the user doesn't want it to break). */
661
  SCHED_FIND_REMOVE (check_insn_exec, NULL);
662
  SCHED_FIND_REMOVE (print_insn_exec, NULL);
663
 
664
#ifdef HAVE_LIBREADLINE
665
  initialize_readline ();       /* Bind our completer. */
666
#endif
667
 
668
  for (;;)
669
    {
670
#ifdef HAVE_LIBREADLINE
671
      cur_arg = readline ("(sim) ");
672 494 jeremybenn
 
673
      if (!cur_arg)
674
        {
675
          sim_done ();
676
        }
677 19 jeremybenn
#else
678
      PRINTF ("(sim) ");
679
 
680
      cur_arg = fgets (b2, sizeof (b2), stdin);
681
 
682
      if (!cur_arg)
683
        sim_done ();
684
 
685
      if (!*cur_arg)
686
        {
687
          usleep (1000);
688
          continue;
689
        }
690
#endif
691
 
692
#ifdef HAVE_LIBREADLINE
693
      if (!*cur_arg)
694
        {
695
          if (prev_str)
696
            {
697
              free (cur_arg);
698
              cur_arg = prev_str;
699
            }
700
        }
701
      else
702
        {
703
          prev_str = cur_arg;
704
          add_history (cur_arg);
705
        }
706
#else
707
      cur_arg = strip_space (cur_arg);
708
      if (*cur_arg == '\n')
709
        strcpy (cur_arg, prev_str);
710
      else
711
        strcpy (prev_str, cur_arg);
712
#endif
713
 
714
      if ((redirstr = strchr (cur_arg, '>')))
715
        {
716
          redirstr = strip_space (++redirstr);
717
 
718 240 julius
          while (!isspace ((int)*redirstr) && *redirstr)
719 19 jeremybenn
            redirstr++;
720
          *redirstr = '\0';
721
 
722
          redirstr = strchr (cur_arg, '>');
723
          *redirstr = '\0';
724
 
725
          redirstr = strip_space (++redirstr);
726
          runtime.sim.fout = fopen (redirstr, "w+");
727
          if (!runtime.sim.fout)
728
            runtime.sim.fout = stdout;
729
        }
730
 
731
      if (*cur_arg)
732
        {
733
          argc = 0;
734
          while (*cur_arg)
735
            {
736
              argv[argc] = cur_arg;
737
              argc++;
738 240 julius
              while (!isspace ((int)*cur_arg) && *cur_arg)
739 19 jeremybenn
                cur_arg++;
740
              if (*cur_arg)
741
                {
742
                  *cur_arg = '\0';
743
                  cur_arg = strip_space (cur_arg + 1);
744
                }
745
              else
746
                *cur_arg = '\0';
747
              if (argc == 5)
748
                {
749
                  fprintf (stderr,
750
                           "Too many arguments given to command `%s'\n",
751
                           argv[0]);
752
                  break;
753
                }
754
            }
755
 
756
          for (cur_cmd = sim_commands; cur_cmd->name; cur_cmd++)
757
            {
758
              if (!strcmp (cur_cmd->name, argv[0]))
759
                {
760
                  if (cur_cmd->cmd_handle (argc, argv))
761
                    {
762
                      runtime.sim.iprompt = 0;
763
                      runtime.sim.iprompt_run = 0;
764
                      return;
765
                    }
766
                  break;
767
                }
768
            }
769
 
770
          if (!cur_cmd->name)
771
            PRINTF ("%s: Unknown command.\n", argv[0]);
772
        }
773
 
774
      if (redirstr)
775
        {
776
          redirstr = NULL;
777
          fclose (runtime.sim.fout);
778
          runtime.sim.fout = stdout;
779
        }
780
 
781
    }
782
}
783
 
784
#ifdef HAVE_LIBREADLINE
785
 
786
char *command_generator ();
787
char **sim_completion ();
788
 
789
/* Tell the GNU readline library how to complete.  We want to try to complete
790
   on command names if this is the first word in the line, or on filenames
791
   if not. */
792
static void
793
initialize_readline (void)
794
{
795
  /* Allow conditional parsing of the ~/.inputrc file. */
796
  rl_readline_name = "or1ksim";
797
 
798
  /* Tell the completer that we want a crack first. */
799
  rl_attempted_completion_function = sim_completion;
800
 
801
}
802
 
803
/* Attempt to complete on the contents of TEXT.  START and END bound the
804
   region of rl_line_buffer that contains the word to complete.  TEXT is
805
   the word to complete.  We can use the entire contents of rl_line_buffer
806
   in case we want to do some simple parsing.  Return the array of matches,
807
   or NULL if there aren't any. */
808
/* FIXME: Handle arguments to the `set' command */
809
char **
810
sim_completion (char *text, int start, int end)
811
{
812
  char **matches;
813
 
814
  matches = NULL;
815
 
816
  /* If this word is at the start of the line, then it is a command
817
     to complete.  Otherwise it is the name of a file in the current
818
     directory. */
819
  if (!start)
820
    matches = rl_completion_matches (text, command_generator);
821
 
822
  return matches;
823
}
824
 
825
/* Generator function for command completion.  STATE lets us know whether
826
   to start from scratch; without any state (i.e. STATE == 0), then we
827
   start at the top of the list. */
828
char *
829
command_generator (char *text, int state)
830
{
831
  static int list_index, len;
832
  const char *name;
833
 
834
  /* If this is a new word to complete, initialize now.  This includes
835
     saving the length of TEXT for efficiency, and initializing the index
836
     variable to 0. */
837
  if (!state)
838
    {
839
      list_index = 0;
840
      len = strlen (text);
841
    }
842
 
843
  /* Return the next name which partially matches from the command list. */
844
  while ((name = sim_commands[list_index].name))
845
    {
846
      list_index++;
847
 
848
      if (strncmp (name, text, len) == 0)
849
        return strdup (name);
850
    }
851
 
852
  /* If no names matched, then return NULL. */
853
  return NULL;
854
}
855
 
856
/* Repeats the last command.  */
857
char *
858
repeat_last_command ()
859
{
860
  int offset = where_history ();
861
  HIST_ENTRY *hist;
862
 
863
  if ((hist = history_get (offset)))
864
    return strdup (hist->line);
865
  return 0;
866
}
867
 
868
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.