home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / m / mawk11as.zip / ERROR.C < prev    next >
C/C++ Source or Header  |  1991-12-18  |  8KB  |  370 lines

  1.  
  2. /********************************************
  3. error.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13.  
  14. /* $Log:    error.c,v $
  15.  * Revision 5.1  91/12/05  07:55:48  brennan
  16.  * 1.1 pre-release
  17.  * 
  18. */
  19.  
  20.  
  21. #include  "mawk.h"
  22. #include  "scan.h"
  23. #include  "bi_vars.h"
  24.  
  25. #ifndef  EOF
  26. #define  EOF  (-1)
  27. #endif
  28.  
  29. /* statics */
  30. static void  PROTO( rt_where, (void) ) ;
  31. static void  PROTO( unexpected_char, (void) ) ;
  32. static void  PROTO( missing, (int, char *, int) ) ;
  33. static char *PROTO( type_to_str, (int) ) ;
  34.  
  35. extern int NR_flag ; /* on if tracking NR */
  36.  
  37.  
  38. static struct token_str  {
  39. short token ;
  40. char *str ; }  token_str[] = {
  41. EOF , "end of file" ,
  42. NL , "end of line",
  43. SEMI_COLON , ";" ,
  44. LBRACE , "{" ,
  45. RBRACE , "}" ,
  46. SC_FAKE_SEMI_COLON, "}",
  47. LPAREN , "(" ,
  48. RPAREN , ")" ,
  49. LBOX , "[",
  50. RBOX , "]",
  51. QMARK , "?",
  52. COLON , ":",
  53. OR, "||",
  54. AND, "&&",
  55. ASSIGN , "=" ,
  56. ADD_ASG, "+=",
  57. SUB_ASG, "-=",
  58. MUL_ASG, "*=",
  59. DIV_ASG, "/=",
  60. MOD_ASG, "%=",
  61. POW_ASG, "^=",
  62. EQ  , "==" ,
  63. NEQ , "!=",
  64. LT, "<" ,
  65. LTE, "<=" ,
  66. GT, ">",
  67. GTE, ">=" ,
  68. MATCH, string_buff,
  69. PLUS , "+" ,
  70. MINUS, "-" ,
  71. MUL , "*" ,
  72. DIV, "/"  , 
  73. MOD, "%" ,
  74. POW, "^" ,
  75. NOT, "!" ,
  76. COMMA, "," ,
  77. INC_or_DEC , string_buff ,
  78. DOUBLE  , string_buff ,
  79. STRING_  , string_buff ,
  80. ID  , string_buff ,
  81. FUNCT_ID  , string_buff ,
  82. BUILTIN  , string_buff ,
  83. IO_OUT , string_buff ,
  84. IO_IN, "<" ,
  85. PIPE, "|" ,
  86. DOLLAR, "$" ,
  87. FIELD, "$" ,
  88. 0, (char *) 0 } ;
  89.  
  90. /* if paren_cnt >0 and we see one of these, we are missing a ')' */
  91. static int missing_rparen[] =
  92. { EOF, NL, SEMI_COLON, SC_FAKE_SEMI_COLON, RBRACE, 0 } ;
  93.  
  94. /* ditto for '}' */
  95. static int missing_rbrace[] =
  96. { EOF, BEGIN, END , 0 } ;
  97.  
  98. static void missing( c, n , ln)
  99.   int c ;
  100.   char *n ;
  101.   int ln ;
  102. { char *s0, *s1 ;
  103.  
  104.   if ( pfile_name )
  105.   { s0 = pfile_name ; s1 = ": " ; }
  106.   else s0 = s1 = "" ;
  107.  
  108.   errmsg(0, "%s%sline %u: missing %c near %s" ,s0, s1, ln, c, n) ; 
  109. }  
  110.  
  111. void  yyerror(s)
  112.   char *s ; /* we won't use s as input 
  113.   (yacc and bison force this).
  114.   We will use s for storage to keep lint or the compiler
  115.   off our back */
  116. { struct token_str *p ;
  117.   int *ip ;
  118.  
  119.   s = (char *) 0 ;
  120.  
  121.   for ( p = token_str ; p->token ; p++ )
  122.       if ( current_token == p->token )
  123.       { s = p->str ; break ; }
  124.  
  125.   if ( ! s )  /* search the keywords */
  126.          s = find_kw_str(current_token) ;
  127.  
  128.   if ( s )
  129.   {
  130.     if ( paren_cnt )
  131.         for( ip = missing_rparen ; *ip ; ip++)
  132.           if ( *ip == current_token )
  133.           { missing(')', s, token_lineno) ;
  134.             paren_cnt = 0 ;
  135.             goto done ;
  136.           }
  137.  
  138.     if ( brace_cnt )
  139.         for( ip = missing_rbrace ; *ip ; ip++)
  140.           if ( *ip == current_token )
  141.           { missing('}', s, token_lineno) ;
  142.             brace_cnt = 0 ;
  143.             goto done ;
  144.           }
  145.  
  146.     compile_error("syntax error at or near %s", s) ;
  147.  
  148.   }
  149.   else  /* special cases */
  150.   switch ( current_token )
  151.   {
  152.     case UNEXPECTED :
  153.             unexpected_char() ; 
  154.             goto done ;
  155.  
  156.     case BAD_DECIMAL :
  157.             compile_error(
  158.               "syntax error in decimal constant %s",
  159.               string_buff ) ;
  160.             break ;
  161.  
  162.     case RE :
  163.             compile_error(
  164.             "syntax error at or near /%s/", 
  165.             string_buff ) ;
  166.             break ;
  167.  
  168.     default :
  169.             compile_error("syntax error") ;
  170.             break ;
  171.   }
  172.   return ;
  173.  
  174. done :
  175.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  176. }
  177.  
  178. /* system provided errnos and messages */
  179. #ifndef MSDOS_MSC       /* don't need the declarations */
  180. #ifndef THINK_C         /* don't WANT the declarations */
  181. extern int sys_nerr ;
  182. extern char *sys_errlist[] ;
  183. #endif
  184. #endif
  185.  
  186. #if  HAVE_STDARG_H
  187. #include <stdarg.h>
  188.  
  189. /* generic error message with a hook into the system error 
  190.    messages if errnum > 0 */
  191.  
  192. void  errmsg(int errnum, char *format, ...)
  193. { va_list args ;
  194.  
  195.   fprintf(stderr, "%s: " , progname) ;
  196.   va_start(args, format) ;
  197.   (void) vfprintf(stderr, format, args) ;
  198.   va_end(args) ;
  199. #ifdef THINK_C
  200.   if ( errnum > 0 )
  201.     fprintf(stderr, " (%s)" , strerror(errnum) ) ;
  202. #else
  203.   if ( errnum > 0 && errnum < sys_nerr )
  204.     fprintf(stderr, " (%s)" , sys_errlist[errnum]) ;
  205. #endif
  206.   fprintf( stderr, "\n") ;
  207. }
  208.  
  209. void  compile_error(char *format, ...)
  210. { va_list args ;
  211.   char *s0, *s1 ;
  212.  
  213.   /* with multiple program files put program name in
  214.      error message */
  215.   if ( pfile_name )
  216.   { s0 = pfile_name ; s1 = ": " ; }
  217.   else
  218.   { s0 = s1 = "" ; }
  219.  
  220.   fprintf(stderr, "%s: %s%sline %u: " , progname, s0, s1,token_lineno) ;
  221.   va_start(args, format) ;
  222.   vfprintf(stderr, format, args) ;
  223.   va_end(args) ;
  224.   fprintf(stderr, "\n") ;
  225.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  226. }
  227.  
  228. void  rt_error( char *format, ...)
  229. { va_list args ;
  230.  
  231.   fprintf(stderr, "%s: run time error: " , progname ) ;
  232.   va_start(args, format) ;
  233.   vfprintf(stderr, format, args) ;
  234.   va_end(args) ;
  235.   putc('\n',stderr) ;
  236.   rt_where() ;
  237.   mawk_exit(1) ;
  238. }
  239.  
  240. #else
  241.  
  242. #include <varargs.h>
  243.  
  244. /*  void errmsg(errnum, format, ...) */
  245.  
  246. void  errmsg( va_alist)
  247.   va_dcl
  248. { va_list ap ;
  249.   int errnum ;
  250.   char *format ;
  251.  
  252.   fprintf(stderr, "%s: " , progname) ;
  253.   va_start(ap) ;
  254.   errnum = va_arg(ap, int) ;
  255.   format = va_arg(ap, char *) ;
  256.   (void) vfprintf(stderr, format, ap) ;
  257. #ifdef THINK_C
  258.   if ( errnum > 0 )
  259.     fprintf(stderr, " (%s)" , strerror(errnum) ) ;
  260. #else
  261.   if ( errnum > 0 && errnum < sys_nerr )
  262.     fprintf(stderr, " (%s)" , sys_errlist[errnum]) ;
  263. #endif
  264.   fprintf( stderr, "\n") ;
  265. }
  266.  
  267. void compile_error( va_alist )
  268.   va_dcl
  269. { va_list args ;
  270.   char *format ;
  271.   char *s0, *s1 ;
  272.  
  273.   if ( pfile_name ) /* print program filename too */
  274.   { s0 = pfile_name ; s1 = ": " ; }
  275.   else s0 = s1 = "" ;
  276.  
  277.   fprintf(stderr, "%s: %s%sline %u: " , progname, s0, s1,token_lineno) ;
  278.   va_start(args) ;
  279.   format = va_arg(args, char *) ;
  280.   vfprintf(stderr, format, args) ;
  281.   va_end(args) ;
  282.   fprintf(stderr, "\n") ;
  283.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  284. }
  285.  
  286. void  rt_error( va_alist )
  287.   va_dcl
  288. { va_list args ;
  289.   char *format ;
  290.  
  291.   fprintf(stderr, "%s: run time error: " , progname ) ;
  292.   va_start(args) ;
  293.   format = va_arg(args, char *) ;
  294.   vfprintf(stderr, format, args) ;
  295.   va_end(args) ;
  296.   putc('\n',stderr) ;
  297.   rt_where() ;
  298.   mawk_exit(1) ;
  299. }
  300.  
  301. #endif
  302.  
  303. void bozo(s)
  304.   char *s ;
  305. { errmsg(0, "bozo: %s" , s) ; mawk_exit(1) ; }
  306.  
  307. void overflow(s, size)
  308.   char *s ; unsigned size ;
  309. { errmsg(0 , "program limit exceeded: %s size=%u", s, size) ;
  310.   mawk_exit(1) ; }
  311.  
  312.  
  313. /* print as much as we know about where a rt error occured */
  314.  
  315. static void rt_where()
  316. {
  317.   if ( FILENAME->type != C_STRING ) cast1_to_s(FILENAME) ;
  318.   if ( TEST2(NR) != TWO_DOUBLES ) cast2_to_d(NR) ;
  319.  
  320.   fprintf(stderr, "\tFILENAME=\"%s\"", string(FILENAME)->str) ;
  321.   if ( NR_flag ) 
  322.       fprintf(stderr, " FNR=%g NR=%g" , FNR->dval, NR->dval) ;
  323.  
  324.   fprintf(stderr, "\n") ;
  325. }
  326.  
  327. /* run time */
  328. void rt_overflow(s, size)
  329.   char *s ; unsigned size ;
  330.   errmsg(0 , "program limit exceeded: %s size=%u", s, size) ;
  331.   rt_where() ;
  332.   mawk_exit(1) ;
  333. }
  334.  
  335. static void unexpected_char()
  336. { int c = yylval.ival ;
  337.  
  338.   fprintf(stderr, "%s: %u: ", progname, token_lineno) ;
  339.   if ( c > ' ')
  340.       fprintf(stderr, "unexpected character '%c'\n" , c) ;
  341.   else
  342.       fprintf(stderr, "unexpected character 0x%02x\n" , c) ;
  343. }
  344.  
  345. static char *type_to_str( type )
  346.   int type ;
  347. { char *retval ;
  348.  
  349.   switch( type )
  350.   {
  351.     case  ST_VAR :  retval = "variable" ; break ;
  352.     case  ST_ARRAY :  retval = "array" ; break ;
  353.     case  ST_FUNCT :  retval = "function" ; break ;
  354.     case  ST_LOCAL_VAR : retval = "local variable" ; break ;
  355.     case  ST_LOCAL_ARRAY : retval = "local array" ; break ;
  356.     default : bozo("type_to_str") ;
  357.   }
  358.   return retval ;
  359. }
  360.  
  361. /* emit an error message about a type clash */
  362. void type_error(p)
  363.   SYMTAB *p ;
  364. { compile_error("illegal reference to %s %s", 
  365.     type_to_str(p->type) , p->name) ;
  366. }
  367.  
  368.  
  369.