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

Subversion Repositories openrisc

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

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
#if DYNAMIC_EXECUTION
310
  PRINTF
311
    ("WARNING: Patching registers may not work with the dynamic execution model\n");
312
#endif
313
  return 0;
314
}
315
 
316
static int
317
sim_cmd_pc (int argc, char **argv)      /* patch PC */
318
{
319
#if DYNAMIC_EXECUTION
320
  PRINTF ("Patching the pc in the dynamic execution model doesn't work\n");
321
#else
322
  if (argc != 2)
323
    {
324
      PRINTF ("pc <value>\n");
325
      return 0;
326
    }
327
 
328
  cpu_state.pc = strtoul (argv[1], NULL, 0);
329
  pcnext = cpu_state.pc + 4;
330
#endif
331
  return 0;
332
}
333
 
334
static int
335
sim_cmd_breaks (int argc, char **argv)  /* print breakpoints */
336
{
337
  print_breakpoints ();
338
  return 0;
339
}
340
 
341
static int
342
sim_cmd_break (int argc, char **argv)   /* set/clear breakpoint */
343
{
344
#if DYNAMIC_EXECUTION
345
  PRINTF
346
    ("Setting simulator breakpoints is not support with the recompiler\n");
347
  return 0;
348
#else
349
  char *p;
350
  oraddr_t addr;
351
  struct label_entry *l;
352
 
353
  if (argc != 2)
354
    {
355
      PRINTF ("break <label or address>\n");
356
      return 0;
357
    }
358
 
359
  addr = strtoul (argv[1], &p, 0);
360
  if (*p)
361
    {
362
      l = find_label (argv[1]);
363
      if (l)
364
        set_insnbrkpoint (l->addr);
365
      else
366
        PRINTF ("Label `%s' does not exist\n", argv[1]);
367
    }
368
  else
369
    set_insnbrkpoint (addr);
370
  return 0;
371
#endif
372
}
373
 
374
static int
375
sim_cmd_r (int argc, char **argv)       /* dump regs */
376
{
377
  dumpreg ();
378
  return 0;
379
}
380
 
381
static int
382
sim_cmd_de (int argc, char **argv)      /* disassemble */
383
{
384
  static oraddr_t from = 0, to = 0;
385
 
386
  if (argc >= 2)
387
    {
388
      if (argv[1][0] == '_')
389
        from = eval_label (argv[1]);
390
      else
391
        from = strtoul (argv[1], NULL, 0);
392
      to = from + 0x40;
393
    }
394
 
395
  if (argc >= 3)
396
    to = strtoul (argv[2], NULL, 0);
397
 
398
  disassemble_memory (from, to, 1);
399
  PRINTF ("\n");
400
  return 0;
401
}
402
 
403
static int
404
sim_cmd_reset (int argc, char **argv)   /* reset simulator */
405
{
406
  sim_reset ();
407
  return 0;
408
}
409
 
410
static int
411
sim_cmd_hist (int argc, char **argv)    /* dump history */
412
{
413
  int i;
414
  struct hist_exec *cur;
415
  if (!config.sim.history)
416
    {
417
      PRINTF ("Simulation history disabled.\n");
418
      return 0;
419
    }
420
  for (i = HISTEXEC_LEN, cur = hist_exec_tail->next; i; i--, cur = cur->next)
421
    disassemble_memory (cur->addr, cur->addr + 4, 1);
422
  PRINTF ("\n");
423
  return 0;
424
}
425
 
426
/* Called when it is suspisous that runtime.sim.instructions has reached
427
 * to_insn_num */
428
void
429
check_insn_exec (void *dat)
430
{
431
  if (runtime.cpu.instructions < to_insn_num)
432
    {
433
      /* Instruction count has not yet been reached, reschedule */
434
      long long int delta = to_insn_num - runtime.cpu.instructions;
435
      SCHED_ADD (check_insn_exec, NULL,
436
                 (delta > INT32_MAX) ? INT32_MAX : delta);
437
      return;
438
    }
439
  handle_sim_command ();
440
}
441
 
442
void
443
print_insn_exec (void *dat)
444
{
445
  dumpreg ();
446
  if (runtime.cpu.instructions < to_insn_num)
447
    {
448
      /* Instruction count has not yet been reached, reschedule */
449
      sched_next_insn (print_insn_exec, NULL);
450
      return;
451
    }
452
  handle_sim_command ();
453
}
454
 
