4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
43 * This software is copyright(C) 1982 by Pavel Curtis
45 * Permission is granted to reproduce and distribute
46 * this file by any means so long as no fee is charged
47 * above a nominal handling fee and so long as this
48 * notice is always included in the copies.
50 * Other rights are reserved except as explicitly granted
51 * by written permission of the author.
53 * Computer Science Dept.
60 * Pavel.Cornell@Udel-Relay(ARPAnet)
61 * decvax!cornell!pavel(UUCPnet)
65 * comp_scan.c --- Lexical scanner for terminfo compiler.
67 * $Log: RCS/comp_scan.v $
68 * Revision 2.1 82/10/25 14:45:55 pavel
69 * Added Copyright Notice
71 * Revision 2.0 82/10/24 15:17:12 pavel
72 * Beta-one Test Release
74 * Revision 1.3 82/08/23 22:30:03 pavel
75 * The REAL Alpha-one Release Version
77 * Revision 1.2 82/08/19 19:10:06 pavel
78 * Alpha Test Release One
80 * Revision 1.1 82/08/12 18:37:46 pavel
91 #define iswhite(ch) (ch == ' ' || ch == '\t')
94 static int first_column
; /* See 'next_char()' below */
96 static void backspace(void);
97 void err_abort(char *fmt
, ...);
98 void syserr_abort(char *fmt
, ...);
99 void warning(char *fmt
, ...);
100 void reset_input(void);
101 void panic_mode(int);
109 * Scans the input for the next token, storing the specifics in the
110 * global structure 'curr_token' and returning one of the following:
112 * NAMES A line beginning in column 1. 'name'
113 * will be set to point to everything up to
114 * but not including the first comma on the line.
115 * BOOLEAN An entry consisting of a name followed by
116 * a comma. 'name' will be set to point to the
117 * name of the capability.
118 * NUMBER An entry of the form
120 * 'name' will be set to point to the capability
121 * name and 'valnumber' to the number given.
122 * STRING An entry of the form
124 * 'name' is set to the capability name and
125 * 'valstring' to the string of characters, with
126 * input translations done.
127 * CANCEL An entry of the form
129 * 'name' is set to the capability name and
131 * EOF The end of the file has been reached.
141 static char buffer
[1024];
143 int dot_flag
= FALSE
;
147 } while (ch
== '\n' || (isascii(ch
) && iswhite(ch
)));
156 } while (ch
== ' ' || ch
== '\t');
159 if (! isascii(ch
) || ! isalnum(ch
)) {
160 warning("Illegal character - '%c'", ch
);
170 while (ch
!= ',' && ch
!= '\n' && ch
!= EOF
) {
176 err_abort("Premature EOF");
177 else if (ch
== '\n') {
178 warning("Newline in middle of terminal name");
183 curr_token
.tk_name
= buffer
;
187 while (isascii(ch
) && isalnum(ch
)) {
195 curr_token
.tk_name
= buffer
;
200 if (next_char() != ',')
201 warning("Missing comma");
202 curr_token
.tk_name
= buffer
;
208 if ((ch
= next_char()) == ',')
209 warning("Missing numeric value");
211 if ((ch
= next_char()) == '0') {
212 if ((ch
= next_char()) == 'x' ||
215 while (isascii(ch
) &&
221 else if (ch
>= 'a' &&
233 while (ch
>= '0' && ch
<= '7') {
242 while (isascii(ch
) && isdigit(ch
)) {
243 number
= number
* 10 + ch
- '0';
248 warning("Missing comma");
249 curr_token
.tk_name
= buffer
;
250 curr_token
.tk_valnumber
= number
;
255 ch
= trans_string(ptr
);
256 if (ch
!= '\0' && ch
!= ',')
257 warning("Missing comma");
259 warning("NULL string value");
260 curr_token
.tk_name
= buffer
;
261 curr_token
.tk_valstring
= ptr
;
266 warning("Illegal character - '%c'", ch
);
268 } /* end else (first_column == FALSE) */
269 } /* end else (ch != EOF) */
271 if (dot_flag
== TRUE
)
272 DEBUG(8, "Commented out ", "");
274 if (debug_level
>= 8) {
275 fprintf(stderr
, "Token: ");
278 fprintf(stderr
, "Boolean; name='%s'\n",
283 fprintf(stderr
, "Number; name = '%s', value = %d\n",
284 curr_token
.tk_name
, curr_token
.tk_valnumber
);
288 fprintf(stderr
, "String; name = '%s', value = '%s'\n",
289 curr_token
.tk_name
, curr_token
.tk_valstring
);
293 fprintf(stderr
, "Cancel; name = '%s'\n",
298 fprintf(stderr
, "Names; value = '%s'\n",
303 fprintf(stderr
, "End of file\n");
307 warning("Bad token type");
311 if (dot_flag
== TRUE
) /* if commented out, use the next one */
323 * Returns the next character in the input stream. Comments and leading
324 * white space are stripped. The global state variable 'firstcolumn' is
325 * set TRUE if the character returned is from the first column of the
326 * inputline. The global variable curr_line is incremented for each new.
327 * line. The global variable curr_file_pos is set to the file offset
328 * of the beginning of each line.
332 int curr_column
= -1;
338 /* LINTED E_FUNC_SET_NOT_USED */
342 if (curr_column
< 0 || curr_column
> 1023 ||
343 line
[curr_column
] == '\0') {
345 curr_file_pos
= ftell(stdin
);
347 if ((rtn_value
= fgets(line
, 1024, stdin
)) == NULL
)
351 while (*p
&& iswhite(*p
)) {
357 while (isascii(line
[curr_column
]) && iswhite(line
[curr_column
]))
361 if (curr_column
== 0 && line
[0] != '\n')
364 first_column
= FALSE
;
366 return (line
[curr_column
++]);
376 syserr_abort("Backspaced off beginning of line");
384 * Resets the input-reading routines. Used after a seek has been done.
400 * Reads characters using next_char() until encountering a comma, a new
401 * entry, or end-of-file. The returned value is the character which
402 * caused reading to stop. The following translations are done on the
405 * ^X goes to ctrl-X (i.e. X & 037)
406 * {\E,\n,\r,\b,\t,\f} go to
407 * {ESCAPE,newline,carriage-return,backspace,tab,formfeed}
408 * {\^,\\} go to {carat,backslash}
409 * \ddd (for ddd = up to three octal digits) goes to
418 trans_string(char *ptr
)
420 register int count
= 0;
425 while ((ch
= next_char()) != ',' && ch
!= EOF
&& !first_column
) {
429 err_abort("Premature EOF");
431 if (!isascii(ch
) || ! isprint(ch
)) {
432 warning("Illegal ^ character - '%c'", ch
);
436 *(ptr
++) = (char)0200;
439 } else if (ch
== '\\') {
442 err_abort("Premature EOF");
444 if (ch
>= '0' && ch
<= '7') {
446 for (i
= 0; i
< 2; i
++) {
449 err_abort("Premature EOF");
451 if (ch
< '0' || ch
> '7') {
456 number
= number
* 8 + ch
- '0';
461 *(ptr
++) = (char)number
;
465 case 'e': *(ptr
++) = '\033'; break;
468 case 'n': *(ptr
++) = '\n'; break;
470 case 'r': *(ptr
++) = '\r'; break;
472 case 'b': *(ptr
++) = '\010'; break;
474 case 's': *(ptr
++) = ' '; break;
476 case 'f': *(ptr
++) = '\014'; break;
478 case 't': *(ptr
++) = '\t'; break;
480 case '\\': *(ptr
++) = '\\'; break;
482 case '^': *(ptr
++) = '^'; break;
484 case ',': *(ptr
++) = ','; break;
486 case ':': *(ptr
++) = ':'; break;
489 warning("Illegal character in \\"
493 } /* endswitch (ch) */
494 } /* endelse (ch < '0' || ch > '7') */
495 } /* end else if (ch == '\\') */
497 if (ch
!= '\n') *(ptr
++) = ch
;
503 warning("Very long string found. Missing comma?");
507 warning("Premature EOF - missing comma?");
508 /* start of new description */
509 else if (first_column
) {
511 warning("Missing comma?");
512 /* pretend we did get a comma */
524 * Panic mode error recovery - skip everything until a "ch" is found.