/* rep.c Starting module for second generation replicator. */ #include #include #include #include "alpo.h" #include "rpldef.h" #include "dprmdoc.h" #include "tcl.h" #include "tk.h" #include "nra_defs.h" #include "nra_type.h" #include "nra_srv.h" #include "nra_service.h" #include "rep_hif.h" #define REP 2 #define MAXSTRLEN 80 #define MAX_STR 100 #define MAX_VALUE 1000 typedef struct symAssocIdxType { int alpo; int global; int card; int user; int last; } symAssocIdxType; typedef struct symAssocType { unsigned char symbol[MAX_STR]; unsigned char value[MAX_VALUE]; } symAssocType; struct { unsigned char symbol[100]; unsigned char value[512]; } entry_matrix[150][50]; /* extern struct { int stack; int card; int picture_set; int picture; } hif_buttons[1000]; */ Alpo *alpo; unsigned char country[100]; extern unsigned char err_str[20][100]; int check_links = 1; /* Attempt to resolve hyperlinks. Used by rich.c */ int format_lines = 0; /* Don't fill format_text array. Used by rich.c */ FILE *fd_alpo; FILE *fd_rpl; FILE *fd_rpldef; FILE *fd_hif; FILE *lnk_fd; #define SYM_ASSOC_LEN 5000 symAssocType symbol_table[SYM_ASSOC_LEN]; symAssocIdxType symbol_indices; unsigned char current_card_type[100]; unsigned char rpl_line[5000]; int eof_reached = 0; /* Symbol table related functions. */ /* * InitSymArray - intializes the symbol associative array. This array orders * the symbols by precedence with the lowest precedence first and the highest * last. This is because the lowest precedence symbols are global in scope. * By putting the dynamic, card specific symbols last, we reduce symbol * movement in the stack. We return with the global symbols from alpo first, * the global symbols from repdef second, and the dynamic card and user * defined symbols last. */ #define HEX_RAD 16 #define MAX_GLOBAL_DEFS 25 #define MAX_FIELD_LENGTH 30 #define MAX_NAME_LENGTH 30 #define MAX_FIELDS 50 #define MAX_CARD_TYPES 50 void symbol_table_init () { int i = 0; int j = 0; unsigned char temp[MAX_ASSOC_STR]; unsigned char buf[5000]; unsigned char current_value[100]; int value_index = 0; int globals_index = 0; memset ((void *) symbol_table, 0, sizeof(symAssocType) * SYM_ASSOC_LEN); if (alpo->numIcons > (SYM_ASSOC_LEN/2)) { printf("Too many alpo icons for symbol table. Exiting. \n"); exit(1); } symbol_indices.alpo = 0; for (i = 0; inumIcons; i++) { strcpy (symbol_table[i].symbol, alpo->icon[i].name); sprintf(temp,"%x", alpo->icon[i].number); strcpy (symbol_table[i].value, temp); } symbol_indices.global = i; /* read top line of .rpl file */ if (fgets(buf,1000,fd_rpl)==NULL) { printf("Empty rpl file. Exiting. \n"); exit(1); } for (j=0; buf[j]; j++) { if (buf[j] == '|') { current_value[value_index] = '\0'; strcpy (symbol_table[i].symbol, global_defs[globals_index]); strcpy (symbol_table[i].value, current_value); i++; globals_index++; value_index = 0; continue; } current_value[value_index++] = buf[j]; } symbol_indices.card = i -1; symbol_indices.user = i -1; symbol_indices.last = i -1; return; } void ClearCardSyms(symAssocIdxType symAssocIdx, symAssocType symAssoc[]) { int i; for (i=symAssocIdx.card; i -a \n"); printf (" OR \n"); printf (" -a -s -c \n"); return (1); } while (--argc) { ++argv; switch (**argv) { case '-': switch (*((*argv)+1)) { case 'r': case 'R': if (--argc) { ++argv; strcpy(RplFile, *argv); RplFile_OK = 1; } break; case 'a': case 'A': if (--argc) { ++argv; strcpy(AlpoFile, *argv); AlpoFile_OK = 1; } break; case 's': case 'S': if (--argc) { ++argv; sscanf(*argv,"%d",&starting_stack); stack_ok = 1; } break; case 'c': case 'C': if (--argc) { ++argv; sscanf(*argv,"%d",&starting_card); card_ok = 1; } break; default: BadArg = 1; break; } /* end switch */ break; default: BadArg = 1; break; } /* end switch */ } /* end while */ if ( !AlpoFile_OK || BadArg ) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ("ERROR : Command line arguments not valid\n"); exit(1); } if ( (!card_ok && stack_ok ) || (card_ok && !stack_ok ) ) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ("ERROR : must specify both starting stack and card\n"); printf ("for interactive mode.\n"); exit(1); } if ( card_ok && stack_ok ) rep_interactive = 1; /* Alpo Malloc */ alpo = alp_mallocAlpo(); if (alpo == NULL) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ("ERROR : Couldn't malloc Alpo structure!\n"); return 1; } /* Open files */ if ((fd_alpo = fopen(AlpoFile,"r")) == (FILE *)NULL ) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ("ERROR : alpo file missing!\n"); exit(0); } if ((fd_rpldef = fopen("rpldef","r")) == NULL) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ( "ERROR : Could not open rpldef. Exiting.\n"); exit(1); } for (j=0;AlpoFile[j];j++) { if (AlpoFile[j] == '.') break; country[j] = AlpoFile[j]; } country[j] = '\0'; strcpy(LnkFile,country); strcat(LnkFile,".lnk"); if ((lnk_fd = fopen (LnkFile, "r")) == NULL) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ( "ERROR : Could not open lnk file '%s'. Exiting.\n", LnkFile); exit(1); } /* Initialize the drawparm module */ if (!DprmDoc(country)) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); fprintf (stderr, "\nError initializing the drawparameter file"); return(1); } /* Read alpo */ status = alp_readAlpo (fd_alpo, alpo); fclose (fd_alpo); if (status < 0) { switch (status) { case TOKEN_NOT_FOUND: sprintf (msg, "%s - TOKEN_NOT_FOUND", AlpoFile); break; case BEGIN_NOT_FOUND: sprintf (msg, "%s - BEGIN_NOT_FOUND", AlpoFile); break; case END_NOT_FOUND: sprintf (msg, "%s - END_NOT_FOUND", AlpoFile); break; case BAD_POINTER: sprintf (msg, "%s - BAD_POINTER", AlpoFile); break; case MEM_ALLOC_ERR: sprintf (msg, "%s - MEM_ALLOC_ERR", AlpoFile); break; case FONT_NOT_FOUND: sprintf (msg, "%s - FONT_NOT_FOUND", AlpoFile); break; case UNKNOWN_EXPANSION: sprintf (msg, "%s - UNKNOWN_EXPANSION", AlpoFile); break; case UNKNOWN_PLACEMENT: sprintf (msg, "%s - UNKNOWN_PLACEMENT", AlpoFile); break; } strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ( "ERROR : %s\n", msg); return 1; } /* Read the rpldef file. */ read_rpldef(); rpl_line[0] = '\0'; eof_reached = 0; /* ... new routine, simulate_tmp, needs to use this string for visual simulation */ /* ... a general check for re-initialization should be made. */ if (!rep_interactive) { /* open rpl file */ if ((fd_rpl = fopen(RplFile,"r")) == (FILE *)NULL ) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ("ERROR : Could not find indicated .rpl file!\n"); exit(0); } /* name .hif after the rpl file */ strcpy (HifFile, RplFile); for (i=strlen(HifFile)-1; i > 0 && HifFile[i-1] != '.'; i--); strcpy (&HifFile[i], "hif"); if ((fd_hif = fopen (HifFile, "w")) == NULL) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf ( "ERROR : Could not open output file '%s'. Exiting.\n", HifFile); exit(1); } /* Read symbol values from alpo and from the top of the .rpl file (globals). */ symbol_table_init ( ); /* read STACK_TOP */ read_top_stack(); write_tmp_to_hif(); /* read card from .rpl until EOF */ while (!eof_reached && card_from_rpl()) { current_card++; read_template(); write_tmp_to_hif(); ClearCardSyms(symbol_indices,symbol_table); ClearUserSyms(symbol_indices,symbol_table); } /* write one more line */ fprintf (fd_hif, "\\end_HIFF\n"); fclose (fd_hif); printf ("REPLICAT %s ... DONE\n", HifFile); } else { /* Open srvman.dat and load in picture and sound data */ if (load_srv_man()) fprintf(stderr,"Couldn't load service file: %s\n",SRV_MAN_DAT); /* First stack and card */ rc = load_stack ( starting_stack ); if (rc) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf("Couldn't load stack %d.\n",starting_stack); exit(1); } rc = load_card ( starting_card ); /* calls card_from_rpl() */ if (rc) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf("Couldn't load card %d.\n",starting_card); exit(1); } current_stack = starting_stack; current_card = starting_card; init_tcl(); if (using_rpl) { if (read_template()) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf("Could not simulate first stack and card \n"); exit(1); } } if (simulate_tmp()) { strcpy(string,_DATE_); printf("rep: Last Built %s.\n",string); printf("Could not simulate first stack and card \n"); exit(1); } /* Event loop */ while (tk_NumMainWindows > 0) { Tk_DoOneEvent(0); /* this and the previous line are the normal Tk_MainLoop */ if (Button_down) { if (Button_number) { dispatch_signal(Button_number, IIS_EVENT_SIG); Button_number = 0; } Button_down = 0; if (raise_buttons()) /* Bring the buttons to the top of input plane */ { printf("Problem raising buttons.\n"); exit(1); } } if (Update_request) { Update_request = 0; sim_return = 0; temp_return = 0; looped = 0; /* JUST FOR NOW, we always re-load stack even on relative stack jumps */ do { looped++; if (temp_return || sim_return) { starting_stack = one_stack_back; starting_card = one_card_back; } rc = load_stack (starting_stack); if (rc) { sprintf(err_str[0],"Couldn't load stack %d.",starting_stack); sprintf(err_str[1],""); rep_error(REP); rc = load_stack(current_stack); if (rc) { printf("Couldn't re-load stack %d!\n",current_stack); exit(1); } rc = load_card(current_card); if (rc) { printf("Couldn't re-load card %d!\n",current_card); exit(1); } } else { rc = load_card (starting_card); if (rc) { sprintf(err_str[0],"Couldn't load card %d.",starting_card); sprintf(err_str[1],""); rep_error(REP); rc = load_stack(current_stack); if (rc) { printf("Couldn't re-load stack %d!\n",current_stack); exit(1); } rc = load_card(current_card); if (rc) { printf("Couldn't re-load card %d!\n",current_card); exit(1); } } } one_stack_back = current_stack; one_card_back = current_card; current_stack = starting_stack; current_card = starting_card; if (using_rpl) { temp_return = read_template(); } if (!temp_return) { sim_return = simulate_tmp(); } } while (temp_return || sim_return); /* If read_template and simulate_tmp return 0, card was read and simulated properly. */ /* If didn't loop more than once, button_down was successful. erase error messages. */ if (looped <= 1) { rep_err_erase(); } } /* End if (Update_request) */ if (Redraw_request) { /* ... this and the button_down code above need to share methods. */ if (using_rpl) { if (read_template()) { printf("Redraw failed reading template \n"); exit(1); } if (simulate_tmp()) { printf("Redraw failed simulating template\n"); exit(1); } } else { rc = load_stack(current_stack); if (rc) { printf("Couldn't re-load stack!\n"); exit(1); } rc = load_card(current_card); if (rc) { printf("Couldn't re-load card!\n"); exit(1); } if (simulate_tmp()) { printf("Redraw failed\n"); exit(1); } } Redraw_request = 0; } if (Exit_request) { clean_up_xpm(); exit(0); } } } /* Free */ alp_freeAlpo (alpo); fclose (lnk_fd); fclose (fd_rpldef); exit(0); } write_tmp_to_hif() { fputs(tmp_hif,fd_hif); } int load_stack ( int desired_stack ) { unsigned char RplFile [MAXSTRLEN]; unsigned char HifFile [MAXSTRLEN]; if(using_rpl)fclose(fd_rpl); if(using_hif)fclose(fd_hif); rpl_line[0] = '\0'; sprintf(RplFile,"stack_%d.rpl",desired_stack); sprintf(HifFile,"stack_%d.hif",desired_stack); /* try to open rpl file */ if ((fd_rpl = fopen(RplFile,"r")) == (FILE *)NULL ) { if ((fd_hif = fopen(HifFile,"r")) == (FILE *)NULL ) { return 1; } else { using_hif = 1; using_rpl = 0; } }else { using_hif = 0; using_rpl = 1; } /* Read symbol values from alpo and from the top of the .rpl file (globals). */ if (using_rpl) symbol_table_init ( ); return 0; } int check_card; int just_checking = 0; int load_card( int desired_card ) { int i, rc; int first_char, line = 1; unsigned char buf[2000]; if (using_rpl) { if (desired_card < 1) return 1; for (i=0; i < desired_card ; i++) { if ( (first_char = getc(fd_rpl)) == EOF ) { fprintf(stderr,"Unexpected EOF trying to read first character of rpl file line %d. Exitting.\n",line); exit(1); } while (first_char != '~') { if ( fgets(buf,1000,fd_rpl) == NULL ) { fprintf(stderr,"Unexpected EOF trying to read line from rpl file line %d. Exitting.\n",line); exit(1); } line++; if ( (first_char = getc(fd_rpl)) == EOF ) { fprintf(stderr,"Unexpected EOF trying to read first character of rpl file line %d. Exitting.\n",line); exit(1); } } if ( i < (desired_card - 1) ) { if ( fgets(buf,1000,fd_rpl) == NULL ) { fprintf(stderr,"Unexpected EOF trying to read line from rpl file line %d. Exitting.\n",line); exit(1); } line++; } else { ungetc(first_char,fd_rpl); } } card_from_rpl(); } if (using_hif) { /* read HifFile into tmp_hif */ tmp_hif[0] = '\0'; fseek (fd_hif,0,0); while (fgets(buf,1000,fd_hif)) strcat(tmp_hif,buf); /* check for card */ check_card = desired_card; just_checking = 1; rc = simulate_tmp(); just_checking = 0; if (!rc) return 1; } return 0; } int card_from_rpl() { int i,j; int card_type; int line_index = 0; int line = 0; /* Read card line from .rpl file or rpl_line */ if ((!strlen(rpl_line)) && (fgets(rpl_line,1000,fd_rpl)==NULL)) { eof_reached = 1; return 0; } if (rpl_line[0] != '~') { printf("Something wrong with .rpl file.\n"); printf("Expected card line, didn't get it.\n"); printf("Exiting\n"); exit(0); } /* get card type */ for (i=0, line_index=1; rpl_line[line_index] != '|'; i++,line_index++ ) { current_card_type[i] = rpl_line[line_index]; } current_card_type[i] = '\0'; #ifdef REP_DEBUG printf("Found card %s in rpl file.\n",current_card_type); #endif line_index++; card_type = -1; for (i=0; strlen(card_types[i].name); i++ ) { if (!strcmp(current_card_type,card_types[i].name)) { card_type = i; break; } } if (card_type == -1) { printf("Couldn't find card type %s in rpldef file.\n", current_card_type); printf("Exiting.\n"); exit(0); } memset(entry_matrix,0,sizeof(entry_matrix)); /* Get Card field values. Using card type, update symbol table & indices */ for (i=0;strlen(card_types[card_type].field_names[i]);i++) { strcpy(symbol_table[symbol_indices.card+i].symbol, card_types[card_type].field_names[i]); for (j=0;(rpl_line[line_index] != '|') && rpl_line[line_index];j++,line_index++) { symbol_table[symbol_indices.card+i].value[j] = rpl_line[line_index]; } if (rpl_line[line_index] == '|') { line_index++; symbol_table[symbol_indices.card+i].value[j] = '\0'; } else { /* reached end of line before '|' */ for (;;) { if (fgets(rpl_line,1000,fd_rpl)==NULL) { printf("Rpl end-of-file reached before field end for card field values. Exiting.\n"); exit(1); } line_index = 0; /* append lines to value until '|' reached */ for (;(rpl_line[line_index] != '|') && rpl_line[line_index];j++,line_index++) { symbol_table[symbol_indices.card+i].value[j] = rpl_line[line_index]; } if (rpl_line[line_index] == '|') break; } symbol_table[symbol_indices.card+i].value[j] = '\0'; /* Text must be the last card field */ /* otherwise, there's no easy way to tell the "remainder" from another entry */ } } symbol_indices.user = symbol_indices.card + i; symbol_indices.last = symbol_indices.card + i - 1; /* Get entry field values from .rpl */ if (fgets(rpl_line,1000,fd_rpl)==NULL) { eof_reached = 1; return 1; } for (line = 0; rpl_line[0] != '~'; line++) { line_index = 0; /* Get entry values. Using card type, update entry_matrix & indices */ for (i=0;strlen(card_types[card_type].list_field_names[i]);i++) { strcpy(entry_matrix[line][i].symbol, card_types[card_type].list_field_names[i]); for (j=0;rpl_line[line_index] != '|' && rpl_line[line_index] ;j++,line_index++) { entry_matrix[line][i].value[j] = rpl_line[line_index]; } if (rpl_line[line_index] == '|') { entry_matrix[line][i].value[j] = '\0'; line_index++; } else { /* reached end of line before '|' */ for (;;) { if (fgets(rpl_line,1000,fd_rpl)==NULL) { printf("Rpl end-of-file reached before field end for card entry %d. Exiting.\n",line); exit(1); } line_index = 0; /* append lines to value until '|' reached */ for (;(rpl_line[line_index] != '|') && rpl_line[line_index];j++,line_index++) { entry_matrix[line][i].value[j] = rpl_line[line_index]; } if (rpl_line[line_index] == '|') break; } entry_matrix[line][i].value[j] = '\0'; } } entry_matrix[line][i].value[0] = '\0'; entry_matrix[line+1][0].value[0] = '\0'; entry_matrix[line+1][0].symbol[0] = '\0'; /* Get line of values from rpl */ if (fgets(rpl_line,1000,fd_rpl)==NULL) { eof_reached = 1; return 1; } } return 1; } int linecount(unsigned char *string) { int i, count; count = 0; for (i=0;string[i];i++) { if (string[i] == '\n') count++; } return count; }