From: David Schleef Date: Wed, 28 Jul 2010 07:57:23 +0000 (-0700) Subject: Add logging to orc_parse X-Git-Tag: orc-0.4.7~109 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1ec9e071beefa0a35a7936507c52eb0bb60f9841;p=platform%2Fupstream%2Forc.git Add logging to orc_parse And (finally) some error reporting in orcc. --- diff --git a/orc/orccompiler.c b/orc/orccompiler.c index 82eede6..16423b8 100644 --- a/orc/orccompiler.c +++ b/orc/orccompiler.c @@ -259,7 +259,7 @@ orc_program_compile_full (OrcProgram *program, OrcTarget *target, orc_compiler_allocate_codemem (compiler); if (compiler->error) goto error; - ORC_INFO("compiling for target"); + ORC_INFO("compiling for target \"%s\"", compiler->target->name); compiler->target->compile (compiler); if (compiler->error) goto error; diff --git a/orc/orcparse.c b/orc/orcparse.c index a6eef1b..688ec62 100644 --- a/orc/orcparse.c +++ b/orc/orcparse.c @@ -30,19 +30,33 @@ struct _OrcParser { OrcOpcodeSet *opcode_set; OrcProgram *program; + OrcProgram *error_program; OrcProgram **programs; int n_programs; int n_programs_alloc; + + char *log; + int log_size; + int log_alloc; }; static void orc_parse_get_line (OrcParser *parser); static OrcStaticOpcode * get_opcode (OrcParser *parser, const char *opcode); +static void orc_parse_log (OrcParser *parser, const char *format, ...); +static int opcode_n_args (OrcStaticOpcode *opcode); +static void orc_parse_sanity_check (OrcParser *parser, OrcProgram *program); int orc_parse (const char *code, OrcProgram ***programs) { + return orc_parse_full (code, programs, NULL); +} + +int +orc_parse_full (const char *code, OrcProgram ***programs, char **log) +{ OrcParser _parser; OrcParser *parser = &_parser; @@ -50,9 +64,12 @@ orc_parse (const char *code, OrcProgram ***programs) parser->code = code; parser->code_length = strlen (code); - parser->line_number = -1; + parser->line_number = 0; parser->p = code; parser->opcode_set = orc_opcode_set_get ("sys"); + parser->log = malloc(100); + parser->log_alloc = 100; + parser->log_size = 0; while (parser->p[0] != 0) { char *p; @@ -105,6 +122,9 @@ orc_parse (const char *code, OrcProgram ***programs) if (token[0][0] == '.') { if (strcmp (token[0], ".function") == 0) { + if (parser->program) { + orc_parse_sanity_check (parser, parser->program); + } parser->program = orc_program_new (); orc_program_set_name (parser->program, token[1]); if (parser->n_programs == parser->n_programs_alloc) { @@ -163,7 +183,8 @@ orc_parse (const char *code, OrcProgram ***programs) int size = strtol (token[1], NULL, 0); orc_program_add_parameter_float (parser->program, size, token[2]); } else { - ORC_ERROR("ERROR: unknown directive: %s", token[0]); + orc_parse_log (parser, "error: line %d: unknown directive: %s\n", + parser->line_number, token[0]); } } else { OrcStaticOpcode *o; @@ -171,6 +192,14 @@ orc_parse (const char *code, OrcProgram ***programs) o = get_opcode (parser, token[0]); if (o) { + int n_args = opcode_n_args (o); + + if (n_tokens != 1 + n_args) { + orc_parse_log (parser, "error: line %d: too %s arguments for %s (expected %d)\n", + parser->line_number, (n_tokens < 1+n_args) ? "few" : "many", + token[0], n_args); + } + if (n_tokens == 4) { char *end; int imm = strtol (token[3], &end, 0); @@ -190,14 +219,24 @@ orc_parse (const char *code, OrcProgram ***programs) token[1], token[2]); } } else { - printf("ERROR: unknown token[0]: %s\n", token[0]); + orc_parse_log (parser, "error: line %d: unknown opcode: %s\n", + parser->line_number, + token[0]); } } } + if (parser->program) { + orc_parse_sanity_check (parser, parser->program); + } if (parser->line) free (parser->line); + if (log) { + *log = parser->log; + } else { + free (parser->log); + } *programs = parser->programs; return parser->n_programs; } @@ -216,6 +255,62 @@ get_opcode (OrcParser *parser, const char *opcode) return NULL; } +static int +opcode_n_args (OrcStaticOpcode *opcode) +{ + int i; + int n = 0; + for(i=0;idest_size[i] != 0) n++; + } + for(i=0;isrc_size[i] != 0) n++; + } + return n; +} + +static void +orc_parse_log_valist (OrcParser *parser, const char *format, va_list args) +{ + char s[100]; + int len; + + if (parser->error_program != parser->program) { + sprintf(s, "In function %s:\n", parser->program->name); + len = strlen(s); + + if (parser->log_size + len > parser->log_alloc) { + parser->log_alloc += 100; + parser->log = realloc (parser->log, parser->log_alloc); + } + + strcpy (parser->log + parser->log_size, s); + parser->log_size += len; + parser->error_program = parser->program; + } + + vsprintf(s, format, args); + len = strlen(s); + + if (parser->log_size + len > parser->log_alloc) { + parser->log_alloc += 100; + parser->log = realloc (parser->log, parser->log_alloc); + } + + strcpy (parser->log + parser->log_size, s); + parser->log_size += len; +} + +static void +orc_parse_log (OrcParser *parser, const char *format, ...) +{ + va_list var_args; + + va_start (var_args, format); + orc_parse_log_valist (parser, format, var_args); + va_end (var_args); +} + static void orc_parse_get_line (OrcParser *parser) { @@ -245,3 +340,53 @@ orc_parse_get_line (OrcParser *parser) } +static void +orc_parse_sanity_check (OrcParser *parser, OrcProgram *program) +{ + int i; + int j; + + for(i=0;i<=ORC_VAR_T15;i++) { + if (program->vars[i].size == 0) continue; + for(j=i+1;j<=ORC_VAR_T15;j++) { + if (program->vars[j].size == 0) continue; + + if (strcmp (program->vars[i].name, program->vars[j].name) == 0) { + orc_parse_log (parser, "error: duplicate variable name: %s\n", + program->vars[i].name); + } + } + } + + for(i=0;in_insns;i++){ + OrcInstruction *insn = program->insns + i; + OrcStaticOpcode *opcode = insn->opcode; + + for(j=0;jdest_size[j] == 0) continue; + if (program->vars[insn->dest_args[j]].used && + program->vars[insn->dest_args[j]].vartype == ORC_VAR_TYPE_DEST) { + orc_parse_log (parser, "error: destination \"%s\" written multiple times\n", + program->vars[insn->dest_args[j]].name); + } + program->vars[insn->dest_args[j]].used = TRUE; + } + + for(j=0;jsrc_size[j] == 0) continue; + if (program->vars[insn->src_args[j]].used && + program->vars[insn->src_args[j]].vartype == ORC_VAR_TYPE_SRC) { + orc_parse_log (parser, "error: source \"%s\" read multiple times\n", + program->vars[insn->src_args[j]].name); + } + if (!program->vars[insn->src_args[j]].used && + program->vars[insn->src_args[j]].vartype == ORC_VAR_TYPE_TEMP) { + orc_parse_log (parser, "error: variable \"%s\" used before being written\n", + program->vars[insn->src_args[j]].name); + } + } + + } + +} + diff --git a/orc/orcparse.h b/orc/orcparse.h index c7588be..0d56f4d 100644 --- a/orc/orcparse.h +++ b/orc/orcparse.h @@ -7,6 +7,7 @@ ORC_BEGIN_DECLS int orc_parse (const char *code, OrcProgram ***programs); +int orc_parse_full (const char *code, OrcProgram ***programs, char **log); ORC_END_DECLS diff --git a/tools/orcc.c b/tools/orcc.c index 4759f53..e855523 100644 --- a/tools/orcc.c +++ b/tools/orcc.c @@ -77,6 +77,7 @@ main (int argc, char *argv[]) char *include_file = NULL; char *compat_version = VERSION; FILE *output; + char *log = NULL; orc_init (); orc_test_init (); @@ -171,12 +172,19 @@ main (int argc, char *argv[]) } if (output_file == NULL) { - if (mode == MODE_IMPL) { - output_file = "out.c"; - } else if (mode == MODE_HEADER) { - output_file = "out.h"; - } else if (mode == MODE_TEST) { - output_file = "out_test.c"; + switch (mode) { + case MODE_IMPL: + output_file = "out.c"; + break; + case MODE_HEADER: + output_file = "out.h"; + break; + case MODE_TEST: + output_file = "out_test.c"; + break; + case MODE_ASSEMBLY: + output_file = "out.s"; + break; } } @@ -186,7 +194,8 @@ main (int argc, char *argv[]) exit(1); } - n = orc_parse (code, &programs); + n = orc_parse_full (code, &programs, &log); + printf("%s", log); output = fopen (output_file, "w"); if (!output) {