📄 macro.c
字号:
/*Copyright (c) 2000, Red Hat, Inc.This file is part of Source-Navigator.Source-Navigator is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as publishedby the Free Software Foundation; either version 2, or (at your option)any later version.Source-Navigator is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public License alongwith Source-Navigator; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330, Boston,MA 02111-1307, USA.*/#include <ctype.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <tcl.h>#include "srchtbl.h"#include "cpdefines.h"#include "cplex.h"#include "cpkeyw.h"#include "sn.h"#include "longstr.h"#define my_isxdigit(x) (isxdigit(x))#define my_isdigit(x) (isdigit(x))#define my_isalnum(x) (isalnum(x))# define input() (yyleng++,(yychar=(*yyptr++)))# define unput() (yyleng--,yyptr--)# define d_TokenReturn(x) \ { \ Token_t Token = f_TokenCreate(); \ Token->lex = x; \ Token->sString.text = yytext; \ Token->sString.leng = yyleng; \ return Token; \ }int (*Paf_Word) (char *word,int len,char **parameter_list,char **macro);static SearchTable *pbtrMacro;static unsigned char *yyptr;static Macro_t f_MacroCreate( sString_t sStringName );static void f_MacroDestroy( Macro_t Macro );static int f_MacroProcess1( Macro_t Macro );static int f_MacroProcess2( Macro_t Macro, sString_t sStringName, sString_t *psStringParameter, int iParameter );static Token_t my_TokenInput( void );static Token_t f_ParameterPosition( Param_t Param, int position );static void __TokenPrint( Token_t Token );static char *Strdup( char *pc );static void FreeMacroEntry( SearchEntry *entry );int iMacroCount;/* Cache for Paf_Word function. * This function read and process the macros, and save the processed values in * a cache. */extern Macro_t f_MacroFind( sString_t sString ){ SearchEntry entry; SearchEntry *pentry; if( Paf_Word == 0 ) return 0; if( pbtrMacro == 0 ) { pbtrMacro = SearchTableCreate(1000,SEARCH_HASH_TABLE,FreeMacroEntry); } entry.key = sString.text; entry.key_len = sString.leng; entry.data = 0; entry.data_len = 0; entry.flag = SEARCH_DUP_KEY; if(( pentry = (*pbtrMacro->search)( &pbtrMacro, entry ))) { return (Macro_t) pentry->data; } else { int retval; char *parameter_list; char *macro; retval = (*Paf_Word)( sString.text, sString.leng, ¶meter_list, ¯o ); if( retval == PAF_WORD_DEFINE || retval == PAF_WORD_REPLACE ) /* 27.11.97 rigo */ { Macro_t Macro = f_MacroCreate( sString ); Macro->parameter_list = Strdup( parameter_list ); Macro->macro = Strdup( macro ); Macro->paf_typ = retval; /* 27.11.97 rigo */ Macro->typ = parameter_list == 0 ? CPP_DEFINE : CPP_MACRO; if( f_MacroProcess1( Macro ) == 0 ) /* OK */ { iMacroCount++; entry.data = Macro; (*pbtrMacro->add)( &pbtrMacro, entry ); f_MacroProcess( Macro ); return Macro; } else { f_MacroDestroy( Macro ); return 0; } } else if( retval == PAF_WORD_UNDEF ) { Macro_t Macro = f_MacroCreate( sString ); Macro->paf_typ = retval; /* 27.11.97 rigo */ Macro->typ = CPP_UNDEF; iMacroCount++; entry.data = Macro; (*pbtrMacro->add)( &pbtrMacro, entry ); return Macro; } else /* retval == PAF_WORD_NONE */ { return 0; } }}static Macro_t f_MacroCreate( sString_t sStringName ){ Macro_t Macro; Macro = (Macro_t) ckalloc( sizeof( Macro[0] )); Macro->parameter_list = 0; Macro->macro = 0; Macro->paf_typ = 0; /* 27.11.97 rigo */ Macro->typ = 0; Macro->tilt = False; Macro->sStringName = sStringName; Macro->Token = 0; Macro->TokenProcessed = 0; Macro->MacroNext = Macro; Macro->MacroPrev = Macro; return Macro;}static void f_MacroDestroy( Macro_t Macro ){ extern int bCheckOfToken2; if( Macro ) {#ifdef TEST printf( "MacroDestroy: %*.*s\n" , Macro->sStringName.leng , Macro->sStringName.leng , Macro->sStringName.text );#endif if( Macro->parameter_list ) ckfree( Macro->parameter_list ); if( Macro->macro ) ckfree( Macro->macro ); bCheckOfToken2 = True; f_TokenFreeAll( Macro->Token ); f_TokenFreeAll( Macro->TokenProcessed ); bCheckOfToken2 = False; ckfree ((char*)Macro); /* 27.11.97 rigo */ }}static int f_MacroProcess1( Macro_t Macro ){ Token_t Token; sString_t sStringName; sString_t asStringParameter[100]; int iParameter = 0; if( Macro->parameter_list ) { yyptr = (unsigned char *) Macro->parameter_list; while( True ) { if(( Token = my_TokenInput())->lex == SN_IDENTIFIER ) { asStringParameter[iParameter++] = Token->sString; f_TokenFree( Token ); } else if( iParameter == 0 && Token->lex == 0 ) { f_TokenFree( Token ); return f_MacroProcess2( Macro, sStringName, asStringParameter, iParameter ); } else { printf( "lex error [3]: %s\n", Macro->parameter_list ); f_TokenFree( Token ); return -1; /* ERROR */ } if(( Token = my_TokenInput())->lex == 0 ) { f_TokenFree( Token ); return f_MacroProcess2( Macro, sStringName, asStringParameter, iParameter ); } else if( Token->lex != ',' ) { printf( "lex error [4]: %s\n", Macro->parameter_list ); f_TokenFree( Token ); return -1; /* ERROR */ } f_TokenFree( Token ); } } else { /********************* define *********************/ return f_MacroProcess2( Macro, sStringName, 0, 0 ); }}static int f_MacroProcess2( Macro_t Macro, sString_t sStringName, sString_t *psStringParameter, int iParameter ){ Token_t Token; if( Macro->macro == 0 ) return 0; /* 25.11.97 rigo */ yyptr = (unsigned char *) Macro->macro; while( True ) { Token = my_TokenInput(); Token->iParameter = -1; if( Token->lex == 0 ) { f_TokenFree( Token ); break; } if( Token->lex == SN_IDENTIFIER ) { int leng = Token->sString.leng; int i; for( i = 0; i < iParameter; i++ ) { if( leng == psStringParameter[i].leng && strncmp( (const char *) Token->sString.text , (const char *) psStringParameter[i].text , leng ) == 0 ) { Token->iParameter = i; } } } f_TokenAppend( &Macro->Token, Token ); } return 0; /* OK */}static Token_t my_TokenInput( void ){ unsigned char *yytext; int yyleng; int yychar; int yycharprev;/* if( TokenUnput ) *//* { *//* Token_t Token = TokenUnput; *//* TokenUnput = 0; *//* return Token; *//* } */ while( 1 ) { yytext = yyptr; yyleng = 0; input(); switch( yychar ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if( yychar == '0' && ( input() == 'X' || yychar == 'x' )) { /* hexa nummer */ while( my_isxdigit( input())) { } if( yychar == 'l' || yychar == 'L' ) { d_TokenReturn( SN_LONGconstant ) } else if( yychar == 'u' || yychar == 'U' ) { d_TokenReturn( SN_INTEGERconstant ) } else { unput(); d_TokenReturn( SN_INTEGERconstant ) } } else { int bFloat = False; unput(); while( my_isdigit( input())) { } if( yychar == '.' ) { bFloat = True; while( my_isdigit( input())) { } } if( yychar == 'E' || yychar == 'e' ) { bFloat = True; input(); if( yychar == '+' || yychar == '-' ) { } else { unput(); } while( my_isdigit( input())) { } if( yychar == '.' ) { while( my_isdigit( input())) { } } } if( yychar == 'l' || yychar == 'L' ) { if( bFloat ) d_TokenReturn( SN_FLOATINGconstant ) else d_TokenReturn( SN_LONGconstant ) } else if( yychar == 'u' || yychar == 'U' ) { if( bFloat ) d_TokenReturn( SN_FLOATINGconstant ) else d_TokenReturn( SN_INTEGERconstant ) } else { unput(); if( bFloat ) d_TokenReturn( SN_FLOATINGconstant ) else d_TokenReturn( SN_INTEGERconstant ) } } case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'x': case 'y': case 'v': case 'w': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'X': case 'Y': case 'V': case 'W': case 'Z': case '_': case '$': { register int ihash = 0; register int j = 0; int keyword; int is_cpp; do { if( j++ < 6 && ihash < HASH_MAX ) { ihash += c_hash[ (int) yychar ]; } } while( my_isalnum( input()) || yychar == '_' || yychar == '$' ); unput(); if( ihash < HASH_MAX && LexKeyWordTab[ihash].leng == yyleng && strncmp( LexKeyWordTab[ihash].pcName, (char *)yytext, yyleng ) == 0 ) { keyword = LexKeyWordTab[ihash].wLexId; is_cpp = LexKeyWordTab[ihash].is_cpp; } else { keyword = 0; is_cpp = 0; } { Token_t Token = f_TokenCreate(); Token->lex = SN_IDENTIFIER; Token->keyword = keyword; Token->is_cpp = is_cpp; Token->sString.text = yytext; Token->sString.leng = yyleng; return Token; } } case ' ': case '\t': case '\r': case '\n': break; case '"': while( input()) { if( yychar == '\\' ) {/* A \ utani karaktert lenyeljuk. Ha \ utan cr+lf jon, akkor midkettot lenyeljuk */ input(); if( yychar == '\r' ) { input(); if( yychar != '\n' ) { unput(); } } } else if( yychar == '"' ) { break; } else if( yychar == '\n' ) { unput(); break; } } d_TokenReturn( SN_STRINGliteral ) case '\'': while( input()) { if( yychar == '\\' ) {/* A \ utani karaktert lenyeljuk. Ha \ utan cr+lf jon, akkor midkettot lenyeljuk */ input(); if( yychar == '\r' ) { input(); if( yychar != '\n' ) { unput(); } } } else if( yychar == '\'' ) { break; } else if( yychar == '\n' ) { unput(); break; } } d_TokenReturn( SN_CHARACTERconstant ) case '#': d_TokenReturn( yychar ) case '<': /* <, <<, <=, <<= */ switch( input()) { case '<': switch( input()) { case '=': d_TokenReturn( SN_LSassign ) default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -