void GUI_Input::DrawText() { int h; int x,y; x = 3; h = TTF_FontHeight(GetFont()); y = (my_height - h)/2; // draw text char DrawText[10]; strcpy(DrawText, GetDrawText()); my_strupr(DrawText); if(DrawText[0] != 0){ PG_DrawObject::DrawText(x+offset_x,y+2, DrawText, textcolor, GetFont()); } }
int main( int argc, char *argv[] ) /********************************/ { FILE *in; FILE *out; char buf[MAX_LINE_LEN]; int elt; char *end; char *line; char type[50]; if( argc != 4 ) { printf( "FORMAT: parsectl [input file] [output file] [Ctl data name]\n" ); return( -1 ); } in = fopen( argv[1], "r" ); if( in == NULL ) { printf( "Could not open input file: %s\n", argv[1] ); return( -1 ); } out = fopen( argv[2], "w" ); if( out == NULL ) { printf( "Could not open output file: %s\n", argv[2] ); return( -1 ); } fputs( "/**** DO NOT MODIFY THIS FILE BY HAND. CREATED BY PARSECTL ****/\n\n\n", out ); /* Create Data struct definition */ fputs( "struct {\n", out ); fputs( " int num_ctls;\n", out ); for( elt = 0;; ++elt ) { line = get_line( buf, in ); if( line == NULL ) { break; } end = strpbrk( line, White_space ); if( end == NULL ) { printf( "No control on line %d\n", Line ); goto error; } *end = '\0'; strcpy( type, line ); line = get_line( buf, in ); // skip over data_offset if( line == NULL ) { printf( "No data offset at line %d\n", Line ); goto error; } fputs( " struct {\n", out ); fputs( " ctl_type type;\n", out ); fputs( " int control;\n", out ); fputs( " bool modified;\n", out ); fputs( " unsigned int data_offset;\n", out ); fputs( " union {\n", out ); line = get_line( buf, in ); // skip over data if( line == NULL ) { printf( "No data at line %d\n", Line ); goto error; } if( !empty_data( line ) ) { fprintf( out, " %s d1;\n", my_strlwr( type ) ); } fputs( " ctl_info d2;\n", out ); fputs( " } d3;\n", out ); fprintf( out, " } d%-d;\n", elt ); } fclose( in ); fprintf( out, "} %s = {\n", argv[3] ); fprintf( out, "%d,\n", elt ); in = fopen( argv[1], "r" ); for( ;; ) { line = get_line( buf, in ); if( line == NULL ) { break; } end = strpbrk( line, White_space ); *end = '\0'; ++end; fprintf( out, "{ %s, %s, false,", my_strupr( line ), end ); line = get_line( buf, in ); fprintf( out, " %s", line ); line = get_line( buf, in ); if( !empty_data( line ) ) { fprintf( out, ", %s },\n", line ); } else { fputs( "},\n", out ); } } fputs( "};\n\n", out ); fclose( in ); fclose( out ); return( 0 ); error: fclose( in ); fclose( out ); return( 1 ); }
int parse_directive(struct prog_info *pi) { int directive, pragma; int ok = True; int i; char *next, *data, buf[140]; struct file_info *fi_bak; struct def *def; struct data_list *incpath, *dl; next = get_next_token(pi->fi->scratch, TERM_SPACE); my_strupr(pi->fi->scratch); directive = lookup_keyword(directive_list, pi->fi->scratch + 1, True); if(directive == -1) { print_msg(pi, MSGTYPE_ERROR, "Unknown directive: %s", pi->fi->scratch); return(True); } switch(directive) { case DIRECTIVE_BYTE: if (!next) { print_msg(pi, MSGTYPE_ERROR, ".BYTE needs a size operand"); return(True); } if (pi->segment == pi->cseg) print_msg(pi, MSGTYPE_ERROR, ".BYTE directive cannot be used within the code segment (.CSEG)"); get_next_token(next, TERM_END); if (!get_expr(pi, next, &i)) return(False); if ((pi->pass == PASS_2) && pi->list_line && pi->list_on) { fprintf(pi->list_file, "%c:%06x %s\n", pi->segment->ident, pi->segment->addr, pi->list_line); pi->list_line = NULL; } if (i > 0) { fix_orglist(pi->segment); advance_ip(pi->segment, i); def_orglist(pi->segment); } break; case DIRECTIVE_CSEG: fix_orglist(pi->segment); def_orglist(pi->cseg); break; case DIRECTIVE_CSEGSIZE: break; case DIRECTIVE_DB: if((pi->pass == PASS_2) && pi->list_line && pi->list_on) { fprintf(pi->list_file, " %s\n", pi->list_line); pi->list_line = NULL; } return(parse_db(pi, next)); // break; /* Directive .def */ case DIRECTIVE_DEF: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".DEF needs an operand"); return(True); } data = get_next_token(next, TERM_EQUAL); if(!(data && (tolower(data[0]) == 'r') && isdigit(data[1]))) { print_msg(pi, MSGTYPE_ERROR, "%s needs a register (e.g. .def BZZZT = r16)", next); return(True); } i = atoi(&data[1]); /* check range of given register */ if(i > 31) print_msg(pi, MSGTYPE_ERROR, "R%d is not a valid register", i); /* check if this reg is already assigned */ for(def = pi->first_def; def; def = def->next) { if(def->reg == i && pi->pass == PASS_1 && !pi->NoRegDef) { print_msg(pi, MSGTYPE_WARNING, "r%d is already assigned to '%s'!", i, def->name); return(True); } } /* check if this regname is already defined */ for(def = pi->first_def; def; def = def->next) { if(!nocase_strcmp(def->name, next)) { if(pi->pass == PASS_1 && !pi->NoRegDef) { print_msg(pi, MSGTYPE_WARNING, "'%s' is already assigned as r%d but will now be set to r%i!", next, def->reg, i); } def->reg = i; return(True); } } /* B.A.: Check, if symbol is already defined as a label or constant */ if(pi->pass == PASS_2) { if(get_label(pi,next,NULL)) print_msg(pi, MSGTYPE_WARNING, "Name '%s' is used for a register and a label", next); if(get_constant(pi,next,NULL)) print_msg(pi, MSGTYPE_WARNING, "Name '%s' is used for a register and a constant", next); } def = malloc(sizeof(struct def)); if(!def) { print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); return(False); } def->next = NULL; if(pi->last_def) pi->last_def->next = def; else pi->first_def = def; pi->last_def = def; def->name = malloc(strlen(next) + 1); if(!def->name) { print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); return(False); } strcpy(def->name, next); def->reg = i; break; case DIRECTIVE_DEVICE: if(pi->pass == PASS_2) return(True); if(!next) { print_msg(pi, MSGTYPE_ERROR, ".DEVICE needs an operand"); return(True); } if (pi->device->name != NULL) { /* B.A.: Check for multiple device definitions */ print_msg(pi, MSGTYPE_ERROR, "More than one .DEVICE definition"); } if (pi->cseg->count || pi->dseg->count || pi->eseg->count) { /* B.A.: Check if something was already assembled */ print_msg(pi, MSGTYPE_ERROR, ".DEVICE definition must be before any code lines"); } else { if ((pi->cseg->addr != pi->cseg->lo_addr ) || (pi->dseg->addr != pi->dseg->lo_addr ) || (pi->eseg->addr != pi->eseg->lo_addr )) { /* B.A.: Check if something was already assembled XXX probably redundant */ print_msg(pi, MSGTYPE_ERROR, ".DEVICE definition must be before any .ORG directive"); } } get_next_token(next, TERM_END); pi->device = get_device(pi,next); if (!pi->device) { print_msg(pi, MSGTYPE_ERROR, "Unknown device: %s", next); pi->device = get_device(pi,NULL); /* B.A.: Fix segmentation fault if device is unknown */ } /* Now that we know the device type, we can * start memory allocation from the correct offsets. */ fix_orglist(pi->segment); rewind_segments(pi); def_orglist(pi->segment); break; case DIRECTIVE_DSEG: fix_orglist(pi->segment); def_orglist(pi->dseg); if (pi->dseg->hi_addr == 0) { /* XXX move to emit */ print_msg(pi, MSGTYPE_ERROR, "Can't use .DSEG directive because device has no RAM"); } break; case DIRECTIVE_DW: if (pi->segment->flags & SEG_BSS_DATA) { print_msg(pi, MSGTYPE_ERROR, "Can't use .DW directive in data segment (.DSEG)"); return(True); } while (next) { data = get_next_token(next, TERM_COMMA); if(pi->pass == PASS_2) { if(!get_expr(pi, next, &i)) return(False); if((i < -32768) || (i > 65535)) print_msg(pi, MSGTYPE_WARNING, "Value %d is out of range (-32768 <= k <= 65535). Will be masked", i); } if (pi->pass == PASS_2) { if (pi->list_line && pi->list_on) { fprintf(pi->list_file, " %s\n", pi->list_line); pi->list_line = NULL; fprintf(pi->list_file, "%c:%06x %04x\n", pi->segment->ident, pi->segment->addr, i); } if (pi->segment == pi->eseg) { write_ee_byte(pi, pi->eseg->addr, (unsigned char)i); write_ee_byte(pi, pi->eseg->addr + 1, (unsigned char)(i >> 8)); } if (pi->segment == pi->cseg) { write_prog_word(pi, pi->cseg->addr, i); } } if (pi->segment == pi->eseg) advance_ip(pi->eseg, 2); if (pi->segment == pi->cseg) advance_ip(pi->cseg, 1); next = data; } break; case DIRECTIVE_ENDM: case DIRECTIVE_ENDMACRO: print_msg(pi, MSGTYPE_ERROR, "No .MACRO found before .ENDMACRO"); break; case DIRECTIVE_EQU: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".EQU needs an operand"); return(True); } data = get_next_token(next, TERM_EQUAL); if(!data) { print_msg(pi, MSGTYPE_ERROR, "%s needs an expression (e.g. .EQU BZZZT = 0x2a)", next); return(True); } get_next_token(data, TERM_END); if(!get_expr(pi, data, &i)) return(False); if(test_label(pi,next,"%s have already been defined as a label")!=NULL) return(True); if(test_variable(pi,next,"%s have already been defined as a .SET variable")!=NULL) return(True); /* B.A. : New. Forward references allowed. But check, if everything is ok ... */ if(pi->pass==PASS_1) { /* Pass 1 */ if(test_constant(pi,next,"Can't redefine constant %s, use .SET instead")!=NULL) return(True); if(def_const(pi, next, i)==False) return(False); } else { /* Pass 2 */ int j; if(get_constant(pi, next, &j)==False) { /* Defined in Pass 1 and now missing ? */ print_msg(pi, MSGTYPE_ERROR, "Constant %s is missing in pass 2", next); return(False); } if(i != j) { print_msg(pi, MSGTYPE_ERROR, "Constant %s changed value from %d in pass1 to %d in pass 2", next,j,i); return(False); } /* OK. Definition is unchanged */ } if((pi->pass == PASS_2) && pi->list_line && pi->list_on) { fprintf(pi->list_file, " %s\n", pi->list_line); pi->list_line = NULL; } break; case DIRECTIVE_ESEG: fix_orglist(pi->segment); def_orglist(pi->eseg); if(pi->device->eeprom_size == 0) { /* XXX */ print_msg(pi, MSGTYPE_ERROR, "Can't use .ESEG directive because device has no EEPROM"); } break; case DIRECTIVE_EXIT: pi->fi->exit_file = True; break; /*** .include ***/ case DIRECTIVE_INCLUDE: if(!next) { print_msg(pi, MSGTYPE_ERROR, "Nothing to include"); return(True); } next = term_string(pi, next); if((pi->pass == PASS_2) && pi->list_line && pi->list_on) { fprintf(pi->list_file, " %s\n", pi->list_line); pi->list_line = NULL; } // Test if include is in local directory ok = test_include(next); data = NULL; if(!ok) for(incpath = GET_ARG_LIST(pi->args, ARG_INCLUDEPATH); incpath && !ok; incpath = incpath->next) { i = strlen(incpath->data); if(data) free(data); data = malloc(i + strlen(next) + 2); if(!data) { print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL); return(False); } strcpy(data, incpath->data); if((data[i - 1] != '\\') && (data[i - 1] != '/')) data[i++] = '/'; strcpy(&data[i], next); //printf("testing: %s\n", data); ok = test_include(data); } if(ok) { fi_bak = pi->fi; ok = parse_file(pi, data ? data : next); pi->fi = fi_bak; } else print_msg(pi, MSGTYPE_ERROR, "Cannot find include file: %s", next); if(data) free(data); break; /*** .includepath ***/ case DIRECTIVE_INCLUDEPATH: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".INCLUDEPATH needs an operand"); return(True); } data = get_next_token(next, TERM_SPACE); if(data) { print_msg(pi, MSGTYPE_ERROR, ".INCLUDEPATH needs an operand!!!"); get_next_token(data, TERM_END); if(!get_expr(pi, data, &i)) return(False); } next = term_string(pi, next); /* get arg list start pointer */ incpath = GET_ARG_LIST(pi->args, ARG_INCLUDEPATH); /* search for last element */ if(incpath == NULL) { dl = malloc(sizeof(struct data_list)); data = malloc(strlen(next)+1); if(dl && data) { dl->next = NULL; strcpy(data, next); dl->data = data; SET_ARG_LIST(pi->args, ARG_INCLUDEPATH, dl); } else { printf("Error: Unable to allocate memory\n"); return(False); } } else add_arg(&incpath, next); break; case DIRECTIVE_LIST: if(pi->pass == PASS_2) if(pi->list_file) pi->list_on = True; break; case DIRECTIVE_LISTMAC: if(pi->pass == PASS_2) SET_ARG_I(pi->args, ARG_LISTMAC, True); break; case DIRECTIVE_MACRO: return(read_macro(pi, next)); // break; case DIRECTIVE_NOLIST: if(pi->pass == PASS_2) pi->list_on = False; break; case DIRECTIVE_ORG: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".ORG needs an operand"); return(True); } get_next_token(next, TERM_END); if(!get_expr(pi, next, &i)) return(False); fix_orglist(pi->segment); pi->segment->addr = i; /* XXX advance */ def_orglist(pi->segment); if(pi->fi->label) pi->fi->label->value = i; if((pi->pass == PASS_2) && pi->list_line && pi->list_on) { fprintf(pi->list_file, " %s\n", pi->list_line); pi->list_line = NULL; } break; case DIRECTIVE_SET: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".SET needs an operand"); return(True); } data = get_next_token(next, TERM_EQUAL); if(!data) { print_msg(pi, MSGTYPE_ERROR, "%s needs an expression (e.g. .SET BZZZT = 0x2a)", next); return(True); } get_next_token(data, TERM_END); if(!get_expr(pi, data, &i)) return(False); if(test_label(pi,next,"%s have already been defined as a label")!=NULL) return(True); if(test_constant(pi,next,"%s have already been defined as a .EQU constant")!=NULL) return(True); return(def_var(pi, next, i)); // break; case DIRECTIVE_DEFINE: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".DEFINE needs an operand"); return(True); } data = get_next_token(next, TERM_SPACE); if(data) { get_next_token(data, TERM_END); if(!get_expr(pi, data, &i)) return(False); } else i = 1; if(test_label(pi,next,"%s have already been defined as a label")!=NULL) return(True); if(test_variable(pi,next,"%s have already been defined as a .SET variable")!=NULL) return(True); /* B.A. : New. Forward references allowed. But check, if everything is ok ... */ if(pi->pass==PASS_1) { /* Pass 1 */ if(test_constant(pi,next,"Can't redefine constant %s, use .SET instead")!=NULL) return(True); if(def_const(pi, next, i)==False) return(False); } else { /* Pass 2 */ int j; if(get_constant(pi, next, &j)==False) { /* Defined in Pass 1 and now missing ? */ print_msg(pi, MSGTYPE_ERROR, "Constant %s is missing in pass 2", next); return(False); } if(i != j) { print_msg(pi, MSGTYPE_ERROR, "Constant %s changed value from %d in pass1 to %d in pass 2", next,j,i); return(False); } /* OK. Definition is unchanged */ } if((pi->pass == PASS_2) && pi->list_line && pi->list_on) { fprintf(pi->list_file, " %s\n", pi->list_line); pi->list_line = NULL; } break; case DIRECTIVE_NOOVERLAP: if (pi->pass == PASS_1) { fix_orglist(pi->segment); pi->segment_overlap = SEG_DONT_OVERLAP; def_orglist(pi->segment); } break; case DIRECTIVE_OVERLAP: if (pi->pass == PASS_1) { fix_orglist(pi->segment); pi->segment_overlap = SEG_ALLOW_OVERLAP; def_orglist(pi->segment); } break; case DIRECTIVE_PRAGMA: if (!next) { print_msg(pi, MSGTYPE_ERROR, "PRAGMA needs an operand, %s should be specified", snprint_list(buf, sizeof(buf), pragma_list)); return(True); } my_strupr(next); data = get_next_token(next, TERM_SPACE); pragma = lookup_keyword(pragma_list, next, False); switch (pragma) { case PRAGMA_OVERLAP: if (pi->pass == PASS_1) { int overlap_setting = OVERLAP_UNDEFINED; if (data) { my_strupr(data); overlap_setting = lookup_keyword(overlap_value, data, False); }; switch (overlap_setting) { case OVERLAP_DEFAULT: pi->effective_overlap = GET_ARG_I(pi->args, ARG_OVERLAP); break; case OVERLAP_IGNORE: case OVERLAP_WARNING: case OVERLAP_ERROR: pi->effective_overlap = overlap_setting; break; default: print_msg(pi, MSGTYPE_ERROR, "For PRAGMA %s directive" " %s should be specified as the parameter", next, snprint_list(buf, sizeof(buf), overlap_value)); return(False); } } return(True); break; default: if(pi->pass == PASS_2) print_msg(pi, MSGTYPE_MESSAGE, "PRAGMA %s directive currently ignored", next); return(True); } break; case DIRECTIVE_UNDEF: // TODO break; case DIRECTIVE_IFDEF: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".IFDEF needs an operand"); return(True); } get_next_token(next, TERM_END); /* B.A. : Forward referenc is not allowed for ifdef and ifndef */ /* Store undefined symbols in blacklist in pass1 and check, if they are still undefined in pass2 */ if(get_symbol(pi, next, NULL)) { #if 0 // If it's not defined in the first pass, but was defined later // then it should be considered OK with regards to ifdef..endif and // ifndef..endif code sections. Removed this code. if(pi->pass==PASS_2) { /* B.A. : 'Still undefined'-test in pass 2 */ if(test_blacklist(pi,next,"Forward reference (%s) not allowed in .ifdef directive")!=NULL) return(False); } #else pi->conditional_depth++; #endif } else { if(pi->pass==PASS_1) { /* B.A. : Store undefined symbols in pass 1 */ if(def_blacklist(pi, next)==False) return(False); } if(!spool_conditional(pi, False)) return(False); } break; case DIRECTIVE_IFNDEF: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".IFNDEF needs an operand"); return(True); } get_next_token(next, TERM_END); /* B.A. : Forward referenc is not allowed for ifdef and ifndef */ /* Store undefined symbols in blacklist in pass1 and check, if they are still undefined in pass2 */ if(!get_symbol(pi, next, NULL)) { #if 0 if(pi->pass==PASS_2) { /* B.A. : 'Still undefined'-test in pass 2 */ // If it's not defined in the first pass, but was defined later // then it should be considered OK with regards to ifdef..endif and // ifndef..endif code sections. Removed this code. if(test_blacklist(pi,next,"Forward reference (%s) not allowed in .ifndef directive")!=NULL) return(False); } if(!spool_conditional(pi, False)) return(False); #else pi->conditional_depth++; #endif } else { if(pi->pass==PASS_1) { /* B.A. : Store undefined symbols in pass 1 */ if(def_blacklist(pi, next)==False) return(False); } if(!spool_conditional(pi, False)) return(False); } break; case DIRECTIVE_IF: if(!next) { print_msg(pi, MSGTYPE_ERROR, ".IF needs an expression"); return(True); } get_next_token(next, TERM_END); if(!get_expr(pi, next, &i)) return(False); if(i) pi->conditional_depth++; else { if(!spool_conditional(pi, False)) return(False); } break; case DIRECTIVE_ELSE: case DIRECTIVE_ELIF: case DIRECTIVE_ELSEIF: if(!spool_conditional(pi, True)) return(False); break; case DIRECTIVE_ENDIF: if(pi->conditional_depth == 0) print_msg(pi, MSGTYPE_ERROR, "Too many .ENDIF"); else pi->conditional_depth--; break; case DIRECTIVE_MESSAGE: if(pi->pass == PASS_1) return(True); if(!next) { print_msg(pi, MSGTYPE_ERROR, "No message parameter supplied"); return(True); } /* B.A : Extended .MESSAGE. Now a comma separated list like in .db is possible and not only a string */ print_msg(pi, MSGTYPE_MESSAGE_NO_LF, NULL); /* Prints Line Header (filename, linenumber) without trailing /n */ while(next) { /* Modified code from parse_db(). Thank you :-) */ data = get_next_token(next, TERM_COMMA); if(next[0] == '\"') { /* string parsing */ next = term_string(pi, next); print_msg(pi, MSGTYPE_APPEND,"%s",next); while(*next != '\0') { next++; } } else { if(!get_expr(pi, next, &i)) { print_msg(pi, MSGTYPE_APPEND,"\n"); /* Add newline */ return(False); } print_msg(pi, MSGTYPE_APPEND,"0x%02X",i); } next = data; } print_msg(pi, MSGTYPE_APPEND,"\n"); /* Add newline */ break; case DIRECTIVE_WARNING: if(pi->pass == PASS_1) return(True); if(!next) { print_msg(pi, MSGTYPE_ERROR, "No warning string supplied"); return(True); } next = term_string(pi, next); print_msg(pi, MSGTYPE_WARNING, next); break; case DIRECTIVE_ERROR: if(!next) { /* B.A : Fix segfault bug if .error without parameter was used */ print_msg(pi, MSGTYPE_ERROR, "No error string supplied"); return(True); } next = term_string(pi, next); print_msg(pi, MSGTYPE_ERROR, "%s", next); pi->error_count = pi->max_errors; if(pi->pass == PASS_1) return(True); break; }