#include <phantasmal/phrase.h> #include <phantasmal/log.h> #include <phantasmal/lpc_names.h> #include <limits.h> #include <type.h> /********************* Loading phrases from files **********************/ private mapping phrasepaths; /* Local prototypes */ mapping load_filemanaged_file(string path); object get_filemanaged_phrase(string path, string ident); void save_filemanaged_file(string path); void new_filemanaged_file(string path); static void create(varargs int clone) { if(!find_object(UNQ_PARSER)) compile_object(UNQ_PARSER); phrasepaths = ([ ]); } void upgraded(varargs int clone) { mixed *files; int ctr, any_failures; any_failures = 0; files = map_indices(phrasepaths); phrasepaths = ([ ]); for(ctr = 0; ctr < sizeof(files); ctr++) { if(!load_filemanaged_file(files[ctr])) any_failures = 1; } if(any_failures) { LOGD->write_syslog("Can't reload all files in phrase repository " + object_name(this_object()), LOG_ERR); } } object file_phrase(string path, string ident) { mapping file; file = phrasepaths[path]; if(!file) { /* Load phrases from file */ file = load_filemanaged_file(path); if(!file) { LOGD->write_syslog("Requested phrase from nonexistent file " + path, LOG_WARN); return nil; } } if(file[ident]) { return file[ident]; } LOGD->write_syslog("Couldn't find phrase " + ident + " in file.", LOG_WARN); return nil; } mapping load_filemanaged_file(string path) { string contents; mixed* unq_data; mapping filemap; int iter; object phrase; /* Even if MAX_STRING_SIZE is obsolete, this'll let us limit the size of the file we read, which is a good thing. */ contents = read_file(path, 0, MAX_STRING_SIZE - 1); if(strlen(contents) > MAX_STRING_SIZE - 3) { /* File is too long... */ LOGD->write_syslog("File " + path + " is too large to load as a phrase file!", LOG_ERR); return nil; } /* Load as UNQ */ unq_data = UNQ_PARSER->basic_unq_parse(contents); if(!unq_data) { LOGD->write_syslog("Can't parse filemanaged phrase file!", LOG_ERR); return nil; } if(sizeof(unq_data) == 0) return nil; if(sizeof(unq_data) % 2) return nil; /* Error - odd sized array */ iter = 0; filemap = ([ ]); while(iter < sizeof(unq_data)) { if(!unq_data[iter] || unq_data[iter] == "") { if(STRINGD->is_whitespace(unq_data[iter + 1])) { /* Anonymous, top-level whitespace -- skip it */ iter += 2; continue; } LOGD->write_syslog("Anonymous top-level data parsing UNQ!", LOG_ERR); return nil; } if(typeof(unq_data[iter + 1]) == T_STRING) { phrase = PHRASED->new_simple_english_phrase(unq_data[iter + 1]); } else if(typeof(unq_data[iter + 1]) == T_ARRAY) { phrase = PHRASED->unq_to_phrase(unq_data[iter + 1]); if(!phrase) { LOGD->write_syslog("Null phrase from unq_to_phrase!", LOG_ERR); return nil; } } else { LOGD->write_syslog("Unrecognized data type " + typeof(unq_data[iter + 1]) + " returned by UNQ", LOG_ERR); return nil; } if(filemap[unq_data[iter]]) { LOGD->write_syslog("Repeated label " + unq_data[iter] + " in file " + path + ". Ignoring.", LOG_WARN); } else { filemap[unq_data[iter]] = phrase; } iter += 2; } phrasepaths[path] = filemap; return filemap; }