/* * NAME: vartext.c * DESCRIPTION: variable-to-text translators */ inherit "/std/string"; inherit "/std/eefun"; # include "vartext.h" # include <dgd/type.h> /* * NAME: type_str() * DESCRIPTION: return a string indicating value type */ static string type_str(mixed var) { switch (typeof(var)) { case T_INT: return "int"; case T_FLOAT: return "float"; case T_STRING: return "string"; case T_OBJECT: return "object"; case T_ARRAY: return "mixed *"; case T_MAPPING: return "mapping"; default: error("Unknown return value from typeof()"); } } /* * NAME: elements_of_arr() * DESCRIPTION: return a string representing the elements of an array */ private string elements_of_arr(mixed *var) { int i, sz; string str; str = ""; for (i = 0, sz = sizeof(var); i < sz; ++i) str += " " + var2str(var[i]) + (i < sz - 1 ? "," : ""); return str; } /* * NAME: elements_of_map() * DESCRIPTION: return a string representing the elements of a mapping */ private string elements_of_map(mapping var) { mixed *keys, *values; int i, sz; string str; keys = map_indices(var); values = map_values(var); str = ""; for (i = 0, sz = sizeof(keys); i < sz; ++i) str += " " + var2str(keys[i]) + " : " + var2str(values[i]) + (i < sz - 1 ? "," : ""); return str; } /* * NAME: var2str() * DESCRIPTION: given a variable of any type, return a string representation */ static string var2str(mixed var) { switch (typeof(var)) { case T_INT: return (string) var; case T_FLOAT: return flt2str(var); case T_STRING: return "\"" + escape_str(var) + "\""; case T_OBJECT: return object_name(var); case T_ARRAY: return "({" + elements_of_arr((mixed *) var) + " })"; case T_MAPPING: return "([" + elements_of_map(var) + " ])"; default: return "#unknown"; } } /* * NAME: tokenize() * DESCRIPTION: convert a string into an array of tokens */ private mixed **tokenize(string str) { mixed **tokens; int i, j, sz, val, neg, flt; float flval; tokens = ({ }); for (i = 0, sz = strlen(str); i < sz; ++i) switch (str[i]) { case ' ': case '\t': case '\n': continue; case ',': tokens += ({ ({ ',' }) }); break; case ':': tokens += ({ ({ ':' }) }); break; case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (neg = (str[i] == '-')) { if (i == sz - 1) break; ++i; } if (str[i] == '.') { val = 0; --i; } else val = str[i] - '0'; while (++i < sz && str[i] >= '0' && str[i] <= '9') val = 10 * val + str[i] - '0'; if (i < sz && str[i] == '.') { int hund; flt = 1; flval = (float) val; hund = 1; while (++i < sz && str[i] >= '0' && str[i] <= '9') flval += (1.0 / ((float) (hund *= 10))) * (float) (str[i] - '0'); } else flt = 0; if (i < sz - 1) --i; if (flt) { if (neg) flval = -flval; tokens += ({ ({ '.', flval }) }); } else { if (neg) val = -val; tokens += ({ ({ '1', val }) }); } break; case '\"': if (i == sz - 1) continue; for (j = i + 1; j < sz; ++j) { if (str[j] == '\\') { ++j; continue; } if (str[j] == '\"') break; } tokens += ({ ({ '\"', unescape_str(str[i + 1 .. j - 1]) }) }); i = j; break; case '/': case '#': for (j = i + 1; j < sz; ++j) { if (str[j] == ' ' || str[j] == ',' || str[j] == ':' || str[j] == '}' || str[j] == ']') break; } if (str[i] == '/') tokens += ({ ({ '/', find_object(str[i .. j - 1]) }) }); i = j - 1; break; case '(': if (i == sz - 1) continue; if (str[++i] == '{') tokens += ({ ({ '{' }) }); else if (str[i] == '[') tokens += ({ ({ '[' }) }); break; case ']': if (i == sz - 1) continue; if (str[++i] == ')') tokens += ({ ({ ']' }) }); break; case '}': if (i == sz - 1) continue; if (str[++i] == ')') tokens += ({ ({ '}' }) }); break; } return tokens; } /* * NAME: parse_element() * DESCRIPTION: given an array of tokens, parse the first data element * RETURNS: ({ element, next_token_index }) */ private mixed *parse_element(mixed **tokens, int item) { int i, sz; mixed *arr, *elem, *key; mapping map; sz = sizeof(tokens); if (sz == 0 || item >= sz) return ({ 0, item }); switch (tokens[item][0]) { case '1': case '.': case '\"': case '/': return ({ tokens[item][1], item + 1 }); case '{': arr = ({ }); for (i = item + 1; i < sz; ++i) { switch (tokens[i][0]) { case ',': continue; case '}': break; default: elem = parse_element(tokens, i); arr += ({ elem[0] }); i = elem[1] - 1; continue; } break; } return ({ arr, i + 1 }); case '[': map = ([ ]); for (i = item + 1; i < sz; ++i) { if (tokens[i][0] == ':') { elem = parse_element(tokens, i + 1); if (key != 0) { map[key[0]] = elem[0]; key = 0; } i = elem[1] - 1; continue; } if (tokens[i][0] == ',') continue; if (tokens[i][0] == ']') break; key = parse_element(tokens, i); i = key[1] - 1; } return ({ map, i + 1 }); } return ({ 0, item + 1 }); } /* * NAME: str2var() * DESCRIPTION: given a string representing a value, return that value */ static mixed str2var(string str) { if (str == 0) return 0; return parse_element(tokenize(str), 0)[0]; }