wrdencod.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,273 行 · 第 1/3 页
C
1,273 行
{
char code1[10]; // - byte[1] of code
char code2[10]; // - byte[2] of code (optional)
int retn; // - return value
GUESS :: NO_ERRS
retn = write_c_delim();
QUITIF( retn != 0 );
space_put_out += 1;
stxcpy( code1 , code & 0x3f );
IF( code & LARGE_BIT )
space_put_out += 1;
stxcpy( code2 , code >> 8 );
retn = write_c_strs_eol( "ENC_BIT | "
, "LARGE_BIT | "
, code1
, ", "
, code2
, NULL );
ELSE
retn = write_c_strs_eol( "ENC_BIT | "
, code1
, NULL );
ENDIF
ENDGUESS
return( retn );
}
static int print_encod_text() // PRINT ENCODED TEXT
{
int retn; // - return value
GUESS :: NO_ERRS
retn = beg_part( "MSG_SCOPE unsigned char MSG_MEM encoded_text[] =" );
QUITIF( retn != 0 ) :: NO_ERRS;
retn = _ring_walk_int( (void ***)RingWords, print_text_encod, 0 );
QUITIF( retn != 0 ) :: NO_ERRS;
retn = _ring_walk_int( (void ***)RingPhrases, print_phrase_encod, 0 );
QUITIF( retn != 0 ) :: NO_ERRS;
retn = _ring_walk_int( (void **)RingMessages, &print_sentence, 0 );
QUITIF( retn != 0 ) :: NO_ERRS;
retn = end_part();
ENDGUESS
return( retn );
}
static int print_word_count() // PRINT WORD COUNT
{
int retn; // - return value
char encwrds[10]; // - string of number of encoded words
GUESS :: NO_ERRS
utoa( enc_words , encwrds , 10 );
retn = write_c_strs_eol
( "MSG_SCOPE unsigned short MSG_MEM word_count = "
, encwrds
, ";"
, NULL );
QUITIF( retn != 0 );
retn = write_c_eol();
ENDGUESS
return( retn );
}
static int print_offset() // PRINT OFFSET OF WORD, PHRASE, OR MESSAGE
{
int retn; // - return value
char len[10]; // - length in text form
GUESS :: NO_ERRS
space_put_out += 2;
utoa( lenwords , len , 10 );
retn = write_c_delim();
QUITIF( retn != 0 );
retn = write_c_line( len );
ENDGUESS
return( retn );
}
static int prt_msg_offset( // PRINT OFFSET OF A MESSAGE
MESSAGE *msg ) // - the message
{
int retn; // - return value
WORD *word; // - current word/phrase
WORD **wordp; // - points in vector of words
unsigned count; // - counts words
GUESS :: NO_ERRS
retn = print_offset();
QUITIF( retn != 0 );
FOR( wordp = msg->words, count = msg->codes
; count > 0
; --count )
word = *wordp++;
IF( word->code & ENC_BIT )
IF( word->code & LARGE_BIT )
++ lenwords;
ENDIF
ELSE
lenwords += strlen( word->text );
ENDIF
++ lenwords;
ENDFOR
++ lenwords;
ENDGUESS
return( retn );
}
static int prt_enc_word_offset( // PRINT OFFSET OF ENCODED WORD
WORD *curr ) // - current record
{
int retn; // - return value
IF( curr->code & ENC_BIT )
retn = print_offset();
lenwords += strlen( curr->text ) + 1;
ELSE
retn = 0;
ENDIF
return( retn );
}
static int print_text_table() // PRINT TEXT TABLE IN FILE
{
int retn; // - return value
GUESS :: NO_ERRS
retn = beg_part( "MSG_SCOPE unsigned short MSG_MEM text_table[] = " );
QUITIF( retn != 0 );
lenwords = 0;
retn = _ring_walk_int( (void **)RingWords , prt_enc_word_offset, 0 );
QUITIF( retn != 0 );
retn = _ring_walk_int( (void **)RingPhrases , prt_msg_offset, 0 );
QUITIF( retn != 0 );
retn = _ring_walk_int( (void **)RingMessages , prt_msg_offset, 0 );
QUITIF( retn != 0 );
retn = end_part();
ENDGUESS
return( retn );
}
static int print_group_num( // PRINT GROUP NUMBER
MESSAGE *curr ) // - current message
{
int retn; // - return value
char putwrds[5]; // - string of numwords;
GUESS :: NO_ERRS
retn = 0;
QUITIF( curr->number != 0 )
utoa( numwords , putwrds , 10 );
retn = write_c_delim();
QUITIF( retn != 0 ) :: NO_ERRS
retn = write_c_line( putwrds );
ENDGUESS
++numwords;
return( retn );
}
static int print_group_table( // PRINT GROUP_TABLE
int index) // - group indexer
{
int retn; // - return value
GUESS :: NO_ERRS
retn = beg_part( "MSG_SCOPE unsigned short MSG_MEM group_table[]= " );
QUITIF( retn != 0 );
numwords = index;
retn = _ring_walk_int( (void **)RingMessages , print_group_num, 0 );
QUITIF( retn != 0 );
retn = end_part();
ENDGUESS
return( retn );
}
static void encode_phrases() // ENCODE PHRASES
{
unsigned number; // - phrase number
MESSAGE *phrase; // - current phrase
phrase = RingPhrases;
IF( phrase != NULL )
number = enc_words;
LOOP
phrase = phrase->next;
phrase->number = ( number & 0x3f )
| ( ( number & 0xffc0 ) << 2 )
| ENC_BIT;
IF( number++ >= 64 )
phrase->number |= LARGE_BIT;
ENDIF
UNTIL( phrase == RingPhrases );
ENDIF
}
static void encode_dec( // DECIDE ENCODE
WORD *curr ) // - current record
{
IF( ( enc_words < 64 )
&&( ( ( curr->count - 1 )*( strlen( curr->text ) ) ) > 3 ) )
curr->code = enc_words + ENC_BIT;
++enc_words;
ELSEIF ( ( enc_words >= 64 )&&
( ( ( curr->count - 1 )*( strlen( curr->text ) - 1 ) ) > 4 ) )
curr->code = ( enc_words & 0x3f ) + ( (enc_words & 0x3fc0 ) << 2 ) +
ENC_BIT + LARGE_BIT;
++enc_words;
ENDIF
}
static void encode_words() // ENCODE WORDS
{
enc_words = 0;
_ring_walk( (void **)RingWords , encode_dec );
}
static int compare_word_counts( // COMPARE WORDS, USING COUNTS, FOR SORT
WORD *op1, // - word(1) (current)
WORD *op2 ) // - word(2) (being inserted)
{
return( op2->count - op1->count );
}
static void sort_words() // SORT WORDS
{
_ring_sort( (void ***)&RingWords, &compare_word_counts );
}
static int compare_phr_counts( // COMPARE WORDS, USING COUNTS, FOR SORT
MESSAGE *op1, // - phrase(1) (current)
MESSAGE *op2 ) // - phrase(2) (being inserted)
{
return( op2->count - op1->count );
}
static void sort_phrases() // SORT WORDS
{
_ring_sort( (void ***)&RingPhrases, &compare_phr_counts );
}
static int write_define( // WRITE DEFINE STATEMENTS
int (*writer) // - writer
( const char * ) ) // - - string
{
unsigned fmt_size;
int retn; // - return
char msg[80]; // - message buffer
GUESS :: NO_ERRS
retn = (*writer)( "#define ENC_BIT 0x80" );
QUITIF( retn != 0 );
retn = (*writer)( "#define LARGE_BIT 0x40" );
QUITIF( retn != 0 );
// messages involve an extra ' ' at the end
// so we'll add 16 and round up to mos 16 to be absolutely safe
fmt_size = ( ( msg_size + 16 ) + 0x0f ) & ~ 0x0f;
stucpy( stpcpy( msg, "#define MAX_MSG " ), fmt_size );
retn = (*writer)( msg );
QUITIF( retn != 0 );
retn = (*writer)( "" );
QUITIF( retn != 0 );
ENDGUESS
return( retn );
}
static int create_output() // CREATE OUTPUT
{
int retn; // - return value
GUESS :: NO_OPEN
retn = open_c_file( messages );
QUITIF( retn == 0 );
ADMIT :: ENCODE_TEXT
sort_words();
encode_words();
sort_phrases();
encode_phrases();
write_define( &write_c_line );
retn = print_group_table( enc_words + enc_phrases );
QUITIF( retn != 0 );
retn = print_text_table();
QUITIF( retn != 0 );
retn = print_word_count( );
QUITIF( retn != 0 );
retn = print_encod_text();
QUITIF( retn != 0 );
IF( RingGroups != NULL )
retn = print_group_prefix();
QUITIF( retn != 0 );
ENDIF
retn = close_c_file();
ENDGUESS
return( retn );
}
static void create_level( // CREATE A LEVEL ENTRY
MESSAGE *msg ) // - current entry
{
char buffer[16]; // - record buffer
buffer[0] = delim[0];
delim[0] = ',';
stucpy( buffer+1, ( msg->type << 4 ) + msg->level );
write_h_line( buffer );
}
static int create_levels() // CREATE LEVELS FILE
{
int retn; // - return value
GUESS :: NO_OPEN
retn = open_h_file( levels );
QUITIF( retn == 0 );
ADMIT :: LEVELS
write_h_line( "typedef enum" );
write_h_line( "{ MSG_TYPE_ERROR" );
write_h_line( ", MSG_TYPE_WARNING" );
write_h_line( ", MSG_TYPE_INFO" );
write_h_line( ", MSG_TYPE_ANSI" );
write_h_line( ", MSG_TYPE_ANSIERR" );
write_h_line( ", MSG_TYPE_ANSIWARN" );
write_h_line( ", MSG_TYPE_ANSICOMP" );
write_h_line( ", MSG_TYPE_EXTWARN" );
write_h_line( "} MSG_TYPE;" );
write_h_line( " " );
write_h_line( "static unsigned char msg_level[] =" );
delim[0] = '{';
_ring_walk( (void**)RingMessages, &create_level );
write_h_line( "};" );
retn = close_h_file();
ENDGUESS
return retn;
}
static int process_group( // GRP OPTION FOUND
const char *scanner ) // - line scanner
{
int retn; // - return value
char *name; // - group name
unsigned length; // - length of given word
WORD *new; // - new group name
GUESS :: NO_GROUP
scanner = scan_over_black_space( scanner );
scan_name( &scanner , &name , &length );
QUITIF( length > 0 ) :: NO_GROUP;
retn = msgerr( "No group name present" );
ADMIT :: NO_ERRS
retn = alloc_ring( &RingGroups , sizeof( struct word ) + length ,
&new );
QUITIF( retn != 0 ) :: NO_ERRS;
stvcpy( new->text , name , length );
ENDGUESS
return( retn );
}
static int alloc_message( // ALLOCATE A MESSAGE ENTRY (OR PHRASE)
void **ring, // - ring
WORD **words, // - words vector
unsigned count, // - number of words
unsigned number ) // - message number
{
int retn; // - return code
MESSAGE *msg; // - new message
GUESS :: NO_ERRS
substitute_phrases( words, &count );
retn = alloc_ring( ring, sizeof( struct message ) +
(count - 1 )*( sizeof( WORD * ) ) , &msg );
QUITIF( retn != 0 );
memcpy( msg->words, words, count * sizeof( WORD * ) );
msg->codes = count;
msg->count = 0;
msg->number = number;
msg->type = MSG_TYPE_ERROR;
msg->level = 0;
ENDGUESS
return( retn );
}
static int scan_level( // SCAN LEVEL
const char *cptr, // - line scanner
unsigned *level ) // - level scanned
{
int retn; // - return code
GUESS :: NO_LEVEL
cptr = scan_over_white_space( cptr );
if( *cptr == '.' ) {
cptr = scan_over_white_space( cptr + 1 );
}
QUITIF( *cptr != '\0' );
retn = msgerr( "No warning level" );
ADMIT :: BAD_LEVEL
QUITIF( isdigit( *cptr ) );
retn = msgerr( "Invalid warning level" );
ADMIT :: MORE_JUNK
*level = *cptr - '0';
++cptr;
if( *cptr != '\0' && isdigit( *cptr ) ) {
*level *= 10;
*level += *cptr - '0';
++cptr;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?