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 "odl.h"
00026
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
00047
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
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
00338 hints->setStyle("implicit");
00339 }
00340 else if (!strcmp(value.c_str(), "explicit")) {
00341 hints->attr_style = GenCodeHints::ExplicitAttrStyle;
00342
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
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")) {
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
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
00688
00689
00690 }
00691
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
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())
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