diff --git a/src/avrpart.c b/src/avrpart.c index 5bab5a2b..29bfbcc2 100644 --- a/src/avrpart.c +++ b/src/avrpart.c @@ -579,7 +579,7 @@ AVRPART * avr_new_part(void) p->reset_disposition = RESET_DEDICATED; p->retry_pulse = PIN_AVR_SCK; p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING; - p->config_file[0] = 0; + p->config_file = NULL; p->lineno = 0; memset(p->signature, 0xFF, 3); p->ctl_stack_type = CTL_STACK_NONE; diff --git a/src/config.c b/src/config.c index 00ac8b0e..4308407e 100644 --- a/src/config.c +++ b/src/config.c @@ -50,8 +50,8 @@ LISTID part_list; LISTID programmers; bool is_alias; -int lineno; -const char * infile; +int cfg_lineno; +char * cfg_infile; extern char * yytext; @@ -76,8 +76,8 @@ int init_config(void) programmers = lcreat(NULL, 0); is_alias = false; - lineno = 1; - infile = NULL; + cfg_lineno = 1; + cfg_infile = NULL; return 0; } @@ -99,7 +99,7 @@ int yyerror(char * errmsg, ...) va_start(args, errmsg); vsnprintf(message, sizeof(message), errmsg, args); - avrdude_message(MSG_INFO, "%s: error at %s:%d: %s\n", progname, infile, lineno, message); + avrdude_message(MSG_INFO, "%s: error at %s:%d: %s\n", progname, cfg_infile, cfg_lineno, message); va_end(args); @@ -116,7 +116,7 @@ int yywarning(char * errmsg, ...) va_start(args, errmsg); vsnprintf(message, sizeof(message), errmsg, args); - avrdude_message(MSG_INFO, "%s: warning at %s:%d: %s\n", progname, infile, lineno, message); + avrdude_message(MSG_INFO, "%s: warning at %s:%d: %s\n", progname, cfg_infile, cfg_lineno, message); va_end(args); @@ -329,15 +329,22 @@ int read_config(const char * file) FILE * f; int r; - f = fopen(file, "r"); - if (f == NULL) { - avrdude_message(MSG_INFO, "%s: can't open config file \"%s\": %s\n", + if(!(cfg_infile = realpath(file, NULL))) { + avrdude_message(MSG_INFO, "%s: can't determine realpath() of config file \"%s\": %s\n", progname, file, strerror(errno)); return -1; } - lineno = 1; - infile = file; + f = fopen(cfg_infile, "r"); + if (f == NULL) { + avrdude_message(MSG_INFO, "%s: can't open config file \"%s\": %s\n", + progname, cfg_infile, strerror(errno)); + free(cfg_infile); + cfg_infile = NULL; + return -1; + } + + cfg_lineno = 1; yyin = f; r = yyparse(); @@ -349,5 +356,41 @@ int read_config(const char * file) fclose(f); + if(cfg_infile) { + free(cfg_infile); + cfg_infile = NULL; + } + return r; } + + +// Linear-search cache for a few often-referenced strings +char *cache_string(const char *file) { + static char **fnames; + static int n=0; + + if(!file) + return NULL; + + // Exists in cache? + for(int i=0; ilineno; + int temp = cfg_lineno; cfg_lineno = current_prog->lineno; yywarning("programmer %s overwrites previous definition %s:%d.", id, existing_prog->config_file, existing_prog->lineno); - lineno = temp; + cfg_lineno = temp; } lrmv_d(programmers, existing_prog); pgm_free(existing_prog); @@ -311,8 +311,8 @@ prog_decl : yyerror("could not create pgm instance"); YYABORT; } - strcpy(current_prog->config_file, infile); - current_prog->lineno = lineno; + current_prog->config_file = cache_string(cfg_infile); + current_prog->lineno = cfg_lineno; } | K_PROGRAMMER K_PARENT TKN_STRING @@ -329,8 +329,8 @@ prog_decl : free_token($3); YYABORT; } - strcpy(current_prog->config_file, infile); - current_prog->lineno = lineno; + current_prog->config_file = cache_string(cfg_infile); + current_prog->lineno = cfg_lineno; free_token($3); } ; @@ -380,11 +380,11 @@ part_def : existing_part = locate_part(part_list, current_part->id); if (existing_part) { { /* temporarily set lineno to lineno of part start */ - int temp = lineno; lineno = current_part->lineno; + int temp = cfg_lineno; cfg_lineno = current_part->lineno; yywarning("part %s overwrites previous definition %s:%d.", current_part->id, existing_part->config_file, existing_part->lineno); - lineno = temp; + cfg_lineno = temp; } lrmv_d(part_list, existing_part); avr_free_part(existing_part); @@ -402,8 +402,8 @@ part_decl : yyerror("could not create part instance"); YYABORT; } - strcpy(current_part->config_file, infile); - current_part->lineno = lineno; + current_part->config_file = cache_string(cfg_infile); + current_part->lineno = cfg_lineno; } | K_PART K_PARENT TKN_STRING { @@ -420,8 +420,8 @@ part_decl : free_token($3); YYABORT; } - strcpy(current_part->config_file, infile); - current_part->lineno = lineno; + current_part->config_file = cache_string(cfg_infile); + current_part->lineno = cfg_lineno; free_token($3); } @@ -1362,7 +1362,7 @@ mem_spec : if (ps <= 0) avrdude_message(MSG_INFO, "%s, line %d: invalid page size %d, ignored\n", - infile, lineno, ps); + cfg_infile, cfg_lineno, ps); else current_mem->page_size = ps; free_token($3); diff --git a/src/lexer.l b/src/lexer.l index 38d988db..4db95f6d 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -73,19 +73,19 @@ SIGN [+-] # { /* The following eats '#' style comments to end of line */ BEGIN(comment); } [^\n] { /* eat comments */ } -\n { lineno++; BEGIN(INITIAL); } +\n { cfg_lineno++; BEGIN(INITIAL); } "/*" { /* The following eats multiline C style comments */ int c; int comment_start; - comment_start = lineno; + comment_start = cfg_lineno; while (1) { while (((c = input()) != '*') && (c != EOF)) { /* eat up text of comment, but keep counting lines */ if (c == '\n') - lineno++; + cfg_lineno++; } if (c == '*') { @@ -256,7 +256,7 @@ yes { yylval=new_token(K_YES); return K_YES; } "(" { yylval = NULL; pyytext(); return TKN_LEFT_PAREN; } ")" { yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; } -"\n" { lineno++; } +"\n" { cfg_lineno++; } [ \r\t]+ { /* ignore whitespace */ } c: { yyerror("possible old-style config file entry\n" diff --git a/src/libavrdude.h b/src/libavrdude.h index 57d91937..5e0e7807 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -277,8 +277,8 @@ typedef struct avrpart { LISTID mem; /* avr memory definitions */ LISTID mem_alias; /* memory alias definitions */ - char config_file[PATH_MAX]; /* config file where defined */ - int lineno; /* config file line number */ + char *config_file; /* config file where defined */ + int lineno; /* config file line number */ } AVRPART; #define AVR_MEMDESCLEN 64 @@ -726,7 +726,7 @@ typedef struct programmer_t { int (*parseextparams) (struct programmer_t * pgm, LISTID xparams); void (*setup) (struct programmer_t * pgm); void (*teardown) (struct programmer_t * pgm); - char config_file[PATH_MAX]; /* config file where defined */ + char *config_file; /* config file where defined */ int lineno; /* config file line number */ void *cookie; /* for private use by the programmer */ char flag; /* for private use of the programmer */ diff --git a/src/pgm.c b/src/pgm.c index 4580cbbd..d85f35e4 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -79,7 +79,7 @@ PROGRAMMER * pgm_new(void) pgm->usbpid = lcreat(NULL, 0); pgm->desc[0] = 0; pgm->type[0] = 0; - pgm->config_file[0] = 0; + pgm->config_file = NULL; pgm->lineno = 0; pgm->baudrate = 0; pgm->initpgm = NULL;