summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c1372
1 files changed, 1372 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..2882216
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,1372 @@
+
+/***************************************************************
+ 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 <defs.h>
+
+#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 ***********************/