% Copyright (c) 1991: Marcel Roelofs and Peter Gragert % University of Twente, Enschede, The Netherlands % @@(#) rtangle.ch (91/03/11) @x @u @@; @@; @@; @@; @y @u #define NEWLINES_IN_MACROS @@; @@; @@; @@; @z @x if (isdigit(c) || c=='\\' || c=='.') @@;/*spider*/ else if (isalpha(c) || c=='_' || c=='$') @@;/*spider*/ else if (c=='\'' || c=='\"') @@;/*spider*/ @y if (isdigit(c)) @@;/*spider*/ else if (isalpha(c) || c=='_' || c=='!') @@;/*spider*/ else if (c=='\"') @@;/*spider*/ @z @x @ @= {/*spider*/ id_first=--loc; while (isalpha(*++loc) || isdigit(*loc) || *loc=='_'); if (*loc=='$') while (isdigit(*++loc)||*loc=='$'); /* make room for \$\$ and \$nnn suffixes */ id_loc=loc; return(identifier); } @y @ @= {/*spider*/ id_first=--loc; if (c=='!') ++loc; while (isalpha(*++loc) || isdigit(*loc) || *loc=='_' || *loc=='!') if (*loc=='!') ++loc; id_loc=loc; return(identifier); } @z @x @ \cee\ strings and character constants, delimited by double and single quotes, respectively, can contain newlines or instances of their own delimiters if they are protected by a backslash. We follow this convention, but do not allow the string to be longer than |longest_name|. @= {/*spider*/ ASCII delim = c; /* what started the string */ @# /* if it's not a single-character literal, it's a tick mark or an |at_sign| */ if (delim=='\'' && (loc+1>=limit || (*loc != '\\' && *loc!=at_sign && loc[1]!='\'') || (*loc=='\\' && (loc+2>=limit||loc[2]!='\'')) || (*loc==at_sign && (loc+2>=limit||loc[1]!=at_sign||loc[2]!='\'')) )) goto mistake; id_first = mod_text+1; id_loc = mod_text; *++id_loc=delim; while (1) { if (loc>=limit) { if(*(limit-1)!='\\') { err_print("! String didn't end"); loc=limit; break; @.String didn't end@> } if(get_line()==0) { err_print("! Input ended in middle of string"); loc=buffer; break; @.Input ended in middle of string@> } else if (++id_loc<=mod_text_end) *id_loc=@`\n'; /* will print as \.{"\\\\\\n"} */ } if ((c=*loc++)==delim) { if (++id_loc<=mod_text_end) *id_loc=c; break; } if (c=='\\') { if (loc>=limit) continue; if (++id_loc<=mod_text_end) *id_loc = '\\'; c=*loc++; } if (++id_loc<=mod_text_end) *id_loc=c; } if (id_loc>=mod_text_end) { printf("\n! String too long: "); @.String too long@> ASCII_write(mod_text+1,25); printf("..."); mark_error; } id_loc++; return(string); } @y @ \cee\ strings are delimited by double quotes and must be restricted to one line. Double quotes in strings must be doubled and we allow no string to be longer than |longest_name|. @= {/*spider*/ ASCII delim = c; /* what started the string */ @# id_first = mod_text+1; id_loc = mod_text; *++id_loc=delim; while (1) { if (loc>=limit) { err_print("! String didn't end"); loc=limit; @.String didn't end@> if (get_line()==0) { err_print("! Input ended in middle of string"); loc=buffer; @.Input ended in middle of string@> } break; } if ((c=*loc++)==delim) { if (++id_loc<=mod_text_end) *id_loc=c; if (*loc==delim) loc++; else break; } if (++id_loc<=mod_text_end) *id_loc=c; } if (id_loc>=mod_text_end) { printf("\n! String too long: "); @.String too long@> ASCII_write(mod_text+1,25); printf("..."); mark_error; } id_loc++; return(string); } @z