eyedbodl.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 "odl.h"
00026 //#include "imdl.h"
00027 #include <eyedb/odlgen_utils.h>
00028 
00029 using namespace eyedb;
00030 using namespace std;
00031 
00032 namespace eyedb {
00033   extern Bool odl_smartptr;
00034 }
00035 
00036 #include "GetOpt.h"
00037 
00038 extern void
00039 rootclass_manage(odlAgregSpec agreg_spec);
00040 
00041 static int
00042 usage(const char *msg = 0, const char *etc = 0)
00043 {
00044   static const char sep[] = "";
00045   static const char us[] = "eyedbodl ";
00046   //static const char nl[] = "\n";
00047   //  static const char sp[] = "         ";
00048   static const char nl[] = "";
00049   static const char sp[] = " ";
00050 
00051   if (msg) {
00052     fprintf(stderr, "%seyedbodl: ", sep);
00053     fprintf(stderr, msg, etc);
00054     fprintf(stderr, "\n", sep);
00055     return 1;
00056   }
00057 
00058   fprintf(stderr, "\nUsage:\n");
00059   fprintf(stderr, "%s--gencode=C++ [--package=PACKAGE]%s", us, nl);
00060 
00061   fprintf(stderr, "%s[--output-dir=DIRNAME] [--output-file-prefix=PREFIX]%s",
00062           sp, nl);
00063   fprintf(stderr, "%s[--schema-name=SCHNAME] [--namespace=NAMESPACE] [--use-smart-pointers=yes|no]%s", sp, nl);
00064   fprintf(stderr, "%s[--class-prefix=PREFIX] [--db-class-prefix=DBPREFIX]%s", sp, nl);
00065   fprintf(stderr, "%s[--attr-style=implicit|explicit]%s", sp, nl);
00066   fprintf(stderr, "%s[--dynamic-attr]%s", sp, nl);
00067   fprintf(stderr, "%s[--gen-class-stubs] [--class-enums=yes|no]%s", sp, nl);
00068   fprintf(stderr, "%s[--c-suffix=SUFFIX] [--h-suffix=SUFFIX] [--export]%s",
00069           sp, nl);
00070 
00071   fprintf(stderr, "%s[--down-casting=yes|no] [--gencode-error-policy=status|exception]%s",
00072           sp, nl);
00073   fprintf(stderr, "%s[--attr-cache=yes|no] [--rootclass=ROOTCLASS] [--no-rootclass]%s", sp, nl);
00074   fprintf(stderr, "%s[--cpp=CPP] [--cpp-flags=FLAGS] [--no-cpp]%s%sODLFILE|-|-d DBNAME|--database=DBNAME [OPENFLAGS]\n", sp, nl, sp);
00075 
00076  
00077   fprintf(stderr, "\n%s--gencode=Java --package=PACKAGE%s", us, nl);
00078 
00079   fprintf(stderr, "%s[--output-dir=DIRNAME] [--output-file-prefix=PREFIX]%s",
00080           sp, nl);
00081   fprintf(stderr, "%s[--schema-name=SCHNAME]%s", sp, nl);
00082   fprintf(stderr, "%s[--class-prefix=PREFIX] [--db-class-prefix=DBPREFIX]%s", sp, nl);
00083   fprintf(stderr, "%s[--attr-style=implicit|explicit]%s", sp, nl);
00084   fprintf(stderr, "%s[--dynamic-attr]%s", sp, nl);
00085   fprintf(stderr, "%s[--down-casting=yes|no] [--gencode-error-policy=status|exception]%s",
00086           sp, nl);
00087   fprintf(stderr, "%s[--cpp=CPP] [--cpp-flags=FLAGS] [--no-cpp]%s%sODLFILE|-|-d DBNAME|--database=DBNAME [OPENFLAGS]\n", sp, nl, sp);
00088 
00089 #ifdef SUPPORT_CORBA
00090   fprintf(stderr, "\n%s--gencode Orbix|Orbacus|IDL --package PACKAGE -idl-module MODULE\n", us);
00091 
00092   fprintf(stderr, "%s[--imdl IMDLFILE] [--idl-target IDLFILE] [--output-dir DIRNAME] [--no-generic-idl]\n",
00093           sp);
00094   fprintf(stderr, "%s[--generic-idl IDLFILE] [--class-prefix PREFIX]\n", sp);
00095   fprintf(stderr, "%s[--factory yes|no] [--sync yes|no] [--comments yes|no]\n", sp);
00096   fprintf(stderr, "%s[--cpp CPP [--cpp-flags FLAGS [--no-cpp] ODLFILE|-|-d DBNAME|--database=DBNAME [OPENFLAGS]\n", sp);
00097 #endif
00098 
00099   fprintf(stderr, "\n%s--gencode=ODL -d DBNAME|--database=DBNAME [--system-class] [-o ODLFILE] [OPENFLAGS]%s", us, nl);
00100   fprintf(stderr, "\n%s--diff -d DBNAME|--database=DBNAME [--system-class] [OPENFLAGS]%s", us, nl);
00101   fprintf(stderr, "%s[--cpp=CPP] [--cpp-flags=FLAGS] [--no-cpp] ODLFILE|-\n",
00102           sp);
00103 
00104   fprintf(stderr, "\n%s-u|-update -d DBNAME|--database=DBNAME%s", us, nl);
00105   fprintf(stderr, "%s[--db-class-prefix=DBPREFIX] [OPENFLAGS]%s", sp, nl);
00106   fprintf(stderr, "%s[--schema-name=SCHNAME] [--rmv-undef-attrcomp=yes|no]%s%s[--update-index=yes|no]%s", sp, nl, sp, nl);
00107   fprintf(stderr, "%s[--cpp=CPP] [--cpp-flags=FLAGS] [--no-cpp]%s%s[--rmcls=CLASS...] [--rmsch] [ODLFILE|-]\n",
00108           sp, nl, sp);
00109   fprintf(stderr, "\n%s--checkfile ODLFILE|-\n", us);
00110 
00111   fprintf(stderr, "\n%s--help\n", us);
00112 
00113   return 1;
00114 }
00115 
00116 static void
00117 help()
00118 {
00119   fprintf(stderr, "One must specify one and only one of the following major options:\n");
00120   fprintf(stderr, "--gencode=C++                 Generates C++ code\n");
00121   fprintf(stderr, "--gencode=Java                Generates Java code\n");
00122 
00123 #ifdef SUPPORT_CORBA
00124   fprintf(stderr, "--gencode Orbix               Generates Orbix code (IDL and C++ stubs)\n");
00125   fprintf(stderr, "--gencode Orbacus             Generates Orbacus code (IDL and C++ stubs)\n");
00126   fprintf(stderr, "--gencode IDL                 Generates IDL\n");
00127 #endif
00128 
00129   fprintf(stderr, "--gencode=ODL                 Generates ODL\n");
00130   fprintf(stderr, "--update|-u                   Updates schema in database DBNAME\n");
00131   fprintf(stderr, "--diff                        Displays the differences between a database schema and an odl file\n");
00132   fprintf(stderr, "--checkfile                   Check input ODL file\n");
00133   fprintf(stderr, "--help                        Displays the current information\n");
00134 
00135   fprintf(stderr, "\nThe following options must be added to the --gencode=C++ or Java option:\n");
00136   fprintf(stderr, "ODLFILE|-|-d DBNAME|--database=DBNAME Input ODL file (or - for standard input) or the database name\n");
00137 
00138   fprintf(stderr, "\nThe following options can be added to the --gencode=C++ or Java option:\n");
00139   fprintf(stderr, "--package=PACKAGE             Package name\n");
00140   fprintf(stderr, "--output-dir=DIRNAME          Output directory for generated files\n");
00141   fprintf(stderr, "--output-file-prefix=PREFIX   Ouput file prefix (default is the package name)\n");
00142   fprintf(stderr, "--class-prefix=PREFIX         Prefix to be put at the begining of each runtime class\n");
00143   fprintf(stderr, "--db-class-prefix=PREFIX      Prefix to be put at the begining of each database class\n");
00144   fprintf(stderr, "--attr-style=implicit         Attribute methods have the attribute name\n");
00145   fprintf(stderr, "--attr-style=explicit         Attribute methods have the attribute name prefixed by get/set (default)\n");
00146   fprintf(stderr, "--schema-name=SCHNAME         Schema name (default is PACKAGE)\n");
00147   fprintf(stderr, "--export                      Export class instances in the .h file\n");
00148   fprintf(stderr, "--dynamic-attr                Uses a dynamic fetch for attributes in the get and set methods\n");
00149   fprintf(stderr, "--down-casting=yes            Generates the down casting methods (the default)\n");
00150   fprintf(stderr, "--down-casting=no             Does not generate the down casting methods\n");
00151   fprintf(stderr, "--attr-cache=yes              Use a second level cache for attribute value\n");
00152   fprintf(stderr, "--attr-cache=no               Does not use a second level cache for attribute value (the default)\n");
00153   fprintf(stderr, "\nFor the --gencode=C++ option only\n");
00154   fprintf(stderr, "--namespace=NAMESPACE         Define classes with the namespace NAMESPACE\n");
00155   fprintf(stderr, "--use-smart-pointers=yes|no   The generated C++ code will use (=yes) smart pointers or not (=no)\n");
00156   fprintf(stderr, "--c-suffix=SUFFIX             Use SUFFIX as the C file suffix\n");
00157   fprintf(stderr, "--h-suffix=SUFFIX             Use SUFFIX as the H file suffix\n");
00158   fprintf(stderr, "--gen-class-stubs             Generates a file class_stubs.h for each class\n");
00159   fprintf(stderr, "--class-enums=yes             Generates enums within a class\n");
00160   fprintf(stderr, "--class-enums=no              Do not generate enums within a class (default)\n");
00161   fprintf(stderr, "--gencode-error-policy=status Status oriented error policy (the default)\n");
00162   fprintf(stderr, "--gencode-error-policy=exception Exception oriented error policy\n");
00163   fprintf(stderr, "--rootclass=ROOTCLASS         Use ROOTCLASS name for the root class instead of the package name\n");
00164   fprintf(stderr, "--no-rootclass                Does not use any root class\n");
00165 
00166   fprintf(stderr, "\nThe following options can be added to the --gencode=ODL option:\n");
00167   fprintf(stderr, "--system-class                Generates system class ODL\n");
00168 #ifdef SUPPORT_CORBA
00169   fprintf(stderr, "\nThe following options must be added to the --gencode=Orbix, Orbacus or IDL option:\n");
00170   fprintf(stderr, "--package=PACKAGE             Package name\n");
00171   fprintf(stderr, "--idl-module MODULE           The IDL module name\n");
00172   fprintf(stderr, "\nOne of the following options must be added to the --gencode Orbix or Orbacus option:\n");
00173   fprintf(stderr, "ODLFILE|-|-d DBNAME|--database=DBNAME Input ODL file (- is the standard input) or\n");
00174   fprintf(stderr, "                                the database which contains the schema\n");
00175 
00176   fprintf(stderr, "\nThe following options can be added to the --gencode Orbix, Orbacus or IDL option:\n");
00177   fprintf(stderr, "--output-dir DIRNAME          Output directory for generated files\n");
00178   fprintf(stderr, "--imdl IMDLFILE|-             IMDL file (- is the standard input)\n");
00179   fprintf(stderr, "--idl-target IDLFILE          The target IDL file\n");
00180   fprintf(stderr, "--no-generic-idl              The EyeDB generic IDL file 'eyedb.idl' will not\n");
00181   fprintf(stderr, "                                be automatically included in the IDML file\n");
00182   fprintf(stderr, "--generic-idl IDLFILE         Give the location of the EyeDB generic IDL file\n");
00183   fprintf(stderr, "                                'eyedb.idl'\n");
00184   fprintf(stderr, "--factory yes                 The factory interface will be generated\n");
00185   fprintf(stderr, "                                (the default when -idl-target is not used)\n");
00186   fprintf(stderr, "--factory no                  The factory interface will not be generated\n");
00187   fprintf(stderr, "                                (the default when -idl-target is used)\n");
00188   fprintf(stderr, "--sync yes|no                 The backend runtime objects will be synchronized\n");
00189   fprintf(stderr, "                                (yes the default), or not synchronized (no) with the database\n");
00190   fprintf(stderr, "--comments yes|no             Does (yes) or does not (no) generate mapping\n");
00191   fprintf(stderr, "                                comments in the IDL\n");
00192 #endif
00193 
00194   fprintf(stderr, "\nThe following option must be added to the --update|-u option:\n");
00195   fprintf(stderr, "-d DBNAME|--database=DBNAME   Database for which operation is performed\n");
00196 
00197   fprintf(stderr, "\nThe following options can be added to the --update|-u option:\n");
00198   fprintf(stderr, "ODLFILE|-                     Input ODL file or '-' (standard input)\n");
00199   fprintf(stderr, "--schema-name=SCHNAME         Schema name (default is package)\n");
00200   fprintf(stderr, "--db-class-prefix=PREFIX      Prefix to be put at the begining of each database class\n");
00201   fprintf(stderr, "--rmv-undef-attrcomp=yes|no   Removes (yes) or not (no) the undefined attribute components (constraint, index and implementation). Default is no\n");
00202   fprintf(stderr, "--update-index=yes|no         Updates (yes) or not (no) the index with a different implementation in the DB. Default is no\n");
00203   fprintf(stderr, "--rmcls=CLASS...              Removes the given class list\n");
00204   fprintf(stderr, "--rmsch                       Removes the entire schema\n");
00205 
00206   fprintf(stderr, "\nThe following options must be added to the --diff option:\n");
00207   fprintf(stderr, "-d DBNAME|--database=DBNAME Database for which the schema difference is performed\n");
00208   fprintf(stderr, "ODLFILE                       The input ODL file for which the schema difference is performed\n");
00209   fprintf(stderr, "\nThe following options can be added to the --diff option:\n");
00210   fprintf(stderr, "--system-class                Performs difference on system classes also\n");
00211   fprintf(stderr, "\nThe following option must be added to the --checkfile option:\n");
00212   fprintf(stderr, "ODLFILE|-                     Input ODL file or '-' (standard input)\n");
00213 
00214 #ifdef SUPPORT_CORBA
00215   fprintf(stderr, "\nThe following options can be added when an ODLFILE, an IDLFILE\n");
00216   fprintf(stderr, "or an IMDLFILE is set:\n");
00217 #else
00218   fprintf(stderr, "\nThe following options can be added when an ODLFILE is set:\n");
00219 #endif
00220   fprintf(stderr, "--cpp=CPP                     Uses CPP preprocessor instead of the default one\n");
00221   fprintf(stderr, "--cpp-flags=CPP_FLAGS         Adds CPP_FLAGS to the preprocessing command\n");
00222   fprintf(stderr, "--no-cpp                      Does not use any preprocessor\n");
00223   //fprintf(stderr, "\nThe following options can be added when the -d DBNAME|--database=DBNAME is used:,\n");
00224 
00225   print_use_help(cerr);
00226 
00227   fflush(stderr);
00228 }
00229 
00230 static char *package = NULL;
00231 static char *module = NULL;
00232 static char *prefix = "";
00233 static char *db_prefix = "";
00234 static char *c_namespace = NULL;
00235 static char *schname = 0;
00236 static Bool _export = False;
00237 static const char *prog;
00238 static char *odlfile = 0;
00239 
00240 static Bool update = False;
00241 static Bool diff = False;
00242 static Bool checkfile = False;
00243 static unsigned int open_flags;
00244 static const char *dbname = NULL;
00245 static Bool orbix_gen = False;
00246 static Bool orbacus_gen = False;
00247 #ifdef SUPPORT_CORBA
00248 static Bool idl_gen = False;
00249 #endif
00250 static Bool odl_gen = False;
00251 static Bool cplus_gen = False;
00252 static Bool java_gen = False;
00253 static GenCodeHints *hints;
00254 static char *imdlfile = NULL;
00255 #ifdef SUPPORT_CORBA
00256 static char *idltarget = NULL;
00257 #endif
00258 static Schema *m;
00259 static Database *db = NULL;
00260 static char *ofile = NULL;
00261 #ifdef SUPPORT_CORBA
00262 static char *generic_idl = NULL;
00263 static Bool no_generic_idl = False;
00264 static Bool no_factory = False;
00265 static Bool no_factory_set = False;
00266 #endif
00267 static Bool comments = True;
00268 static const char *odl_tmpfile;
00269 static const char *cpp_cmd = "cc -E";
00270 static Bool no_rootclass = False;
00271 static std::string cpp_flags;
00272 #define MISSING "missing argument after "
00273 #define OPTION  " option"
00274 
00275 #define GETOPT(X, OPT) \
00276 do { \
00277   if (i+1 >= argc) \
00278     return usage(MISSING #OPT OPTION); \
00279   X = argv[i+1]; \
00280   i += 2; \
00281 } while(0)
00282 
00283 static int
00284 getOpts(int argc, char *argv[], Bool &dirname_set)
00285 {
00286   prog = argv[0];
00287   dirname_set = False;
00288 
00289   for (int n = 1; n < argc; n++) {
00290     char *s = argv[n];
00291 
00292     string value;
00293     if (GetOpt::parseLongOpt(s, "output-dir", &value)) {
00294       hints->setDirName(value.c_str());
00295       dirname_set = True;
00296     }
00297     else if (GetOpt::parseLongOpt(s, "output-file-prefix", &value)) {
00298       hints->setFilePrefix(value.c_str());
00299     }
00300     else if (GetOpt::parseLongOpt(s, "package", &value)) {
00301       package = strdup(value.c_str());
00302     }
00303     else if (GetOpt::parseLongOpt(s, "gendate", &value)) {
00304       if (!strcasecmp(value.c_str(), "yes"))
00305         hints->gen_date = True;
00306       else if (!strcasecmp(value.c_str(), "no"))
00307         hints->gen_date = False;
00308       else
00309         return usage("needs `yes' or `no' after --gendate option");
00310     }
00311     else if (GetOpt::parseLongOpt(s, "schema-name", &value)) {
00312       schname = strdup(value.c_str());
00313     }
00314     else if (!strcmp(s, "--export")) {
00315       _export = True;
00316     }
00317     else if (GetOpt::parseLongOpt(s, "comments", &value)) {
00318       if (!strcasecmp(value.c_str(), "yes"))
00319         comments = True;
00320       else if (!strcasecmp(value.c_str(), "no"))
00321         comments = False;
00322       else
00323         return usage("needs `yes' or `no' after --comments option");
00324     }
00325     else if (!strcmp(s, "--admin")) {
00326       open_flags |= _DBAdmin;
00327     }
00328     else if (!strcmp(s, "--local")) {
00329       open_flags |= _DBOpenLocal;
00330     }
00331     else if (!strcmp(s, "--dynamic-attr")) {
00332       odl_dynamic_attr = True;
00333     }
00334     else if (GetOpt::parseLongOpt(s, "attr-style", &value)) {
00335       if (!strcmp(value.c_str(), "implicit")) {
00336         hints->attr_style = GenCodeHints::ImplicitAttrStyle;
00337         // backward compatibility
00338         hints->setStyle("implicit");
00339       }
00340       else if (!strcmp(value.c_str(), "explicit")) {
00341         hints->attr_style = GenCodeHints::ExplicitAttrStyle;
00342         // backward compatibility
00343         hints->setStyle("explicit");
00344       }
00345       else {
00346         Status s = hints->setStyle(value.c_str());
00347         if (s) {
00348           s->print();
00349           return 1;
00350         }
00351       }
00352     }
00353     else if (GetOpt::parseLongOpt(s, "class-prefix", &value)) {
00354       prefix = strdup(value.c_str());
00355     }
00356     else if (GetOpt::parseLongOpt(s, "namespace", &value)) {
00357       c_namespace = strdup(value.c_str());
00358     }
00359     else if (GetOpt::parseLongOpt(s, "use-smart-pointers", &value)) {
00360       const char *s = value.c_str();
00361       if (!strcasecmp(s, "yes"))
00362         odl_smartptr = True;
00363       else if (!strcasecmp(s, "no"))
00364         odl_smartptr = False;
00365       else
00366         return usage("must set yes or no behind --use-smart-pointers");
00367     }
00368     else if (GetOpt::parseLongOpt(s, "db-class-prefix", &value)) {
00369       db_prefix = strdup(value.c_str());
00370     }
00371     else if (GetOpt::parseLongOpt(s, "rmv-undef-attrcomp", &value)) {
00372       cerr << "warning: --rmv-undef-attrcomp option is not yet implemented\n";
00373       return 1;
00374     }
00375     else if (GetOpt::parseLongOpt(s, "update-index", &value)) {
00376       if (!strcasecmp(value.c_str(), "yes"))
00377         odl_update_index = True;
00378       else if (!strcasecmp(value.c_str(), "no"))
00379         odl_update_index = False;
00380       else
00381         return usage("yes or no is expected after --update-index option");
00382     }
00383     else if (GetOpt::parseLongOpt(s, "rmcls", &value)) {
00384       // must split classname with ','
00385       char *p = strdup(value.c_str());
00386       for (;;) {
00387         char *q = strchr(p, ',');
00388         if (q)
00389           *q = 0;
00390 
00391         odl_cls_rm.insertObject(p);
00392 
00393         if (!q)
00394           break;
00395         p = q+1;
00396       }
00397     }
00398     else if (!strcmp(s, "--rmsch")) {
00399       odl_sch_rm = True;
00400     }
00401     else if (!strcmp(s, "--gen-class-stubs")) {
00402       hints->gen_class_stubs = True;
00403     }
00404     else if (GetOpt::parseLongOpt(s, "class-enums", &value)) {
00405       if (!strcasecmp(value.c_str(), "yes"))
00406         hints->class_enums = True;
00407       else if (!strcasecmp(value.c_str(), "no"))
00408         hints->class_enums = False;
00409       else
00410         return usage("yes or no is expected after --class-enums option");
00411 
00412     }
00413     else if (GetOpt::parseLongOpt(s, "c-suffix", &value)) {
00414       hints->setCSuffix(value.c_str());
00415     }
00416     else if (GetOpt::parseLongOpt(s, "h-suffix", &value)) {
00417       hints->setHSuffix(value.c_str());
00418     }
00419     else if (GetOpt::parseLongOpt(s, "down-casting", &value)) {
00420       if (!strcasecmp(value.c_str(), "yes"))
00421         hints->gen_down_casting = True;
00422       else if (!strcasecmp(value.c_str(), "no"))
00423         hints->gen_down_casting = False;
00424       else
00425         return usage("yes or no is expected after --down-casting option");
00426     }
00427     else if (GetOpt::parseLongOpt(s, "attr-cache", &value)) {
00428       if (!strcasecmp(value.c_str(), "yes"))
00429         hints->attr_cache = True;
00430       else if (!strcasecmp(value.c_str(), "no"))
00431         hints->attr_cache = False;
00432       else
00433         return usage("yes or no is expected after --attr-cache option");
00434     }
00435     else if (GetOpt::parseLongOpt(s, "gencode-error-policy", &value)) {
00436       if (!strcasecmp(value.c_str(), "status"))
00437         hints->error_policy = GenCodeHints::StatusErrorPolicy;
00438       else if (!strcasecmp(value.c_str(), "exception"))
00439         hints->error_policy = GenCodeHints::ExceptionErrorPolicy;
00440       else
00441         return usage("status or exception is expected after --error-policy option");
00442     }
00443     else if (GetOpt::parseLongOpt(s, "gencode", &value)) {
00444       if (!strcasecmp(value.c_str(), "c++")) {
00445         cplus_gen = True;
00446         odl_lang = ProgLang_C;
00447       }
00448       else if (!strcasecmp(value.c_str(), "java")) {
00449         java_gen = True;
00450         odl_lang = ProgLang_Java;
00451       }
00452       else if (!strcasecmp(value.c_str(), "odl"))
00453         odl_gen = True;
00454       else
00455         return usage("C++, Java or ODL is expected after --gencode");
00456     }
00457     else if (GetOpt::parseLongOpt(s, "database", &value)) {
00458       if (!dbname)
00459         dbname = strdup(value.c_str());
00460       else
00461         return usage("cannot specified two databases");
00462     }
00463     else if (!strcmp(s, "-d")) {
00464       if (n+1 >= argc)
00465         return usage("missing argument after -d");
00466       if (!dbname) {
00467         dbname = strdup(argv[n+1]);
00468         n++;
00469       }
00470       else
00471         return usage("cannot specified two databases");
00472     }
00473     else if (GetOpt::parseLongOpt(s, "cpp", &value)) {
00474       cpp_cmd = value.c_str();
00475     }
00476     else if (GetOpt::parseLongOpt(s, "nocpp", &value)) {
00477       cpp_cmd = 0;
00478     }
00479     else if (GetOpt::parseLongOpt(s, "no-rootclass")) {
00480       no_rootclass = True;
00481     }
00482     else if (GetOpt::parseLongOpt(s, "rootclass", &value)) {
00483       odl_rootclass = strdup(value.c_str());
00484     }
00485     else if (GetOpt::parseLongOpt(s, "cpp-flags", &value)) {
00486       cpp_flags = strdup(value.c_str());
00487     }
00488     else if (!strcmp(s, "-o")) {
00489       if (n+1 >= argc)
00490         return usage("missing argument after -o");
00491       ofile = strdup(argv[n+1]);
00492       n++;
00493     }
00494     else if (!strcmp(s, "--update") || !strcmp(s, "-u")) {
00495       update = True;
00496     }
00497     else if (!strcmp(s, "--diff")) {
00498       diff = True;
00499       no_rootclass = True;
00500     }
00501     else if (!strcmp(s, "--checkfile")) {
00502       checkfile = True;
00503     }
00504     else if (!strcmp(s, "--help") || !strcmp(s, "-h")) {
00505       usage();
00506       fprintf(stderr, "\n");
00507       help();
00508       exit(0);
00509     }
00510     else if (!strcmp(s, "--system-class")) { // internal use only!
00511       odl_system_class = True;
00512     }
00513     else if (!strcmp(s, "-") || (!odlfile && s[0] != '-')) {
00514       if (!odlfile)
00515         odlfile = argv[n];
00516     }
00517     else
00518       return usage();
00519   }
00520 
00521 
00522 #ifdef SUPPORT_CORBA
00523   if (orbix_gen || orbacus_gen || idl_gen)
00524     no_rootclass = True;
00525 #endif
00526 
00527   if (no_rootclass)
00528     odl_rootclass = 0;
00529   else if (!odl_rootclass)
00530     odl_rootclass = "Root";
00531 
00532 #ifdef SUPPORT_CORBA
00533   if (idltarget && !no_factory_set)
00534     no_factory = True;
00535 
00536   if (orbix_gen)
00537     cpp_flags += " -DEYEDBORBIX";
00538   else if (orbacus_gen)
00539     cpp_flags += " -DEYEDBORBACUS";
00540 #endif
00541 
00542   return 0;
00543 }
00544 
00545 static const char *
00546 get_gen_opt()
00547 {
00548   if (odl_lang == ProgLang_Java)
00549     return "Java";
00550   if (odl_lang == ProgLang_C)
00551     return "C++";
00552 #ifdef SUPPORT_CORBA
00553   if (idl_gen)
00554     return "IDL";
00555   if (orbix_gen)
00556     return "Orbix";
00557   if (orbacus_gen)
00558     return "Orbacus";
00559 #endif
00560   return "";
00561 }
00562 
00563 static int
00564 check_package()
00565 {
00566   const char *p = package;
00567   char c = *p;
00568 
00569   if (!c)
00570     return 0;
00571 
00572   if (!((c >= 'a' && c <= 'z') ||
00573         (c >= 'A' && c <= 'Z') ||
00574         (c == '_') || (java_gen && c == '.')))
00575     return 1;
00576 
00577   while (c=*++p)
00578     if (!((c >= 'a' && c <= 'z') ||
00579           (c >= 'A' && c <= 'Z') ||
00580           (c >= '0' && c <= '9') ||
00581           (c == '_') || (java_gen && c == '.')))
00582       return 1;
00583 
00584   return 0;
00585 }
00586 
00587 static void
00588 make_package(char *&package, const char *odlfile)
00589 {
00590   if (package || !odlfile)
00591     return;
00592 
00593   char *s = strdup(odlfile);
00594   char *x = strrchr(s, '.');
00595   if (x) *x = 0;
00596   x = strrchr(s, '/');
00597 
00598   if (x)
00599     package = strdup(x+1);
00600   else
00601     package = strdup(s);
00602   free(s);
00603 }
00604 
00605 static int
00606 checkOpts(Bool dirname_set)
00607 {
00608   int nopts = 0;
00609 
00610   if (cplus_gen) nopts++;
00611   if (java_gen)  nopts++;
00612 #ifdef SUPPORT_CORBA
00613   if (orbix_gen) nopts++;
00614   if (orbacus_gen) nopts++;
00615   if (idl_gen)   nopts++;
00616 #endif
00617   if (odl_gen)   nopts++;
00618   if (update)    nopts++;
00619   if (diff)      nopts++;
00620   if (checkfile) nopts++;
00621 
00622   // one and only one major option
00623   if (nopts == 0 || nopts > 1)
00624     {
00625       usage("one and only one major option must be specified:\n"
00626             "\t    --gencode=C++\n"
00627             "\t    --gencode=Java\n"
00628 #ifdef SUPPORT_CORBA
00629             "\t    --gencode=Orbix\n"
00630             "\t    --gencode=Orbacus\n"
00631             "\t    --gencode=IDL\n"
00632 #endif
00633             "\t    --gencode=ODL\n"
00634             "\t    --update|-u\n"
00635             "\t    --diff\n"
00636             "\t    --checkfile\n"
00637             "\t    --help");
00638       fprintf(stderr, "\n");
00639       return usage();
00640     }
00641 
00642   const char *opackage = package;
00643   make_package(package, odlfile);
00644 
00645   if (update && !dbname)
00646     return usage("Must specified -d DBNAME|--database=DBNAME option when -u is used");
00647 
00648 #ifdef SUPPORT_CORBA
00649   if ((orbix_gen || orbacus_gen || idl_gen) && !package)
00650     return usage("--package is a mandatory option when -gencode Orbix|Orbacus|IDL is used");
00651 
00652   if ((orbix_gen || orbacus_gen || idl_gen) && !module)
00653     return usage("--idl-module is a mandatory option when -gencode Orbix|Orbacus|IDL is used");
00654 #endif
00655 
00656   if (odl_lang && !package)
00657     return usage("--package is a mandatory option when -gencode Java|C++ or -u is used");
00658 
00659   if ((odl_lang || odl_gen) && dbname && odlfile)
00660     return usage("cannot specify both a database and an ODL file");
00661 
00662   if (!package)
00663     package = "";
00664 
00665   if (check_package()) {
00666     std::string s = std::string("invalid package name '") + package + "'.\n"
00667       "A package name must be under the form [a-zA_Z_][a-zA-Z0-9_]*";
00668     if (!opackage) s += "\nUse the -package option";
00669     return usage(s.c_str());
00670   }
00671 
00672 #ifdef SUPPORT_CORBA
00673   if (ofile && !odl_gen && !idl_gen)
00674     return usage("-o option may be used only with -gencode ODL option");
00675 #endif
00676 
00677   if (java_gen && !dirname_set)
00678     hints->setDirName(package);
00679 
00680 #ifdef SUPPORT_CORBA
00681   if (orbix_gen || orbacus_gen || idl_gen || odl_lang)
00682     {
00683       if (!odlfile && !dbname)
00684         return usage("using --gencode=%s : must specify an ODLFILE or a database (-d DBNAME|--database=DBNAME)", get_gen_opt());
00685 
00686       /*
00687         if (odlfile && dbname)
00688         return usage("using -gencode %s : must specify an ODLFILE or a database (-d DBNAME)", get_gen_opt());
00689       */
00690     }
00691   //else
00692 #endif
00693 
00694   if (odl_cls_rm.getCount() > 0 && odl_sch_rm)
00695     return usage("cannot use both --rmcls and --rmsch options");
00696   else if (update && (odl_sch_rm || odl_cls_rm.getCount() > 0)) {
00697     // nop
00698   }
00699   else if (!cplus_gen && !java_gen && !odl_gen && !odlfile)
00700     return usage("an ODLFILE must be specified; use '-' for standard input");
00701 
00702   if (diff) {
00703     if (!odlfile || !dbname)
00704       return usage();
00705   }
00706 
00707   if (update && *prefix)
00708     return usage();
00709     
00710   return 0;
00711 }
00712 
00713 static int
00714 checkDb()
00715 {
00716   if (!schname) {
00717     schname = package;
00718     if (!schname || !*schname)
00719       schname = "UNTITLED";
00720   }
00721 
00722   if (dbname) {
00723     Connection *conn = new Connection();
00724     Status s;
00725 
00726     if (s = conn->open()) {
00727       fprintf(stderr, "eyedbodl: ");
00728       s->print(stderr);
00729       return 1;
00730     }
00731       
00732     db = new Database(dbname);
00733     
00734     if (s = db->open(conn, (Database::OpenFlag)
00735                      ((update ? Database::DBRWAdmin :
00736                        Database::DBSRead) | open_flags))) {
00737       fprintf(stderr, "eyedbodl: ");
00738       s->print(stderr);
00739       return 1;
00740     }
00741   }
00742 
00743   return 0;
00744 }
00745 
00746 int
00747 realize(int argc, char *argv[])
00748 {
00749   TransactionParams::setGlobalDefaultMagOrder(100000);
00750 
00751   eyedb::init(argc, argv);
00752 
00753   const char *x;
00754 
00755   x = eyedb::ClientConfig::getCValue("cpp_cmd");
00756   if (x) cpp_cmd = eyedb::ClientConfig::getCValue("cpp_cmd");
00757 
00758   x = eyedb::ClientConfig::getCValue("cpp_flags");
00759   if (x) cpp_flags = x;
00760 
00761   hints = new GenCodeHints();
00762 
00763   hints->setDirName(".");
00764 
00765   Bool dirname_set;
00766 
00767   if (getOpts(argc, argv, dirname_set))
00768     return 1;
00769 
00770   if (checkOpts(dirname_set))
00771     return 1;
00772 
00773   if (!hints->fileprefix)
00774     hints->setFilePrefix(package);
00775 
00776   if (checkDb()) // on doit faire seulement une partie de ca
00777     return 1;
00778 
00779   Status s = Success;
00780 
00781   Exception::setMode(Exception::ExceptionMode);
00782 
00783   try {
00784     if (update)
00785       s = db->updateSchema(odlfile, package, schname, db_prefix,
00786                            stdout, cpp_cmd, cpp_flags.c_str());
00787 
00788     else if (diff)
00789       s = Schema::displaySchemaDiff(db, odlfile, package, db_prefix, stdout,
00790                                     cpp_cmd, cpp_flags.c_str());
00791 
00792 #ifdef SUPPORT_CORBA
00793     else if (idl_gen)
00794       s = Schema::genIDL(db, odlfile, package, module, schname, prefix,
00795                          db_prefix, idltarget, imdlfile, no_generic_idl,
00796                          generic_idl, no_factory, imdl_synchro,
00797                          hints, comments, cpp_cmd, cpp_flags.c_str(), ofile);
00798 #endif
00799     else if (odl_gen)
00800       s = Schema::genODL(db, odlfile, package, schname,
00801                          prefix, db_prefix,  ofile, cpp_cmd,
00802                          cpp_flags.c_str());
00803 
00804 #ifdef SUPPORT_CORBA
00805     else if (orbix_gen || orbacus_gen)
00806       s = Schema::genORB((orbix_gen ? "orbix" : "orbacus"),
00807                          db, odlfile, package, module, schname, prefix,
00808                          db_prefix, idltarget, imdlfile, no_generic_idl,
00809                          generic_idl, no_factory, imdl_synchro,
00810                          hints, comments, cpp_cmd, cpp_flags.c_str());
00811 
00812 #endif
00813     else if (odl_lang == ProgLang_C)
00814       s = Schema::genC_API(db, odlfile, package, schname,
00815                            c_namespace, prefix,
00816                            db_prefix, _export, hints, cpp_cmd,
00817                            cpp_flags.c_str());
00818 
00819     else if (odl_lang == ProgLang_Java)
00820       s = Schema::genJava_API(db, odlfile, package, schname, prefix,
00821                               db_prefix, _export, hints, cpp_cmd,
00822                               cpp_flags.c_str());
00823 
00824     else if (checkfile)
00825       s = Schema::checkODL(odlfile, package, cpp_cmd, cpp_flags.c_str());
00826 
00827   } catch(Exception &e) {
00828     cerr << "\neyedbodl: ";
00829     cerr << e << endl;
00830     return 1;
00831   }
00832 
00833   if (s) {
00834     fprintf(stderr, "\neyedbodl: ");
00835     s->print(stderr);
00836     return 1;
00837   }
00838 
00839   return 0;
00840 }
00841 
00842 int
00843 main(int argc, char *argv[])
00844 {
00845   int r = realize(argc, argv);
00846   if (odl_tmpfile) unlink(odl_tmpfile);
00847   return r;
00848 }
00849 

Generated on Mon Dec 22 18:15:54 2008 for eyedb by  doxygen 1.5.3