1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
/* ************************************************************************
* The Amulet User Interface Development Environment *
* ************************************************************************
* This code was written as part of the Amulet project at *
* Carnegie Mellon University, and has been placed in the public *
* domain. If you are using this code or any part of Amulet, *
* please contact amulet@cs.cmu.edu to be put on the mailing list. *
* ************************************************************************/
/* This file contains a procedure to parse strings into Amulet types.
It is used by the inspector and also by scripting.
Designed and implemented by Brad Myers
*/
#include <am_inc.h>
#include WIDGETS_ADVANCED__H
#include REGISTRY__H
//returns true if input can be parsed as a wanted_type.
//If returns true, then output_value is set with the actual value.
bool Am_Parse_Input_As_Type(Am_String input, Am_Value_Type wanted_type,
Am_Value &output_value) {
Am_ID_Tag type_class = Am_Type_Class (wanted_type);
switch (type_class) {
case Am_SIMPLE_TYPE:
switch(wanted_type) {
case Am_BOOL:
if (input == "true") {
output_value = true;
return true;
}
else if (input == "false") {
output_value = false;
return true;
}
//else fall through to the INT case
case Am_INT:
case Am_LONG:
case Am_FLOAT:
case Am_DOUBLE: {
//Am_String_To_Long_Or_Float is defined in widgets_advanced.h
bool ok = Am_String_To_Long_Or_Float(input, output_value);
if (ok) {
if (output_value.type != wanted_type) {
if (output_value.type == Am_FLOAT) {
if (wanted_type == Am_DOUBLE) {
output_value = (double)output_value;
return true;
}
return false; //want int, got float
}
else if (output_value.type == Am_LONG) { //user provided a long
if (wanted_type == Am_BOOL)
output_value = output_value.Valid();
else if (wanted_type == Am_INT)
output_value = (int)output_value;
else if (wanted_type == Am_FLOAT)
output_value = (float)output_value;
else if (wanted_type == Am_DOUBLE)
output_value = (double)output_value;
else Am_ERROR("Unknown wanted type " << wanted_type);
}
else Am_ERROR("Unexpected return type " << output_value.type
<< " on " << output_value);
}
return true;
}
else return false;
}
case Am_STRING:
output_value = input;
return true;
case Am_CHAR: {
char* s = input;
if (strlen(s) == 1) {
char c = s[0];
output_value = c;
return true;
}
else return false;
}
default:
return false; //Unsupported simple type (Am_VOIDPTR, Am_PROC, etc.)
}
break;
case Am_METHOD:
case Am_WRAPPER:
if (wanted_type == Am_Value_List::Type_ID()) {
std::cout << "** Can't edit value lists yet. Sorry.\n";
return false;
}
else {
char* s = input;
if (!strcmp(s, "(0L)") || !strcmp(s, "(NULL)") || !strcmp(s, "0") ||
!strncmp(s, "Am_No_", 6)) {
output_value.type = wanted_type;
output_value.value.wrapper_value = 0;
return true;
}
if (wanted_type == Am_OBJECT) {
if (s[0] == '<') { //remove the <> around the name
unsigned int i;
for (i = 1; i < (strlen(s)-1); i++)
s[i-1] = s[i];
s[i] = 0;
}
}
const Am_Registered_Type* the_item =
Am_Get_Named_Item((const char *)input);
if (the_item != (0L) && the_item->ID() == wanted_type) {
if (type_class == Am_METHOD)
output_value = (Am_Method_Wrapper*)the_item;
else {
Am_Wrapper* wrap = (Am_Wrapper*)the_item;
wrap->Note_Reference ();
output_value = wrap;
}
return true;
}
return false;
}
case Am_ENUM: {
Am_Type_Support* ws = Am_Find_Support (wanted_type);
if (ws) {
output_value = ws->From_String(input);
if (output_value.Exists())
return true;
}
return false;
}
default:
std::cerr << "** Unknown type class " << type_class
<< " on type " << wanted_type <<std::endl <<std::flush;
return false;
} //end switch
}
bool Am_Parse_Input_As_List_Of_Type(Am_String input, Am_Value_Type wanted_type,
Am_Value &output_value) {
char *s = input;
if (strncmp(s, "LIST(", 5)) return false; //not a list
char* real_part = strchr(s, '[');
real_part++;
std::cout << "parse " << input << " found real part '" << real_part
<< "'\n" <<std::flush;
char* token = strtok(real_part, ",]");
std::cout << "first token `" << token << "'\n" <<std::flush;
Am_String token_str;
Am_Value_List return_values;
bool ok;
Am_Value sub_value;
while (token) {
if (token[0] == ' ') token++;
token_str = token;
ok = Am_Parse_Input_As_Type(token_str, wanted_type, sub_value);
std::cout << "parsing " << token_str << " ok " << ok
<< " value " << sub_value;
if (!ok) return false;
return_values.Add(sub_value);
token = strtok((0L), ",]");
std::cout << "next token is `" << token << "'\n" <<std::flush;
}
output_value = return_values;
return true;
}
|