00001 #include "xi-Template.h"
00002 #include "xi-util.h"
00003
00004 namespace xi {
00005
00006 void XStr::append(const char* _s) {
00007 len += strlen(_s);
00008 if (len >= blklen) {
00009 while (len >= blklen) {
00010 blklen += SZ;
00011 }
00012 char* tmp = s;
00013 s = new char[blklen];
00014 strcpy(s, tmp);
00015 delete[] tmp;
00016 }
00017 strcat(s, _s);
00018 }
00019
00020 void XStr::append(char c) {
00021 char tmp[2];
00022 tmp[0] = c;
00023 tmp[1] = '\0';
00024 append(tmp);
00025 }
00026
00027 void XStr::initTo(const char* _s) {
00028 len = strlen(_s);
00029 blklen = SZ;
00030 while (len >= blklen) {
00031 blklen += SZ;
00032 }
00033 s = new char[blklen];
00034 strcpy(s, _s);
00035 }
00036
00037 XStr::XStr() { initTo(""); }
00038 XStr::XStr(const char* _s) { initTo(_s); }
00039 XStr::XStr(const XStr& _s) { initTo(_s.get_string_const()); }
00040
00041 void XStr::clear() {
00042 delete[] s;
00043 initTo("");
00044 }
00045
00046 XStr& XStr::operator<<(int i) {
00047 char tmp[100];
00048 sprintf(tmp, "%d", i);
00049 append(tmp);
00050 return *this;
00051 }
00052
00053 void XStr::line_append(const char c) {
00054 XStr xs;
00055 for (unsigned int i = 0; i < len; i++) {
00056 if (s[i] == '\n')
00057 xs << c << "\n";
00058 else
00059 xs << s[i];
00060 }
00061 delete[] s;
00062 initTo(xs.charstar());
00063 }
00064
00065 void XStr::line_append_padding(const char c, int lineWidth) {
00066 XStr xs;
00067 int count = 0;
00068
00069 for (unsigned int i = 0; i < len; i++) {
00070 if (s[i] == '\n') {
00071
00072 while (count++ < lineWidth - 1) xs << " ";
00073 xs << c << "\n";
00074 count = 0;
00075 } else if (s[i] == '\t') {
00076
00077 xs << " ";
00078 count += 2;
00079 } else {
00080
00081 xs << s[i];
00082 count++;
00083 }
00084 }
00085 delete[] s;
00086 initTo(xs.charstar());
00087 }
00088
00089 void XStr::spew(const char* b, const char* a1, const char* a2, const char* a3,
00090 const char* a4, const char* a5) {
00091 using std::cout;
00092 int i, length = strlen(b);
00093 for (i = 0; i < length; i++) {
00094 switch (b[i]) {
00095 case '\001':
00096 if (a1 == 0) {
00097 cout << "Internal Error\n";
00098 abort();
00099 }
00100 append(a1);
00101 break;
00102 case '\002':
00103 if (a2 == 0) {
00104 cout << "Internal Error\n";
00105 abort();
00106 }
00107 append(a2);
00108 break;
00109 case '\003':
00110 if (a3 == 0) {
00111 cout << "Internal Error\n";
00112 abort();
00113 }
00114 append(a3);
00115 break;
00116 case '\004':
00117 if (a4 == 0) {
00118 cout << "Internal Error\n";
00119 abort();
00120 }
00121 append(a4);
00122 break;
00123 case '\005':
00124 if (a5 == 0) {
00125 cout << "Internal Error\n";
00126 abort();
00127 }
00128 append(a5);
00129 break;
00130 default:
00131 append(b[i]);
00132 }
00133 }
00134 }
00135
00136 void XStr::replace(const char a, const char b) {
00137 for (unsigned int i = 0; i < len; i++) {
00138 if (s[i] == a) s[i] = b;
00139 }
00140 }
00141
00142 extern const char* cur_file;
00143
00144
00145 void die(const char* why, int line) {
00146 if (line == -1)
00147 fprintf(stderr, "%s: Charmxi fatal error> %s\n", cur_file, why);
00148 else
00149 fprintf(stderr, "%s:%d: Charmxi fatal error> %s\n", cur_file, line, why);
00150 exit(1);
00151 }
00152
00153 char* fortranify(const char* s, const char* suff1, const char* suff2, const char* suff3) {
00154 int i, len1 = strlen(s), len2 = strlen(suff1), len3 = strlen(suff2),
00155 len4 = strlen(suff3);
00156 int c = len1 + len2 + len3 + len4;
00157 char str[1024], strUpper[1024];
00158 strcpy(str, s);
00159 strcat(str, suff1);
00160 strcat(str, suff2);
00161 strcat(str, suff3);
00162 for (i = 0; i < c + 1; i++) str[i] = tolower(str[i]);
00163 for (i = 0; i < c + 1; i++) strUpper[i] = toupper(str[i]);
00164 char* retVal;
00165 retVal = new char[2 * c + 20];
00166 strcpy(retVal, "FTN_NAME(");
00167 strcat(retVal, strUpper);
00168 strcat(retVal, ",");
00169 strcat(retVal, str);
00170 strcat(retVal, ")");
00171
00172 return retVal;
00173 }
00174
00175 XStr generateTemplateSpec(TVarList* tspec, bool printDefault) {
00176 XStr str;
00177
00178 if (tspec) {
00179 str << "template <";
00180 tspec->genLong(str, printDefault);
00181 str << "> ";
00182 }
00183
00184 return str;
00185 }
00186
00187 const char* forWhomStr(forWhom w) {
00188 switch (w) {
00189 case forAll:
00190 return Prefix::Proxy;
00191 case forIndividual:
00192 return Prefix::ProxyElement;
00193 case forSection:
00194 return Prefix::ProxySection;
00195 case forIndex:
00196 return Prefix::Index;
00197 case forPython:
00198 return "";
00199 default:
00200 return NULL;
00201 };
00202 }
00203
00204
00205 void templateGuardBegin(bool templateOnly, XStr& str) {
00206 if (templateOnly)
00207 str << "#ifdef "
00208 << "CK_TEMPLATES_ONLY\n";
00209 else
00210 str << "#ifndef "
00211 << "CK_TEMPLATES_ONLY\n";
00212 }
00213 void templateGuardEnd(XStr& str) { str << "#endif /* CK_TEMPLATES_ONLY */\n"; }
00214
00215
00216
00217 std::string addLineNumbers(char* str, const char* filename) {
00218 int lineNo = 1;
00219 std::string s(str);
00220 for (int i = 0; i < s.length(); ++i) {
00221 switch (s[i]) {
00222 case '\n':
00223 lineNo++;
00224 break;
00225 case '#':
00226 if (i > 0 && s[i - 1] == '\n' && s[i + 1] == '\n') {
00227 std::stringstream ss;
00228 ss << "#line " << lineNo + 1 << " \"" << filename << "\"";
00229 s.replace(s.begin() + i, s.begin() + i + 1, ss.str());
00230 }
00231 }
00232 }
00233 return s;
00234 }
00235
00236
00237 void sanitizeRange(std::string& code, int i, int j) {
00238 for (int k = i; k <= j; ++k) {
00239 switch (code[k]) {
00240 case '{':
00241 code[k] = 0x0E;
00242 break;
00243 case '}':
00244 code[k] = 0x0F;
00245 break;
00246 case '(':
00247 code[k] = 0x10;
00248 break;
00249 case ')':
00250 code[k] = 0x11;
00251 break;
00252 case '[':
00253 code[k] = 0x12;
00254 break;
00255 case ']':
00256 code[k] = 0x13;
00257 break;
00258 case ';':
00259 code[k] = 0x14;
00260 break;
00261 case ':':
00262 code[k] = 0x15;
00263 break;
00264 case ',':
00265 code[k] = 0x16;
00266 break;
00267 default:
00268 break;
00269 }
00270 }
00271 }
00272
00273 void desanitizeCode(std::string& code) {
00274 for (int i = 0; i < code.size(); ++i) {
00275 switch (code[i]) {
00276 case 0x0E:
00277 code[i] = '{';
00278 break;
00279 case 0x0F:
00280 code[i] = '}';
00281 break;
00282 case 0x10:
00283 code[i] = '(';
00284 break;
00285 case 0x11:
00286 code[i] = ')';
00287 break;
00288 case 0x12:
00289 code[i] = '[';
00290 break;
00291 case 0x13:
00292 code[i] = ']';
00293 break;
00294 case 0x14:
00295 code[i] = ';';
00296 break;
00297 case 0x15:
00298 code[i] = ':';
00299 break;
00300 case 0x16:
00301 code[i] = ',';
00302 break;
00303 default:
00304 break;
00305 }
00306 }
00307 }
00308
00309 void sanitizeComments(std::string& code) {
00310 int h, i;
00311
00312 if(code.length() == 0)
00313 return;
00314
00315 for (i = 0; i < code.length() - 1; ++i) {
00316 if (code[i] == '/') {
00317 h = i + 2;
00318 switch (code[i + 1]) {
00319 case '*':
00320
00321 i += 2;
00322 for (; !(code[i] == '*' && code[i + 1] == '/'); ++i)
00323 ;
00324 break;
00325
00326 case '/':
00327
00328 while (code[++i] != '\n')
00329 ;
00330 break;
00331
00332 default:
00333
00334 continue;
00335 break;
00336 }
00337
00338 sanitizeRange(code, h, i - 1);
00339 ++i;
00340 }
00341 }
00342 }
00343
00344 void sanitizeStrings(std::string& code) {
00345 int h, i;
00346 bool in_string = false;
00347 for (i = 0; i < code.size(); ++i) {
00348 if (code[i] == '\\') {
00349
00350
00351 ++i;
00352 } else if (code[i] == '"') {
00353 if (in_string) {
00354 sanitizeRange(code, h, i - 1);
00355 in_string = false;
00356 } else {
00357 h = i + 1;
00358 in_string = true;
00359 }
00360 }
00361 }
00362 }
00363
00364
00365 std::string _get_caret_line(int err_line_start, int first_col, int last_col) {
00366 std::string caret_line(first_col - err_line_start - 1, ' ');
00367 caret_line += std::string(last_col - first_col + 1, '^');
00368
00369 return caret_line;
00370 }
00371
00372 void _pretty_header(std::string type, std::string msg, int first_col, int last_col,
00373 int first_line, int last_line) {
00374 std::cerr << cur_file << ":" << first_line << ":";
00375
00376 if (first_col != -1) std::cerr << first_col << "-" << last_col << ": ";
00377
00378 std::cerr << type << ": " << msg << std::endl;
00379 }
00380
00381 void _pretty_print(std::string type, std::string msg, int first_col, int last_col,
00382 int first_line, int last_line) {
00383 _pretty_header(type, msg, first_col, last_col, first_line, last_line);
00384
00385 if (first_line <= inputBuffer.size() && first_line <= last_line &&
00386 first_col <= last_col) {
00387 std::string err_line = inputBuffer[first_line - 1];
00388
00389 if (err_line.length() != 0) {
00390 int err_line_start = err_line.find_first_not_of(" \t\r\n");
00391 err_line.erase(0, err_line_start);
00392
00393 std::string caret_line;
00394 if (first_col != -1)
00395 caret_line = _get_caret_line(err_line_start, first_col, last_col);
00396
00397 std::cerr << " " << err_line << std::endl;
00398
00399 if (first_col != -1) std::cerr << " " << caret_line;
00400 std::cerr << std::endl;
00401 }
00402 }
00403 }
00404
00405 void pretty_msg(std::string type, std::string msg, int first_col, int last_col,
00406 int first_line, int last_line) {
00407 if (first_line == -1) first_line = lineno;
00408 if (last_line == -1) last_line = lineno;
00409 _pretty_print(type, msg, first_col, last_col, first_line, last_line);
00410 }
00411
00412 void pretty_msg_noline(std::string type, std::string msg, int first_col, int last_col,
00413 int first_line, int last_line) {
00414 if (first_line == -1) first_line = lineno;
00415 if (last_line == -1) last_line = lineno;
00416 _pretty_header(type, msg, first_col, last_col, first_line, last_line);
00417 }
00418
00419 }
00420
00421 namespace Prefix {
00422
00423 const char* Proxy = "CProxy_";
00424 const char* ProxyElement = "CProxyElement_";
00425 const char* ProxySection = "CProxySection_";
00426 const char* Message = "CMessage_";
00427 const char* Index = "CkIndex_";
00428 const char* Python = "CkPython_";
00429
00430 }