diff --git a/readme.txt b/readme.txt index d0608888..66faf392 100644 --- a/readme.txt +++ b/readme.txt @@ -50,12 +50,15 @@ Release notes: 1c/04, Lib 1.2.4: + Compiler: multiple definitions for the same style class or + metadata predicate now produce a warning. + Compiler: improved dictionary word matching accuracy. - Compiler: Improved ordering of strings in WRIT chunk, which + Compiler: improved ordering of strings in WRIT chunk, which improves performance on slow platforms like 6502. - 1c/03, Lib 1.2.4: + 1c/03, Lib 1.2.3: Language: CSS text-decoration: reverse has been replaced with -iftf-reverse-video: reverse for compatibility reasons. diff --git a/src/backend.c b/src/backend.c index d1782ba3..5de64227 100644 --- a/src/backend.c +++ b/src/backend.c @@ -300,7 +300,7 @@ int main(int argc, char **argv) { need_meta = prg->totallines > 100; - prg->meta_ifid = decode_metadata_str(BI_STORY_IFID, 0, prg, &prg->arena); + prg->meta_ifid = decode_metadata_str(BI_STORY_IFID, 0, prg, &prg->arena, "story ifid", -1); if(!prg->meta_ifid) { if(!strcmp(format, "zblorb")) { // Mandatory for zblorb, make it an error report(LVL_ERR, 0, "An IFID is mandatory for the blorb output format."); @@ -315,25 +315,25 @@ int main(int argc, char **argv) { prg->meta_ifid = 0; } - prg->meta_author = decode_metadata_str(BI_STORY_AUTHOR, 0, prg, &prg->arena); + prg->meta_author = decode_metadata_str(BI_STORY_AUTHOR, 0, prg, &prg->arena, "story author", -1); if(!prg->meta_author) { if(need_meta) { report(LVL_WARN, 0, "No author declared."); } prg->meta_author = "Anonymous"; } - prg->meta_title = decode_metadata_str(BI_STORY_TITLE, 0, prg, &prg->arena); + prg->meta_title = decode_metadata_str(BI_STORY_TITLE, 0, prg, &prg->arena, "story title", -1); if(!prg->meta_title) { if(need_meta) { report(LVL_WARN, 0, "No title declared."); } prg->meta_title = "An Interactive Fiction"; } - prg->meta_noun = decode_metadata_str(BI_STORY_NOUN, 0, prg, &prg->arena); + prg->meta_noun = decode_metadata_str(BI_STORY_NOUN, 0, prg, &prg->arena, "story noun", -1); if(!prg->meta_noun) { prg->meta_noun = "An Interactive Fiction"; } - prg->meta_blurb = decode_metadata_str(BI_STORY_BLURB, 0, prg, &prg->arena); + prg->meta_blurb = decode_metadata_str(BI_STORY_BLURB, 0, prg, &prg->arena, "story blurb", -1); predname = find_builtin(prg, BI_STORY_RELEASE); if(predname && (pred = predname->pred)->nclause) { @@ -342,8 +342,14 @@ int main(int argc, char **argv) { exit(1); } prg->meta_release = pred->clauses[0]->params[0]->value; - } else if(need_meta) { - report(LVL_WARN, 0, "No release number declared."); + if(pred->nclause > 1) { + report(LVL_WARN, pred->clauses[0]->line, "%d separate definitions found for (story release $). Only the first (at this line) will be used.", pred->nclause); + } + } else { + if(need_meta) { + report(LVL_WARN, 0, "No release number declared."); + } + prg->meta_release = 1; } if(serial_overridden) { diff --git a/src/frontend.c b/src/frontend.c index 1e2a7e90..c19830f7 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -2399,26 +2399,43 @@ static void assign_select_statements(struct program *prg) { selectforms = 0; } -char *decode_metadata_str(int builtin, struct word *param, struct program *prg, struct arena *arena) { +char *decode_metadata_str(int builtin, struct word *param, struct program *prg, struct arena *arena, const char *report_as, int lib_file) { struct predname *predname; struct predicate *pred; - char *buf; + char *buf = 0; int i; + int nfound = 0; + int nlib = 0; + line_t whichline = 0; predname = find_builtin(prg, builtin); pred = predname->pred; for(i = 0; i < pred->nclause; i++) { if(!param || (pred->clauses[i]->params[0]->kind == AN_DICTWORD && pred->clauses[i]->params[0]->word == param)) { - if(decode_output(&buf, pred->clauses[i]->body, 0, 0, arena, "Story metadata")) { - return buf; - } else { - return 0; + if(!nfound) { // First one found + if(!decode_output(&buf, pred->clauses[i]->body, 0, 0, arena, "Story metadata")) { + buf = 0; // Failed to decode into buf + } + whichline = pred->clauses[i]->line; + } + nfound ++; + if(FILENUMPART(pred->clauses[i]->line) == lib_file) { // This one was in a library file + nlib ++; } } } - return 0; + if(nfound - nlib > 1) { + if(param) { + report(LVL_WARN, whichline, "%d separate definitions found for (%s @%s) outside of the library. Only the first (at this line) will be used.", nfound, report_as, param->name); + } else { + // Disabling the warnings for meta predicates, which can usefully have defaults given in the library. Now they will only exist for style classes. + // report(LVL_WARN, whichline, "%d separate definitions found for (%s). Only the first (at this line) will be used.", nfound, report_as); + } + } + + return buf; } int frontend(struct program *prg, int nfile, char **fname, dictmap_callback_t dictmap_callback) { @@ -2896,7 +2913,7 @@ int frontend(struct program *prg, int nfile, char **fname, dictmap_callback_t di for(i = 0; i < prg->nboxclass; i++) { struct boxclass *bc = &prg->boxclasses[i]; - char *css = decode_metadata_str(BI_STYLEDEF, bc->class, prg, &lexer.temp_arena); + char *css = decode_metadata_str(BI_STYLEDEF, bc->class, prg, &lexer.temp_arena, "style class", lexer.lib_file); char *param, *str; struct boxclassline *bcl, **bclptr; diff --git a/src/frontend.h b/src/frontend.h index 3843a824..90dd23e4 100644 --- a/src/frontend.h +++ b/src/frontend.h @@ -16,7 +16,7 @@ int body_succeeds(struct astnode *an); int body_might_stop(struct astnode *an); int body_succeeds_at_most_once(struct astnode *an); void frontend_add_builtins(struct program *prg); -char *decode_metadata_str(int builtin, struct word *param, struct program *prg, struct arena *arena); +char *decode_metadata_str(int builtin, struct word *param, struct program *prg, struct arena *arena, const char *report_as, int lib_file); int frontend(struct program *prg, int nfile, char **fname, dictmap_callback_t dictmap_callback); int frontend_inject_query(struct program *prg, struct predname *predname, struct predname *tailpred, struct word *prompt, const uint8_t *str); diff --git a/stdlib.dg b/stdlib.dg index 8250ee02..d4add1c3 100644 --- a/stdlib.dg +++ b/stdlib.dg @@ -1,5 +1,5 @@ -(library version) Library version 1.2.3. +(library version) Library version 1.2.4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Global variables @@ -5148,12 +5148,6 @@ (story author or default) (story author) (story author or default) Anonymous -%% Don't warn about querying these; however, this does not disable the warning -%% about them not being defined (for a sufficiently large story): - -(story title) (fail) -(story author) (fail) - %% We can safely supply defaults for the following: (story release 1) @@ -5161,6 +5155,14 @@ (story noun) An interactive fiction +%% Don't warn about querying these; however, this does not disable the warning +%% about them not being defined (for a sufficiently large story): + +(story title) (fail) +(story author) (fail) +(story noun) (fail) +(story release $) (fail) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Game over