odlgen_utils.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021   Author: Eric Viara <viara@sysra.com>
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     // C++ keywords
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     // Java keywords
00109     reserve("final");
00110     reserve("synchonized");
00111 
00112     // eyedb methods (non exhaustive list)
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     //reserve("clone");
00136     reserve("getClass");
00137     reserve("getIDR");
00138     reserve("getIDRSize");
00139     //reserve("getType");
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; // keep it for now
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; // not needed
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; // not needed
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; // added the 10/3/00
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)); // opTypeStr(d->op));
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 }

Generated on Mon Dec 22 18:16:00 2008 for eyedb by  doxygen 1.5.3