OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

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

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

powered by: WebSVN 2.1.0

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