STATIC TOKEN_T lexDotName( void ) /******************************** * Given that the last character was a DOT, input the maximum string * possible, and check if it is a TOK_DOTNAME, TOK_SUF, or TOK_SUFSUF * Special cases to look for: "."{dirc}; ".."{dirc}; ".."{extc}+; * and "."{extc}+"." * recognizes: * "."{extc}* TOK_SUF * "."{extc}*"."{extc}* TOK_SUFSUF * "{"path"}""."{extc}*"{"path"}""."{extc} TOK_SUFSUF * "."{dot-name} TOK_DOTNAME * "."{dirc} passes to lexFileName() * ".."{dirc} passes to lexFileName() */ { char ext[MAX_SUFFIX]; unsigned pos; STRM_T s; STRM_T s2; TOKEN_T ret; pos = 0; if( *targ_path != NULLCHAR ) { FreeSafe( targ_path ); targ_path = ""; } if( *dep_path != NULLCHAR ) { FreeSafe( dep_path ); dep_path = ""; } dep_path = getCurlPath(); s = PreGetCH(); if( s != DOT ) { PrtMsg( ERR | LOC | INVALID_SUFSUF ); return( TOK_NULL ); } else { ext[pos++] = DOT; s = PreGetCH(); } if( isdirc( s ) || s == PATH_SPLIT || s == ';' ) { // check for "."{dirc} UnGetCH( s ); if( *dep_path != NULLCHAR ) { PrtMsg( ERR | LOC | INVALID_SUFSUF ); } return( lexFileName( DOT ) ); } if( s == DOT ) { /* check if ".."{extc} or ".."{dirc} */ s2 = PreGetCH(); /* probe one character */ UnGetCH( s2 ); if( isdirc( s2 ) || s2 == PATH_SPLIT || s2 == ';' ) { // is ".."{dirc} UnGetCH( s ); if( *dep_path != NULLCHAR ) { PrtMsg( ERR | LOC | INVALID_SUFSUF ); } return( lexFileName( DOT ) ); } } else { /* get string {extc}+ */ while( pos < MAX_SUFFIX && isextc( s ) && s != L_CURL_PAREN ) { ext[pos++] = s; s = PreGetCH(); } if( pos == MAX_SUFFIX ) { PrtMsgExit(( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_SUFFIX - 1 )); } ext[pos] = NULLCHAR; } UnGetCH( s ); targ_path = getCurlPath(); s = PreGetCH(); /* next char */ if( s == DOT ) { /* maybe of form "."{extc}*"."{extc}* */ ext[pos++] = s; for( s = PreGetCH(); pos < MAX_SUFFIX && isextc( s ); s = PreGetCH() ) { ext[pos++] = s; } if( pos == MAX_SUFFIX ) { PrtMsgExit(( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_SUFFIX - 1 )); //NOTREACHED } ext[pos] = NULLCHAR; ret = TOK_SUFSUF; } else { if( *targ_path != NULLCHAR && *dep_path != NULLCHAR ) { PrtMsg( ERR | LOC | INVALID_SUFSUF ); } ret = TOK_SUF; } UnGetCH( s ); /* put back what we don't need */ if( *targ_path != NULLCHAR && *dep_path != NULLCHAR && ret == TOK_SUF ) { PrtMsg( ERR | LOC | INVALID_SUFSUF ); } else if( ret == TOK_SUF && checkDotName( ext ) ) { return( TOK_DOTNAME ); } CurAttr.u.ptr = StrDupSafe( ext ); return( ret ); }
TOKEN_T LexParser( STRM_T s ) /************************************ * returns: next token for parser * remarks: possibly defines a macro */ { static BOOLEAN atstart = TRUE; char *p; for( ;; ) { if( atstart ) { /* atstart == TRUE if either of these succeed */ if( isws( s ) ) { /* cmd line */ return( lexCmd() ); } if( ismacc( s ) && checkMacro( s ) ) { /* check if macro = body */ s = PreGetCH(); continue; } atstart = FALSE; UnGetCH( s ); /* put back our probe */ s = STRM_MAGIC; /* force macro expansion */ } switch( s ) { case STRM_END: atstart = TRUE; return( TOK_END ); case EOL: atstart = TRUE; return( TOK_EOL ); case STRM_TMP_LEX_START: case STRM_MAGIC: p = DeMacroDoubleQuote( FALSE ); /* expand to next white space */ if( *p == NULLCHAR ) { /* already at ws */ FreeSafe( p ); s = PreGetCH(); /* eat the ws */ while( isws( s ) ) { s = PreGetCH(); } if( s == EOL ) { atstart = TRUE; return( TOK_EOL ); } if( s == STRM_END ) { atstart = TRUE; return( TOK_END ); } UnGetCH( s ); p = DeMacroDoubleQuote( FALSE ); } UnGetCH( STRM_MAGIC ); /* mark spot we have to expand from nxt */ InsString( p, TRUE ); /* put expansion in stream */ break; case SPACE: /* fall through */ case TAB: break; case L_CURL_PAREN: /* could only be a sufsuf */ case DOT: UnGetCH( s ); return( lexDotName() ); /* could be a file... */ case SEMI: /* treat semi-colon as {nl}{ws} */ InsString( "\n ", FALSE ); break; /* try again */ case COLON: s = PreGetCH(); if( s == COLON ) { return( TOK_DCOLON ); } UnGetCH( s ); return( TOK_SCOLON ); default: if( isfilec( s ) || s == DOUBLEQUOTE || ( (Glob.compat_nmake || Glob.compat_posix) && s == SPECIAL_TMP_DOL_C ) ) { return( lexFileName( s ) ); } PrtMsg( WRN | LOC | UNKNOWN_TOKEN, s ); break; } s = PreGetCH(); /* fetch a character */ } }
TOKEN_T LexParser( STRM_T s ) /************************************ * returns: next token for parser * remarks: possibly defines a macro */ { static bool atstart = true; char *p; for( ;; ) { if( atstart ) { /* atstart == true if either of these succeed */ if( sisws( s ) ) { /* cmd line */ return( lexCmd() ); } if( sismacc( s ) && checkMacro( s ) ) { /* check if macro = body */ s = PreGetCHR(); continue; } atstart = false; UnGetCHR( s ); /* put back our probe */ s = STRM_MAGIC; /* force macro expansion */ } switch( s ) { case STRM_END: atstart = true; return( TOK_END ); case '\n': atstart = true; return( TOK_EOL ); case STRM_TMP_LEX_START: case STRM_MAGIC: p = DeMacroDoubleQuote( false ); /* expand to next white space */ if( *p == NULLCHAR ) { /* already at ws */ FreeSafe( p ); s = PreGetCHR(); /* eat the ws */ while( sisws( s ) ) { s = PreGetCHR(); } if( s == '\n' ) { atstart = true; return( TOK_EOL ); } if( s == STRM_END ) { atstart = true; return( TOK_END ); } UnGetCHR( s ); p = DeMacroDoubleQuote( false ); } UnGetCHR( STRM_MAGIC ); /* mark spot we have to expand from nxt */ InsString( p, true ); /* put expansion in stream */ break; case ' ': case '\t': break; case '{': /* could only be a sufsuf */ case '.': UnGetCHR( s ); return( lexDotName() ); /* could be a file... */ case ';': /* treat semi-colon as {nl}{ws} */ InsString( "\n ", false ); break; /* try again */ case ':': s = PreGetCHR(); if( s == ':' ) { return( TOK_DCOLON ); } UnGetCHR( s ); return( TOK_SCOLON ); default: if( sisfilec( s ) || s == '\"' || ( (Glob.compat_nmake || Glob.compat_posix) && s == SPECIAL_TMP_DOLLAR ) ) { return( lexFileName( s ) ); } PrtMsg( WRN | LOC | UNKNOWN_TOKEN, s ); break; } s = PreGetCHR(); /* fetch a character */ } }