Changeset 7389
- Timestamp:
- 2004-05-24T16:45:38+12:00 (20 years ago)
- Location:
- trunk/gsdl/src/recpt
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gsdl/src/recpt/formattools.cpp
r7266 r7389 777 777 // Decision is a piece of text (probably a macro like _cgiargmode_). 778 778 else { 779 780 // hunt for any metadata in string, which might be uses in 781 // to test a condition, e.g. [Format] eq 'PDF' 782 format_t* dummyformat = new format_t(); 783 // update which metadata fields needed 784 // (not interested in updatng formatlistptr) 785 parse_string (text, dummyformat, metadata, getParents); 786 delete dummyformat; 787 779 788 formatlistptr->decision.command = dText; 780 789 formatlistptr->decision.text = text; … … 976 985 } 977 986 987 static bool char_is_whitespace(const char c) 988 { 989 return ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r')); 990 991 } 992 993 static int scan_over_whitespace(const text_t& outstring, const int start_pos) 994 { 995 int pos = start_pos; 996 while (pos<outstring.size()) { 997 if (!char_is_whitespace(outstring[pos])) { 998 break; 999 } 1000 pos++; 1001 } 1002 1003 return pos; 1004 } 1005 1006 static int rscan_over_whitespace(const text_t& outstring, const int start_pos) 1007 { 1008 int pos = start_pos; 1009 while (pos>=0) { 1010 if (!char_is_whitespace(outstring[pos])) { 1011 break; 1012 } 1013 pos--; 1014 } 1015 1016 return pos; 1017 } 1018 1019 static int rscan_for_whitespace(const text_t& outstring, const int start_pos) 1020 { 1021 int pos = start_pos; 1022 while (pos>=0) { 1023 if (char_is_whitespace(outstring[pos])) { 1024 break; 1025 } 1026 pos--; 1027 } 1028 1029 return pos; 1030 } 1031 1032 1033 static int rscan_for(const text_t& outstring, const int start_pos, 1034 const char find_c) 1035 { 1036 int pos = start_pos; 1037 while (pos>=0) { 1038 char c = outstring[pos]; 1039 if (outstring[pos] == find_c) { 1040 break; 1041 } 1042 pos--; 1043 } 1044 1045 return pos; 1046 } 1047 1048 text_t extract_substr(const text_t& outstring, const int start_pos, 1049 const int end_pos) 1050 { 1051 text_t extracted_str; 1052 extracted_str.clear(); 1053 1054 for (int pos=start_pos; pos<=end_pos; pos++) { 1055 extracted_str.push_back(outstring[pos]); 1056 } 1057 1058 return extracted_str; 1059 } 1060 1061 1062 static text_t expand_potential_metadata(ResultDocInfo_t &docinfo, 1063 const text_t& intext) 1064 { 1065 text_t outtext; 1066 1067 // decide if dealing with metadata or text 1068 1069 text_t::const_iterator beginbracket = intext.begin(); 1070 text_t::const_iterator endbracket = (intext.end() - 1); 1071 1072 // Decision is based on a metadata element 1073 if ((*beginbracket == '[') && (*endbracket == ']')) { 1074 // Ignore the surrounding square brackets 1075 text_t meta_text = substr (beginbracket+1, endbracket); 1076 1077 metadata_t meta; 1078 meta.metaname = meta_text; 1079 meta.parentcommand = pNone; 1080 meta.metacommand = mSibling; 1081 1082 bool getParents =false; 1083 outtext = get_meta (docinfo,meta); 1084 } 1085 else { 1086 outtext = intext; 1087 } 1088 1089 return outtext; 1090 } 1091 1092 1093 1094 1095 static bool uses_expression(ResultDocInfo_t &docinfo, 1096 const text_t& outstring, text_t& lhs_expr, 1097 text_t& op_expr, text_t& rhs_expr) 1098 { 1099 // Note: the string may not be of the form: str1 op str2, however 1100 // to deterine this we have to process it on the assumption it is, 1101 // and if at any point an 'erroneous' value is encountered, return 1102 // false and let something else have a go at evaluating it 1103 1104 // Starting at the end of the string and working backwards .. 1105 1106 const int outstring_len = outstring.size(); 1107 1108 // skip over white space 1109 int rhs_end = rscan_over_whitespace(outstring,outstring_len-1); 1110 1111 if (rhs_end<=0) { 1112 // no meaningful text or (rhs_end==0) no room for operator 1113 return false; 1114 } 1115 1116 // check for ' or " and then scan over token 1117 const char potential_quote = outstring[rhs_end]; 1118 int rhs_start=rhs_end; 1119 bool quoted = false; 1120 1121 if ((potential_quote == '\'') || (potential_quote == '\"')) { 1122 rhs_end--; 1123 rhs_start = rscan_for(outstring,rhs_end-1,potential_quote) +1; 1124 quoted = true; 1125 } 1126 else { 1127 rhs_start = rscan_for_whitespace(outstring,rhs_end-1) +1; 1128 } 1129 1130 if ((rhs_end-rhs_start)<=0) { 1131 // no meaningful rhs expression 1132 return false; 1133 } 1134 1135 // form rhs_expr 1136 rhs_expr = extract_substr(outstring,rhs_start,rhs_end); 1137 1138 // skip over white space 1139 1140 const int to_whitespace = (quoted) ? 2 : 1; 1141 1142 int op_end = rscan_over_whitespace(outstring,rhs_start-to_whitespace); 1143 int op_start = rscan_for_whitespace(outstring,op_end-1)+1; 1144 1145 1146 if (op_end-op_start<=0) { 1147 // no meaningful expression operator 1148 return false; 1149 } 1150 1151 op_expr = extract_substr(outstring,op_start,op_end); 1152 1153 1154 // check for operator 1155 if ((op_expr != "eq") && (op_expr != "ne")) { 1156 // not a valid operator 1157 return false; 1158 } 1159 1160 int lhs_end = rscan_over_whitespace(outstring,op_start-1); 1161 if (lhs_end<=0) { 1162 // no meaningful lhs expression 1163 return false; 1164 } 1165 1166 int lhs_start = scan_over_whitespace(outstring,0); 1167 1168 // form lhs_expr from remainder of string 1169 lhs_expr = extract_substr(outstring,lhs_start,lhs_end); 1170 1171 // Now we know we have a valid expression, look up any 1172 // metadata terms 1173 1174 rhs_expr = expand_potential_metadata(docinfo,rhs_expr); 1175 lhs_expr = expand_potential_metadata(docinfo,lhs_expr); 1176 1177 return true; 1178 } 1179 1180 static bool eval_expression_true(const text_t& lhs_expr,const text_t& op_expr, 1181 const text_t& rhs_expr, ostream& logout) 1182 { 1183 if (op_expr == "eq") { 1184 return (lhs_expr == rhs_expr); 1185 } 1186 else if (op_expr == "ne" ) { 1187 return (lhs_expr != rhs_expr); 1188 } 1189 else { 1190 logout << "Error: '" << op_expr << "' is not a recognised operator." << endl; 1191 } 1192 1193 return false; 1194 } 1195 1196 978 1197 static text_t get_if (const text_t& collection, recptproto* collectproto, 979 1198 ResultDocInfo_t &docinfo, displayclass &disp, … … 982 1201 text_tmap &options, ostream& logout) 983 1202 { 984 985 1203 // If the decision component is a metadata element, then evaluate it 986 1204 // to see whether we output the "then" or the "else" clause … … 1005 1223 disp.expandstring (decision.text, outstring); 1006 1224 1225 // Check for if expression in form: str1 op str2 1226 // (such as [x] eq "y") 1227 text_t lhs_expr, op_expr, rhs_expr; 1228 if (uses_expression(docinfo, outstring,lhs_expr,op_expr,rhs_expr)) { 1229 if (eval_expression_true(lhs_expr,op_expr,rhs_expr,logout)) { 1230 if (ifptr != NULL) { 1231 return get_formatted_string (collection, collectproto, docinfo, disp, ifptr, 1232 options, logout); 1233 } 1234 else { 1235 return ""; 1236 } 1237 } else { 1238 if (elseptr != NULL) { 1239 return get_formatted_string (collection, collectproto, docinfo, disp, elseptr, 1240 options, logout); 1241 } 1242 else { 1243 return ""; 1244 } 1245 } 1246 } 1247 1248 1007 1249 // This is a tad tricky. When we expand a string like _cgiargmode_, that is 1008 1250 // a cgi argument macro that has not been set, it evaluates to itself. 1009 1251 // Therefore, were have to say that a piece of text evalautes true if 1010 1252 // it is non-empty and if it is a cgi argument evaulating to itself. 1253 1011 1254 if ((outstring != "") && !((outstring == decision.text) && (outstring[0] == '_'))) { 1012 1255 if (ifptr != NULL) -
trunk/gsdl/src/recpt/formattools.h
r6710 r7389 53 53 54 54 // The decision component of an {If}{decision,true-text,false-text} 55 // formatstring. T e decision can be based on metadata or on text;55 // formatstring. The decision can be based on metadata or on text; 56 56 // normally that text would be a macro like _cgiargmode_. --gordon 57 57 struct decision_t {
Note:
See TracChangeset
for help on using the changeset viewer.