home *** CD-ROM | disk | FTP | other *** search
- /*
- C* -- Token parsing routines (character routines) for the preprocessor.
-
- source: tok.c
- started: October 7, 1985
- version:
- January 6, 1987
- March 7, 1989
-
- PUBLIC DOMAIN SOFTWARE
-
- The CSTAR program was placed in the public domain on June 15, 1991,
- by its author and sole owner,
-
- Edward K. Ream
- 1617 Monroe Street
- Madison, WI 53711
- (608) 257-0802
-
- CSTAR may be used for any commercial or non-commercial purpose.
-
- See cstar.h or cstar.c for a DISCLAIMER OF WARRANTIES.
- */
- #include "cstar.h"
-
- /*
- Externally visible routines:
- */
- int t_number (void);
- void t_string (char * symbol);
- void t_comment (void);
- void t_id (char * symbol);
-
- /*
- Scan past a comment. Allow nested comments if nest_flag is TRUE.
- Surprisingly, this routine needs to be as fast as possible.
- */
- void
- t_comment(void)
- {
- register int clevel;
- int start_line;
- char line [LONG_DIGITS];
-
- TICK("t_comment");
-
- /* Save starting line number for run-on comments. */
- start_line = t_line;
- clevel = 1;
-
- for (;;) {
- switch (ch) {
-
- /* Don't read past end of file. */
- case END_FILE:
- goto runon;
-
- case '\n':
- /* Keep track of line numbering. */
- sysnext();
-
- /*
- Bump the line count and output a newline
- if this is used in a standalone preprocessor.
- Do NOT allow directives here.
- */
- do_nl();
- begin_line(FALSE);
- TRACEP("t_comment", printf("new line %d\n", t_line));
- continue;
-
- case '\r':
- sysnext();
- continue;
-
- case '/':
-
- sysnext();
- if (ch == '*') {
- sysnext();
- if (nest_flag) {
- clevel++;
- }
- }
- continue;
-
- case '*':
-
- sysnext();
- if (ch == '/') {
- sysnext();
- if (--clevel == 0) {
- return;
- }
- }
- continue;
-
-
- default:
- sysnext();
- }
- }
-
- runon:
- (void) conv2s(start_line, line);
- t_2error("File ends in a comment starting at line ", line);
- }
-
- /*
- Put an identifier into symbol[] and its length in the global t_length.
- Surprisingly, this routine should be as fast as possible.
- */
- void
- t_id(register char * symbol)
- {
- register int length;
- register char ch1;
-
- TICK("t_id");
-
- length = 0;
- while (ch1 = ch, isid2(ch1)) {
- *symbol++ = ch1;
- length++;
- sysnext();
- }
- *symbol = '\0';
- t_length = length;
- }
-
- /*
- Parse an integer constant (octal, decimal or hexadecimal).
- Put the value in t_value.
- Return the token type (INT_TYPE, LONG_TYPE).
-
- Legal forms: ddd, 0ddd, 0xddd
- */
- int
- t_number(void)
- {
- TICK("t_number");
-
- /* Defaults. */
- t_value = 0;
-
- /* Leading 0 or 0x changes base. */
- if (ch == '0') {
- sysnext();
- if (ch == 'x' || ch == 'X') {
- sysnext();
- scan_number(16);
- }
- else if (isdigit(ch)) {
- scan_number(8);
- }
- else {
- /* Lone '0'. */
- t_value = 0;
- }
- }
- else {
- scan_number(10);
- }
-
- if (ch == 'l' || ch == 'L') {
- sysnext();
- return LONG_TOK;
- }
- else {
- return INT_TOK;
- }
- }
-
- /*
- Put a string into symbol[] and its length in the global t_length.
-
- This is used to parse both strings and character constants.
- */
- void
- t_string(register char * symbol)
- {
- register char delim;
- register int length;
- int start_line;
- char msg [100];
- char line [10];
-
- TICK("t_string");
-
- /* Save starting line number for error messages. */
- start_line = t_line;
-
- /* Skip over the opening double quote */
- delim = ch;
- sysnext();
-
- length = 0;
- while (length < MAX_SYMBOL - 1) {
-
- TICK("t_string1");
-
- switch(ch) {
-
- case END_FILE:
- case '\n':
- goto runon1;
-
- case '\r':
- sysnext();
- continue;
-
- case '"':
- case '\'':
- if (ch == delim) {
- sysnext();
- *symbol++ = '\0';
- t_length = length;
- return;
- }
- else{
- *symbol++ = ch;
- length++;
- sysnext();
- }
- continue;
-
- case '\\':
-
- sysnext();
- if (ch == END_FILE) {
- goto runon1;
- }
- else if (skip_crlf()) {
- /* Ignore back slash and newline. */
- t_line++;
- }
- else {
- *symbol++ = '\\';
- *symbol++ = ch;
- length += 2;
- sysnext();
- }
- continue;
-
- default:
- *symbol++ = ch;
- length++;
- sysnext();
- }
- }
-
- conv2s(start_line, line);
- strcpy(msg, "String starting at line ");
- strcat(msg, line);
- strcat(msg, " is too long.");
- t_error(msg);
- *symbol = '\0';
- t_length = length;
- return;
-
- runon1:
- t_error("String crosses a line.");
- *symbol = '\0';
- t_length = length;
- }
-