Browse Source

Cleaned up the script engine's get_val() function
- changed the long if-spaghetti into a compact switch statement
- changed its behavior so that it exits if !sd and it requires one
- upon exiting, it will now ensure that meaningful values get returned (the old code would return random memory / crash)
- removed many !sd checks since they are done at the beginning now

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9812 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 18 years ago
parent
commit
6bf7170064
2 changed files with 76 additions and 83 deletions
  1. 7 0
      Changelog-Trunk.txt
  2. 69 83
      src/map/script.c

+ 7 - 0
Changelog-Trunk.txt

@@ -4,6 +4,13 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2007/02/06
+	* Cleaned up the script engine's get_val() function [ultramage]
+	- changed the long if-spaghetti into a compact switch statement
+	- changed its behavior so that it exits if !sd and it requires one
+	- upon exiting, it will now ensure that meaningful values get returned
+	  (the old code had no qualms about returning random junk from memory
+	   for integer queries, and crashing for string queries)
+	- removed many !sd checks since they are done at the beginning now
 	* Fixed #lvup having the gm level check backwards.
 	* Fixed the stormgust freeze counter going up even if the attack is
 	  blocked/cancelled.

+ 69 - 83
src/map/script.c

@@ -1886,95 +1886,81 @@ struct map_session_data *script_rid2sd(struct script_state *st)
 
 
 /*==========================================
- * •Ï�”‚̓ǂݎæ‚è
- *------------------------------------------
- */
-int get_val(struct script_state*st,struct script_data* data)
+ * Retrieves the value of a script variable
+ *------------------------------------------*/
+int get_val(struct script_state* st, struct script_data* data)
 {
-	struct map_session_data *sd=NULL;
-	if(data->type==C_NAME){
-		char *name=str_buf+str_data[data->u.num&0x00ffffff].str;
-		char prefix=*name;
-		char postfix=name[strlen(name)-1];
-
-		if(not_server_variable(prefix)){
-			if((sd=script_rid2sd(st))==NULL)
-				ShowError("get_val error name?:%s\n",name);
-		}
-		if(postfix=='$'){
-
-			data->type=C_CONSTSTR;
-			if( prefix=='@'){
-				if(sd)
-					data->u.str = pc_readregstr(sd,data->u.num);
-			}else if(prefix=='$'){
-				data->u.str = (char *)idb_get(mapregstr_db,data->u.num);
-			}else if(prefix=='#'){
-				if( name[1]=='#'){
-					if(sd)
-					data->u.str = pc_readaccountreg2str(sd,name);
-				}else{
-					if(sd)
-					data->u.str = pc_readaccountregstr(sd,name);
-				}
- 			}else if(prefix=='.') {
-				struct linkdb_node **n;
-				if( data->ref ) {
-					n = data->ref;
-				} else if( name[1] == '@' ) {
-					n = st->stack->var_function;
-				} else {
-					n = &st->script->script_vars;
-				}
-				data->u.str = linkdb_search(n, (void*)data->u.num );
-			}else{
-				if(sd)
-				data->u.str = pc_readglobalreg_str(sd,name);
- 			} // [zBuffer]
-			/*else{
-				ShowWarning("script: get_val: illegal scope string variable.\n");
-				data->u.str = "!!ERROR!!";
-			}*/
-			if( data->u.str == NULL )
-				data->u.str ="";
+	struct map_session_data* sd = NULL;
+	char *name, prefix, postfix;
+	
+	if(data->type != C_NAME) return 0;
 
-		}else{
+	name = str_buf + str_data[data->u.num&0x00ffffff].str;
+	prefix = name[0]; postfix = name[strlen(name)-1];
 
-			data->type=C_INT;
-			if(str_data[data->u.num&0x00ffffff].type==C_INT){
-				data->u.num = str_data[data->u.num&0x00ffffff].val;
-			}else if(str_data[data->u.num&0x00ffffff].type==C_PARAM){
-				if(sd)
-					data->u.num = pc_readparam(sd,str_data[data->u.num&0x00ffffff].val);
-			}else if(prefix=='@'){
-				if(sd)
-					data->u.num = pc_readreg(sd,data->u.num);
-			}else if(prefix=='$'){
-				data->u.num = (int)idb_get(mapreg_db,data->u.num);
-			}else if(prefix=='#'){
-				if( name[1]=='#'){
-					if(sd)
-						data->u.num = pc_readaccountreg2(sd,name);
-				}else{
-					if(sd)
-						data->u.num = pc_readaccountreg(sd,name);
-				}
-			}else if(prefix=='.'){
-				struct linkdb_node **n;
-				if( data->ref ) {
-					n = data->ref;
-				} else if( name[1] == '@' ) {
-					n = st->stack->var_function;
-				} else {
-					n = &st->script->script_vars;
-				}
-				data->u.num = (int)linkdb_search(n, (void*)data->u.num);
-			}else{
-				if(sd)
-					data->u.num = pc_readglobalreg(sd,name);
+	if(not_server_variable(prefix)) {
+		sd = script_rid2sd(st);
+		if (!sd) { // needs player attached
+			// throw error, load some meaningful default values and return
+			ShowError("get_val error, cannot access player variable '%s'\n", name);
+			if (postfix == '$') { data->type = C_CONSTSTR; data->u.str = ""; } else { data->type = C_INT; data->u.num = 0; }
+			return 0;
+		}			
+	}
+
+	if(postfix == '$') { // string variable
+
+		data->type = C_CONSTSTR;
+
+		switch (prefix) {
+		case '@':
+			data->u.str = pc_readregstr(sd, data->u.num); break;
+		case '$':
+			data->u.str = (char *)idb_get(mapregstr_db,data->u.num); break;
+		case '#':
+			data->u.str = (name[1] == '#') ? pc_readaccountreg2str(sd, name) : pc_readaccountregstr(sd, name); break;
+		case '.': {
+			struct linkdb_node** n;
+			n = (data->ref) ? data->ref : (name[1] == '@') ? st->stack->var_function : &st->script->script_vars;
+			data->u.str = linkdb_search(n, (void*)data->u.num);
+			}
+			break;
+		default:
+			data->u.str = pc_readglobalreg_str(sd, name); break;
+		}
+
+		if( data->u.str == NULL )
+			data->u.str = "";
+
+	} else { // integer variable
+
+		data->type = C_INT;
+
+		if(str_data[data->u.num&0x00ffffff].type == C_INT) {
+			data->u.num = str_data[data->u.num&0x00ffffff].val;
+		} else if(str_data[data->u.num&0x00ffffff].type == C_PARAM) {
+			data->u.num = pc_readparam(sd, str_data[data->u.num&0x00ffffff].val);
+		}
+		else
+		switch (prefix) {
+		case '@':
+			data->u.num = pc_readreg(sd, data->u.num); break;
+		case '$':
+			data->u.num = (int)idb_get(mapreg_db, data->u.num); break;
+		case '#':
+			data->u.num = (name[1] == '#') ? pc_readaccountreg2(sd, name) : pc_readaccountreg(sd, name); break;
+		case '.': {
+			struct linkdb_node** n;
+			n = (data->ref) ? data->ref : (name[1] == '@') ? st->stack->var_function : &st->script->script_vars;
+			data->u.num = (int)linkdb_search(n, (void*)data->u.num);
 			}
+			break;
+		default:
+			data->u.num = pc_readglobalreg(sd, name); break;
 		}
+
 	}
+
 	return 0;
 }
 /*==========================================