455
static int
456
sim_cmd_run (int argc, char **argv)     /* run */
457
{
458
  runtime.sim.hush = 0;
459
  if (argc >= 3)
460
    {
461
      if (!strcmp (argv[2], "hush"))
462
        runtime.sim.hush = 1;
463
    }
464
 
465
  if (argc >= 2)
466
    {
467
      if ((to_insn_num = strtoll (argv[1], NULL, 0)) != -1)
468
        {
469
          if (runtime.sim.hush)
470
            {
471
              /* Schedule a job to run in to_insn_num cycles time since an instruction
472
               * may execute in only 1 cycle.  check_insn_exec will check if the right
473
               * number of instructions have been executed.  If not it will
474
               * reschedule.  */
475
              SCHED_ADD (check_insn_exec, NULL,
476
                         (to_insn_num > INT32_MAX) ? INT32_MAX : to_insn_num);
477
            }
478
          else
479
            {
480
              /* The user wants to see the execution dumps.  Schedule a task to show
481
               * it to him after each cycle */
482
              sched_next_insn (print_insn_exec, NULL);
483
            }
484
          to_insn_num += runtime.cpu.instructions;
485
        }
486
      else
487
        {
488
          if (!runtime.sim.hush)
489
            sched_next_insn (print_insn_exec, NULL);
490
        }
491
    }
492
  else
493
    /* Run 0 instructions */
494
    return 0;
495
 
496
  return 1;
497
}
498
 
499
static int
500
sim_cmd_stall (int argc, char **argv)   /* Added by CZ 210801 */
501
{
502
#if DYNAMIC_EXECUTION
503
  PRINTF ("Can't stall the cpu with the dynamic recompiler\n");
504
  return 0;
505
#else
506
  set_stall_state (1);
507
  runtime.sim.iprompt = 0;
508
  runtime.sim.hush = 1;
509
  return 1;
510
#endif
511
}
512
 
513
static int
514
sim_cmd_unstall (int argc, char **argv) /* Added by CZ 210801 */
515
{
516
#if DYNAMIC_EXECUTION
517
  PRINTF ("Can't unstall the cpu with the dynamic recompiler\n");
518
  return 0;
519
#else
520
  set_stall_state (0);
521
  return 0;
522
#endif
523
}
524
 
525
static int
526
sim_cmd_stats (int argc, char **argv)   /* stats */
527
{
528
  if (argc != 2)
529
    {
530
      PRINTF ("stats <stat no. or `clear'>\n");
531
      return 0;
532
    }
533
 
534
  if (strcmp (argv[1], "clear") == 0)
535
    {
536
      initstats ();
537
      PRINTF ("Cleared.\n");
538
    }
539
  else
540
    {
541
      printstats (strtoul (argv[1], NULL, 0));
542
    }
543
  return 0;
544
}
545
 
546
static int
547
sim_cmd_info (int argc, char **argv)    /* configuration info */
548
{
549
  struct sim_stat *cur_stat = sim_stats;
550
 
551
  /* Display info about various modules */
552
  sprs_status ();
553
  PRINTF ("\n");
554
  memory_table_status ();
555
  if (config.dc.enabled)
556
    dc_info ();
557
 
558
  if (config.bpb.enabled)
559
    bpb_info ();
560
  if (config.bpb.btic)
561
    btic_info ();
562
 
563
  while (cur_stat)
564
    {
565
      cur_stat->stat_func (cur_stat->dat);
566
      cur_stat = cur_stat->next;
567
    }
568
 
569
  return 0;
570
}
571
 
572
static int
573
sim_cmd_setdbch (int argc, char **argv) /* Toggle debug channel on/off */
574
{
575
  if (argc != 2)
576
    {
577
      PRINTF ("setdbch <channel>\n");
578
      return 0;
579
    }
580
  parse_dbchs (argv[1]);
581
  return 0;
582
}
583
 
584
static int
585
sim_cmd_debug (int argc, char **argv)   /* debug mode */
586
{
587
  config.sim.debug ^= 1;
588
  return 0;
589
}
590
 
591
static int
592
sim_cmd_profile (int argc, char **argv) /* run profiler utility */
593
{
594
  return  main_profiler (argc, argv, 0);
595
}
596
 
597
static int
598
sim_cmd_mprofile (int argc, char **argv)        /* run mprofiler utility */
599
{
600
  return  main_mprofiler (argc, argv, 0);
601
}
602
 
603
static int
604
sim_cmd_cuc (int argc, char **argv)     /* run Custom Unit Compiler */
605
{
606
  main_cuc (runtime.sim.filename);
607
  return 0;
608
}
609
 
