2 /********************************************
4 copyright 1991, 1992 Michael D. Brennan
6 This is a source file for mawk, an implementation of
7 the AWK programming language.
9 Mawk is distributed without warranty under the terms of
10 the GNU General Public License, version 2, 1991.
11 ********************************************/
15 * Revision 1.6 1995/06/06 00:18:22 mike
16 * change mawk_exit(1) to mawk_exit(2)
18 * Revision 1.5 1994/12/13 00:26:33 mike
19 * rt_nr and rt_fnr for run-time error messages
21 * Revision 1.4 1994/09/23 00:20:00 mike
22 * minor bug fix: handle \ in eat_nl()
24 * Revision 1.3 1993/07/17 13:22:49 mike
25 * indent and general code cleanup
27 * Revision 1.2 1993/07/04 12:51:44 mike
28 * start on autoconfig changes
30 * Revision 1.1.1.1 1993/07/03 18:58:11 mike
33 * Revision 5.3 1993/01/22 14:55:46 mike
34 * trivial change for unexpected_char()
36 * Revision 5.2 1992/10/02 23:26:04 mike
39 * Revision 5.1 1991/12/05 07:55:48 brennan
55 static void PROTO( rt_where, (void) ) ;
56 static void PROTO( missing, (int, char *, int) ) ;
57 static char *PROTO( type_to_str, (int) ) ;
61 #define vfprintf simple_vfprintf
65 /* for run time error messages only */
66 unsigned rt_nr , rt_fnr ;
68 static struct token_str {
70 char *str ; } token_str[] = {
71 {EOF , "end of file" },
76 {SC_FAKE_SEMI_COLON, "}"},
107 {INC_or_DEC , string_buff },
108 {DOUBLE , string_buff },
109 {STRING_ , string_buff },
111 {FUNCT_ID , string_buff },
112 {BUILTIN , string_buff },
113 {IO_OUT , string_buff },
120 /* if paren_cnt >0 and we see one of these, we are missing a ')' */
121 static int missing_rparen[] =
122 { EOF, NL, SEMI_COLON, SC_FAKE_SEMI_COLON, RBRACE, 0 } ;
125 static int missing_rbrace[] =
126 { EOF, BEGIN, END , 0 } ;
128 static void missing( c, n , ln)
135 { s0 = pfile_name ; s1 = ": " ; }
138 errmsg(0, "%s%sline %u: missing %c near %s" ,s0, s1, ln, c, n) ;
142 char *s ; /* we won't use s as input
143 (yacc and bison force this).
144 We will use s for storage to keep lint or the compiler
146 { struct token_str *p ;
151 for ( p = token_str ; p->token ; p++ )
152 if ( current_token == p->token )
153 { s = p->str ; break ; }
155 if ( ! s ) /* search the keywords */
156 s = find_kw_str(current_token) ;
161 for( ip = missing_rparen ; *ip ; ip++)
162 if ( *ip == current_token )
163 { missing(')', s, token_lineno) ;
169 for( ip = missing_rbrace ; *ip ; ip++)
170 if ( *ip == current_token )
171 { missing('}', s, token_lineno) ;
176 compile_error("syntax error at or near %s", s) ;
179 else /* special cases */
180 switch ( current_token )
188 "syntax error in decimal constant %s",
194 "syntax error at or near /%s/",
199 compile_error("syntax error") ;
205 if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(2) ;
209 /* generic error message with a hook into the system error
210 messages if errnum > 0 */
212 void errmsg VA_ALIST2(int , errnum, char *, format)
215 fprintf(stderr, "%s: " , progname) ;
217 VA_START2(args, int, errnum, char *, format) ;
218 vfprintf(stderr, format, args) ;
221 if ( errnum > 0 ) fprintf(stderr, " (%s)" , strerror(errnum) ) ;
223 fprintf( stderr, "\n") ;
226 void compile_error VA_ALIST(char *, format)
230 /* with multiple program files put program name in
233 { s0 = pfile_name ; s1 = ": " ; }
237 fprintf(stderr, "%s: %s%sline %u: " , progname, s0, s1,token_lineno) ;
238 VA_START(args, char *, format) ;
239 vfprintf(stderr, format, args) ;
241 fprintf(stderr, "\n") ;
242 if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(2) ;
245 void rt_error VA_ALIST( char *, format)
248 fprintf(stderr, "%s: run time error: " , progname ) ;
249 VA_START(args, char *, format) ;
250 vfprintf(stderr, format, args) ;
261 errmsg(0, "bozo: %s" , s) ;
265 void overflow(s, size)
266 char *s ; unsigned size ;
268 errmsg(0 , "program limit exceeded: %s size=%u", s, size) ;
273 /* print as much as we know about where a rt error occured */
275 static void rt_where()
277 if ( FILENAME->type != C_STRING ) cast1_to_s(FILENAME) ;
279 fprintf(stderr, "\tFILENAME=\"%s\" FNR=%u NR=%u\n",
280 string(FILENAME)->str, rt_fnr, rt_nr) ;
284 void rt_overflow(s, size)
285 char *s ; unsigned size ;
287 errmsg(0 , "program limit exceeded: %s size=%u", s, size) ;
294 { int c = yylval.ival ;
296 fprintf(stderr, "%s: %u: ", progname, token_lineno) ;
297 if ( c > ' ' && c < 127 )
298 fprintf(stderr, "unexpected character '%c'\n" , c) ;
300 fprintf(stderr, "unexpected character 0x%02x\n" , c) ;
303 static char *type_to_str( type )
309 case ST_VAR : retval = "variable" ; break ;
310 case ST_ARRAY : retval = "array" ; break ;
311 case ST_FUNCT : retval = "function" ; break ;
312 case ST_LOCAL_VAR : retval = "local variable" ; break ;
313 case ST_LOCAL_ARRAY : retval = "local array" ; break ;
314 default : bozo("type_to_str") ;
319 /* emit an error message about a type clash */
322 { compile_error("illegal reference to %s %s",
323 type_to_str(p->type) , p->name) ;
330 /* a minimal vfprintf */
331 int simple_vfprintf( fp, format, argp)
347 putc(*q, fp) ; q++ ; continue ;
350 /* mark the start with p */
351 p = ++q ; t = xbuff + 1 ;
353 if ( *q == '-' ) *t++ = *q++ ;
354 while ( scan_code[*(unsigned char*)q] == SC_DIGIT ) *t++ = *q++ ;
357 while ( scan_code[*(unsigned char*)q] == SC_DIGIT ) *t++ = *q++ ;
360 if ( *q == 'l' ) { l_flag = 1 ; *t++ = *q++ ; }
364 *t = *q++ ; t[1] = 0 ;
373 if ( l_flag ) fprintf(fp, xbuff, va_arg(argp,long) ) ;
374 else fprintf(fp, xbuff, va_arg(argp, int)) ;
378 fprintf(fp, xbuff, va_arg(argp, char*)) ;
383 fprintf(fp, xbuff, va_arg(argp, double)) ;
392 return 0 ; /* shut up */
395 #endif /* USE_SIMPLE_VFPRINTF */