00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "eyedb_p.h"
00026 #include "Attribute_p.h"
00027 #include <string.h>
00028 #include <map>
00029
00030 namespace eyedb {
00031
00032 static std::map<std::string, bool> map_rw;
00033
00034 inline void reserve(const std::string &s)
00035 {
00036 map_rw[s] = true;
00037 }
00038
00039 void init_reserved_words()
00040 {
00041 if (map_rw.size())
00042 return;
00043
00044
00045 reserve("asm");
00046 reserve("auto");
00047 reserve("bool");
00048 reserve("break");
00049 reserve("case");
00050 reserve("catch");
00051 reserve("char");
00052 reserve("class");
00053 reserve("const");
00054 reserve("const_cast");
00055 reserve("continue");
00056 reserve("default");
00057 reserve("delete");
00058 reserve("do");
00059 reserve("double");
00060 reserve("dynamic_cast");
00061 reserve("else");
00062 reserve("enum");
00063 reserve("explicit");
00064 reserve("extern");
00065 reserve("false");
00066 reserve("float");
00067 reserve("for");
00068 reserve("friend");
00069 reserve("goto");
00070 reserve("if");
00071 reserve("inline");
00072 reserve("int");
00073 reserve("long");
00074 reserve("mutable");
00075 reserve("namespace");
00076 reserve("new");
00077 reserve("operator");
00078 reserve("private");
00079 reserve("protected");
00080 reserve("public");
00081 reserve("register");
00082 reserve("reinterpret_cast");
00083 reserve("return");
00084 reserve("short");
00085 reserve("signed");
00086 reserve("sizeof");
00087 reserve("static");
00088 reserve("static_cast");
00089 reserve("struct");
00090 reserve("switch");
00091 reserve("template");
00092 reserve("this");
00093 reserve("throw");
00094 reserve("true");
00095 reserve("try");
00096 reserve("typedef");
00097 reserve("typeid");
00098 reserve("typename");
00099 reserve("union");
00100 reserve("unsigned");
00101 reserve("using");
00102 reserve("virtual");
00103 reserve("void");
00104 reserve("volatile");
00105 reserve("wchar_t");
00106 reserve("while");
00107
00108
00109 reserve("final");
00110 reserve("synchonized");
00111
00112
00113 reserve("gbxObject");
00114 reserve("getRefCount");
00115 reserve("isLocked");
00116 reserve("incrRefCount");
00117 reserve("decrRefCount");
00118 reserve("lock");
00119 reserve("unlock");
00120 reserve("isOnStack");
00121 reserve("release");
00122 reserve("setTag");
00123 reserve("getTag");
00124 reserve("userGarbage");
00125 reserve("keep");
00126 reserve("unkeep");
00127 reserve("getObjectCount");
00128 reserve("getHeapSize");
00129 reserve("isValidObject");
00130 reserve("setObjMapped");
00131 reserve("isObjMapped");
00132 reserve("getObjMap");
00133
00134 reserve("Object");
00135
00136 reserve("getClass");
00137 reserve("getIDR");
00138 reserve("getIDRSize");
00139
00140 reserve("getOid");
00141 reserve("getCTime");
00142 reserve("getMTime");
00143 reserve("getStringCTime");
00144 reserve("getStringMTime");
00145 reserve("getLock");
00146 reserve("setLock");
00147 reserve("setUserData");
00148 reserve("getUserData");
00149 reserve("getAllUserData");
00150 reserve("isModify");
00151 reserve("setDatabase");
00152 reserve("create");
00153 reserve("update");
00154 reserve("realize");
00155 reserve("remove");
00156 reserve("store");
00157 reserve("apply");
00158 reserve("trace");
00159 reserve("toString");
00160 reserve("getDataspace");
00161 reserve("getLocation");
00162 reserve("setDataspace");
00163 reserve("move");
00164 reserve("setProtection");
00165 reserve("setValue");
00166 reserve("isUnrealizable");
00167 reserve("isRemoved");
00168 reserve("getDatabase");
00169
00170 reserve("Agregat");
00171 reserve("getValue");
00172 reserve("setItemSize");
00173 reserve("getItemSize");
00174 reserve("setItemValue");
00175 reserve("setItemOid");
00176 reserve("getItemOid");
00177
00178 reserve("Struct");
00179 reserve("Union");
00180 }
00181
00182 GenCodeHints::GenCodeHints()
00183 {
00184 attr_style = ExplicitAttrStyle;
00185 style = NULL;
00186 setStyle("explicit");
00187
00188 gen_class_stubs = False;
00189 class_enums = False;
00190 gen_down_casting = True;
00191 attr_cache = False;
00192 error_policy = StatusErrorPolicy;
00193 dirname = strdup(".");
00194 fileprefix = NULL;
00195 stubs = NULL;
00196 c_suffix = strdup(".cc");
00197 h_suffix = strdup(".h");
00198 gen_date = True;
00199
00200 init_reserved_words();
00201 }
00202
00203 Status
00204 GenCodeHints::setStyle(const char *file)
00205 {
00206 delete style;
00207 style = new Style(file);
00208 return style->getStatus();
00209 }
00210
00211 static char *upper_case(const char *p, char *s = 0)
00212 {
00213 char c, *q;
00214
00215 s = (!s ? strdup(p) : s);
00216 q = s;
00217
00218 while (c = *p) {
00219 *q = c;
00220 if (c >= 'a' && c <= 'z')
00221 *q += 'A' - 'a';
00222
00223 q++; p++;
00224 }
00225
00226 *q = 0;
00227 return s;
00228 }
00229
00230 static char *lower_case(const char *p, char *s = 0)
00231 {
00232 char c, *q;
00233
00234 s = (!s ? strdup(p) : s);
00235 q = s;
00236
00237 while (c = *p) {
00238 *q = c;
00239 if (c >= 'A' && c <= 'Z')
00240 *q += c + 'a' - 'A';
00241
00242 q++; p++;
00243 }
00244
00245 *q = 0;
00246 return s;
00247 }
00248
00249 static char *capitalize_case(const char *p, char *s = 0)
00250 {
00251 char c, *q;
00252 int state = 0;
00253
00254 s = (!s ? strdup(p) : s);
00255 q = s;
00256
00257 while(c = *p) {
00258 if (!state || (c == '_' && *(p+1))) {
00259 *q = (c == '_' ? *++p : *p);
00260
00261 if (*q >= 'a' && *q <= 'z')
00262 *q += 'A' - 'a';
00263 state = 1;
00264 }
00265 else
00266 *q = *p;
00267
00268 q++;
00269 p++;
00270 }
00271
00272 *q = 0;
00273 return s;
00274 }
00275
00276 static char *
00277 getStaticString()
00278 {
00279 #define NN 8
00280 static int round = 0;
00281 static char str[NN][256];
00282
00283 if (round >= NN)
00284 round = 0;
00285
00286 return str[round++];
00287 }
00288
00289 static const char *capitalize_fun(const char *s)
00290 {
00291 return capitalize_case(s, getStaticString());
00292 }
00293
00294 static const char *upper_fun(const char *s)
00295 {
00296 return upper_case(s, getStaticString());
00297 }
00298
00299 static const char *lower_fun(const char *s)
00300 {
00301 return lower_case(s, getStaticString());
00302 }
00303
00304 static const char *ident_fun(const char *s)
00305 {
00306 return s;
00307 }
00308
00309 GenCodeHints::Style::Style(const char *file)
00310 {
00311 memset(desc, 0, sizeof(desc));
00312
00313 if (!strcasecmp(file, "implicit")) {
00314 desc[tGet].fmt = strdup("%IN");
00315 desc[tSet].fmt = strdup("%IN");
00316 desc[tGetOid].fmt = strdup("%IN_oid");
00317 desc[tSetOid].fmt = strdup("%IN_oid");
00318 desc[tGetCount].fmt = strdup("%IN_cnt");
00319 desc[tSetCount].fmt = strdup("%IN_cnt");
00320 desc[tGetColl].fmt = strdup("%IN");
00321 desc[tSetColl].fmt = strdup("%IN");
00322 desc[tAddItemToColl].fmt = strdup("addto_%IN");
00323 desc[tRmvItemFromColl].fmt = strdup("rmvfrom_%IN");
00324 desc[tSetItemInColl].fmt = strdup("setin_%IN_at");
00325 desc[tUnsetItemInColl].fmt = strdup("unsetin_%IN_at");
00326 desc[tGetItemAt].fmt = strdup("%IN_at");
00327 desc[tGetOidItemAt].fmt = strdup("%IN_oidat");
00328 desc[tRetrieveItemAt].fmt = strdup("%IN_at");
00329 desc[tRetrieveOidItemAt].fmt = strdup("%IN_oidat");
00330 desc[tCast].fmt = strdup("%IP%CN_");
00331 desc[tSafeCast].fmt = strdup("%IP%CN_c");
00332 }
00333 else if (!strcasecmp(file, "explicit")) {
00334 desc[tGet].fmt = strdup("get%CN");
00335 desc[tSet].fmt = strdup("set%CN");
00336 desc[tGetOid].fmt = strdup("get%CNOid");
00337 desc[tSetOid].fmt = strdup("set%CNOid");
00338 desc[tGetCount].fmt = strdup("get%CNCount");
00339 desc[tSetCount].fmt = strdup("set%CNCount");
00340 desc[tGetColl].fmt = strdup("get%CNColl");
00341 desc[tSetColl].fmt = strdup("set%CNColl");
00342 desc[tAddItemToColl].fmt = strdup("addTo%CNColl");
00343 desc[tRmvItemFromColl].fmt = strdup("rmvFrom%CNColl");
00344 desc[tSetItemInColl].fmt = strdup("setIn%CNCollAt");
00345 desc[tUnsetItemInColl].fmt = strdup("unsetIn%CNCollAt");
00346 desc[tGetItemAt].fmt = strdup("get%CNAt");
00347 desc[tGetOidItemAt].fmt = strdup("get%CNOidAt");
00348 desc[tRetrieveItemAt].fmt = strdup("retrieve%CNAt");
00349 desc[tRetrieveOidItemAt].fmt = strdup("retrieve%CNOidAt");
00350 desc[tCast].fmt = strdup("%UP%CN_");
00351 desc[tSafeCast].fmt = strdup("%UP%CN_c");
00352 }
00353 else {
00354 parse_file(file);
00355 if (status)
00356 return;
00357 }
00358
00359 status = compile();
00360 }
00361
00362 static const char *
00363 make_fmt(const char *fmt)
00364 {
00365 static char sfmt[64];
00366 char *p = sfmt;
00367 char c;
00368 while (c = *fmt) {
00369 if (c == '%') {
00370 *p++ = c;
00371 c = *++fmt;
00372 if (c == 'n' || c == 'N')
00373 *p++ = 'I';
00374 }
00375 *p++ = *fmt++;
00376 }
00377
00378 *p = 0;
00379 return sfmt;
00380 }
00381
00382 void
00383 GenCodeHints::Style::parse_file(const char *file)
00384 {
00385 FILE *fd = fopen(file, "r");
00386 if (!fd) {
00387 status = Exception::make(IDB_ERROR,
00388 "cannot open user file style '%s'",
00389 file);
00390 return;
00391 }
00392
00393 char line[128];
00394 int nlines = 0;
00395
00396 while (fgets(line, sizeof(line)-1, fd)) {
00397 char optype_str[64], fmt_str[64];
00398 int r = sscanf(line, "%s %s\n", optype_str, fmt_str);
00399
00400 nlines++;
00401
00402 if (r <= 0 || *optype_str == '#')
00403 continue;
00404
00405 if (r != 2) {
00406 status =
00407 Exception::make(IDB_ERROR,
00408 "syntax error in user file style '%s' "
00409 "at line %d",
00410 file, nlines);
00411 return;
00412 }
00413
00414 int i;
00415 for (i = 0; i < tLastOp; i++)
00416 if (!strcasecmp(optype_str, opTypeStr((OpType)i))) {
00417 desc[i].fmt = strdup(make_fmt(fmt_str));
00418 desc[i].op = (OpType)i;
00419 break;
00420 }
00421
00422 if (i == tLastOp) {
00423 status =
00424 Exception::make(IDB_ERROR,
00425 "syntax error in user file style '%s' "
00426 "at line %d",
00427 file, nlines);
00428 return;
00429 }
00430 }
00431 }
00432
00433 const char *
00434 GenCodeHints::Style::opTypeStr(OpType op)
00435 {
00436 if (op == tGet)
00437 return "GET";
00438 if (op == tSet)
00439 return "SET";
00440 if (op == tGetOid)
00441 return "tGetOid";
00442 if (op == tSetOid)
00443 return "SETOID";
00444 if (op == tGetCount)
00445 return "GETCOUNT";
00446 if (op == tSetCount)
00447 return "SETCOUNT";
00448 if (op == tGetColl)
00449 return "GETCOLL";
00450 if (op == tSetColl)
00451 return "SETCOLL";
00452 if (op == tAddItemToColl)
00453 return "ADD_ITEM_TO_COLL";
00454 if (op == tRmvItemFromColl)
00455 return "RMV_ITEM_FROM_COLL";
00456 if (op == tSetItemInColl)
00457 return "SET_ITEM_IN_COLL";
00458 if (op == tUnsetItemInColl)
00459 return "UNSET_ITEM_IN_COLL";
00460 if (op == tGetItemAt)
00461 return "GET_ITEM_AT";
00462 if (op == tGetOidItemAt)
00463 return "GETOID_ITEM_AT";
00464 if (op == tRetrieveItemAt)
00465 return "RETRIEVE_ITEM_AT";
00466 if (op == tRetrieveOidItemAt)
00467 return "RETRIEVEOID_ITEM_AT";
00468 if (op == tCast)
00469 return "CAST";
00470 if (op == tSafeCast)
00471 return "SAFE_CAST";
00472 abort();
00473 }
00474
00475 Status GenCodeHints::Style::compile(Desc *d)
00476 {
00477 char c, *p, *q;
00478
00479 p = d->fmt;
00480 d->comp.cnt = 0;
00481 q = d->comp.cfmt = (char *)malloc(strlen(d->fmt)+1);
00482
00483 while (c =*p) {
00484 if (c == '%') {
00485 Desc::CompDesc::Item *item = &d->comp.items[d->comp.cnt++];
00486
00487 *q++ = *p++;
00488 c = *p;
00489 switch (c) {
00490 case 'c': case 'C':
00491 item->fun = capitalize_fun;
00492 *q++ = 's'; break;
00493
00494 case 'u': case 'U':
00495 item->fun = upper_fun;
00496 *q++ = 's'; break;
00497
00498 case 'l': case 'L':
00499 item->fun = lower_fun;
00500 *q++ = 's'; break;
00501
00502 case 'i': case 'I':
00503 item->fun = ident_fun;
00504 *q++ = 's'; break;
00505
00506 default:
00507 return Exception::make(IDB_ERROR,
00508 "invalid style format '%s'",
00509 d->fmt);
00510 }
00511
00512 c = *++p;
00513 switch(c) {
00514 case 'n': case 'N':
00515 item->which = Desc::CompDesc::Item::Name; break;
00516
00517 case 'p': case 'P':
00518 item->which = Desc::CompDesc::Item::Prefix; break;
00519
00520 default:
00521 return Exception::make(IDB_ERROR,
00522 "invalid style format '%s'",
00523 d->fmt);
00524 }
00525
00526 p++;
00527 }
00528 else
00529 *q++ = *p++;
00530 }
00531
00532 *q = 0;
00533
00534 return Success;
00535 }
00536
00537 Status GenCodeHints::Style::compile()
00538 {
00539 for (int i = 0; i < tLastOp; i++) {
00540 Desc *d = &desc[i];
00541 if (!d->fmt)
00542 return Exception::make(IDB_ERROR,
00543 "format is not set for operation '%s'",
00544 opTypeStr((OpType)i));
00545 Status s = compile(d);
00546 if (s)
00547 return s;
00548 }
00549
00550 return Success;
00551 }
00552
00553 const char *
00554 GenCodeHints::Style::getString(GenCodeHints::OpType op,
00555 const char *name,
00556 const char *prefix)
00557 {
00558 if (status)
00559 return "";
00560
00561 static char str[256];
00562 Desc *d = &desc[op];
00563 const char *s[4] = {0};
00564 for (int i = 0; i < d->comp.cnt; i++) {
00565 Desc::CompDesc::Item *item = &d->comp.items[i];
00566 if (item->which == Desc::CompDesc::Item::Name)
00567 s[i] = item->fun(name);
00568 else if (item->which == Desc::CompDesc::Item::Prefix)
00569 s[i] = item->fun(prefix);
00570 else
00571 s[i] = "";
00572 }
00573
00574 sprintf(str, d->comp.cfmt, s[0], s[1], s[2], s[3]);
00575
00576 for (;;) {
00577 if (map_rw.find(str) == map_rw.end())
00578 break;
00579 strcat(str, "_");
00580 }
00581 return str;
00582 }
00583
00584 GenCodeHints::Style::~Style()
00585 {
00586 }
00587 }