home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_300
/
357_01
/
cstar1.exe
/
TOK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-18
|
4KB
|
266 lines
/*
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;
}