610
static int
611
sim_cmd_set (int argc, char **argv)     /* configuration info */
612
{
613
  set_config_command (argc, argv);
614
  return 0;
615
}
616
 
617
static char *
618
strip_space (char *str)
619
{
620 240 julius
  while (isblank ((int)*str) && *str)
621 19 jeremybenn
    str++;
622
  return str;
623
}
624
 
625
struct sim_command
626
{
627
  const char *name;
628
  int (*cmd_handle) (int argc, char **argv);
629
};
630
 
631
static const struct sim_command sim_commands[] = {
632
  {"q", sim_cmd_quit},
633
  {"help", sim_cmd_help},
634
  {"t", sim_cmd_trace},
635
  {"dm", sim_cmd_dm},
636
  {"dv", sim_cmd_dv},
637
  {"dh", sim_cmd_dh},
638
  {"pm", sim_cmd_pm},
639
  {"cm", sim_cmd_cm},
640
  {"pr", sim_cmd_pr},
641
  {"pc", sim_cmd_pc},
642
  {"breaks", sim_cmd_breaks},
643
  {"break", sim_cmd_break},
644
  {"r", sim_cmd_r},
645
  {"de", sim_cmd_de},
646
  {"reset", sim_cmd_reset},
647
  {"hist", sim_cmd_hist},
648
  {"stall", sim_cmd_stall},
649
  {"unstall", sim_cmd_unstall},
650
  {"stats", sim_cmd_stats},
651
  {"info", sim_cmd_info},
652
  {"run", sim_cmd_run},
653
  {"setdbch", sim_cmd_setdbch},
654
  {"debug", sim_cmd_debug},
655
  {"profile", sim_cmd_profile},
656
  {"mprofile", sim_cmd_mprofile},
657
  {"cuc", sim_cmd_cuc},
658
  {"set", sim_cmd_set},
659
  {NULL, NULL}
660
};
661
 
662
#ifdef HAVE_LIBREADLINE
663
static void initialize_readline (void);
664
#endif
665
 
666
void
667
handle_sim_command (void)
668
{
669
  char *redirstr;
670
  int argc;
671
  char *argv[5];
672
  char *cur_arg;
673
  const struct sim_command *cur_cmd;
674
#ifdef HAVE_LIBREADLINE
675
  static char *prev_str = NULL;
676
#else
677
  char b2[500];
678
  static char prev_str[500] = { 0 };
679
#endif
680
 
681
  runtime.sim.iprompt_run = 1;
682
 
683
  /* Make sure that check_insn_exec is not left hanging in the scheduler (and
684
   * breaking the sim when the user doesn't want it to break). */
685
  SCHED_FIND_REMOVE (check_insn_exec, NULL);
686
  SCHED_FIND_REMOVE (print_insn_exec, NULL);
687
 
688
#ifdef HAVE_LIBREADLINE
689
  initialize_readline ();       /* Bind our completer. */
690
#endif
691
 
692
  for (;;)
693
    {
694
#ifdef HAVE_LIBREADLINE
695
      cur_arg = readline ("(sim) ");
696 494 jeremybenn
 
697
      if (!cur_arg)
698
        {
699
          sim_done ();
700
        }
701 19 jeremybenn
#else
702
      PRINTF ("(sim) ");
703
 
704
      cur_arg = fgets (b2, sizeof (b2), stdin);
705
 
706
      if (!cur_arg)
707
        sim_done ();
708
 
709
      if (!*cur_arg)
710
        {
711
          usleep (1000);
712
          continue;
713
        }
714
#endif
715
 
716
#ifdef HAVE_LIBREADLINE
717
      if (!*cur_arg)
718
        {
719
          if (prev_str)
720
            {
721
              free (cur_arg);
722
              cur_arg = prev_str;
723
            }
724
        }
725
      else
726
        {
727
          prev_str = cur_arg;
728
          add_history (cur_arg);
729
        }
730
#else
731
      cur_arg = strip_space (cur_arg);
732
      if (*cur_arg == '\n')
733
        strcpy (cur_arg, prev_str);
734
      else
735
        strcpy (prev_str, cur_arg);
736
#endif
737
 
738
      if ((redirstr = strchr (cur_arg, '>')))
739
        {
740
          redirstr = strip_space (++redirstr);
741
 
742 240 julius
          while (!isspace ((int)*redirstr) && *redirstr)
743 19 jeremybenn
            redirstr++;
744
          *redirstr = '\0';
745
 
746
          redirstr = strchr (cur_arg, '>');
747
          *redirstr = '\0';
748
 
749
          redirstr = strip_space (++redirstr);
750
          runtime.sim.fout = fopen (redirstr, "w+");
751
          if (!runtime.sim.fout)
752
            runtime.sim.fout = stdout;
753
        }
754
 
755
      if (*cur_arg)
756
        {
757
          argc = 0;
758
          while (*cur_arg)
759
            {
760
              argv[argc] = cur_arg;
761
              argc++;
762 240 julius
              while (!isspace ((int)*cur_arg) && *cur_arg)
763 19 jeremybenn
                cur_arg++;
764
              if (*cur_arg)
765
                {
766
                  *cur_arg = '\0';
767
                  cur_arg = strip_space (cur_arg + 1);
768
                }
769
              else
770
                *cur_arg = '\0';
771
              if (argc == 5)
772
                {
773
                  fprintf (stderr,
774
                           "Too many arguments given to command `%s'\n",
775
                           argv[0]);
776
                  break;
777
                }
778
            }
779
 
780
          for (cur_cmd = sim_commands; cur_cmd->name; cur_cmd++)
781
            {
782
              if (!strcmp (cur_cmd->name, argv[0]))
783
                {
784
                  if (cur_cmd->cmd_handle (argc, argv))
785
                    {
786
                      runtime.sim.iprompt = 0;
787
                      runtime.sim.iprompt_run = 0;
788
                      return;
789
                    }
790
                  break;
791
                }
792
            }
793
 
794
          if (!cur_cmd->name)
795
            PRINTF ("%s: Unknown command.\n", argv[0]);
796
        }
797
 
798
      if (redirstr)
799
        {
800
          redirstr = NULL;
801
          fclose (runtime.sim.fout);
802
          runtime.sim.fout = stdout;
803
        }
804
 
805
    }
806
}
807
 
808
#ifdef HAVE_LIBREADLINE
809
 
810
char *command_generator ();
811
char **sim_completion ();
812
 
813
/* Tell the GNU readline library how to complete.  We want to try to complete
814
   on command names if this is the first word in the line, or on filenames
815
   if not. */
816
static void
817
initialize_readline (void)
818
{
819
  /* Allow conditional parsing of the ~/.inputrc file. */
820
  rl_readline_name = "or1ksim";
821
 
822
  /* Tell the completer that we want a crack first. */
823
  rl_attempted_completion_function = sim_completion;
824
 
825
}
826
 
827
/* Attempt to complete on the contents of TEXT.  START and END bound the
828
   region of rl_line_buffer that contains the word to complete.  TEXT is
829
   the word to complete.  We can use the entire contents of rl_line_buffer
830
   in case we want to do some simple parsing.  Return the array of matches,
831
   or NULL if there aren't any. */
832
/* FIXME: Handle arguments to the `set' command */
833
char **
834
sim_completion (char *text, int start, int end)
835
{
836
  char **matches;
837
 
838
  matches = NULL;
839
 
840
  /* If this word is at the start of the line, then it is a command
841
     to complete.  Otherwise it is the name of a file in the current
842
     directory. */
843
  if (!start)
844
    matches = rl_completion_matches (text, command_generator);
845
 
846
  return matches;
847
}
848
 
849
/* Generator function for command completion.  STATE lets us know whether
850
   to start from scratch; without any state (i.e. STATE == 0), then we
851
   start at the top of the list. */
852
char *
853
command_generator (char *text, int state)
854
{
855
  static int list_index, len;
856
  const char *name;
857
 
858
  /* If this is a new word to complete, initialize now.  This includes
859
     saving the length of TEXT for efficiency, and initializing the index
860
     variable to 0. */
861
  if (!state)
862
    {
863
      list_index = 0;
864
      len = strlen (text);
865
    }
866
 
867
  /* Return the next name which partially matches from the command list. */
868
  while ((name = sim_commands[list_index].name))
869
    {
870
      list_index++;
871
 
872
      if (strncmp (name, text, len) == 0)
873
        return strdup (name);
874
    }
875
 
876
  /* If no names matched, then return NULL. */
877
  return NULL;
878
}
879
 
880
/* Repeats the last command.  */
881
char *
882
repeat_last_command ()
883
{
884
  int offset = where_history ();
885
  HIST_ENTRY *hist;
886
 
887
  if ((hist = history_get (offset)))
888
    return strdup (hist->line);
889
  return 0;
890
}
891
 
892
#endif

powered by: WebSVN 2.1.0

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