/*************************************************************** MAIN.C This file containts main routine of ZUBR. PART OF : ZUBR - Parsers generator for multiple syntax language compilers . COMPILE : . NOTE : NONE . Copyright (C) 1995 - 2026 by Andrey V.Kosteltsev. All Rights Reserved. ***************************************************************/ /* This file contant RUSSIAN letters( code-page: UTF-8 ) ***************************************************************/ #include #ifndef __NO_COMPILE /*************************************************************** Name : IS_ADMISSIBLE(c) ( macros ) Description : the folloving symbol is illegal in file_name and file_prefix (compilers pass of space) all systems: u" / * ? | < > += FAT : + = ; [ ] space += HPFS : & Concepts : - the folloving symbols | < > & include in file name if its begin of symbol '\"' - symbol '\"' may by include in file name if -b option use without space Value : if( c is legal character ) return TRUE; if( c is illegal character ) return FALSE; ***************************************************************/ #define IS_ADMISSIBLE(c) ((c) != '\"' && \ (c) != '*' && \ (c) != '?' && \ (c) != '|' && \ (c) != '>' && \ (c) != '<' && \ (c) != '+' && \ (c) != '=' && \ (c) != ';' && \ (c) != '[' && \ (c) != ']' && \ (c) != '&') /* (c) != '/' && \ */ /* (c) != ' ') */ /*************************************************************************/ /* flags of command line is global variables: */ /* in defs.h its define as extern */ char bflag; /* use prefix for variables and zubr_lex, zubr_parse */ char p_name_flag; /* name for zubr_parse() and header file */ char l_name_flag; /* name for zubr_lex() */ char iflag; /* include extern tokens definitions */ char dflag; char lflag; char pflag; /* .cpp extention */ char rflag; char sflag; /* static option */ char tflag; /* trase option */ char vflag; char C_mem; /* signal for done() / memory allocate ? */ char D_mem; char R_mem; char V_mem; __mpu_char16_t *file_prefix = (__mpu_char16_t *)MPU_UCS2( "z" ); /* only this file */ __mpu_char16_t *myname = (__mpu_char16_t *)MPU_UCS2( "zubr" ); /* in defs.h define as extern */ __mpu_char16_t temp_form[256]; /* only this file */ /* global: in defs.h define as extern */ int lineno; int outline; /* global: in defs.h define as extern */ __mpu_char16_t *parse_func_name; __mpu_char16_t *lex_func_name; __mpu_char16_t *inc_token_filename; __mpu_char16_t *name_prefix; __mpu_char16_t *name_prefix_upper; __mpu_char16_t *parse_header_file_name; /* header for zubr_parse() function */ __mpu_char16_t *action_file_name; __mpu_char16_t *text_file_name; __mpu_char16_t *union_file_name; __mpu_char16_t *input_file_name; __mpu_char16_t *output_file_name; __mpu_char16_t *defines_file_name; __mpu_char16_t *code_file_name; __mpu_char16_t *verbose_file_name; /* global: in defs.h define as extern */ mpu_FILE *parse_header_file; /* header for zubr_parse() function */ mpu_FILE *action_file; /* a temp file, used to save actions associated */ /* with rules until the parser is written */ mpu_FILE *text_file; /* a temp file, used to save text until all */ /* symbols have been defined */ mpu_FILE *union_file; /* a temp file, used to save the union */ /* definition until all symbol have been */ /* defined */ mpu_FILE *input_file; /* the input file */ mpu_FILE *output_file; /* z_tab.c */ mpu_FILE *defines_file; /* z_tab.h */ mpu_FILE *code_file; /* z_code.c (used when the -r option is specified) */ mpu_FILE *verbose_file; /* z.output */ /* global: in defs.h define as extern */ int nitems; int nrules; int nsyms; int ntokens; int nvars; /* global: in defs.h define as extern */ int start_symbol; __mpu_char16_t **symbol_name; int *symbol_value; int *symbol_prec; char *symbol_assoc; /* global: in defs.h define as extern */ int *ritem; int *rlhs; int *rrhs; int *rprec; char *rassoc; /* global: in defs.h define as extern */ int **derives; char *nullable; /* static int out_unix_mode = 1; */ /* static int out_msg_lang; */ static void welcome( void ) { mpu_fprintf( mpu_stderr, MPU_UCS2( "\ zubr (ZUBR) %s\n\ Copyright (C) 1995 - 2026 Andrey V.Kosteltsev.\n\ This is free software. There is NO warranty; not even\n\ for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" ), ZUBR_VERSION ); } int main( int argc, char *argv[] ) /************************************************************************* Description : ZUBR Concepts : - LALR(1) Use Global Variable: Use Functions : void set_signals (void); | this file void getargs (int argc, char *argv[]); | --/-- void open_files (void); | this file void reader (void); | reader.c lr0 (); | lr0.c lalr (); | lalr.c make_parser (); | mkpar.c verbose (); | verbose.c output (); | output.c void done (int exit_code); | this file Parameters : Command Line Return : [void] *************************************************************************/ { welcome(); set_signals(); { int i; __mpu_char16_t **uargv = calloc( argc + 1, sizeof(*uargv) ); if( !uargv ) no_space(); for( i = 0; i < argc; ++i ) { uargv[i] = zubr_utf8_to_ucs2_dup( argv[i] ); if( !uargv[i] ) fatal( MPU_UCS2( "Invalid UTF-8 command line argument" ) ); } getargs( argc, uargv ); } open_files(); reader(); lr0(); lalr(); make_parser(); verbose(); output(); done( 0 ); /*NOTREACHED*/ return( 0 ); } /******* End of main( int argc, char *argv[] ) ***********************/ void done( int exit_code ) /************************************************************************* Description : delete the .tmp files befor all exit. Concepts : Use Global Variable: mpu_FILE *action_file; | this file mpu_FILE *text_file; | this file mpu_FILE *union_file; | this file mpu_FILE *input_file; | this file mpu_FILE *output_file; | this file mpu_FILE *defines_file; | this file mpu_FILE *code_file; | this file mpu_FILE *verbose_file; | this file char *action_file_name; | this file char *text_file_name; | this file char *union_file_name; | this file char *input_file_name; | this file char *output_file_name; | this file char *defines_file_name; | this file char *code_file_name; | this file char *verbose_file_name; | this file Use Functions : Parameters : int exit_code Return : [void] *************************************************************************/ { if( action_file ) { mpu_fclose( action_file ); zubr_unlink( action_file_name ); } if( action_file_name ) FREE( action_file_name ); if( text_file ) { mpu_fclose( text_file ); zubr_unlink( text_file_name ); } if( text_file_name ) FREE( text_file_name ); if( union_file ) { mpu_fclose( union_file ); zubr_unlink( union_file_name ); } if( union_file_name ) FREE( union_file_name ); if( input_file ) mpu_fclose( input_file ); if( output_file ) mpu_fclose( output_file ); if( output_file_name && C_mem ) FREE( output_file_name ); if( defines_file ) mpu_fclose( defines_file ); if( defines_file_name && D_mem ) FREE( defines_file_name ); if( code_file && rflag ) mpu_fclose( code_file ); if( code_file_name && R_mem ) FREE( code_file_name ); if( verbose_file ) mpu_fclose( verbose_file ); if( verbose_file_name && V_mem ) FREE( verbose_file_name ); if( parse_header_file ) mpu_fclose( parse_header_file ); if( parse_header_file_name ) FREE( parse_header_file_name ); if( parse_func_name ) FREE( parse_func_name ); if( lex_func_name ) FREE( lex_func_name ); if( inc_token_filename ) FREE( inc_token_filename ); if( name_prefix ) FREE( name_prefix ); if( name_prefix_upper ) FREE( name_prefix_upper ); /******************************* this functions declare in file lr0.c and not used in all files of this project *******************************/ if( nullable ) free_nullable(); if( derives ) free_derives(); /*******************************/ exit( exit_code ); } /******* End of done( int exit_code ) ********************************/ void onintr( int sig_number ) /************************************************************************* Description : call done() and exit Concepts : - only for Set_signals() Use Global Variable: Use Functions : void done (int exit_code); | this file Parameters : int sig_number // for signal() system function Return : [void] *************************************************************************/ { sig_number = sig_number; /* no warning */ done( 1 ); } /******* End of onintr( int sig_number ) *****************************/ void set_signals( void ) /************************************************************************* Description : Если родительский процесс не запрещал прерывания, то их надо обрабатывать и уходить. Concepts : - не изменять родительским установкам (see UNIX) Use Global Variable: Use Functions : void onintr (int sig_number); | this file Parameters : [void] Return : [void] *************************************************************************/ { #ifdef SIGINT if( signal(SIGINT, SIG_IGN) != SIG_IGN ) signal( SIGINT, onintr ); #endif #ifdef SIGTERM if( signal(SIGTERM, SIG_IGN) != SIG_IGN ) signal( SIGTERM, onintr ); #endif #ifdef SIGBREAK if( signal(SIGBREAK, SIG_IGN) != SIG_IGN ) signal( SIGBREAK, onintr ); #else #ifdef SIGHUP /* for UNIX-clone operating systems */ if( signal(SIGHUP, SIG_IGN ) != SIG_IGN ) signal( SIGHUP, onintr ); #endif #endif } /******* End of set_signals( void ) **********************************/ void usage( void ) __attribute__((noreturn)); void usage( void ) { mpu_fprintf( mpu_stderr, MPU_UCS2( "ZUBR %s\n" ) MPU_UCS2( "Usage: %s [-dlprstv] [other options] [-bFilePrefix] InputFile\n\n" ) MPU_UCS2( "Options:\n" ) MPU_UCS2( " -b[FilePrefix] set output file prefix\n" ) MPU_UCS2( " -d produce FilePrefix_tab.h\n" ) MPU_UCS2( " -l omit #line directives\n" ) MPU_UCS2( " -r split tables and parser code\n" ) MPU_UCS2( " -t include parser debugging code\n" ) MPU_UCS2( " -v produce FilePrefix.output\n" ) MPU_UCS2( " -p use .cpp extension\n" ) MPU_UCS2( " -s use static storage where applicable\n" ) MPU_UCS2( " -B[name] prefix global parser names\n" ) MPU_UCS2( " -C[FileName] set output code file\n" ) MPU_UCS2( " -D[FileName] set output header file\n" ) MPU_UCS2( " -I[filename] include external token definitions\n" ) MPU_UCS2( " -Lfuncname set lexer function name\n" ) MPU_UCS2( " -Pfuncname set parser function name\n" ) MPU_UCS2( " -R[FileName] split tables and code with code filename\n" ) MPU_UCS2( " -V[FileName] set verbose output filename\n" ) MPU_UCS2( " -o[FileName] set output code filename\n" ) MPU_UCS2( " --help display this help\n" ) MPU_UCS2( " --version display version\n\n" ) MPU_UCS2( "Input and output text files use UTF-8; ZUBR text is UCS-2 internally.\n" ), ZUBR_VERSION, myname ); exit( 1 ); } void is_admissible_name( __mpu_char16_t *s, int prefix_flag ) /************************************************************************* Description : is admissible file_name or file_prefix Concepts : call bad_filename() if prefix_flag = 0 call bad_fileprefix() if prefix_flag = 1 Use Global Variable: Use Functions : IS_ADMISSIBLE(char c) ( macros ) | this file void bad_filename (char *s, int l); | error.c void bad_fileprefix(char *s,int l); | error.c Parameters : char *s; int prefix_flag; Return : [void] *************************************************************************/ { register int l, len; register __mpu_char16_t *ptr; ptr = s; len = mpu_str16len( ptr ); for( l = 0; l < len; ++l ) { if( IS_ADMISSIBLE( *ptr ) ) ptr++; else { if( prefix_flag ) bad_fileprefix( s, l ); else bad_filename( s, l ); } } /* End for( l < len ) */ } /*********** End of is_admissible_name( char *, int ) ****************/ void is_admissible_func_name( __mpu_char16_t *s ) /************************************************************************* Description : is admissible func_name for zubr_lex(), zubr_parse() Concepts : call bad_funcname() Use Global Variable: Use Functions : void bad_funcname (char *s, int l); | error.c Parameters : char *s; Return : [void] *************************************************************************/ { register int l = 0, c; register __mpu_char16_t *ptr; ptr = s; c = *ptr; if( !zubr_is_alpha(c) && c != '_' ) bad_funcname( s, l ); while( (c = *++ptr) ) { ++l; if( !zubr_is_alnum(c) && c != '_' ) bad_funcname( s, l ); } } /******* End of is_admissible_func_name( char *, int ) ***************/ void cut_off_extention( __mpu_char16_t *s ) /************************************************************************* Description : cut off the extention of file_name if it exist Concepts : add '\0' Use Global Variable: Use Functions : Parameters : char *s; Return : [void] *************************************************************************/ { register int l, len; register __mpu_char16_t *ptr; len = mpu_str16len( s ) - 1; ptr = s + len; for( l = len; l > 0 && !IS_DIR_SEPARATOR(*ptr) && *ptr != '.'; --l ) --ptr; if( *ptr == '.' ) { for( l = l; l < len+1; l++ ) s[l] = NUL; } } /*************** End of cut_off_extention( char * ) ******************/ void cut_off_filename( __mpu_char16_t *s ) /************************************************************************* Description : cut off the file_name of full_file_name (stay only the current dir of source file_name) Concepts : add '\0' Use Global Variable: Use Functions : Parameters : char *s; Return : [void] *************************************************************************/ { register int l, len; register __mpu_char16_t *ptr; len = mpu_str16len( s ) - 1; ptr = s + len; for( l = len; l > 0 && !IS_DIR_SEPARATOR(*ptr); --l ) --ptr; if( IS_DIR_SEPARATOR(*ptr) || l == 0 ) { if( IS_DIR_SEPARATOR(*ptr) ) l++; for( l = l; l < len+1; l++ ) s[l] = NUL; } } /************** End of cut_off_filename( char * ) ********************/ void getargs( int argc, __mpu_char16_t *argv[] ) /************************************************************************* Description : read of command line Concepts : Use Global Variable: mpu_FILE *input_file; | this file mpu_FILE *code_file; | this file mpu_FILE *defines_file; | this file mpu_FILE *output_file; | this file mpu_FILE *verbose_file; | this file char *input_file_name; | this file char *code_file_name; | this file char *defines_file_name; | this file char *output_file_name; | this file char *verbose_file_name; | this file char *file_prefix; | this file char *myname; | this file Use Functions : void usage (void); | this file void no_space (void); | error.c is_admissible_name (char *s, int l); | this file is_admissible_func_name ( *s, l ); | this file void cut_off_extention (char *s); | this file Parameters : int argc; char *argv[]; Return : [void] *************************************************************************/ { register int i, c; register __mpu_char16_t *s; register int len; register char C_flag = 0; register char D_flag = 0; register char R_flag = 0; register char V_flag = 0; register char B_flag = 0; register char I_flag = 0; register char L_flag = 0; register char P_flag = 0; __mpu_char16_t *prefix_name_tmp = (__mpu_char16_t *)MPU_UCS2( "" ); __mpu_char16_t *inc_name_tmp = (__mpu_char16_t *)MPU_UCS2( "" ); __mpu_char16_t *lex_name_tmp = (__mpu_char16_t *)MPU_UCS2( "" ); __mpu_char16_t *parse_name_tmp = (__mpu_char16_t *)MPU_UCS2( "" ); if( argc > 0 ) myname = argv[0]; for( i = 1; i < argc; ++i ) { s = argv[i]; if( *s != '-' ) break; switch( *++s ) { case '\0': usage(); case 'B': if( B_flag ) usage(); B_flag = 1; bflag = 1; if( *++s ) { prefix_name_tmp = s; is_admissible_func_name( prefix_name_tmp ); continue; } else continue; case 'C': if( C_flag ) usage(); C_flag = 1; if( *++s ) { output_file_name = s; is_admissible_name( output_file_name, 0 ); continue; } else continue; case '-': ++s; if( !mpu_str16cmp( s, MPU_UCS2( "help" ) ) ) usage(); if( !mpu_str16cmp( s, MPU_UCS2( "version" ) ) ) done( 0 ); bad_option( argv[i] ); case 'd': dflag = 1; break; case 'D': if( D_flag ) usage(); D_flag = 1; if( *++s ) { defines_file_name = s; is_admissible_name( defines_file_name, 0 ); continue; } else continue; case 'I': if( I_flag ) usage(); I_flag = 1; iflag = 1; if( *++s ) { inc_name_tmp = s; is_admissible_name( inc_name_tmp, 0 ); continue; } else continue; case 'L': if( L_flag ) usage(); L_flag = 1; l_name_flag = 1; if( *++s ) { lex_name_tmp = s; is_admissible_func_name( lex_name_tmp ); continue; } else continue; case 'l': lflag = 1; break; case 'o': if( C_flag ) usage(); C_flag = 1; if( *++s ) { output_file_name = s; is_admissible_name( output_file_name, 0 ); continue; } else { if( ++i < argc ) { output_file_name = argv[i]; is_admissible_name( output_file_name, 0 ); continue; } else usage(); } continue; case 'P': if( P_flag ) usage(); P_flag = 1; p_name_flag = 1; if( *++s ) { parse_name_tmp = s; is_admissible_func_name( parse_name_tmp ); continue; } else continue; case 'p': pflag = 1; break; case 'r': rflag = 1; break; case 'R': if( R_flag ) usage(); R_flag = 1; if( *++s ) { code_file_name = s; is_admissible_name( code_file_name, 0 ); continue; } else continue; case 's': sflag = 1; break; case 't': tflag = 1; break; case 'v': vflag = 1; break; case 'V': if( V_flag ) usage(); V_flag = 1; if( *++s ) { verbose_file_name = s; is_admissible_name( verbose_file_name, 0 ); continue; } else continue; case 'b': if( *++s ) { file_prefix = s; is_admissible_name( file_prefix, 1 ); continue; } else { if( ++i < argc ) { file_prefix = argv[i]; is_admissible_name( file_prefix, 1 ); continue; } else usage(); } continue; default: usage(); } /* End switch( *++s ) */ for( ;; ) { switch( *++s ) { case '\0': goto end_of_option; case 'd': dflag = 1; break; case 'l': lflag = 1; break; case 'p': pflag = 1; break; case 'r': rflag = 1; break; case 's': sflag = 1; break; case 't': tflag = 1; break; case 'v': vflag = 1; break; default: usage(); } /* End switch( *++s ) */ } /* End for( ;; ) */ end_of_option: ; } /* End for( i < argc ) */ if( i + 1 != argc ) usage(); /* read input_file_name and check-up IS_ADMISSIBLE(c) */ input_file_name = argv[i]; is_admissible_name( input_file_name, 0 ); if( C_flag ) { if( !output_file_name && !rflag && !R_flag ) { if( pflag ) len = mpu_str16len( input_file_name )+1+ mpu_str16len( PROC_CPP_SUFFIX ); else len = mpu_str16len(input_file_name)+1+ mpu_str16len( PROC_C_SUFFIX ); output_file_name = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( output_file_name == 0 ) no_space(); memset( output_file_name, NUL, len * sizeof(__mpu_char16_t) ); mpu_str16cpy( output_file_name, input_file_name ); cut_off_extention( output_file_name ); if( pflag ) mpu_str16cat( output_file_name, PROC_CPP_SUFFIX ); else mpu_str16cat( output_file_name, PROC_C_SUFFIX ); C_mem = 1; /* memory for output_file_name is allocate */ } else if( rflag || R_flag ) output_file_name = NULL; else C_mem = 0; /* memory for output_file_name not allocate */ } /* Enf if( C_flag ) */ if( D_flag ) { if( !defines_file_name && !dflag ) { len = mpu_str16len( input_file_name )+1+ mpu_str16len( HEADER_SUFFIX ); defines_file_name = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( defines_file_name == 0 ) no_space(); memset( defines_file_name, NUL, len * sizeof(__mpu_char16_t) ); mpu_str16cpy( defines_file_name, input_file_name ); cut_off_extention( defines_file_name ); mpu_str16cat( defines_file_name, HEADER_SUFFIX ); D_mem = 1; /* memory for defines_file_name is allocate */ } else if( dflag ) defines_file_name = NULL; else D_mem = 0; /* memory for defines_file_name not allocate */ } /* Enf if( D_flag ) */ if( R_flag ) { if( !code_file_name && !rflag ) { /* code_file_name */ if( pflag ) len = mpu_str16len( input_file_name )+1+ mpu_str16len( PROC_CPP_SUFFIX ); else len = mpu_str16len( input_file_name )+1+ mpu_str16len( PROC_C_SUFFIX ); code_file_name = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( code_file_name == 0 ) no_space(); memset( code_file_name, NUL, len * sizeof(__mpu_char16_t) ); mpu_str16cpy( code_file_name, input_file_name ); cut_off_extention( code_file_name ); if( pflag ) mpu_str16cat( code_file_name, PROC_CPP_SUFFIX ); else mpu_str16cat( code_file_name, PROC_C_SUFFIX ); R_mem = 1; /* memory for code_file_name is allocate */ } else if( rflag ) code_file_name = NULL; else R_mem = 0; /* memory for code_file_name not allocate */ } /* Enf if( R_flag ) */ if( V_flag ) { if( !verbose_file_name && !vflag ) { len = mpu_str16len( input_file_name )+1+ mpu_str16len( VERBOSE_SUFFIX ); verbose_file_name = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( verbose_file_name == 0 ) no_space(); memset( verbose_file_name, NUL, len * sizeof(__mpu_char16_t) ); mpu_str16cpy( verbose_file_name, input_file_name ); cut_off_extention( verbose_file_name ); mpu_str16cat( verbose_file_name, VERBOSE_SUFFIX ); V_mem = 1; /* memory for verbose_file_name is allocate */ } else if( vflag ) verbose_file_name = NULL; else V_mem = 0; /* memory for verbose_file_name not allocate */ } /* Enf if( V_flag ) */ if( B_flag ) { if( prefix_name_tmp ) { len = mpu_str16len( prefix_name_tmp ) + 1; name_prefix = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( name_prefix == 0 ) no_space(); memset( name_prefix, NUL, len * sizeof(__mpu_char16_t) ); name_prefix_upper = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( name_prefix_upper == 0 ) no_space(); memset( name_prefix_upper, NUL, len * sizeof(__mpu_char16_t) ); mpu_str16cpy( name_prefix, prefix_name_tmp ); s = name_prefix; i = 0; while( (c = *s++) ) { if( zubr_is_alpha(c) ) { name_prefix_upper[i] = zubr_to_upper( name_prefix[i] ); ++i; } else { name_prefix_upper[i] = name_prefix[i]; ++i; } } /* End of while( c = *s++ ) */ } } /* Enf if( B_flag ) */ if( I_flag ) { if( inc_name_tmp ) { len = mpu_str16len( inc_name_tmp ) + 1; inc_token_filename = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( inc_token_filename == 0 ) no_space(); memset( inc_token_filename, NUL, len * sizeof(__mpu_char16_t) ); mpu_str16cpy( inc_token_filename, inc_name_tmp ); } } /* Enf if( I_flag ) */ if( L_flag ) { if( lex_name_tmp ) { len = mpu_str16len( lex_name_tmp ) + 1; lex_func_name = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( lex_func_name == 0 ) no_space(); memset( lex_func_name, NUL, len * sizeof(__mpu_char16_t) ); mpu_str16cpy( lex_func_name, lex_name_tmp ); } } /* Enf if( L_flag ) */ if( P_flag ) { if( parse_name_tmp ) { len = mpu_str16len( parse_name_tmp ) + 1; parse_func_name = (__mpu_char16_t *)MALLOC( len * sizeof(__mpu_char16_t) ); if( parse_func_name == 0 ) no_space(); memset( parse_func_name, NUL, len * sizeof(__mpu_char16_t) ); mpu_str16cpy( parse_func_name, parse_name_tmp ); } } /* Enf if( P_flag ) */ /***************************************************** reset option -s if create code_file or defines_file or define name_prefix (B_flag) *****************************************************/ if( rflag || dflag || R_flag || D_flag /*|| B_flag*/ ) sflag = 0; } /************** End of getargs( int argc, char *argv[] ) *************/ char *allocate( unsigned n ) /************************************************************************* Description : allocate n byte of memory and return pointer Concepts : Use Global Variable: Use Functions : CALLOC(k,n) // macros | defs.h Parameters : unsigned n; Return : char *p; *************************************************************************/ { register char *p; p = NULL; if( n ) { p = CALLOC( 1, n ); if( !p ) no_space(); } return( p ); } /******* End of allocate( unsigned n ) *******************************/ void create_file_names( void ) /************************************************************************* Description : create mames of .tmp files UNIX-compatible options Concepts : getenv (u"TMP") else getenv (u"TEMP") else use current directory Use Global Variable: char *file_prefix = u"z"; | this file char dflag; | this file char pflag; | this file char rflag; | this file char vflag; | this file char *action_file_name; | this file char *text_file_name; | this file char *union_file_name; | this file char *output_file_name; | this file char *defines_file_name; | this file char *code_file_name; | this file char *verbose_file_name; | this file Use Functions : void no_space (void); | error.c void cut_off_filename (char *s); | this file Parameters : [void] Return : [void] *************************************************************************/ { int i, len, nLength; __mpu_char16_t *tmpdir; tmpdir = zubr_getenv( "TMPDIR" ); if( tmpdir == NULL ) tmpdir = zubr_getenv( "TEMP" ); if( tmpdir == NULL ) tmpdir = zubr_getenv( "TMP" ); if( tmpdir == NULL ) /* current working directory */ { tmpdir = (__mpu_char16_t *)MALLOC( 1 * sizeof(__mpu_char16_t) ); *tmpdir = NUL; } #define L_pid 8 #define L_prefix 7 /* see below: u"zubr_%u." */ len = mpu_str16len( tmpdir ); i = len + L_pid + L_prefix + 4; /* L_pid defined for %u <= pid */ /* + 4 for u"_a_", u"_t_", u"_u_" and '\0' */ if( len && !IS_DIR_SEPARATOR(tmpdir[len-1]) ) ++i; action_file_name = MALLOC( i * sizeof(__mpu_char16_t) ); if( action_file_name == 0 ) no_space(); memset( action_file_name, NUL, i * sizeof(__mpu_char16_t) ); /* incinerator */ text_file_name = MALLOC( i * sizeof(__mpu_char16_t) ); if( text_file_name == 0 ) no_space(); memset( text_file_name, NUL, i * sizeof(__mpu_char16_t) ); /* incinerator */ union_file_name = MALLOC( i * sizeof(__mpu_char16_t) ); if( union_file_name == 0 ) no_space(); memset( union_file_name, NUL, i * sizeof(__mpu_char16_t) ); /* incinerator */ mpu_str16cpy( action_file_name, tmpdir ); mpu_str16cpy( text_file_name, tmpdir ); mpu_str16cpy( union_file_name, tmpdir ); if( len && !IS_DIR_SEPARATOR(tmpdir[len-1]) ) { action_file_name[len] = DIR_SEPARATOR; text_file_name[len] = DIR_SEPARATOR; union_file_name[len] = DIR_SEPARATOR; } mpu_sprintf( temp_form, MPU_UCS2( "zubr_%u." ), getpid() ); mpu_str16cat( action_file_name, temp_form ); mpu_str16cat( text_file_name, temp_form ); mpu_str16cat( union_file_name, temp_form ); mpu_str16cat( action_file_name, (__mpu_char16_t *)MPU_UCS2( "_a_" ) ); mpu_str16cat( text_file_name, (__mpu_char16_t *)MPU_UCS2( "_t_" ) ); mpu_str16cat( union_file_name, (__mpu_char16_t *)MPU_UCS2( "_u_" ) ); FREE( tmpdir ); len = mpu_str16len( file_prefix ); if( !output_file_name ) { nLength = mpu_str16len( input_file_name ); output_file_name = (__mpu_char16_t *) MALLOC( (nLength+len+2*MAX_SUFFIX_LEN) * sizeof(__mpu_char16_t) ); /* 2*MAX_SUFFIX_LEN == 2*strlen( MAX_SUFFIX_LEN ) == 2*7 */ /* see defs.h */ if( output_file_name == 0 ) no_space(); memset( output_file_name, NUL, (nLength+len+2*MAX_SUFFIX_LEN) * sizeof(__mpu_char16_t) ); mpu_str16cpy( output_file_name, input_file_name ); cut_off_filename( output_file_name ); mpu_str16cat( output_file_name, file_prefix ); mpu_str16cat( output_file_name, OUTPUT_SUFFIX ); if( pflag ) mpu_str16cat( output_file_name, PROC_CPP_SUFFIX ); else mpu_str16cat( output_file_name, PROC_C_SUFFIX ); C_mem = 1; /* memory for output_file_name is allocate */ } if( dflag ) { nLength = mpu_str16len( input_file_name ); defines_file_name = (__mpu_char16_t *) MALLOC( (nLength+len+2*MAX_SUFFIX_LEN) * sizeof(__mpu_char16_t) ); if( defines_file_name == 0 ) no_space(); memset( defines_file_name, NUL, (nLength+len+2*MAX_SUFFIX_LEN) * sizeof(__mpu_char16_t) ); mpu_str16cpy( defines_file_name, input_file_name ); cut_off_filename( defines_file_name ); mpu_str16cat( defines_file_name, file_prefix ); mpu_str16cat( defines_file_name, DEFINES_SUFFIX ); D_mem = 1; /* memory for defines_file_name is allocate */ } if( rflag ) { nLength = mpu_str16len( input_file_name ); code_file_name = (__mpu_char16_t *) MALLOC( (nLength+len+2*MAX_SUFFIX_LEN) * sizeof(__mpu_char16_t) ); if( code_file_name == 0 ) no_space(); memset( code_file_name, NUL, (nLength+len+2*MAX_SUFFIX_LEN) * sizeof(__mpu_char16_t) ); mpu_str16cpy( code_file_name, input_file_name ); cut_off_filename( code_file_name ); mpu_str16cat( code_file_name, file_prefix ); mpu_str16cat( code_file_name, CODE_SUFFIX ); if( pflag ) mpu_str16cat( code_file_name, PROC_CPP_SUFFIX ); else mpu_str16cat( code_file_name, PROC_C_SUFFIX ); R_mem = 1; /* memory for code_file_name is allocate */ } else if( !code_file_name ) { code_file_name = output_file_name; R_mem = NUL;/*NULL*/ /* not repeat free memory in done() */ } else rflag = 1; /* rflag for use open_files() */ if( vflag ) { nLength = mpu_str16len( input_file_name ); verbose_file_name = (__mpu_char16_t *) MALLOC( (nLength+len+2*MAX_SUFFIX_LEN) * sizeof(__mpu_char16_t) ); if( verbose_file_name == 0 ) no_space(); memset( verbose_file_name, NUL, (nLength+len+2*MAX_SUFFIX_LEN) * sizeof(__mpu_char16_t) ); mpu_str16cpy( verbose_file_name, input_file_name ); cut_off_filename( verbose_file_name ); mpu_str16cat( verbose_file_name, file_prefix ); mpu_str16cat( verbose_file_name, VERBOSE_SUFFIX ); V_mem = 1; /* memory for verbose_file_name is allocate */ } if( p_name_flag ) { if( parse_func_name ) { len = mpu_str16len( parse_func_name ); nLength = mpu_str16len( input_file_name ); parse_header_file_name = (__mpu_char16_t *)MALLOC( (nLength+len+mpu_str16len(HEADER_SUFFIX)) * sizeof(__mpu_char16_t) ); if( parse_header_file_name == 0 ) no_space(); memset( parse_header_file_name, NUL, (nLength+len+mpu_str16len(HEADER_SUFFIX)) * sizeof(__mpu_char16_t) ); mpu_str16cpy( parse_header_file_name, input_file_name ); cut_off_filename( parse_header_file_name ); mpu_str16cpy( parse_header_file_name, parse_func_name ); mpu_str16cat( parse_header_file_name, HEADER_SUFFIX ); } } } /******* End of create_file_names( void ) ****************************/ void open_files( void ) /************************************************************************* Description : open files Concepts : Use Global Variable: char dflag; | this file char rflag; | this file char vflag; | this file char *action_file_name; | this file char *text_file_name; | this file char *union_file_name; | this file char *input_file_name; | this file char *output_file_name; | this file char *defines_file_name; | this file char *code_file_name; | this file char *verbose_file_name; | this file mpu_FILE *action_file; | this file mpu_FILE *text_file; | this file mpu_FILE *union_file; | this file mpu_FILE *input_file; | this file mpu_FILE *output_file; | this file mpu_FILE *defines_file; | this file mpu_FILE *code_file; | this file mpu_FILE *verbose_file; | this file Use Functions : void open_error (char *filename); | error.c int reorder_bytes( char *filename); | twinio.c Parameters : [void] Return : [void] *************************************************************************/ { create_file_names(); input_file = zubr_fopen( input_file_name, "r" ); if( input_file == 0 ) open_error( input_file_name ); action_file = zubr_fopen( action_file_name, "w" ); if( action_file == 0 ) open_error( action_file_name ); text_file = zubr_fopen( text_file_name, "w" ); if( text_file == 0 ) open_error( text_file_name ); if( vflag || verbose_file_name ) /* vflag or V_flag */ { verbose_file = zubr_fopen( verbose_file_name, "w" ); if( verbose_file == 0 ) open_error( verbose_file_name ); vflag = 1; /* if( !vflag ) vflag = 1; // for use oter functions */ } if( dflag || defines_file_name ) /* dflag or D_flag */ { defines_file = zubr_fopen( defines_file_name, "w" ); if( defines_file == 0 ) open_error( defines_file_name ); union_file = zubr_fopen( union_file_name, "w" ); if( union_file == 0 ) open_error( union_file_name ); dflag = 1; /* if( !dflag ) dflag = 1; // for use oter functions */ } output_file = zubr_fopen( output_file_name, "w" ); if( output_file == 0 ) open_error( output_file_name ); if( rflag ) /* rflag or R_flag */ { code_file = zubr_fopen( code_file_name, "w" ); if( code_file == 0 ) open_error( code_file_name ); } else code_file = output_file; if( p_name_flag ) { parse_header_file = zubr_fopen( parse_header_file_name, "w" ); if( parse_header_file == 0 ) open_error( parse_header_file_name ); } } /******* End of open_files( void ) *************************/ #endif /* __NO_COMPILE */ /****************** END OF FILE MAIN.C ***********************/