diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/itemdb.c | 4 | ||||
-rw-r--r-- | src/map/mob.c | 6 | ||||
-rw-r--r-- | src/map/npc.c | 80 | ||||
-rw-r--r-- | src/map/script.c | 364 | ||||
-rw-r--r-- | src/map/script.h | 32 |
5 files changed, 280 insertions, 206 deletions
diff --git a/src/map/itemdb.c b/src/map/itemdb.c index dc4559483..8a7e34ceb 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -37,7 +37,7 @@ int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap) //Absolute priority to Aegis code name. if (*dst != NULL) return 0; - if( strcmpi(item->name,str)==0 ) + if( strcmp(item->name,str)==0 ) // Case sensitive *dst=item; //Second priority to Client displayed name. @@ -61,7 +61,7 @@ struct item_data* itemdb_searchname(const char *str) { continue; // Absolute priority to Aegis code name. - if( strcasecmp(item->name,str) == 0 ) + if( strcmp(item->name,str) == 0 ) // Case sensitive return item; //Second priority to Client displayed name. diff --git a/src/map/mob.c b/src/map/mob.c index 16c33b552..92fa98885 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -95,7 +95,7 @@ int mobdb_searchname(const char *str) monster = mob->db(i); if(monster == mob->dummy) //Skip dummy mobs. continue; - if(strcmpi(monster->name,str)==0 || strcmpi(monster->jname,str)==0 || strcmpi(monster->sprite,str)==0) + if(strcmpi(monster->name,str)==0 || strcmpi(monster->jname,str)==0 || strcmp(monster->sprite,str)==0) // Sprite name case sensitive return i; } @@ -113,9 +113,9 @@ int mobdb_searchname_array_sub(struct mob_db* monster, const char *str, int flag return 0; return strcmpi(monster->jname,str); } - if(strcmp(monster->jname,str) == 0) + if(strcmpi(monster->jname,str) == 0) return 0; - if(strcmp(monster->name,str) == 0) + if(strcmpi(monster->name,str) == 0) return 0; return strcmp(monster->sprite,str); } diff --git a/src/map/npc.c b/src/map/npc.c index 30cb94efe..d82bbdfd9 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -2218,7 +2218,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s return strchr(start,'\n');;//try next } - if( !strcasecmp(w2,"cashshop") ) + if( strcmp(w2,"cashshop") == 0 ) type = CASHSHOP; else type = SHOP; @@ -2971,7 +2971,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st memset(&mobspawn, 0, sizeof(struct spawn_data)); - mobspawn.state.boss = !strcmpi(w2,"boss_monster"); + mobspawn.state.boss = (strcmp(w2,"boss_monster") == 0 ? 1 : 0); // w1=<map name>,<x>,<y>,<xs>,<ys> // w3=<mob name>{,<mob level>} @@ -3593,7 +3593,7 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) { break; } - if( strcmp(w1,"-") !=0 && strcasecmp(w1,"function") != 0 ) + if( strcmp(w1,"-") != 0 && strcmp(w1,"function") != 0 ) {// w1 = <map name>,<x>,<y>,<facing> char mapname[MAP_NAME_LENGTH*2]; x = y = 0; @@ -3601,7 +3601,7 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) { if( !mapindex_name2id(mapname) ) {// Incorrect map, we must skip the script info... ShowError("npc_parsesrcfile: Unknown map '%s' in file '%s', line '%d'. Skipping line...\n", mapname, filepath, strline(buffer,p-buffer)); - if( strcasecmp(w2,"script") == 0 && count > 3 ) + if( strcmp(w2,"script") == 0 && count > 3 ) { if((p = npc->skip_script(p,buffer,filepath)) == NULL) { @@ -3614,7 +3614,7 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) { m = map->mapname2mapid(mapname); if( m < 0 ) { // "mapname" is not assigned to this server, we must skip the script info... - if( strcasecmp(w2,"script") == 0 && count > 3 ) + if( strcmp(w2,"script") == 0 && count > 3 ) { if((p = npc->skip_script(p,buffer,filepath)) == NULL) { @@ -3626,7 +3626,7 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) { } if (x < 0 || x >= map->list[m].xs || y < 0 || y >= map->list[m].ys) { ShowError("npc_parsesrcfile: Unknown coordinates ('%d', '%d') for map '%s' in file '%s', line '%d'. Skipping line...\n", x, y, mapname, filepath, strline(buffer,p-buffer)); - if( strcasecmp(w2,"script") == 0 && count > 3 ) + if( strcmp(w2,"script") == 0 && count > 3 ) { if((p = npc->skip_script(p,buffer,filepath)) == NULL) { @@ -3638,57 +3638,54 @@ int npc_parsesrcfile(const char* filepath, bool runOnInit) { } } - if( strcasecmp(w2,"warp") == 0 && count > 3 ) + if( strcmp(w2,"warp") == 0 && count > 3 ) { -#ifdef ENABLE_CASE_CHECK - if( strcmp(w2, "warp") != 0 ) DeprecationWarning("npc_parsesrcfile", w2, "warp", filepath, strline(buffer, p-buffer)); // TODO -#endif // ENABLE_CASE_CHECK p = npc->parse_warp(w1,w2,w3,w4, p, buffer, filepath); } - else if( (!strcasecmp(w2,"shop") || !strcasecmp(w2,"cashshop")) && count > 3 ) + else if( (strcmp(w2,"shop") == 0 || strcmp(w2,"cashshop") == 0) && count > 3 ) { -#ifdef ENABLE_CASE_CHECK - if( strcasecmp(w2,"shop") == 0 && strcmp(w2, "shop") != 0 ) DeprecationWarning("npc_parsesrcfile", w2, "shop", filepath, strline(buffer, p-buffer)) // TODO - else if( strcasecmp(w2,"cashshop") == 0 && strcmp(w2, "cashshop") != 0 ) DeprecationWarning("npc_parsesrcfile", w2, "cashshop", filepath, strline(buffer, p-buffer)); // TODO -#endif // ENABLE_CASE_CHECK p = npc->parse_shop(w1,w2,w3,w4, p, buffer, filepath); } - else if( strcasecmp(w2,"script") == 0 && count > 3 ) + else if( strcmp(w2,"script") == 0 && count > 3 ) { + if( strcmp(w1,"function") == 0 ) { + p = npc->parse_function(w1, w2, w3, w4, p, buffer, filepath); + } else { #ifdef ENABLE_CASE_CHECK - if( strcmp(w2, "script") != 0 ) DeprecationWarning("npc_parsesrcfile", w2, "script", filepath, strline(buffer, p-buffer)); // TODO - if( strcasecmp(w1, "function") == 0 && strcmp(w1, "function") != 0 ) DeprecationWarning("npc_parsesrcfile", w1, "function", filepath, strline(buffer, p-buffer)); // TODO + if( strcasecmp(w1, "function") == 0 ) DeprecationWarning("npc_parsesrcfile", w1, "function", filepath, strline(buffer, p-buffer)); // TODO #endif // ENABLE_CASE_CHECK - if( strcasecmp(w1,"function") == 0 ) - p = npc->parse_function(w1, w2, w3, w4, p, buffer, filepath); - else p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit); + } } else if( (i=0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3 ) { -#ifdef ENABLE_CASE_CHECK - char temp[10]; safestrncpy(temp, w2, 10); - if( strcmp(temp, "duplicate") != 0 ) DeprecationWarning("npc_parsesrcfile", temp, "duplicate", filepath, strline(buffer, p-buffer)); // TODO -#endif // ENABLE_CASE_CHECK p = npc->parse_duplicate(w1,w2,w3,w4, p, buffer, filepath); } - else if( (strcmpi(w2,"monster") == 0 || strcmpi(w2,"boss_monster") == 0) && count > 3 ) + else if( (strcmp(w2,"monster") == 0 || strcmp(w2,"boss_monster") == 0) && count > 3 ) { -#ifdef ENABLE_CASE_CHECK - if( strcasecmp(w2,"monster") == 0 && strcmp(w2, "monster") != 0 ) DeprecationWarning("npc_parsesrcfile", w2, "monster", filepath, strline(buffer, p-buffer)) // TODO: - else if( strcasecmp(w2,"boss_monster") == 0 && strcmp(w2, "boss_monster") != 0 ) DeprecationWarning("npc_parsesrcfile", w2, "boss_monster", filepath, strline(buffer, p-buffer)); // TODO -#endif // ENABLE_CASE_CHECK p = npc->parse_mob(w1, w2, w3, w4, p, buffer, filepath); } - else if( strcmpi(w2,"mapflag") == 0 && count >= 3 ) + else if( strcmp(w2,"mapflag") == 0 && count >= 3 ) { -#ifdef ENABLE_CASE_CHECK - if( strcmp(w2, "mapflag") != 0 ) DeprecationWarning("npc_parsesrcfile", w2, "mapflag", filepath, strline(buffer, p-buffer)); // TODO -#endif // ENABLE_CASE_CHECK p = npc->parse_mapflag(w1, w2, trim(w3), trim(w4), p, buffer, filepath); } else { +#ifdef ENABLE_CASE_CHECK + if( strcasecmp(w2, "warp") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "warp", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2,"shop") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "shop", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2,"cashshop") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "cashshop", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2, "script") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "script", filepath, strline(buffer, p-buffer)); } // TODO + else if( strncasecmp(w2, "duplicate", 9) == 0 ) { + char temp[10]; + safestrncpy(temp, w2, 10); + DeprecationWarning("npc_parsesrcfile", temp, "duplicate", filepath, strline(buffer, p-buffer)); // TODO + } + else if( strcasecmp(w2,"monster") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "monster", filepath, strline(buffer, p-buffer)); } // TODO: + else if( strcasecmp(w2,"boss_monster") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "boss_monster", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2, "mapflag") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "mapflag", filepath, strline(buffer, p-buffer)); } // TODO + else +#endif // ENABLE_CASE_CHECK ShowError("npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4); p = strchr(p,'\n');// skip and continue } @@ -3752,14 +3749,15 @@ void npc_read_event_script(void) break; } - if( (p=strchr(p,':')) && p && strcmpi(name,p)==0 ) + if( (p=strchr(p,':')) && strcmp(name,p) == 0 ) { -#ifdef ENABLE_CASE_CHECK - if( strcmp(name, p) != 0 ) DeprecationWarning2("npc_read_event_script", p, name, config[i].event_name); // TODO -#endif // ENABLE_CASE_CHECK script_event[i].event[count] = ed; script_event[i].event_name[count] = key.str; script_event[i].event_count++; +#ifdef ENABLE_CASE_CHECK + } else if( p && strcasecmp(name, p) == 0 ) { + DeprecationWarning2("npc_read_event_script", p, name, config[i].event_name); // TODO +#endif // ENABLE_CASE_CHECK } } dbi_destroy(iter); @@ -3905,7 +3903,7 @@ bool npc_unloadfile( const char* filepath ) { bool found = false; for( nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter) ) { - if( nd->path && strcasecmp(nd->path,filepath) == 0 ) { + if( nd->path && strcasecmp(nd->path,filepath) == 0 ) { // FIXME: This can break in case-sensitive file systems found = true; npc->unload_duplicates(nd);/* unload any npcs which could duplicate this but be in a different file */ npc->unload(nd, true); @@ -3997,8 +3995,8 @@ int do_init_npc(bool minimal) { for( i = MAX_NPC_CLASS2_START; i < MAX_NPC_CLASS2_END; i++ ) npc_viewdb2[i - MAX_NPC_CLASS2_START].class_ = i; - npc->ev_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, EVENT_NAME_LENGTH); - npc->ev_label_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, NAME_LENGTH); + npc->ev_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, EVENT_NAME_LENGTH); + npc->ev_label_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, NAME_LENGTH); npc->name_db = strdb_alloc(DB_OPT_BASE, NAME_LENGTH); npc->path_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, 0); diff --git a/src/map/script.c b/src/map/script.c index 107a921f0..3982513d5 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -301,13 +301,47 @@ void check_event(struct script_state *st, const char *evt) /*========================================== * Hashes the input string *------------------------------------------*/ -unsigned int calc_hash(const char* p) -{ +unsigned int calc_hash(const char* p) { unsigned int h; #if defined(SCRIPT_HASH_DJB2) h = 5381; while( *p ) // hash*33 + c + h = ( h << 5 ) + h + ((unsigned char)(*p++)); +#elif defined(SCRIPT_HASH_SDBM) + h = 0; + while( *p ) // hash*65599 + c + h = ( h << 6 ) + ( h << 16 ) - h + ((unsigned char)(*p++)); +#elif defined(SCRIPT_HASH_ELF) // UNIX ELF hash + h = 0; + while( *p ) { + unsigned int g; + h = ( h << 4 ) + ((unsigned char)(*p++)); + g = h & 0xF0000000; + if( g ) { + h ^= g >> 24; + h &= ~g; + } + } +#else // athena hash + h = 0; + while( *p ) + h = ( h << 1 ) + ( h >> 3 ) + ( h >> 5 ) + ( h >> 8 ) + (unsigned char)(*p++); +#endif + + return h % SCRIPT_HASH_SIZE; +} + +/*========================================== + * Hashes the input string in a case insensitive way + *------------------------------------------*/ +unsigned int calc_hash_ci(const char* p) { + unsigned int h = 0; +#ifdef ENABLE_CASE_CHECK + +#if defined(SCRIPT_HASH_DJB2) + h = 5381; + while( *p ) // hash*33 + c h = ( h << 5 ) + h + ((unsigned char)TOLOWER(*p++)); #elif defined(SCRIPT_HASH_SDBM) h = 0; @@ -315,12 +349,11 @@ unsigned int calc_hash(const char* p) h = ( h << 6 ) + ( h << 16 ) - h + ((unsigned char)TOLOWER(*p++)); #elif defined(SCRIPT_HASH_ELF) // UNIX ELF hash h = 0; - while( *p ){ + while( *p ) { unsigned int g; h = ( h << 4 ) + ((unsigned char)TOLOWER(*p++)); g = h & 0xF0000000; - if( g ) - { + if( g ) { h ^= g >> 24; h &= ~g; } @@ -331,6 +364,7 @@ unsigned int calc_hash(const char* p) h = ( h << 1 ) + ( h >> 3 ) + ( h >> 5 ) + ( h >> 8 ) + (unsigned char)TOLOWER(*p++); #endif +#endif // ENABLE_CASE_CHECK return h % SCRIPT_HASH_SIZE; } @@ -352,15 +386,7 @@ int script_search_str(const char* p) int i; for( i = script->str_hash[script->calc_hash(p)]; i != 0; i = script->str_data[i].next ) { - if( strcasecmp(script->get_str(i),p) == 0 ) { -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, ".@", 2) != 0 // Local scope vars are checked separately to decrease false positives - && strcasecmp(p, "disguise") != 0 && strcasecmp(p, "Poison_Spore") != 0 - && strcasecmp(p, "PecoPeco_Egg") != 0 && strcasecmp(p, "Soccer_Ball") != 0 - && strcasecmp(p, "Horn") != 0 && strcasecmp(p, "Treasure_Box_") != 0 - && strcasecmp(p, "Lord_of_Death") != 0 - && strcmp(script->get_str(i),p) != 0 ) DeprecationWarning2("script_search_str", p, script->get_str(i), script->parser_current_file); // TODO -#endif // ENABLE_CASE_CHECK + if( strcmp(script->get_str(i),p) == 0 ) { return i; } } @@ -368,107 +394,121 @@ int script_search_str(const char* p) return -1; } -void script_local_casecheck_clear(void) { +void script_casecheck_clear_sub(struct casecheck_data *ccd) { #ifdef ENABLE_CASE_CHECK - if (script->local_casecheck_str_data) { - aFree(script->local_casecheck_str_data); - script->local_casecheck_str_data = NULL; - } - script->local_casecheck_str_data_size = 0; - script->local_casecheck_str_num = 1; - if (script->local_casecheck_str_buf) { - aFree(script->local_casecheck_str_buf); - script->local_casecheck_str_buf = NULL; - } - script->local_casecheck_str_pos = 0; - script->local_casecheck_str_size = 0; - memset(script->local_casecheck_str_hash, 0, sizeof(script->local_casecheck_str_hash)); + if (ccd->str_data) { + aFree(ccd->str_data); + ccd->str_data = NULL; + } + ccd->str_data_size = 0; + ccd->str_num = 1; + if (ccd->str_buf) { + aFree(ccd->str_buf); + ccd->str_buf = NULL; + } + ccd->str_pos = 0; + ccd->str_size = 0; + memset(ccd->str_hash, 0, sizeof(ccd->str_hash)); #endif // ENABLE_CASE_CHECK } -bool script_local_casecheck_add_str(const char *p, int h) { +void script_global_casecheck_clear(void) { + script_casecheck_clear_sub(&script->global_casecheck); +} + +void script_local_casecheck_clear(void) { + script_casecheck_clear_sub(&script->local_casecheck); +} + +bool script_casecheck_add_str_sub(struct casecheck_data *ccd, const char *p) { #ifdef ENABLE_CASE_CHECK int len, i; - if( script->local_casecheck_str_hash[h] == 0 ) { //empty bucket, add new node here - script->local_casecheck_str_hash[h] = script->local_casecheck_str_num; + int h = script->calc_hash_ci(p); + if( ccd->str_hash[h] == 0 ) { //empty bucket, add new node here + ccd->str_hash[h] = ccd->str_num; } else { const char *s = NULL; - for( i = script->local_casecheck_str_hash[h]; ; i = script->local_casecheck_str_data[i].next ) { - Assert( i >= 0 && i < script->local_casecheck_str_size ); - s = script->local_casecheck_str_buf+script->local_casecheck_str_data[i].str; + for( i = ccd->str_hash[h]; ; i = ccd->str_data[i].next ) { + Assert( i >= 0 && i < ccd->str_size ); + s = ccd->str_buf+ccd->str_data[i].str; if( strcasecmp(s,p) == 0 ) { - if ( strcmp(s,p) != 0 ) { - DeprecationWarning2("script_add_str", p, s, script->parser_current_file); - return true; - } - return false; // string already in list + return true; // string already in list } - if( script->local_casecheck_str_data[i].next == 0 ) + if( ccd->str_data[i].next == 0 ) break; // reached the end } // append node to end of list - script->local_casecheck_str_data[i].next = script->local_casecheck_str_num; + ccd->str_data[i].next = ccd->str_num; } // grow list if neccessary - if( script->local_casecheck_str_num >= script->local_casecheck_str_data_size ) { - script->local_casecheck_str_data_size += 1280; - RECREATE(script->local_casecheck_str_data,struct str_data_struct,script->local_casecheck_str_data_size); - memset(script->local_casecheck_str_data + (script->local_casecheck_str_data_size - 1280), '\0', 1280); + if( ccd->str_num >= ccd->str_data_size ) { + ccd->str_data_size += 1280; + RECREATE(ccd->str_data,struct str_data_struct,ccd->str_data_size); + memset(ccd->str_data + (ccd->str_data_size - 1280), '\0', 1280); } len=(int)strlen(p); // grow string buffer if neccessary - while( script->local_casecheck_str_pos+len+1 >= script->local_casecheck_str_size ) { - script->local_casecheck_str_size += 10240; - RECREATE(script->local_casecheck_str_buf,char,script->local_casecheck_str_size); - memset(script->local_casecheck_str_buf + (script->local_casecheck_str_size - 10240), '\0', 10240); - } - - safestrncpy(script->local_casecheck_str_buf+script->local_casecheck_str_pos, p, len+1); - script->local_casecheck_str_data[script->local_casecheck_str_num].type = C_NOP; - script->local_casecheck_str_data[script->local_casecheck_str_num].str = script->local_casecheck_str_pos; - script->local_casecheck_str_data[script->local_casecheck_str_num].val = 0; - script->local_casecheck_str_data[script->local_casecheck_str_num].next = 0; - script->local_casecheck_str_data[script->local_casecheck_str_num].func = NULL; - script->local_casecheck_str_data[script->local_casecheck_str_num].backpatch = -1; - script->local_casecheck_str_data[script->local_casecheck_str_num].label = -1; - script->local_casecheck_str_pos += len+1; - - script->local_casecheck_str_num++; + while( ccd->str_pos+len+1 >= ccd->str_size ) { + ccd->str_size += 10240; + RECREATE(ccd->str_buf,char,ccd->str_size); + memset(ccd->str_buf + (ccd->str_size - 10240), '\0', 10240); + } + + safestrncpy(ccd->str_buf+ccd->str_pos, p, len+1); + ccd->str_data[ccd->str_num].type = C_NOP; + ccd->str_data[ccd->str_num].str = ccd->str_pos; + ccd->str_data[ccd->str_num].val = 0; + ccd->str_data[ccd->str_num].next = 0; + ccd->str_data[ccd->str_num].func = NULL; + ccd->str_data[ccd->str_num].backpatch = -1; + ccd->str_data[ccd->str_num].label = -1; + ccd->str_pos += len+1; + + ccd->str_num++; #endif // ENABLE_CASE_CHECK return false; } +bool script_global_casecheck_add_str(const char *p) { + return script_casecheck_add_str_sub(&script->global_casecheck, p); +} + +bool script_local_casecheck_add_str(const char *p) { + return script_casecheck_add_str_sub(&script->local_casecheck, p); +} + /// Stores a copy of the string and returns its id. /// If an identical string is already present, returns its id instead. int script_add_str(const char* p) { - int i, h; - int len; - - h = script->calc_hash(p); + int i, len, h = script->calc_hash(p); #ifdef ENABLE_CASE_CHECK + bool alreadyexists = false; if( (strncmp(p, ".@", 2) == 0) ) // Local scope vars are checked separately to decrease false positives - script->local_casecheck_add_str(p, h); + alreadyexists = script->local_casecheck.add_str(p); + else { + alreadyexists = script->global_casecheck.add_str(p); + if( alreadyexists ) { + if( strcasecmp(p, "disguise") == 0 || strcasecmp(p, "Poison_Spore") == 0 + || strcasecmp(p, "PecoPeco_Egg") == 0 || strcasecmp(p, "Soccer_Ball") == 0 + || strcasecmp(p, "Horn") == 0 || strcasecmp(p, "Treasure_Box_") == 0 + || strcasecmp(p, "Lord_of_Death") == 0 + ) // Known duplicates, don't bother warning the user + alreadyexists = false; + } + } #endif // ENABLE_CASE_CHECK if( script->str_hash[h] == 0 ) {// empty bucket, add new node here script->str_hash[h] = script->str_num; } else {// scan for end of list, or occurence of identical string for( i = script->str_hash[h]; ; i = script->str_data[i].next ) { - if( strcasecmp(script->get_str(i),p) == 0 ) { -#ifdef ENABLE_CASE_CHECK - if( (strncmp(p, ".@", 2) != 0) // Local scope vars are checked separately to decrease false positives - && strcasecmp(p, "disguise") != 0 && strcasecmp(p, "Poison_Spore") != 0 - && strcasecmp(p, "PecoPeco_Egg") != 0 && strcasecmp(p, "Soccer_Ball") != 0 - && strcasecmp(p, "Horn") != 0 && strcasecmp(p, "Treasure_Box_") != 0 - && strcasecmp(p, "Lord_of_Death") != 0 - && strcmp(script->get_str(i),p) != 0 ) DeprecationWarning2("script_add_str", p, script->get_str(i), script->parser_current_file); // TODO -#endif // ENABLE_CASE_CHECK + if( strcmp(script->get_str(i),p) == 0 ) { return i; // string already in list } if( script->str_data[i].next == 0 ) @@ -478,6 +518,12 @@ int script_add_str(const char* p) // append node to end of list script->str_data[i].next = script->str_num; } + +#ifdef ENABLE_CASE_CHECK + if( alreadyexists ) { + DeprecationWarning2("script_add_str", p, script->get_str(i), script->parser_current_file); // TODO + } +#endif // ENABLE_CASE_CHECK // grow list if neccessary if( script->str_num >= script->str_data_size ) { @@ -960,8 +1006,9 @@ const char* parse_variable(const char* p) { parse_variable_sub_push(word, p2); // Push variable onto the stack - if( type != C_EQ ) - script->addc(C_REF); + if( type != C_EQ ) { + parse_variable_sub_push(word, p2); // Push variable onto the stack once again (first argument of setr) + } if( type == C_ADD_POST || type == C_SUB_POST ) { // post ++ / -- script->addi(1); @@ -1342,13 +1389,10 @@ const char* parse_syntax(const char* p) switch(*p) { case 'B': case 'b': - if(p2 - p == 5 && !strncasecmp(p,"break",5)) { + if( p2 - p == 5 && strncmp(p,"break",5) == 0 ) { // break Processing char label[256]; int pos = script->syntax.curly_count - 1; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "break", 5) != 0 ) disp_deprecation_message("parse_syntax", "break", p); // TODO -#endif // ENABLE_CASE_CHECK while(pos >= 0) { if(script->syntax.curly[pos].type == TYPE_DO) { sprintf(label,"goto __DO%x_FIN;",script->syntax.curly[pos].index); @@ -1378,16 +1422,17 @@ const char* parse_syntax(const char* p) // Closing decision if, for , while p = script->parse_syntax_close(p + 1); return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 5 && strncasecmp(p, "break", 5) == 0 ) { + disp_deprecation_message("parse_syntax", "break", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'c': case 'C': - if(p2 - p == 4 && !strncasecmp(p,"case",4)) { + if( p2 - p == 4 && strncmp(p, "case", 4) == 0 ) { //Processing case int pos = script->syntax.curly_count-1; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "case", 4) != 0 ) disp_deprecation_message("parse_syntax", "case", p); // TODO -#endif // ENABLE_CASE_CHECK if(pos < 0 || script->syntax.curly[pos].type != TYPE_SWITCH) { disp_error_message("parse_syntax: unexpected 'case' ",p); return p+1; @@ -1460,13 +1505,10 @@ const char* parse_syntax(const char* p) script->syntax.curly[pos].count++; } return p + 1; - } else if(p2 - p == 8 && !strncasecmp(p,"continue",8)) { + } else if( p2 - p == 8 && strncmp(p, "continue", 8) == 0 ) { // Processing continue char label[256]; int pos = script->syntax.curly_count - 1; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "continue", 8) != 0 ) disp_deprecation_message("parse_syntax", "continue", p); // TODO -#endif // ENABLE_CASE_CHECK while(pos >= 0) { if(script->syntax.curly[pos].type == TYPE_DO) { sprintf(label,"goto __DO%x_NXT;",script->syntax.curly[pos].index); @@ -1494,16 +1536,19 @@ const char* parse_syntax(const char* p) //Closing decision if, for , while p = script->parse_syntax_close(p + 1); return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 4 && strncasecmp(p, "case", 4) == 0 ) { + disp_deprecation_message("parse_syntax", "case", p); // TODO + } else if( p2 - p == 8 && strncasecmp(p, "continue", 8) == 0 ) { + disp_deprecation_message("parse_syntax", "continue", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'd': case 'D': - if(p2 - p == 7 && !strncasecmp(p,"default",7)) { + if( p2 - p == 7 && strncmp(p, "default", 7) == 0 ) { // Switch - default processing int pos = script->syntax.curly_count-1; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "default", 7) != 0 ) disp_deprecation_message("parse_syntax", "default", p); // TODO -#endif // ENABLE_CASE_CHECK if(pos < 0 || script->syntax.curly[pos].type != TYPE_SWITCH) { disp_error_message("parse_syntax: unexpected 'default'",p); } else if(script->syntax.curly[pos].flag) { @@ -1535,12 +1580,9 @@ const char* parse_syntax(const char* p) script->syntax.curly[pos].count++; } return p + 1; - } else if(p2 - p == 2 && !strncasecmp(p,"do",2)) { + } else if( p2 - p == 2 && strncmp(p, "do", 2) == 0 ) { int l; char label[256]; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "do", 2) != 0 ) disp_deprecation_message("parse_syntax", "do", p); // TODO -#endif // ENABLE_CASE_CHECK p=script->skip_space(p2); script->syntax.curly[script->syntax.curly_count].type = TYPE_DO; @@ -1553,17 +1595,20 @@ const char* parse_syntax(const char* p) script->set_label(l,script->pos,p); script->syntax.curly_count++; return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 7 && strncasecmp(p, "default", 7) == 0 ) { + disp_deprecation_message("parse_syntax", "default", p); // TODO + } else if( p2 - p == 2 && strncasecmp(p, "do", 2) == 0 ) { + disp_deprecation_message("parse_syntax", "do", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'f': case 'F': - if(p2 - p == 3 && !strncasecmp(p,"for",3)) { + if( p2 - p == 3 && strncmp(p, "for", 3) == 0 ) { int l; char label[256]; int pos = script->syntax.curly_count; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "for", 3) != 0 ) disp_deprecation_message("parse_syntax", "for", p); // TODO -#endif // ENABLE_CASE_CHECK script->syntax.curly[script->syntax.curly_count].type = TYPE_FOR; script->syntax.curly[script->syntax.curly_count].count = 1; script->syntax.curly[script->syntax.curly_count].index = script->syntax.index++; @@ -1634,14 +1679,10 @@ const char* parse_syntax(const char* p) l=script->add_str(label); script->set_label(l,script->pos,p); return p; - } - else if( p2 - p == 8 && strncasecmp(p,"function",8) == 0 ) - {// internal script function + } else if( p2 - p == 8 && strncmp(p, "function", 8) == 0 ) { + // internal script function const char *func_name; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "function", 8) != 0 ) disp_deprecation_message("parse_syntax", "function", p); // TODO -#endif // ENABLE_CASE_CHECK func_name = script->skip_space(p2); p = script->skip_word(func_name); if( p == func_name ) @@ -1699,16 +1740,19 @@ const char* parse_syntax(const char* p) { disp_error_message("expect ';' or '{' at function syntax",p); } +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 3 && strncasecmp(p, "for", 3) == 0 ) { + disp_deprecation_message("parse_syntax", "for", p); // TODO + } else if( p2 - p == 8 && strncasecmp(p, "function", 8) == 0 ) { + disp_deprecation_message("parse_syntax", "function", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'i': case 'I': - if(p2 - p == 2 && !strncasecmp(p,"if",2)) { + if( p2 - p == 2 && strncmp(p, "if", 2) == 0 ) { // If process char label[256]; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "if", 2) != 0 ) disp_deprecation_message("parse_syntax", "if", p); // TODO -#endif // ENABLE_CASE_CHECK p=script->skip_space(p2); if(*p != '(') { //Prevent if this {} non-c script->syntax. from Rayce (jA) disp_error_message("need '('",p); @@ -1726,16 +1770,17 @@ const char* parse_syntax(const char* p) script->addl(script->add_str(label)); script->addc(C_FUNC); return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 2 && strncasecmp(p, "if", 2) == 0 ) { + disp_deprecation_message("parse_syntax", "if", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 's': case 'S': - if(p2 - p == 6 && !strncasecmp(p,"switch",6)) { + if( p2 - p == 6 && strncmp(p, "switch", 6) == 0 ) { // Processing of switch () char label[256]; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "switch", 6) != 0 ) disp_deprecation_message("parse_syntax", "switch", p); // TODO -#endif // ENABLE_CASE_CHECK p=script->skip_space(p2); if(*p != '(') { disp_error_message("need '('",p); @@ -1756,16 +1801,17 @@ const char* parse_syntax(const char* p) } script->addc(C_FUNC); return p + 1; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 6 && strncasecmp(p, "switch", 6) == 0 ) { + disp_deprecation_message("parse_syntax", "switch", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'w': case 'W': - if(p2 - p == 5 && !strncasecmp(p,"while",5)) { + if( p2 - p == 5 && strncmp(p, "while", 5) == 0 ) { int l; char label[256]; -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "while", 5) != 0 ) disp_deprecation_message("parse_syntax", "while", p); // TODO -#endif // ENABLE_CASE_CHECK p=script->skip_space(p2); if(*p != '(') { disp_error_message("need '('",p); @@ -1789,6 +1835,10 @@ const char* parse_syntax(const char* p) script->addl(script->add_str(label)); script->addc(C_FUNC); return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 5 && strncasecmp(p, "while", 5) == 0 ) { + disp_deprecation_message("parse_syntax", "while", p); // TODO +#endif // ENABLE_CASE_CHECK } break; } @@ -1839,14 +1889,11 @@ const char* parse_syntax_close_sub(const char* p,int* flag) script->syntax.curly[pos].count++; p = script->skip_space(p); p2 = script->skip_word(p); - if(!script->syntax.curly[pos].flag && p2 - p == 4 && !strncasecmp(p,"else",4)) { -#ifdef ENABLE_CASE_CHECK - if( strncmp(p, "else", 4) != 0 ) disp_deprecation_message("parse_syntax", "else", p); // TODO -#endif // ENABLE_CASE_CHECK + if( !script->syntax.curly[pos].flag && p2 - p == 4 && strncmp(p, "else", 4) == 0 ) { // else or else - if p = script->skip_space(p2); p2 = script->skip_word(p); - if(p2 - p == 2 && !strncasecmp(p,"if",2)) { + if( p2 - p == 2 && strncmp(p, "if", 2) == 0 ) { // else - if p=script->skip_space(p2); if(*p != '(') { @@ -1861,6 +1908,10 @@ const char* parse_syntax_close_sub(const char* p,int* flag) script->addc(C_FUNC); *flag = 0; return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 2 && strncasecmp(p, "if", 2) == 0 ) { + disp_deprecation_message("parse_syntax", "if", p); // TODO +#endif // ENABLE_CASE_CHECK } else { // else if(!script->syntax.curly[pos].flag) { @@ -1869,6 +1920,10 @@ const char* parse_syntax_close_sub(const char* p,int* flag) return p; } } +#ifdef ENABLE_CASE_CHECK + } else if( !script->syntax.curly[pos].flag && p2 - p == 4 && strncasecmp(p, "else", 4) == 0 ) { + disp_deprecation_message("parse_syntax", "else", p); // TODO +#endif // ENABLE_CASE_CHECK } // Close if script->syntax.curly_count--; @@ -1896,12 +1951,13 @@ const char* parse_syntax_close_sub(const char* p,int* flag) // Skip to the end point if the condition is false p = script->skip_space(p); p2 = script->skip_word(p); - if(p2 - p != 5 || strncasecmp(p,"while",5)) - disp_error_message("parse_syntax: need 'while'",p); - + if( p2 - p != 5 || strncmp(p, "while", 5) != 0 ) { #ifdef ENABLE_CASE_CHECK - if( strncmp(p, "while", 5) != 0 ) disp_deprecation_message("parse_syntax", "while", p); // TODO + if( p2 - p == 5 && strncasecmp(p, "while", 5) == 0 ) disp_deprecation_message("parse_syntax", "while", p); // TODO #endif // ENABLE_CASE_CHECK + disp_error_message("parse_syntax: need 'while'",p); + } + p = script->skip_space(p2); if(*p != '(') { disp_error_message("need '('",p); @@ -2234,7 +2290,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o for(i=0; i<size; i++) linkdb_final(&script->syntax.curly[i].case_label); #ifdef ENABLE_CASE_CHECK - script->local_casecheck_clear(); + script->local_casecheck.clear(); #endif // ENABLE_CASE_CHECK return NULL; } @@ -2251,7 +2307,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o script->size = 0; script->buf = NULL; #ifdef ENABLE_CASE_CHECK - script->local_casecheck_clear(); + script->local_casecheck.clear(); #endif // ENABLE_CASE_CHECK return NULL; } @@ -2269,7 +2325,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o script->size = 0; script->buf = NULL; #ifdef ENABLE_CASE_CHECK - script->local_casecheck_clear(); + script->local_casecheck.clear(); #endif // ENABLE_CASE_CHECK return NULL; } @@ -2294,7 +2350,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o disp_error_message("unexpected end of script",p); // Special handling only label tmpp=script->skip_space(script->skip_word(p)); - if(*tmpp==':' && !(!strncasecmp(p,"default:",8) && p + 7 == tmpp)){ + if(*tmpp==':' && !(strncmp(p,"default:",8) == 0 && p + 7 == tmpp)) { i=script->add_word(p); script->set_label(i,script->pos,p); if( script->parse_options&SCRIPT_USE_LABEL_DB ) @@ -2386,7 +2442,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o code->script_size = script->size; code->script_vars = NULL; #ifdef ENABLE_CASE_CHECK - script->local_casecheck_clear(); + script->local_casecheck.clear(); #endif // ENABLE_CASE_CHECK return code; } @@ -3942,10 +3998,10 @@ void do_final_script(void) { if( script->word_buf != NULL ) aFree(script->word_buf); - if( script->local_casecheck_str_buf ) - aFree(script->local_casecheck_str_buf); - if( script->local_casecheck_str_data ) - aFree(script->local_casecheck_str_data); +#ifdef ENABLE_CASE_CHECK + script->global_casecheck.clear(); + script->local_casecheck.clear(); +#endif // ENABLE_CASE_CHECK ers_destroy(script->st_ers); ers_destroy(script->stack_ers); @@ -3983,6 +4039,10 @@ int script_reload(void) { DBIterator *iter; struct script_state *st; +#ifdef ENABLE_CASE_CHECK + script->global_casecheck.clear(); +#endif // ENABLE_CASE_CHECK + iter = db_iterator(script->st_db); for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) { @@ -18783,14 +18843,24 @@ void script_defaults(void) { script->config.ontouch2_name = "OnTouch";//ontouch2_name (run whenever a char walks into the OnTouch area) // for ENABLE_CASE_CHECK - script->local_casecheck_add_str = script_local_casecheck_add_str; - script->local_casecheck_clear = script_local_casecheck_clear; - script->local_casecheck_str_data = NULL; - script->local_casecheck_str_data_size = 0; - script->local_casecheck_str_num = 1; - script->local_casecheck_str_buf = NULL; - script->local_casecheck_str_size = 0; - script->local_casecheck_str_pos = 0; - memset(script->local_casecheck_str_hash, 0, sizeof(script->local_casecheck_str_hash)); + script->calc_hash_ci = calc_hash_ci; + script->local_casecheck.add_str = script_local_casecheck_add_str; + script->local_casecheck.clear = script_local_casecheck_clear; + script->local_casecheck.str_data = NULL; + script->local_casecheck.str_data_size = 0; + script->local_casecheck.str_num = 1; + script->local_casecheck.str_buf = NULL; + script->local_casecheck.str_size = 0; + script->local_casecheck.str_pos = 0; + memset(script->local_casecheck.str_hash, 0, sizeof(script->local_casecheck.str_hash)); + script->global_casecheck.add_str = script_global_casecheck_add_str; + script->global_casecheck.clear = script_global_casecheck_clear; + script->global_casecheck.str_data = NULL; + script->global_casecheck.str_data_size = 0; + script->global_casecheck.str_num = 1; + script->global_casecheck.str_buf = NULL; + script->global_casecheck.str_size = 0; + script->global_casecheck.str_pos = 0; + memset(script->global_casecheck.str_hash, 0, sizeof(script->global_casecheck.str_hash)); // end ENABLE_CASE_CHECK } diff --git a/src/map/script.h b/src/map/script.h index 75a57d82b..4d2c59d92 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -22,9 +22,9 @@ struct eri; **/ // TODO: Remove temporary code #define ENABLE_CASE_CHECK -#define DeprecationWarning(func, bad, good, file, line) ShowWarning("%s: use of deprecated keyword '%s' (use '%s' instead) in file '%s', line '%d'. This will be a critical error in a near future.\n", (func), (bad), (good), (file), (line)); -#define DeprecationWarning2(func, bad, good, where) ShowWarning("%s: detected possible use of wrong case in a script. Found '%s', probably meant to be '%s' (in '%s'). This will become fatal in a near future.\n", (func), (bad), (good), (where)); -#define disp_deprecation_message(func, good, p) disp_warning_message(func": use of deprecated keyword (use '"good"' instead). This will be a critical error in a near future.", (p)); +#define DeprecationWarning(func, bad, good, file, line) ShowError("%s: use of deprecated keyword '%s' (use '%s' instead) in file '%s', line '%d'.\n", (func), (bad), (good), (file), (line)); +#define DeprecationWarning2(func, bad, good, where) ShowError("%s: detected possible use of wrong case in a script. Found '%s', probably meant to be '%s' (in '%s').\n", (func), (bad), (good), (where)); +#define disp_deprecation_message(func, good, p) disp_warning_message(func": use of deprecated keyword (use '"good"' instead).", (p)); #define NUM_WHISPER_VAR 10 @@ -443,6 +443,19 @@ struct script_syntax_data { int index; // Number of the syntax used in the script }; +struct casecheck_data { + struct str_data_struct *str_data; + int str_data_size; // size of the data + int str_num; // next id to be assigned + // str_buf holds the strings themselves + char *str_buf; + int str_size; // size of the buffer + int str_pos; // next position to be assigned + int str_hash[SCRIPT_HASH_SIZE]; + bool (*add_str) (const char* p); + void (*clear) (void); +}; + /** * Interface **/ @@ -642,16 +655,9 @@ struct script_interface { int (*run_func) (struct script_state *st); const char *(*getfuncname) (struct script_state *st); // for ENABLE_CASE_CHECK - struct str_data_struct *local_casecheck_str_data; - int local_casecheck_str_data_size; // size of the data - int local_casecheck_str_num; // next id to be assigned - // str_buf holds the strings themselves - char *local_casecheck_str_buf; - int local_casecheck_str_size; // size of the buffer - int local_casecheck_str_pos; // next position to be assigned - int local_casecheck_str_hash[SCRIPT_HASH_SIZE]; - bool (*local_casecheck_add_str) (const char* p, int h); - void (*local_casecheck_clear) (void); + unsigned int (*calc_hash_ci) (const char *p); + struct casecheck_data local_casecheck; + struct casecheck_data global_casecheck; // end ENABLE_CASE_CHECK }; |