local void GrabTokens( int parm_cnt, struct macro_parm *formal_parms, const char *mac_name, source_loc *loc ) { MEPTR mentry; int i; int j; TOKEN prev_token; int prev_non_ws_token; unsigned mlen; macro_flags mflags; TOKEN *p_token; mentry = CreateMEntry( mac_name ); mflags = MFLAG_USER_DEFINED; if( parm_cnt < 0 ) { mflags |= MFLAG_VAR_ARGS; parm_cnt = -parm_cnt; } mentry->parm_count = parm_cnt; mentry->src_loc.fno = loc->fno; mentry->src_loc.line = loc->line; mlen = mentry->macro_len; mentry->macro_defn = mlen; MacroOverflow( mlen, 0 ); MacroCopy( mentry, MacroOffset, mlen ); prev_token = T_NULL; prev_non_ws_token = T_NULL; if( CurToken != T_NULL ) { do { CurToken = ScanToken(); } while( CurToken == T_WHITE_SPACE ); if( CurToken == T_SHARP_SHARP ) { CErr1( ERR_MISPLACED_SHARP_SHARP ); PPNextToken(); } } for( ;; ) { i = 0; if( ( CurToken == T_STRING ) && CompFlags.wide_char_string ) { CurToken = T_LSTRING; /* 15-may-92 */ } p_token = (TOKEN *)&TokenBuf[ i ]; *p_token = CurToken; i += sizeof( TOKEN ); if( CurToken == T_NULL ) break; if( CurToken == T_EOF ) break; switch( CurToken ) { case T_SHARP: /* if it is a function-like macro definition */ if( parm_cnt != 0 ) { *p_token = T_MACRO_SHARP; CurToken = T_MACRO_SHARP; /* 26-mar-91 */ } break; case T_SHARP_SHARP: *p_token = T_MACRO_SHARP_SHARP; break; case T_WHITE_SPACE: if( prev_token == T_WHITE_SPACE ) i -= sizeof( TOKEN ); break; case T_ID: j = FormalParm( formal_parms ); if( j != 0 ) { if( (mflags & MFLAG_VAR_ARGS) && (j == parm_cnt - 1) ) CurToken = T_MACRO_VAR_PARM; else CurToken = T_MACRO_PARM; *p_token = CurToken; TokenBuf[ i ] = j - 1; ++i; } else { j = 0; while( (TokenBuf[ i++ ] = Buffer[ j++ ]) != '\0' ) ; /*empty*/ } break; case T_BAD_CHAR: TokenBuf[ i++ ] = Buffer[ 0 ]; if( Buffer[ 1 ] != '\0' ) { *(TOKEN *)&TokenBuf[ i ] = T_WHITE_SPACE; i += sizeof( TOKEN ); } break; case T_CONSTANT: case T_STRING: case T_LSTRING: case T_BAD_TOKEN: case T_PPNUMBER: j = 0; while( (TokenBuf[ i++ ] = Buffer[ j++ ]) != '\0' ) ; /* empty */ break; default: break; } if( CurToken != T_WHITE_SPACE ) { if( prev_non_ws_token == T_MACRO_SHARP && /* 26-mar-91 */ CurToken != T_MACRO_PARM && CurToken != T_MACRO_VAR_PARM ) { CErr1( ERR_MUST_BE_MACRO_PARM ); prev_token = *(TOKEN *)TokenBuf; *(TOKEN *)TokenBuf = T_SHARP; /* 17-jul-92 */ MacroCopy( TokenBuf, MacroOffset + mlen - sizeof( TOKEN ), sizeof( TOKEN ) ); *(TOKEN *)TokenBuf = prev_token; } prev_non_ws_token = CurToken; } prev_token = CurToken; CurToken = ScanToken(); MacroOverflow( mlen + i, mlen ); MacroCopy( TokenBuf, MacroOffset + mlen, i ); mlen += i; } if( prev_non_ws_token == T_MACRO_SHARP ) { CErr1( ERR_MUST_BE_MACRO_PARM ); } if( prev_token == T_WHITE_SPACE ) { mlen -= sizeof( TOKEN ); } MacroOverflow( mlen + sizeof( TOKEN ), mlen ); *(TOKEN *)(MacroOffset + mlen) = T_NULL; mlen += sizeof( TOKEN ); if( prev_non_ws_token == T_SHARP_SHARP ) { CErr1( ERR_MISPLACED_SHARP_SHARP ); } mentry->macro_len = mlen; MacLkAdd( mentry, mlen, mflags ); FreeMEntry( mentry ); MacroSize += mlen; }
static void GrabTokens( mac_parm_count parm_count, macro_flags mflags, MPPTR formal_parms, const char *mac_name, source_loc *loc ) { MEPTR mentry; size_t len; TOKEN prev_token; TOKEN prev_non_ws_token; size_t mlen; mac_parm_count parmno; mentry = CreateMEntry( mac_name, strlen( mac_name ) ); mentry->parm_count = parm_count; mentry->src_loc.fno = loc->fno; mentry->src_loc.line = loc->line; mlen = mentry->macro_len; mentry->macro_defn = mlen; MacroOverflow( mlen, 0 ); MacroCopy( mentry, MacroOffset, mlen ); prev_token = T_NULL; prev_non_ws_token = T_NULL; if( CurToken != T_NULL ) { do { CurToken = ScanToken(); } while( CurToken == T_WHITE_SPACE ); if( CurToken == T_SHARP_SHARP ) { CErr1( ERR_MISPLACED_SHARP_SHARP ); PPNextToken(); } } for( ; CurToken != T_NULL && CurToken != T_EOF ; ) { MTOK( TokenBuf ) = CurToken; len = sizeof( TOKEN ); switch( CurToken ) { case T_SHARP: /* if it is a function-like macro definition */ if( parm_count != 0 ) { CurToken = T_MACRO_SHARP; MTOK( TokenBuf ) = CurToken; } break; case T_SHARP_SHARP: MTOK( TokenBuf ) = T_MACRO_SHARP_SHARP; break; case T_WHITE_SPACE: if( prev_token == T_WHITE_SPACE ) MTOKDEC( len ); break; case T_ID: parmno = FormalParm( formal_parms ); if( parmno != 0 ) { if( (mflags & MFLAG_VAR_ARGS) && (parmno == parm_count - 1) ) { CurToken = T_MACRO_VAR_PARM; } else { CurToken = T_MACRO_PARM; } MTOK( TokenBuf ) = CurToken; MTOKPARM( TokenBuf + len ) = parmno - 1; MTOKPARMINC( len ); } else { memcpy( TokenBuf + len, Buffer, TokenLen + 1 ); len += TokenLen + 1; } break; case T_BAD_CHAR: TokenBuf[len++] = Buffer[0]; if( Buffer[1] != '\0' ) { MTOK( TokenBuf + len ) = T_WHITE_SPACE; MTOKINC( len ); } break; case T_STRING: if( CompFlags.wide_char_string ) { CurToken = T_LSTRING; MTOK( TokenBuf ) = CurToken; } /* fall through */ case T_CONSTANT: case T_LSTRING: case T_BAD_TOKEN: case T_PPNUMBER: memcpy( TokenBuf + len, Buffer, TokenLen + 1 ); len += TokenLen + 1; break; default: break; } if( CurToken != T_WHITE_SPACE ) { if( prev_non_ws_token == T_MACRO_SHARP && CurToken != T_MACRO_PARM && CurToken != T_MACRO_VAR_PARM ) { CErr1( ERR_MUST_BE_MACRO_PARM ); MTOK( MacroOffset + mlen - sizeof( TOKEN ) ) = T_SHARP; } prev_non_ws_token = CurToken; } prev_token = CurToken; CurToken = ScanToken(); MacroOverflow( mlen + len, mlen ); MacroCopy( TokenBuf, MacroOffset + mlen, len ); mlen += len; } if( prev_non_ws_token == T_MACRO_SHARP ) { CErr1( ERR_MUST_BE_MACRO_PARM ); } if( prev_token == T_WHITE_SPACE ) { MTOKDEC( mlen ); } MacroOverflow( mlen + sizeof( TOKEN ), mlen ); MTOK( MacroOffset + mlen ) = T_NULL; MTOKINC( mlen ); if( prev_non_ws_token == T_SHARP_SHARP ) { CErr1( ERR_MISPLACED_SHARP_SHARP ); } mentry->macro_len = mlen; MacLkAdd( mentry, mlen, mflags ); FreeMEntry( mentry ); MacroSize += mlen; }
local void CDefine( void ) { struct macro_parm *mp, *prev_mp, *formal_parms; int parm_cnt, parm_end = 0; int ppscan_mode; char *token_buf; source_loc macro_loc; PPNextToken(); if( CurToken != T_ID ) { ExpectIdentifier(); return; } if( strcmp( Buffer, "defined" ) == 0 ) { CErr1( ERR_CANT_DEFINE_DEFINED ); return; } token_buf = CStrSave( Buffer ); formal_parms = NULL; macro_loc = SrcFileLoc; parm_cnt = -1; /* -1 ==> no () following */ if( CurrChar == '(' ) { /* parms present */ PPNextToken(); /* grab the '(' */ PPNextToken(); parm_cnt = 0; /* 0 ==> () following */ parm_end = 0; prev_mp = NULL; for( ;; ) { if( CurToken == T_RIGHT_PAREN ) break; if( parm_end ) { ExpectingAfter( T_RIGHT_PAREN, T_DOT_DOT_DOT ); return; } if( CurToken != T_DOT_DOT_DOT && !ExpectingToken( T_ID ) ) { return; } ++parm_cnt; if( CurToken == T_DOT_DOT_DOT ) { parm_end = 1; /* can have no more parms after this. */ } mp = (struct macro_parm *)CMemAlloc( sizeof( struct macro_parm ) ); if( formal_parms == NULL ) { formal_parms = mp; } else { if( FormalParm( formal_parms ) ) { CErr2p( ERR_DUPLICATE_MACRO_PARM, Buffer ); } prev_mp->next_macro_parm = mp; } if( CurToken == T_DOT_DOT_DOT ) mp->parm = CStrSave( "__VA_ARGS__" ); else mp->parm = CStrSave( Buffer ); prev_mp = mp; PPNextToken(); if( CurToken == T_RIGHT_PAREN ) break; if( CurToken == T_NULL ) { CErr1( ERR_INVALID_MACRO_DEFN ); break; } if( parm_end ) { ExpectingAfter( T_RIGHT_PAREN, T_DOT_DOT_DOT ); return; } MustRecog( T_COMMA ); if( CurToken != T_DOT_DOT_DOT && !ExpectingToken( T_ID ) ) { return; } } } /* grab replacement tokens */ ppscan_mode = InitPPScan(); // enable T_PPNUMBER tokens GrabTokens( parm_end ? -(parm_cnt + 1) : (parm_cnt + 1), formal_parms, token_buf, ¯o_loc ); FiniPPScan( ppscan_mode ); // disable T_PPNUMBER tokens for( ; (mp = formal_parms) != NULL; ) { formal_parms = mp->next_macro_parm; CMemFree( mp->parm ); CMemFree( mp ); } CMemFree( token_buf ); }
static void CDefine( void ) { MPPTR mp; MPPTR prev_mp; MPPTR formal_parms; mac_parm_count parm_count; macro_flags mflags; bool ppscan_mode; char *token_buf; source_loc macro_loc; PPNextToken(); if( CurToken != T_ID ) { ExpectIdentifier(); return; } if( CMPLIT( Buffer, "defined" ) == 0 ) { CErr1( ERR_CANT_DEFINE_DEFINED ); return; } token_buf = CStrSave( Buffer ); formal_parms = NULL; macro_loc = SrcFileLoc; parm_count = 0; /* 0 ==> no () following */ mflags = MFLAG_USER_DEFINED; if( CurrChar == '(' ) { /* parms present */ PPNextToken(); /* grab the '(' */ PPNextToken(); parm_count = 1; /* 1 ==> () following */ prev_mp = NULL; for( ; CurToken != T_RIGHT_PAREN; ) { if( mflags & MFLAG_VAR_ARGS ) { ExpectingAfter( T_RIGHT_PAREN, T_DOT_DOT_DOT ); return; } if( CurToken != T_DOT_DOT_DOT && !ExpectingToken( T_ID ) ) { return; } ++parm_count; if( CurToken == T_DOT_DOT_DOT ) { mflags |= MFLAG_VAR_ARGS; /* can have no more parms after this. */ } mp = (MPPTR)CMemAlloc( sizeof( MPDEFN ) ); if( formal_parms == NULL ) { formal_parms = mp; } else { if( FormalParm( formal_parms ) ) { CErr2p( ERR_DUPLICATE_MACRO_PARM, Buffer ); } prev_mp->next = mp; } if( CurToken == T_DOT_DOT_DOT ) { mp->parm = CStrSave( "__VA_ARGS__" ); } else { mp->parm = CStrSave( Buffer ); } prev_mp = mp; PPNextToken(); if( CurToken == T_RIGHT_PAREN ) break; if( CurToken == T_NULL ) { CErr1( ERR_INVALID_MACRO_DEFN ); break; } if( mflags & MFLAG_VAR_ARGS ) { ExpectingAfter( T_RIGHT_PAREN, T_DOT_DOT_DOT ); return; } MustRecog( T_COMMA ); if( CurToken != T_DOT_DOT_DOT && !ExpectingToken( T_ID ) ) { return; } } } /* grab replacement tokens */ ppscan_mode = InitPPScan(); // enable T_PPNUMBER tokens GrabTokens( parm_count, mflags, formal_parms, token_buf, ¯o_loc ); FiniPPScan( ppscan_mode ); // disable T_PPNUMBER tokens for( ; (mp = formal_parms) != NULL; ) { formal_parms = mp->next; CMemFree( mp->parm ); CMemFree( mp ); } CMemFree( token_buf ); }