msgencod.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,536 行 · 第 1/3 页
C
1,536 行
grp->num = groupIndex; //set with value
}
}
static void do_emsggrp( char *p ) {
MSGGROUP *grp;
grp = currGroup;
if( !flags.grouped ) {
error( "missing :msggroup\n" );
}
if( grp != NULL ){
grp->emsgIndex = messageCounter;
}
flags.grouped = 0;
flags.have_msg = 0;
groupIndex += 256;
}
static void do_msggrp( char *p ) {
MSGGROUP *grp;
MSGGROUP *cur;
MSGGROUP **end;
size_t len;
int saw_dup;
++groupCounter;
if( flags.grouped ) {
error( "missing :emsggroup\n" );
}else{
if( flags.have_msg ) {
error( ":msgsym not enclosed in :msggrp\n" );
}
}
flags.grouped = 1;
p = skipNonSpace( group, p );
len = strlen( group );
if( !flags.gen_gpick && len != 2 ) {
error( ":msggroup code '%s' not two characters\n", group );
switch( len ) {
case 0 :
group[0] = ' ';
// drops thru
case 1 :
group[1] = ' ';
// drops thru
default :
group[2] = '\0';
}
len = 2;
}
grp = malloc( sizeof( *grp ) +len );
grp->next = NULL;
strcpy( grp->name, group );
messageIndex=0;
grp->msgIndex = messageCounter;
grp->num = groupIndex; //set with default
strncpy( grp->prefix, group, 2 ); //default
grp->prefix[2] = '\0';
currGroup = grp;
end = &allGroups;
saw_dup = 0;
for( ; ; ) {
cur = *end;
if( 0 == cur ) {
*end = grp;
break;
} else {
if( (strcmp( cur->name, group ) == 0)
&& ! saw_dup ) {
error( "msggroup code '%s' same as previous code\n", group );
saw_dup = 1;
}
}
end = &cur->next;
}
}
static void do_msgsym( char *p ) {
MSGSYM *msg;
int i;
size_t len;
++messageCounter;
flags.have_msg = 1;
p = skipNonSpace( sym, p );
len = strlen( sym );
msg = malloc( sizeof( *msg ) + len );
msg->next = *currMSGSYM;
*currMSGSYM = msg;
currMSGSYM = &(msg->next);
msg->sortedByName[0] = NULL;
msg->sortedByName[1] = NULL;
msg->fname = fname;
msg->line = line;
msg->grpIndex = messageIndex;
msg->index = groupIndex + messageIndex;
++messageIndex;
msg->level = 0;
msg->style = 0;
msg->mtype = MSG_TYPE_ERROR;
for( i = LANG_MIN; i < LANG_MAX; ++i ) {
msg->lang_txt[i] = NULL;
}
msg->words = NULL;
strcpy( msg->name, sym );
if( addToSorted( msg ) != NULL ) {
error( "message name has been used before '%s'\n", sym );
}
msg->grp = currGroup;
}
static size_t commonTxt( char *p ) {
size_t len;
len = strlen( p ) + 1;
if( len > maxMsgLen ) {
maxMsgLen = len;
}
return( len );
}
static void do_msgtxt( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
m->lang_txt[LANG_English] = strdup( p );
totalMsgLen += commonTxt( p );
}
static void do_msgjtxt( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
m->lang_txt[LANG_Japanese] = strdup( p );
commonTxt( p );
if( p[0] ) {
langTextCount[LANG_Japanese]++;
}
}
static void do_info( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
p = p;
m->mtype = MSG_TYPE_INFO;
}
static void do_style( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
p = p;
if( m->mtype != MSG_TYPE_WARNING ) {
error( ":style. can only be used with :warning.\n" );
} else {
m->mtype = MSG_TYPE_STYLE;
}
}
static void do_warning( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
m->mtype = MSG_TYPE_WARNING;
m->level = pickUpLevel( p );
}
static void do_ansierr( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
p = p;
m->mtype = MSG_TYPE_ANSIERR;
}
static void do_ansiwarn( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
m->mtype = MSG_TYPE_ANSIWARN;
m->level = pickUpLevel( p );
}
static void do_ansi( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
m->mtype = MSG_TYPE_ANSI;
m->level = pickUpLevel( p );
}
static void do_jck( char *p ) {
MSGSYM *m = mustBeProceededByMSGSYM();
m->mtype = MSG_TYPE_JCK;
m->level = pickUpLevel( p );
}
static void (*processLine[])( char * ) = {
#define def_tag( e ) do_##e,
ALL_TAGS
#undef def_tag
};
static void checkForGMLEscape( char *p )
{
int is_escape;
char c1, c2;
++p;
c1 = *p++;
if( c1 == '\0' || ! isalpha( c1 ) ) {
return;
}
c2 = *p++;
if( c2 == '\0' || ! isalpha( c2 ) ) {
return;
}
is_escape = 0;
if( *p == '\0' || ! isalpha( *p ) ) {
is_escape = 1;
}
if( is_escape ) {
error( "possible GML escape sequence: &%c%c\n", c1, c2 );
}
}
static char *inputIO( void ) {
char c;
char *s;
char *p;
s = currGML;
p = s;
for(;;) {
c = *p;
if( c == '&' ) {
checkForGMLEscape( p );
}
if( c == '\0' ) {
ibuff = NULL;
return( NULL );
}
if( c == '\n' ) break;
if( c == '\r' && p[1] == '\n' ) {
*p = '\0';
++p;
break;
}
++p;
}
currGML = p + 1;
*p = '\0';
ibuff = s;
return( s );
}
static void suckInFile( void ) {
int fh;
struct stat info;
fh = fileno( i_gml );
if( fstat( fh, &info ) != 0 ) {
fatal( "cannot get size of input file" );
}
entireGML = malloc( info.st_size + 2 );
if( read( fh, entireGML, info.st_size ) != info.st_size ) {
fatal( "cannot read entire input file" );
}
entireGML[ info.st_size ] = '\n';
entireGML[ info.st_size + 1 ] = '\0';
currGML = entireGML;
}
static int strPref( MSGSYM *m, char *pref ) {
unsigned len = strlen( pref );
return memcmp( m->name, pref, len );
}
static int percentPresent( char c, char *p ) {
char f;
if( *p == '\0' ) {
// will get the English text so it is fine
return( 1 );
}
for(; *p; ++p ) {
if( *p != '%' ) continue;
f = *++p;
if( f == '\0' ) break;
if( f == c ) {
return( 1 );
}
}
return( 0 );
}
static void checkReplacements( MSGSYM *m, int start_lang, int end_lang ) {
int i;
char c;
char *eng_text;
char *p;
eng_text = m->lang_txt[ LANG_English ];
if( eng_text == NULL ) {
return;
}
for( p = eng_text; *p; ++p ) {
if( *p != '%' ) {
continue;
}
c = *++p;
if( c == '\0' ) break;
for( i = start_lang; i < end_lang; ++i ) {
char *intl_text;
if( i == LANG_English ) continue;
intl_text = m->lang_txt[i];
if( intl_text == NULL ) continue;
if( ! percentPresent( c, intl_text ) ) {
errorLocn( m->fname, m->line, "MSGSYM %s's %s text has format mismatch for %%%c\n", m->name,
langName[ i ], c );
}
}
}
}
static void checkMessages( void ) {
MSGSYM *m;
int start_lang;
int end_lang;
int i;
for( m = messageSyms; m != NULL; m = m->next ) {
if( flags.international ) {
start_lang = LANG_MIN;
end_lang = LANG_MAX;
} else {
start_lang = LANG_English;
end_lang = start_lang + 1;
}
for( i = start_lang; i < end_lang; ++i ) {
if( m->lang_txt[i] == NULL ) {
errorLocn( m->fname, m->line, "MSGSYM %s has no %s text\n", m->name,
langName[ i ] );
}
}
checkReplacements( m, start_lang, end_lang );
if( ! flags.ignore_prefix ) {
switch( m->mtype ) {
#define def_msg_type( e, p ) case MSG_TYPE_##e: if( strPref( m, p ) ) errorLocn( m->fname, m->line, "MSGSYM %s has incorrect prefix (should be " p ")\n", m->name ); break;
ALL_MSG_TYPES
#undef def_msg_type
default:
break;
}
}
}
}
static void readGML( void ) {
char *check;
tag_id tag_id;
char *p;
void (*process)( char * );
suckInFile();
line = 0;
currGroup = NULL;
for(;;) {
++line;
check = inputIO();
if( check == NULL ) break;
if( ibuff[0] != ':' ) {
continue;
}
if( tolower( ibuff[1] ) == 'c'
&& tolower( ibuff[2] ) == 'm'
&& tolower( ibuff[3] ) == 't' ) {
continue;
}
tag_id = getId( ibuff + 1, &p );
if( tag_id == TAG_MAX ) {
continue;
}
process = processLine[ tag_id ];
if( process != NULL ) {
process( p );
}
}
messageIndex=0;
checkMessages();
if( errors ) {
fatal( "cannot continue due to errors" );
}
// messages involve an extra ' ' at the end
// so we'll add 16 and round up to mod 16 to be absolutely safe
maxMsgLen = ( ( maxMsgLen + 16 ) + 0x0f ) & ~ 0x0f;
}
static WORD *addWord( MSGSYM *m ) {
int s;
WORD **h;
WORD *c;
size_t len;
h = &nameWords;
for(;;) {
c = *h;
if( c == NULL ) break;
s = strcmp( c->name, word );
if( s < 0 ) {
h = &(c->sortedByName[0]);
} else if( s > 0 ) {
h = &(c->sortedByName[1]);
} else {
c->references++;
return( c );
}
}
len = strlen( word );
if( len > maxWordLen ) {
maxWordLen = len;
}
if( len > MAX_WORD_LEN ) {
errorLocn( m->fname, m->line, "MSGSYM %s: word '%s' is too long\n", m->name, word );
}
++uniqueWords;
c = calloc( 1, sizeof( *c ) + len );
*h = c;
c->references = 1;
c->index = NO_INDEX;
c->len = len;
c->all = allWords;
allWords = c;
strcpy( c->name, word );
return( c );
}
static int cmpRef( WORD *l, WORD *r ) {
int s;
if( l->references < r->references ) {
return( -1 );
} else if( l->references > r->references ) {
return( 1 );
}
if( l->len < r->len ) {
return( -1 );
} else if( l->len > r->len ) {
return( 1 );
}
if( l->index < r->index ) {
return( -1 );
} else if( l->index > r->index ) {
return( 1 );
}
s = strcmp( l->name, r->name );
assert( s != 0 );
return( s );
}
static void addRef( WORD *w ) {
WORD **h;
WORD *c;
int s;
if( w->references > 1 ) {
++multiRefWords;
}
h = &refWords;
for(;;) {
c = *h;
if( c == NULL ) break;
s = cmpRef( w, c );
if( s < 0 ) {
h = &(c->sortedByRef[0]);
} else if( s > 0 ) {
h = &(c->sortedByRef[1]);
} else {
*h = w;
w->sortedByRef[0] = c;
w->sortedByRef[1] = c->sortedByRef[1];
c->sortedByRef[1] = NULL;
return;
}
}
*h = w;
}
static void sortByRefs( void ) {
WORD *w;
for( w = allWords; w != NULL; w = w->all ) {
addRef( w );
}
}
static void traverseHiToLoRefs( WORD *w, void (*t)( WORD *, void * ), void *data ) {
WORD *r;
while( w != NULL ) {
r = w->sortedByRef[1];
if( r != NULL ) {
traverseHiToLoRefs( r, t, data );
}
t( w, data );
w = w->sortedByRef[0];
}
}
static void splitIntoWords( void ) {
MSGSYM *m;
WORD *w;
WORDREF *r;
WORDREF **a;
char *p;
for( m = messageSyms; m != NULL; m = m->next ) {
p = m->lang_txt[LANG_English];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?