home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_40.arc / DAIMS.ARC / COMMANDS.CPP < prev    next >
Text File  |  1988-02-10  |  7KB  |  258 lines

  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <setjmp.h>
  4. #include <stream.h>
  5. #include <string.h>
  6. #include "chbuffer.hxx"
  7. #include "daims.hxx"
  8. /*
  9.  **
  10.  ** Routines to do the commands in yyparse.y
  11.  */
  12.  
  13. extern int yyparse();
  14.  
  15. char * progname;        /* for error messages */
  16. char * source_name;        /* current source file name */
  17. int lineno;            /* to say where they occurred */
  18. jmp_buf begin;            /* place to return to on error */
  19. extern int ydebug_f;
  20. extern int ldebug_f;
  21. int debug_f;
  22. int trace_f;
  23. int sstep_f;
  24.  
  25. void error(char *s, char * s2)
  26. {
  27.   cerr << s << " " << s2 << "\n";
  28.   exit(1);
  29. }
  30.  
  31. void prompt()
  32. {
  33.   cout << "DAIMS> ";
  34.   cout.flush();
  35. }
  36.  
  37. /* 
  38. -*++ help(): get help inside the DAIMS interpreter
  39. ** 
  40. ** (*++ history: 
  41. **      7 Dec 87    Bruce Eckel    Creation date
  42. ** ++*)
  43. ** 
  44. ** (*++ detailed: The help file contains a general message (printed when
  45. ** "help" is typed by itself) followed by specific messages.  Each specific
  46. ** message begins with the subject name(s) surrounded by curly braces.  If a
  47. ** name within the curly braces is matched, the following text is printed out,
  48. ** until the next '{'
  49. ** ++*)
  50. */
  51.  
  52. void help(char * subject)
  53. {
  54.   char ch;
  55.   char stg[80];
  56.   int NOT_FOUND = 1;
  57.   filebuf helpfile;
  58.   if (helpfile.open(HELP_FILE,input) == 0)
  59.     error("cannot open help file",HELP_FILE);
  60.   istream help(&helpfile);
  61.   if (debug_f) cerr << "subject `" << (int)subject << "'\n";
  62.   if(subject) {
  63.     if (debug_f) cerr << "looking for a subject: " << subject << "\n";
  64.     /* find the subject */
  65.     while (NOT_FOUND) {
  66.       while(help.get(ch)) {
  67.     if (debug_f) cerr.put(ch);
  68.     if (ch == '{') break;    /* subject names in "{}" */
  69.       }
  70.       if (debug_f) cerr << "found left brace\n";
  71.       if (help.eof()) { 
  72.     cerr << "subject \"" << subject << "\" not found\n";
  73.     return;
  74.       }
  75.       do {
  76.     help >> stg;        /* this is a nifty feature */
  77.     if (debug_f) cerr << "checking : " << stg << "\n";
  78.     NOT_FOUND = strcmp(stg,subject); /* zero if equal */
  79.     if(!NOT_FOUND) break;
  80.     if (debug_f) cerr << "NOT_FOUND = " << NOT_FOUND << "\n";
  81.       } while (*stg != '}');
  82.       if (debug_f) if (*stg == '}') cerr << " found right brace\n";
  83.     }
  84.     while(help.get(ch))
  85.       if (ch == '}') break;    /* find the other "subject" brace */
  86.     if (debug_f) cerr << "dumping subject text:\n";
  87.     while(help.get(ch)) {
  88.       if (ch == '{') break;
  89.       cout.put(ch);        /* dump the subject text */
  90.     }
  91.   }
  92.   else {
  93.     if (debug_f) cerr << "subject help";
  94.     while(help.get(ch)) {
  95.       if (ch == '{') break;
  96.       cout.put(ch);        /* dump the help subjects */
  97.     }
  98.   }
  99.   cout << "\n";
  100.  
  101.  
  102. /* 
  103. -*++ source(): get input from a new file, saving the old environment
  104. ** 
  105. ** (*++ history: 
  106. **      7 Dec 87    Bruce Eckel    Creation date
  107. ** ++*)
  108. ** 
  109. ** (*++ detailed: You can source files to any level, since the current
  110. ** environment is saved on the stack and restored when the end of the sourced
  111. ** file is encountered.
  112. ** ++*)
  113. */
  114.  
  115. void source(char * filename)
  116. {
  117.   char dummy[10];
  118.   int tmp_lineno = lineno;    /* save current line count */
  119.   filebuf sourcefile;
  120.   istream tmpcin(cin);        /* to hold cin while sourcing */
  121.   char * oldname = source_name;    /* remember what file called us */
  122.   source_name = filename;    /* source_name is global */
  123.   if (sourcefile.open(filename,input) == 0)
  124.     error("cannot open input file",filename);
  125.   istream source(&sourcefile);
  126.   cin = source;
  127.   lineno = 1;            /* start counting lines in the new file */
  128.   if(oldname && trace_f) {    /* if this file was called from another file */
  129.     cout << "trace: open new source file:\n   ";
  130.     buf.dump();
  131.     cout << "\n";
  132.   }
  133.   else if (trace_f) buf.erase();
  134.   while(yyparse()) {        /* parse the sourced file */
  135.     lineno++;
  136.     if(trace_f)    {        /* if tracing and sourcing a file,  echo */
  137.       cout << "trace: previous output generated by line " << lineno -1;
  138.       cout << " in sourced file " << "\"" << source_name << "\"" << ":\n   ";
  139.       buf.dump();
  140.     }
  141.     if (sstep_f) { cout << "press RET to continue "; gets(dummy); }
  142.   }
  143.   cin = tmpcin;            /* reset the input */
  144.   sourcefile.close();
  145.   lineno = tmp_lineno;        /* reset line number counting */
  146.   source_name = oldname;    /* so the error messages work right */
  147. }
  148.  
  149.  
  150. /* 
  151. -*++ option(): parses command line options
  152. ** 
  153. ** (*++ history: 
  154. **      7 Dec 87    Bruce Eckel    Creation date
  155. ** ++*)
  156. ** 
  157. ** (*++ detailed: 
  158. ** ++*)
  159. */
  160.  
  161. int option(char * opt)
  162. {
  163.     /* Returns true if more options may be in the string */
  164.  
  165.     switch (*opt) {
  166.       case 'y':    /* Yacc debug flag */
  167.     ydebug_f = 1;
  168.     return(1);
  169.       case 'l':    /* Lex debug flag */
  170.     ldebug_f = 1;
  171.     return(1);
  172.       case 'd':    /* general debug flag */
  173.     debug_f = 1;
  174.     return(1);
  175.       case 't': /* source file trace flag */
  176.     trace_f = 1;
  177.     return(1);
  178.       case 's': /* source file single-step flag */
  179.     sstep_f = 1;
  180.     return(1);
  181.       case '\0':    /* End of string */
  182.     return(0);
  183.       default:
  184.     printf("%s: bad option (%c)\n",*opt);
  185.     break;
  186.     }
  187.     return(0);
  188. }
  189.  
  190. void warning (char * s, char * t)
  191. {
  192.   cerr << progname << ": " << s;
  193.   if (t) cerr << " " << t;
  194.   if (source_name) 
  195.     cerr << " near line " << lineno << " in sourced file: " << source_name;
  196.   cerr << "\n";
  197. }
  198.  
  199.  
  200. void execerror(char * s, char * t)
  201. {
  202.   warning(s,t);
  203.   longjmp(begin,0);
  204. }
  205.  
  206. SIG_PF fpecatch()        /* catch floating-point exceptions */
  207. {
  208.   execerror("floating point exceptions", (char *)0 );
  209.   return (SIG_PF)0;
  210. }
  211.  
  212.  
  213. /* 
  214. -*++ main(): The main interpreter loop for daims
  215. ** 
  216. ** (*++ history: 
  217. **      7 Dec 87    Bruce Eckel    Creation date
  218. ** ++*)
  219. ** 
  220. ** (*++ detailed: Sets up to catch control-C's, Floating-point exceptions (not
  221. ** functional yet) parses the command line switches and starts sourcing a file
  222. ** if one was requested on the command line.
  223. ** ++*)
  224. */
  225.  
  226. main(int argc, char *argv[])
  227. {
  228.   progname = argv[0];
  229.   int yreturn;
  230.   char * opt;
  231.   char **av = argv;
  232.   int ac = argc;
  233.   debug_f = ydebug_f = ldebug_f = 0;
  234.  
  235.   /* Parse the command line */
  236.   while (--ac > 0 && (*++av)[0] == '-') {
  237.     for (opt = av[0]+1; option(opt); opt++)
  238.       ;
  239.     cout << "option " << av[0] << "\n";
  240.   }
  241.  
  242.   if (argc > 1 && (*av)[0] != '-') {  source(av[0]); }
  243.   cout << "type \"help\" for help\n";
  244.   setjmp(begin);
  245. //  signal(SIGFPE, fpecatch);
  246.  
  247.  
  248.   do {
  249.     prompt();
  250.     if(debug_f) cerr << "entering yyparse()\n";
  251.     yreturn = yyparse();
  252.     if (trace_f) buf.erase();
  253.     if(debug_f) cerr << "leaving yyparse()\n";
  254.     if (debug_f) cerr << " yyparse returned " << yreturn << "\n";
  255.   } while (yreturn);
  256. }
  257.