odlgen_C.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 "CollectionBE.h"
00027 #include "Attribute_p.h"
00028 #include "odl.h"
00029 #include <string.h>
00030 
00031 //#define DEF_PREFIX "idb"
00032 #define DEF_PREFIX ""
00033 //#define DEF_PREFIX2 "idb"
00034 #define DEF_PREFIX2 ""
00035 
00036 #define NEW_ARGARR // 8/02/03
00037 #define NO_COMMENTS
00038 #define NEW_COMP_POLICY
00039 #define IDBBOOL_STR(X) ((X) ? "eyedb::True" : "eyedb::False")
00040 
00041 #define ATTR_CACHE_DIRECT
00042 
00043 //#define NO_DIRECT_SET // added the 22/09/98
00044 #define SET_COUNT_DIRECT // added the 27/10/98
00045 
00046 #define ODL_STD_STRING
00047 
00048 namespace eyedb {
00049 
00050   extern Bool odl_smartptr;
00051 
00052   // get pointer return form
00053   static const char *getPtrRet()
00054   {
00055     if (odl_smartptr)
00056       return "Ptr ";
00057     return "*";
00058   }
00059 
00060   // get pointer set form
00061   static const char *getPtrSet()
00062   {
00063     if (odl_smartptr)
00064       return "Ptr &";
00065     return "*";
00066   }
00067 
00068   static void
00069   gbx_suspend(GenContext *ctx)
00070   {
00071     fprintf(ctx->getFile(), "%seyedb::gbxAutoGarbSuspender _gbxsusp_;\n",
00072             ctx->get());
00073   }
00074 
00075   static const char classSuffix[] = "_Class";
00076   static const char __agritems[] = "getClass()->getAttributes()";
00077   static const char __agrdyn[] = "_attr";
00078   static const char downCastPrefix[] = "as";
00079   static Bool class_enums;
00080   static Bool attr_cache;
00081   static const char enum_type[] = "Type";
00082 
00083 #define STRBOOL(X) ((X) ? "eyedb::True" : "eyedb::False")
00084 
00085 #define IS_STRING() (typmod.ndims == 1 && \
00086                      !strcmp(cls->getName(), char_class_name) && \
00087                      !isIndirect())
00088 
00089 #define IS_RAW() (typmod.ndims == 1 && \
00090                   !strcmp(cls->getName(), byte_class_name) && \
00091                   !isIndirect())
00092 
00093 #define SCLASS()  (is_string ? "char" : "unsigned char")
00094 #define SARGIN()  (is_string ? "" : ", unsigned int len")
00095 #define SARGOUT() ((is_raw && isVarDim()) ? "unsigned int *len, " : "")
00096 
00097   static char *
00098   purge(const char *x)
00099   {
00100     char *s = (char *)malloc(2 * strlen(x) + 1);
00101     char *p = s;
00102     char c;
00103 
00104     while (c = *x++)
00105       {
00106         if (c == '"')
00107           {
00108             *p++ = '\\';
00109             *p++ = '"';
00110           }
00111         else if (c == '\\')
00112           {
00113             *p++ = '\\';
00114             *p++ = '\\';
00115           }
00116         else if (c == '\n')
00117           *p++ = ' ';
00118         else
00119           *p++ = c;
00120       }
00121 
00122     *p = 0;
00123     return s;
00124   }
00125 
00126   static const char *
00127   atc_set(const char *name)
00128   {
00129     static char _set[128];
00130     sprintf(_set, "__%s_isset__", name);
00131     return _set;
00132   }
00133 
00134   static const char *
00135   atc_cnt(const char *name)
00136   {
00137     static char _cnt[128];
00138     sprintf(_cnt, "__%s_cnt__", name);
00139     return _cnt;
00140   }
00141 
00142   static const char *
00143   atc_name(const char *name)
00144   {
00145     static char _name[128];
00146     sprintf(_name, "__%s__", name);
00147     return _name;
00148   }
00149 
00150   static const char *
00151   atc_this(const char *classname)
00152   {
00153     static char _this[128];
00154     sprintf(_this, "((%s *)this)", classname);
00155     //  return "__this__";
00156     return _this;
00157   }
00158 
00159 #define RETURN_ERROR(FD, CTX, MCLASS, INDENT) \
00160 do { \
00161   if ((MCLASS)->asEnumClass()) \
00162     fprintf((FD), "%s%sif (s) {if (rs) *rs = s; return (%s)0;}\n", (CTX)->get(), INDENT, \
00163             className(MCLASS, False)); \
00164   else \
00165     fprintf((FD), "%s%sif (s) {if (rs) *rs = s; return 0;}\n", (CTX)->get(), INDENT); \
00166 } while(0)
00167 
00168 #define ATTRNAME(NAME, OPTYPE, HINTS) \
00169   (HINTS).style->getString(GenCodeHints::OPTYPE, NAME)
00170 
00171 #define ATTRNAME_1(NAME, OPTYPE, HINTS) \
00172   (HINTS).style->getString(OPTYPE, NAME)
00173 
00174 #define ATTRGET(CL) ((CL)->asCollectionClass() ? \
00175                      GenCodeHints::tGetColl : GenCodeHints::tGet)
00176 
00177 #define ATTRSET(CL) ((CL)->asCollectionClass() ? \
00178                      GenCodeHints::tSetColl : GenCodeHints::tSet)
00179 
00180   static const GenCodeHints *phints;
00181 
00182   static const char *
00183   make_int(int i)
00184   {
00185     static char x[16];
00186     sprintf(x, "%d", i);
00187     return x;
00188   }
00189 
00190   static int
00191   pre(char *name, const char *pre)
00192   {
00193     int len = strlen(pre);
00194     if (!strncmp(name, pre, len))
00195       {
00196         name[len] += 'A' - 'a';
00197         return 1;
00198       }
00199     return 0;
00200   }
00201 
00202   static const char *className(const Class *cls,
00203                                Bool makeC = True,
00204                                Bool makeAlias = False)
00205   {
00206     const char *name = (makeAlias ? cls->getAliasName() : cls->getName());
00207 
00208     if (!strncmp(name, "set<", 4))
00209       return "eyedb::CollSet";
00210   
00211     if (!strncmp(name, "bag<", 4))
00212       return "eyedb::CollBag";
00213   
00214     if (!strncmp(name, "array<", 6))
00215       return "eyedb::CollArray";
00216   
00217     if (!strncmp(name, "list<", 5))
00218       return "eyedb::CollList";
00219 
00220     for (int i = 0; i < idbLAST_Type; i++)
00221       if (!strcmp(name, class_info[i].name))
00222         return Class::classNameToCName(name);
00223 
00224     if (makeC) {
00225       if (!strcmp(name, char_class_name))
00226         return "eyedb::Char";
00227 
00228       if (!strcmp(name, int32_class_name))
00229         return "eyedb::Int32";
00230     
00231       if (!strcmp(name, int64_class_name))
00232         return "eyedb::Int64";
00233       
00234       if (!strcmp(name, int16_class_name))
00235         return "eyedb::Int16";
00236       
00237       if (!strcmp(name, "float"))
00238         return "eyedb::Float";
00239 
00240       if (!strcmp(name, "oid"))
00241         return "eyedb::OidP";
00242 
00243       if (!strcmp(name, "byte"))
00244         return "eyedb::Byte";
00245     }
00246     else {
00247       if (!strcmp(name, int32_class_name))
00248         return "eyedblib::int32";
00249     
00250       if (!strcmp(name, int64_class_name))
00251         return "eyedblib::int64";
00252     
00253       if (!strcmp(name, int16_class_name))
00254         return "eyedblib::int16";
00255     
00256       if (!strcmp(name, "oid"))
00257         return "eyedb::Oid";
00258     
00259       if (!strcmp(name, "byte"))
00260         return "unsigned char";
00261     
00262       if (!strcmp(name, "float"))
00263         return "double";
00264     }
00265 
00266     if (cls->asEnumClass() && class_enums) {
00267       if (Class::isBoolClass(cls)) {
00268         return cls->getCName(True);
00269       }
00270       static std::string enum_s;
00271       enum_s = std::string(name) + "::" + enum_type;
00272       return enum_s.c_str();
00273     }
00274 
00275     const char *sCName = Class::getSCName(name);
00276     return sCName ? sCName : name;
00277   }
00278 
00279   static void dimArgsGen(FILE *fd, int ndims, Bool named = True)
00280   {
00281     for (int i = 0; i < ndims; i++)
00282       {
00283         if (i)
00284           fprintf(fd, ", ");
00285         fprintf(fd, "unsigned int");
00286         if (named)
00287           fprintf(fd, " a%d", i);
00288       }
00289   }
00290 
00291   Status Attribute::generateClassDesc_C(GenContext *ctx)
00292   {
00293     FILE *fd = ctx->getFile();
00294     int ndims = typmod.ndims;
00295 
00296     fprintf(fd, "\n");
00297     if (ndims)
00298       {
00299         fprintf(fd, "%sdims = new int[%d];\n", ctx->get(), ndims);
00300         for (int i = 0; i < ndims; i++)
00301           fprintf(fd, "%sdims[%d] = %d;\n", ctx->get(), i, typmod.dims[i]);
00302       }
00303     else
00304       fprintf(fd, "%sdims = 0;\n", ctx->get());
00305 
00306     fprintf(fd, "%sattr[%d] = new eyedb::Attribute(", ctx->get(), num);
00307 
00308     if (cls->asCollectionClass())
00309       fprintf(fd, "(m ? m->getClass(\"%s\") : %s%s), \"%s\", ",
00310               cls->getAliasName(), cls->getCName(), classSuffix, name);
00311     else if (cls->asEnumClass())
00312       fprintf(fd, "(m ? m->getClass(\"%s\") : %s%s), \"%s\", ",
00313               cls->getAliasName(), cls->getCName(False), classSuffix, name);
00314     else
00315       fprintf(fd, "(m ? m->getClass(\"%s\") : %s%s), \"%s\", ",
00316               cls->getAliasName(), className(cls), classSuffix, name);
00317 
00318     fprintf(fd, "%s, %d, dims);\n", (isIndirect() ? "eyedb::True" : "eyedb::False"), ndims);
00319 
00320     /*
00321       fprintf(fd, "%sattr[%d]->setMagOrder(%d);\n", ctx->get(), num,
00322       getMagOrder());
00323     */
00324 
00325     if (ndims)
00326       fprintf(fd, "%sdelete[] dims;\n", ctx->get());
00327 
00328     if (inv_spec.clsname)
00329       fprintf(fd, "%sattr[%d]->setInverse(\"%s\", \"%s\");\n", ctx->get(), num,
00330               inv_spec.clsname, inv_spec.fname);
00331     else if (inv_spec.item)
00332       fprintf(fd, "%sattr[%d]->setInverse(\"%s\", \"%s\");\n", ctx->get(), num,
00333               inv_spec.item->getClassOwner()->getName(), inv_spec.item->getName());
00334 
00335     return Success;
00336   }
00337 
00338   enum OP {
00339     op_GET = 1,
00340     op_SET,
00341     op_OTHER
00342   };
00343 
00344   static void
00345   dynamic_attr_gen(FILE *fd, GenContext *ctx,
00346                    const Attribute *attr,
00347                    OP set,
00348                    Bool isoid = False,
00349                    Bool is_string = False,
00350                    const char *cast = 0)
00351   {
00352     fprintf(fd, "%sconst eyedb::Attribute *%s = getClass()->getAttribute(\"%s\");\n",
00353             ctx->get(), __agrdyn, attr->getName());
00354     fprintf(fd, "%sif (!%s) {\n", ctx->get(), __agrdyn);
00355     ctx->push();
00356     if (set == op_GET && !isoid)
00357       fprintf(fd, "%sif (isnull) *isnull = eyedb::True;\n", ctx->get());
00358     fprintf(fd, "%sif (dyn%s_error_policy) {\n", ctx->get(), (set ? "set" : "get"));
00359     fprintf(fd, "%s  eyedb::Status s = eyedb::Exception::make(eyedb::IDB_ATTRIBUTE_ERROR, "
00360             "\"object %%s: attribute %%s::%%s not found\", oid.toString(), getClass()->getName(), \"%s\");\n",
00361             ctx->get(), attr->getName());
00362     if (set == op_SET) {
00363       fprintf(fd, "%s  return s;\n", ctx->get());
00364       fprintf(fd, "%s}\n", ctx->get());
00365       fprintf(fd, "%sreturn eyedb::Success;\n", ctx->get());
00366     }
00367     else {
00368       fprintf(fd, "%s  if (rs) *rs = s;\n", ctx->get());
00369       fprintf(fd, "%s}\n", ctx->get());
00370       if (isoid)
00371         fprintf(fd, "%sreturn nulloid;\n", ctx->get());
00372       else if (is_string)
00373         fprintf(fd, "%sreturn \"\";\n", ctx->get());
00374       else if (cast)
00375         fprintf(fd, "%sreturn (%s)0;\n", ctx->get(), cast);
00376       else
00377         fprintf(fd, "%sreturn 0;\n", ctx->get());
00378     }
00379     ctx->pop();
00380     fprintf(fd, "%s}\n\n", ctx->get());
00381   }
00382 
00383   Status
00384   Attribute::generateCollRealizeClassMethod_C(Class *own,
00385                                               GenContext *ctx,
00386                                               const GenCodeHints &hints,
00387                                               Bool isoid,
00388                                               int xacctype)
00389   {
00390     FILE *fd = ctx->getFile();
00391     int ndims = typmod.ndims, i;
00392     const char *comma = (ndims ? ", " : "");
00393     Bool _isref;
00394     eyedblib::int16 _dim;
00395     Class *cl =
00396       ((CollectionClass *)cls)->getCollClass(&_isref, &_dim);
00397     GenCodeHints::OpType acctype = (GenCodeHints::OpType)xacctype;
00398     const char *etc = (acctype == GenCodeHints::tAddItemToColl ?
00399                        ", const eyedb::IndexImpl *idximpl" : "");
00400     const char *accmth = (acctype == GenCodeHints::tAddItemToColl ? "insert" : "suppress");
00401     const char *oclassname = _isref ?
00402       className(cl, True) : className(cl, False);
00403 
00404     if (isoid && cl->asBasicClass())
00405       return Success;
00406 
00407     const char *cast = (cl->asBasicClass() ? "(eyedb::Value)" : "");
00408 
00409     const char *classname;
00410     Bool ordered;
00411     CollectionClass *mcoll = (CollectionClass *)cls;
00412     if (mcoll->asCollSetClass())
00413       {
00414         classname = "eyedb::CollSet";
00415         ordered = False;
00416       }
00417     else if (mcoll->asCollBagClass())
00418       {
00419         classname = "eyedb::CollBag";
00420         ordered = False;
00421       }
00422     else if (mcoll->asCollArrayClass())
00423       {
00424         classname = "eyedb::CollArray";
00425         ordered = True;
00426       }
00427     else if (mcoll->asCollListClass())
00428       {
00429         classname = "eyedb::CollList";
00430         ordered = True;
00431       }
00432 
00433     const char *At = ((acctype == GenCodeHints::tAddItemToColl ||
00434                        acctype == GenCodeHints::tRmvItemFromColl)
00435                       && ordered ? "At" : "");
00436 
00437     const char *etc1 = "";
00438     const char *etc2 = "";
00439     Bool rmv_from_array = (acctype == GenCodeHints::tRmvItemFromColl)
00440       && ordered ? True : False;
00441 
00442     if (rmv_from_array && isoid)
00443       return Success;
00444 
00445     GenCodeHints::OpType nacctype;
00446     if (ordered)
00447       nacctype = (acctype == GenCodeHints::tRmvItemFromColl ?
00448                   GenCodeHints::tUnsetItemInColl :
00449                   GenCodeHints::tSetItemInColl);
00450     else
00451       nacctype = acctype;
00452 
00453     if (!*At)
00454       {
00455         if (acctype == GenCodeHints::tAddItemToColl)
00456           {
00457             etc1 = ", eyedb::Bool noDup";
00458             etc2 = ", noDup";
00459           }
00460         else if (acctype == GenCodeHints::tRmvItemFromColl)
00461           {
00462             etc1 = ", eyedb::Bool checkFirst";
00463             etc2 = ", checkFirst";
00464           }
00465       }
00466 
00467     if (_dim == 1)
00468       {
00469         fprintf(fd, "eyedb::Status %s::%s(%s%s", className(own),
00470                 ATTRNAME_1(name, nacctype, hints),
00471                 (*At ? "int where" : ""),
00472                 (*At && (!rmv_from_array || ndims >= 1) ? ", " : ""));
00473         dimArgsGen(fd, ndims);
00474         if (rmv_from_array)
00475           fprintf(fd, ")\n{\n");
00476         else if (isoid)
00477           fprintf(fd, "%sconst eyedb::Oid &_oid%s)\n{\n", comma, etc);
00478         else
00479           fprintf(fd, "%s%s%s_%s%s%s)\n{\n", comma, oclassname,
00480                   (_isref || !cl->asBasicClass() ? getPtrRet() : " "), name,
00481                   etc1, etc);
00482       }
00483     else if (!strcmp(cl->getName(), char_class_name) && _dim > 1)
00484       {
00485         fprintf(fd, "eyedb::Status %s::%s(%s", className(own),
00486                 ATTRNAME_1(name, nacctype, hints),
00487                 (*At ? "int where, " : ""));
00488         dimArgsGen(fd, ndims);
00489         fprintf(fd, "%sconst char *_%s%s%s)\n{\n", comma, name, etc1, etc);
00490       }
00491     else
00492       return Success;
00493 
00494     gbx_suspend(ctx);
00495 
00496     fprintf(fd, "%seyedb::Status status;\n", ctx->get());
00497 
00498     fprintf(fd, "%s%s *_coll;\n", ctx->get(), classname);
00499     fprintf(fd, "%seyedb::Bool _not_set = eyedb::False;\n", ctx->get());
00500     if (ndims > 1)
00501       {
00502         fprintf(fd, "%seyedb::Size from = a%d;\n", ctx->get(), ndims-1);
00503         for (int i = ndims - 2 ; i >= 0; i--)
00504           fprintf(fd, "%sfrom += a%d * %d;\n", ctx->get(), i, typmod.dims[i]);
00505       }
00506     else
00507       fprintf(fd, "%seyedb::Size from = 0;\n", ctx->get());
00508   
00509     if (odl_dynamic_attr) {
00510       dynamic_attr_gen(fd, ctx, this, op_SET, isoid);
00511       fprintf(fd, "\n%sstatus = %s->getValue(this, (eyedb::Data *)&_coll, 1, from);\n",
00512               ctx->get(), __agrdyn, name);
00513     }
00514     else
00515       fprintf(fd, "\n%sstatus = %s[%d]->getValue(this, (eyedb::Data *)&_coll, 1, from);\n",
00516               ctx->get(), __agritems, num, name);
00517     fprintf(fd, "%sif (status)\n%s  return status;\n\n", ctx->get(), ctx->get());
00518     fprintf(fd, "%sif (!_coll)\n", ctx->get());
00519     fprintf(fd, "%s  {\n", ctx->get());
00520     ctx->push();
00521     fprintf(fd, "%s _not_set = eyedb::True;\n", ctx->get());
00522     fprintf(fd, "%s eyedb::Oid _coll_oid;\n", ctx->get());
00523     if (odl_dynamic_attr)
00524       fprintf(fd, "%s status = %s->getOid(this, &_coll_oid, 1, from);\n",
00525               ctx->get(), __agrdyn, name);
00526     else
00527       fprintf(fd, "%s status = %s[%d]->getOid(this, &_coll_oid, 1, from);\n",
00528               ctx->get(), __agritems, num, name);
00529     fprintf(fd, "%s if (status)\n%s  return status;\n\n", ctx->get(), ctx->get());
00530     fprintf(fd, "%s if (_coll_oid.isValid())\n", ctx->get());
00531     fprintf(fd, "%s   {\n", ctx->get());
00532     ctx->push();
00533     fprintf(fd, "%s status = db->loadObject(&_coll_oid, (eyedb::Object **)&_coll);\n",
00534             ctx->get());
00535     fprintf(fd, "%s if (status)\n%s  return status;\n", ctx->get(), ctx->get());
00536     ctx->pop();
00537     fprintf(fd, "%s   }\n", ctx->get());
00538     fprintf(fd, "%s else\n", ctx->get());
00539     if (acctype == GenCodeHints::tAddItemToColl)
00540       {
00541         fprintf(fd, "%s   {\n", ctx->get());
00542         fprintf(fd, "%s     _coll = new %s(db, \"\", "
00543                 "db->getSchema()->getClass(\"%s\"), %s, idximpl);\n",
00544                 ctx->get(), classname,
00545                 cl->getAliasName(), (_isref ? "eyedb::True" : make_int(_dim)));
00546         //fprintf(fd, "%s     _coll->setMagOrder(mag_order);\n", ctx->get());
00547         fprintf(fd, "%s   }\n", ctx->get());
00548       }
00549     else
00550       fprintf(fd, "%s    return eyedb::Exception::make(eyedb::IDB_ERROR, \"no valid collection in attribute %s::%s\");\n\n", ctx->get(), class_owner->getName(), name);
00551 
00552     ctx->pop();
00553     fprintf(fd, "%s  }\n", ctx->get());
00554     if (rmv_from_array)
00555       fprintf(fd, "\n%sstatus = _coll->suppressAt(where);\n", ctx->get());
00556     else if (isoid)
00557       fprintf(fd, "\n%sstatus = _coll->%s%s(%s_oid);\n", ctx->get(),
00558               accmth, At, (*At ? "where, " : ""));
00559     else
00560       fprintf(fd, "\n%sstatus = _coll->%s%s(%s%s_%s%s);\n", ctx->get(),
00561               accmth, At, (*At ? "where, " : ""),  cast, name,
00562               etc2);
00563     fprintf(fd, "%sif (status || !_not_set)\n%s  return status;\n\n", ctx->get(), ctx->get());
00564     if (odl_dynamic_attr)
00565       fprintf(fd, "\n%sstatus = %s->setValue(this, (eyedb::Data)&_coll, 1, from);\n",
00566               ctx->get(), __agrdyn);
00567     else
00568       fprintf(fd, "\n%sstatus = %s[%d]->setValue(this, (eyedb::Data)&_coll, 1, from);\n",
00569               ctx->get(), __agritems, num);
00570 
00571     fprintf(fd, "%s   _coll->release();\n", ctx->get());
00572     fprintf(fd, "\n%sreturn status;\n", ctx->get());
00573     fprintf(fd, "}\n\n");
00574     return Success;
00575   }
00576 
00577   Status
00578   Attribute::generateCollInsertClassMethod_C(Class *own,
00579                                              GenContext *ctx,
00580                                              const GenCodeHints &hints,
00581                                              Bool isoid)
00582   {
00583     return generateCollRealizeClassMethod_C(own, ctx, hints,
00584                                             isoid,
00585                                             GenCodeHints::tAddItemToColl);
00586   }
00587 
00588   Status
00589   Attribute::generateCollSuppressClassMethod_C(Class *own,
00590                                                GenContext *ctx,
00591                                                const GenCodeHints &hints,
00592                                                Bool isoid)
00593   {
00594     return generateCollRealizeClassMethod_C(own, ctx, hints,
00595                                             isoid, 
00596                                             GenCodeHints::tRmvItemFromColl);
00597   }
00598 
00599   Status
00600   Attribute::generateSetMethod_C(Class *own, GenContext *ctx,
00601                                  const GenCodeHints &hints)
00602   {
00603     if (cls->asCollectionClass())
00604       {
00605         (void)generateCollInsertClassMethod_C(own, ctx, hints, False);
00606         (void)generateCollInsertClassMethod_C(own, ctx, hints, True);
00607 
00608         (void)generateCollSuppressClassMethod_C(own, ctx, hints, False);
00609         (void)generateCollSuppressClassMethod_C(own, ctx, hints, True);
00610       }
00611     return Success;
00612   }
00613 
00614 #define NOT_BASIC() \
00615         (isIndirect() || (!cls->asBasicClass() && !cls->asEnumClass()))
00616 
00617   Status
00618   Attribute::generateSetMethod_C(Class *own, GenContext *ctx,
00619                                  Bool isoid,
00620                                  const GenCodeHints &hints)
00621   {
00622     FILE *fd = ctx->getFile();
00623     int ndims = typmod.ndims, i;
00624     int not_basic = NOT_BASIC();
00625     const char *ref = (not_basic ? getPtrRet() : " ");
00626     const char *ref_set = (not_basic ? getPtrSet() : " ");
00627     const char *comma = (ndims ? ", " : "");
00628     const char *classname = isIndirect() ?
00629       className(cls, True) : className(cls, False);
00630 
00631     if (isoid)
00632       fprintf(fd, "eyedb::Status %s::%s(", className(own),
00633               ATTRNAME(name, tSetOid, hints));
00634     else
00635       fprintf(fd, "eyedb::Status %s::%s(", className(own),
00636               ATTRNAME_1(name, ATTRSET(cls), hints));
00637 
00638     dimArgsGen(fd, ndims, True);
00639 
00640     if (isoid)
00641       fprintf(fd, "%sconst eyedb::Oid &_oid)\n{\n", comma);
00642     else if (cls->asEnumClass())
00643       fprintf(fd, "%s%s%s_%s, eyedb::Bool _check_value)\n{\n",
00644               comma, classname, ref, name);
00645     else
00646       fprintf(fd, "%s%s%s_%s)\n{\n", comma, classname, ref_set, name);
00647 
00648     GenCodeHints::OpType optype = (isoid ? GenCodeHints::tSetOid:
00649                                    GenCodeHints::tSet);
00650 
00651     if (attr_cache)
00652       genAttrCacheSetPrologue(ctx, optype);
00653 
00654     if (odl_dynamic_attr)
00655       dynamic_attr_gen(fd, ctx, this, op_SET, isoid);
00656 
00657     gbx_suspend(ctx);
00658 
00659     fprintf(fd, "%seyedb::Status status;\n", ctx->get());
00660 
00661     if (ndims) {
00662       fprintf(fd, "%seyedb::Size from = a%d;\n", ctx->get(), ndims-1);
00663       for (int i = ndims - 2 ; i >= 0; i--)
00664         fprintf(fd, "%sfrom += a%d * %d;\n", ctx->get(), i, typmod.dims[i]);
00665 
00666       if (isVarDim()) {
00667         fprintf(fd, "\n%seyedb::Size size;\n", ctx->get());
00668         if (odl_dynamic_attr)
00669           fprintf(fd, "%sstatus = %s->getSize(this, size);\n",
00670                   ctx->get(), __agrdyn);
00671         else
00672           fprintf(fd, "%sstatus = %s[%d]->getSize(this, size);\n",
00673                   ctx->get(), __agritems, num);
00674         fprintf(fd, "%sif (status)\n%s  return status;\n\n", ctx->get(),
00675                 ctx->get());
00676         fprintf(fd, "%sif (size <= from)\n", ctx->get());
00677         ctx->push();
00678         if (odl_dynamic_attr)
00679           fprintf(fd, "%sstatus = %s->setSize(this, from+1);\n",
00680                   ctx->get(), __agrdyn);
00681         else
00682           fprintf(fd, "%sstatus = %s[%d]->setSize(this, from+1);\n",
00683                   ctx->get(), __agritems, num);
00684         ctx->pop();
00685         fprintf(fd, "%sif (status)\n%s  return status;\n", ctx->get(),
00686                 ctx->get());
00687       }
00688 
00689       if (isoid) {
00690         if (odl_dynamic_attr)
00691           fprintf(fd, "\n%sstatus = %s->setOid(this, &_oid, 1, from, oid_check);\n",
00692                   ctx->get(), __agrdyn);
00693         else
00694           fprintf(fd, "\n%sstatus = %s[%d]->setOid(this, &_oid, 1, from, oid_check);\n",
00695                   ctx->get(), __agritems, num);
00696         if (attr_cache)
00697           genAttrCacheSetEpilogue(ctx, optype);
00698         fprintf(fd, "%sreturn status;\n", ctx->get());
00699       }
00700 
00701       else if (cls->asEnumClass()) {
00702         fprintf(fd, "%seyedblib::int32 __tmp = _%s;\n", ctx->get(), name);
00703         if (odl_dynamic_attr)
00704           fprintf(fd, "\n%sstatus = %s->setValue(this, (eyedb::Data)&__tmp, 1, from, _check_value);\n",
00705                   ctx->get(), __agrdyn, name);
00706         else
00707           fprintf(fd, "\n%sstatus = %s[%d]->setValue(this, (eyedb::Data)&__tmp, 1, from, _check_value);\n",
00708                   ctx->get(), __agritems, num, name);
00709         if (attr_cache)
00710           genAttrCacheSetEpilogue(ctx, optype);
00711         fprintf(fd, "%sreturn status;\n", ctx->get());
00712       }
00713       else if (not_basic) {
00714         if (odl_smartptr)
00715           fprintf(fd, "\n%seyedb::Object *_o%s = _%s.getObject();\n", ctx->get(),
00716                   name, name);
00717         else
00718           fprintf(fd, "\n%seyedb::Object *_o%s = _%s;\n", ctx->get(), name,
00719                   name);
00720 
00721         if (odl_dynamic_attr)
00722           fprintf(fd, "\n%sstatus = %s->setValue(this, (eyedb::Data)&_o%s, 1, from);\n",
00723                   ctx->get(), __agrdyn, name);
00724         else
00725           fprintf(fd, "\n%sstatus = %s[%d]->setValue(this, (eyedb::Data)&_o%s, 1, from);\n",
00726                   ctx->get(), __agritems, num, name);
00727         if (attr_cache)
00728           genAttrCacheSetEpilogue(ctx, optype);
00729         fprintf(fd, "%sreturn status;\n", ctx->get());
00730       }
00731       else {
00732         if (odl_dynamic_attr)
00733           fprintf(fd, "\n%sstatus = %s->setValue(this, (eyedb::Data)&_%s, 1, from);\n",
00734                   ctx->get(), __agrdyn, name);
00735         else
00736           fprintf(fd, "\n%sstatus = %s[%d]->setValue(this, (eyedb::Data)&_%s, 1, from);\n",
00737                   ctx->get(), __agritems, num, name);
00738         if (attr_cache)
00739           genAttrCacheSetEpilogue(ctx, optype);
00740         fprintf(fd, "%sreturn status;\n", ctx->get());
00741       }
00742     }
00743     else if (isoid) {
00744       if (odl_dynamic_attr)
00745         fprintf(fd, "\n%sstatus = %s->setOid(this, &_oid, 1, 0, oid_check);\n",
00746                 ctx->get(), __agrdyn);
00747       else
00748         fprintf(fd, "\n%sstatus = %s[%d]->setOid(this, &_oid, 1, 0, oid_check);\n",
00749                 ctx->get(), __agritems, num);
00750       if (attr_cache)
00751         genAttrCacheSetEpilogue(ctx, optype);
00752       fprintf(fd, "%sreturn status;\n", ctx->get());
00753     }
00754     else if (cls->asEnumClass()) {
00755       fprintf(fd, "%seyedblib::int32 __tmp = _%s;\n", ctx->get(), name);
00756       if (odl_dynamic_attr)
00757         fprintf(fd, "\n%sstatus = %s->setValue(this, (eyedb::Data)&__tmp, 1, 0, _check_value);\n",
00758                 ctx->get(), __agrdyn, name);
00759       else
00760         fprintf(fd, "\n%sstatus = %s[%d]->setValue(this, (eyedb::Data)&__tmp, 1, 0, _check_value);\n",
00761                 ctx->get(), __agritems, num, name);
00762       if (attr_cache)
00763         genAttrCacheSetEpilogue(ctx, optype);
00764       fprintf(fd, "%sreturn status;\n", ctx->get());
00765     }
00766     else if (not_basic) {
00767       if (odl_smartptr)
00768         fprintf(fd, "\n%seyedb::Object *_o%s = _%s.getObject();\n", ctx->get(),
00769               name, name);
00770       else
00771         fprintf(fd, "\n%seyedb::Object *_o%s = _%s;\n", ctx->get(), name, name);
00772 
00773       if (odl_dynamic_attr)
00774         fprintf(fd, "\n%sstatus = %s->setValue(this, (eyedb::Data)&_o%s, 1, 0);\n",
00775                 ctx->get(), __agrdyn, name);
00776       else
00777         fprintf(fd, "\n%sstatus = %s[%d]->setValue(this, (eyedb::Data)&_o%s, 1, 0);\n",
00778                 ctx->get(), __agritems, num, name);
00779       if (attr_cache)
00780         genAttrCacheSetEpilogue(ctx, optype);
00781       fprintf(fd, "%sreturn status;\n", ctx->get());
00782     }
00783     else {
00784       if (odl_dynamic_attr)
00785         fprintf(fd, "\n%sstatus = %s->setValue(this, (eyedb::Data)&_%s, 1, 0);\n",
00786                 ctx->get(), __agrdyn, name);
00787       else
00788         fprintf(fd, "\n%sstatus = %s[%d]->setValue(this, (eyedb::Data)&_%s, 1, 0);\n",
00789                 ctx->get(), __agritems, num, name);
00790       if (attr_cache)
00791         genAttrCacheSetEpilogue(ctx, optype);
00792       fprintf(fd, "%sreturn status;\n", ctx->get());
00793     }
00794 
00795     fprintf(fd, "}\n\n");
00796 
00797     return Success;
00798   }
00799 
00800 
00801 #define STATUS_ARG(HINTS, COMMA) \
00802 (((HINTS).error_policy == GenCodeHints::StatusErrorPolicy) ? \
00803  ((COMMA) ? ", eyedb::Status *rs" : "eyedb::Status *rs") : "")
00804 
00805 #define STATUS_PROTO(HINTS, COMMA) \
00806 (((HINTS).error_policy == GenCodeHints::StatusErrorPolicy) ? \
00807  ((COMMA) ? ", eyedb::Status * = 0" : "eyedb::Status * = 0") : "")
00808 
00809   Status
00810   Attribute::generateCollGetMethod_C(Class *own, GenContext *ctx,
00811                                      Bool isoid,
00812                                      const GenCodeHints &hints,
00813                                      const char *_const)
00814   {
00815     FILE *fd = ctx->getFile();
00816     int ndims = typmod.ndims, i;
00817     Bool _isref;
00818     eyedblib::int16 _dim;
00819     Class *cl = const_cast<Class *>(cls->asCollectionClass()->getCollClass(&_isref, &_dim));
00820     int not_basic = _isref || (!cl->asBasicClass() && !cl->asEnumClass());
00821     const char *ref = (not_basic ? getPtrRet() : " ");
00822     const char *starg    = STATUS_ARG(hints, False);
00823     const char *stargcom = STATUS_ARG(hints, True);
00824     const char *classname = isIndirect() ?
00825       className(cls, True) : className(cls, False);
00826     const char *oclassname = _isref ?
00827       className(cl, True) : className(cl, False);
00828     const char *comma = (ndims ? ", " : "");
00829 
00830     Bool ordered = (cls->asCollArrayClass() || cls->asCollListClass()) ? True : False;
00831     if (isoid) {
00832       if (!_isref)
00833         return Success;
00834 
00835       if (ordered) { // 24/09/05
00836         fprintf(fd, "eyedb::Oid %s::%s(unsigned int ind, ",
00837                 own->getName(),
00838                 ATTRNAME_1(name, (ordered ? GenCodeHints::tRetrieveOidItemAt : GenCodeHints::tGetOidItemAt), hints));
00839         dimArgsGen(fd, ndims, True);
00840         fprintf(fd, "%seyedb::Status *rs) const\n", comma);
00841         fprintf(fd, "{\n");
00842 
00843         fprintf(fd, "%seyedb::Oid tmp;;\n", ctx->get());
00844         /*
00845           fprintf(fd, "%seyedb::Status s, *ps;\n", ctx->get());
00846           fprintf(fd, "%sps = (rs ? rs : &s);\n\n", ctx->get());
00847         */
00848         fprintf(fd, "%seyedb::Status s;\n", ctx->get());
00849       
00850         fprintf(fd, "%sconst eyedb::Collection%s coll = %s(", ctx->get(),
00851                 getPtrRet(),
00852                 ATTRNAME(name, tGetColl, hints));
00853 
00854         for (i = 0; i < ndims; i++)
00855           fprintf(fd, "a%d, ", i);
00856 
00857         fprintf(fd, "(eyedb::Bool *)0, rs);\n\n", ctx->get());
00858         fprintf(fd, "%sif (!coll || (rs && *rs))\n", ctx->get());
00859         fprintf(fd, "%s  return tmp;\n\n", ctx->get());
00860       
00861         if (cls->asCollArrayClass() || cls->asCollListClass())
00862           fprintf(fd, "%ss = coll->asCollArray()->retrieveAt(ind, tmp);\n", ctx->get());
00863         else
00864           fprintf(fd, "%ss = coll->getOidAt(ind, tmp);\n", ctx->get());
00865         fprintf(fd, "%sif (s && rs) *rs = s;\n", ctx->get());
00866         fprintf(fd, "%sreturn tmp;\n", ctx->get());
00867         fprintf(fd, "}\n\n");
00868         return Success;
00869       }
00870     }
00871 
00872     if (!*_const && cl->asBasicClass())
00873       return Success;
00874 
00875     // 24/09/05
00876     if (!ordered)
00877       return Success;
00878       
00879     if (!strcmp(cl->getName(), char_class_name) && _dim > 1) {
00880       fprintf(fd, "const char *%s::%s(unsigned int ind, ",
00881               own->getName(),
00882               ATTRNAME_1(name, (ordered ? GenCodeHints::tRetrieveItemAt : GenCodeHints::tGetItemAt), hints));
00883     }
00884     else if (_dim == 1)
00885       fprintf(fd, "%s%s%s%s::%s(unsigned int ind, ",
00886               _const, oclassname, ref, own->getName(),
00887               ATTRNAME_1(name, (ordered ? GenCodeHints::tRetrieveItemAt : GenCodeHints::tGetItemAt), hints));
00888     else {
00889       //fprintf(stderr, "collection of dimensional item is not implemented: %s::%s\n", class_owner->getName(), name);
00890       return Success;
00891     }
00892 
00893     dimArgsGen(fd, ndims, True);
00894     fprintf(fd, "%seyedb::Bool *isnull, eyedb::Status *rs) %s\n", comma, _const);
00895     fprintf(fd, "{\n");
00896 
00897     /*
00898       fprintf(fd, "%seyedb::Status s, *ps;\n", ctx->get());
00899       fprintf(fd, "%sps = (rs ? rs : &s);\n\n", ctx->get());
00900     */
00901     fprintf(fd, "%seyedb::Status s;\n", ctx->get());
00902 
00903     fprintf(fd, "%sconst eyedb::Collection%s coll = %s(", ctx->get(),
00904             getPtrRet(),
00905             ATTRNAME(name, tGetColl, hints));
00906 
00907     for (i = 0; i < ndims; i++)
00908       fprintf(fd, "a%d, ", i);
00909 
00910     fprintf(fd, "isnull, rs);\n\n", ctx->get());
00911     fprintf(fd, "%sif (!coll || (rs && *rs))\n", ctx->get());
00912     if (not_basic)
00913       {
00914         fprintf(fd, "%s  return (%s *)0;\n\n", ctx->get(), oclassname);
00915         fprintf(fd, "%s%s *tmp = 0;\n", ctx->get(), oclassname);
00916         if (cls->asCollArrayClass() || cls->asCollListClass())
00917           fprintf(fd, "%ss = coll->asCollArray()->retrieveAt(ind, (eyedb::Object*&)tmp);\n", ctx->get());
00918         else
00919           fprintf(fd, "%ss = coll->getObjectAt(ind, (eyedb::Object*&)tmp);\n", ctx->get());
00920       }
00921     else
00922       {
00923         fprintf(fd, "%s  return 0;\n\n", ctx->get(), oclassname);
00924         fprintf(fd, "%seyedb::Value tmp;\n", ctx->get());
00925         if (cls->asCollArrayClass() || cls->asCollListClass())
00926           fprintf(fd, "%ss = coll->asCollArray()->retrieveAt(ind, tmp);\n", ctx->get());
00927         else
00928           fprintf(fd, "%ss = coll->getValueAt(ind, tmp);\n", ctx->get());
00929       }
00930 
00931     if (not_basic)
00932       {
00933         fprintf(fd, "%sif (s) {if (rs) *rs = s; return (%s *)0;}\n", ctx->get(), oclassname);
00934         fprintf(fd, "%sreturn tmp;\n", ctx->get());
00935       }
00936     else
00937       {
00938         fprintf(fd, "%sif (s) {if (rs) *rs = s; return 0;}\n", ctx->get());
00939         fprintf(fd, "%sreturn tmp.%s;\n", ctx->get(),
00940                 Value::getAttributeName(cl, (_isref || (_dim > 1)) ?
00941                                         True : False));
00942       }
00943 
00944     fprintf(fd, "}\n\n");
00945     return Success;
00946   }
00947 
00948   Status
00949   Attribute::generateGetMethod_C(Class *own, GenContext *ctx,
00950                                  Bool isoid,
00951                                  const GenCodeHints &hints,
00952                                  const char *_const)
00953   {
00954     FILE *fd = ctx->getFile();
00955     int ndims = typmod.ndims, i;
00956     int not_basic = NOT_BASIC();
00957     const char *ref = (not_basic ? getPtrRet() : " ");
00958     const char *pure_ref = (not_basic ? "*" : " ");
00959     const char *starg    = STATUS_ARG(hints, False);
00960     const char *stargcom = STATUS_ARG(hints, True);
00961     const char *classname = isIndirect() ?
00962       className(cls, True) : className(cls, False);
00963 
00964     if (isoid)
00965       fprintf(fd, "eyedb::Oid %s::%s(", className(own),
00966               ATTRNAME(name, tGetOid, hints));
00967     else
00968       fprintf(fd, "%s%s%s%s::%s(", _const, classname, ref,
00969               className(own), ATTRNAME_1(name, ATTRGET(cls), hints));
00970 
00971     dimArgsGen(fd, ndims, True);
00972 
00973     if (isoid)
00974       //      fprintf(fd, "%s) %s\n{\n", (ndims ? stargcom : starg), _const);
00975       fprintf(fd, "%s) %s\n{\n", (ndims ? stargcom : starg), "const");
00976     else
00977       fprintf(fd, "%seyedb::Bool *isnull%s) %s\n{\n", (ndims ? ", " : ""),
00978               stargcom, (!not_basic ? "const" : _const));
00979 
00980     int const_obj = (!isoid && not_basic);
00981 
00982     GenCodeHints::OpType optype = (isoid ? GenCodeHints::tGetOid:
00983                                    GenCodeHints::tGet);
00984     if (attr_cache)
00985       genAttrCacheGetPrologue(ctx, optype);
00986 
00987     if (odl_dynamic_attr)
00988       dynamic_attr_gen(fd, ctx, this, op_GET, isoid, False,
00989                        cls->asEnumClass() ?
00990                        className(cls, True) : 0);
00991 
00992     gbx_suspend(ctx);
00993 
00994     if (isoid)
00995       fprintf(fd, "%seyedb::Oid __tmp;\n", ctx->get());
00996     else
00997       {
00998         if (const_obj)
00999           fprintf(fd, "%seyedb::Object *__o = 0, *__go;\n", ctx->get());
01000         else if (cls->asEnumClass())
01001           fprintf(fd, "%seyedblib::int32 %s__tmp%s;\n", ctx->get(),
01002                   ref,
01003                   (!strcmp(cls->getName(), "oid") ? "" : " = 0"));
01004         else
01005           fprintf(fd, "%s%s%s__tmp%s;\n", ctx->get(),
01006                   classname, ref,
01007                   (!strcmp(cls->getName(), "oid") ? "" : " = 0"));
01008       }
01009 
01010     const char *psret = "";
01011     if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01012       {
01013         /*
01014           fprintf(fd, "%seyedb::Status s, *ps;\n", ctx->get());
01015           fprintf(fd, "%sps = (rs ? rs : &s);\n", ctx->get());
01016           psret = "*ps = ";
01017         */
01018         fprintf(fd, "%seyedb::Status s;\n", ctx->get());
01019         psret = "s = ";
01020       }
01021 
01022     if (ndims)
01023       {
01024         fprintf(fd, "%seyedb::Size from = a%d;\n", ctx->get(), ndims-1);
01025         for (int i = ndims - 2 ; i >= 0; i--)
01026           fprintf(fd, "%sfrom += a%d * %d;\n", ctx->get(), i, typmod.dims[i]);
01027 
01028         if (odl_dynamic_attr) {
01029           if (isoid)
01030             fprintf(fd, "\n%s%s%s->getOid(this, &__tmp, 1, from);\n",
01031                     ctx->get(), psret, __agrdyn);
01032           else
01033             fprintf(fd, "\n%s%s%s->getValue(this, (eyedb::Data *)&%s, 1, from, isnull);\n",
01034                     ctx->get(), psret, __agrdyn, (const_obj ? "__o" : "__tmp"));
01035         }
01036         else {
01037           if (isoid)
01038             fprintf(fd, "\n%s%s%s[%d]->getOid(this, &__tmp, 1, from);\n",
01039                     ctx->get(), psret, __agritems, num);
01040           else
01041             fprintf(fd, "\n%s%s%s[%d]->getValue(this, (eyedb::Data *)&%s, 1, from, isnull);\n",
01042                     ctx->get(), psret, __agritems, num, (const_obj ? "__o" : "__tmp"));
01043         }
01044       }
01045     else if (isoid) {
01046       if (odl_dynamic_attr)
01047         fprintf(fd, "\n%s%s%s->getOid(this, &__tmp, 1, 0);\n",
01048                 ctx->get(), psret, __agrdyn);
01049       else
01050         fprintf(fd, "\n%s%s%s[%d]->getOid(this, &__tmp, 1, 0);\n",
01051                 ctx->get(), psret, __agritems, num);
01052     }
01053     else {
01054       if (odl_dynamic_attr)
01055         fprintf(fd, "\n%s%s%s->getValue(this, (eyedb::Data *)&%s, 1, 0, isnull);\n",
01056                 ctx->get(), psret, __agrdyn, (const_obj ? "__o" : "__tmp"));
01057       else
01058         fprintf(fd, "\n%s%s%s[%d]->getValue(this, (eyedb::Data *)&%s, 1, 0, isnull);\n",
01059                 ctx->get(), psret, __agritems, num, (const_obj ? "__o" : "__tmp"));
01060     }
01061 
01062     if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01063       {
01064         if (isoid || !strcmp(cls->getName(), "oid"))
01065           fprintf(fd, "%sif (s) {if (rs) *rs = s; return nulloid;}\n\n",
01066                   ctx->get());
01067         else
01068           RETURN_ERROR(fd, ctx, cls, "");
01069       }
01070 
01071     if (const_obj)
01072       {
01073         if (isIndirect())
01074           {
01075             fprintf(fd, "\n%sif (__o)\n", ctx->get());
01076             fprintf(fd, "%s  {\n", ctx->get());
01077             if (!cls->asCollectionClass()) // added the 23/08/99
01078               {
01079                 fprintf(fd, "   %sif (eyedb::ObjectPeer::isGRTObject(__o)) {\n", ctx->get());
01080                 if (attr_cache)
01081                   {
01082                     ctx->push();
01083                     ctx->push();
01084                     genAttrCacheGetEpilogue(ctx, optype);
01085                     ctx->pop();
01086                     ctx->pop();
01087                   }
01088               
01089                 fprintf(fd, "     %sreturn (%s *)__o;\n", ctx->get(),
01090                         classname);
01091                 fprintf(fd, "   %s}\n", ctx->get());
01092                 fprintf(fd, "   %s__go = (%s *)make_object(__o, eyedb::False);\n", ctx->get(), classname);
01093                 fprintf(fd, "   %sif (__go)\n", ctx->get());
01094                 fprintf(fd, "   %s {\n", ctx->get());
01095                 ctx->push();
01096                 fprintf(fd, "   %s__o = __go;\n", ctx->get());
01097                 if (odl_dynamic_attr)
01098                   fprintf(fd, "   %s%s%s->setValue((Agregat *)this, (eyedb::Data)&__o, 1, %s);\n",
01099                           ctx->get(), psret, __agrdyn, (ndims ? "from" : "0"));
01100                 else
01101                   fprintf(fd, "   %s%s%s[%d]->setValue((Agregat *)this, (eyedb::Data)&__o, 1, %s);\n",
01102                           ctx->get(), psret, __agritems, num, (ndims ? "from" : "0"));
01103 
01104                 fprintf(fd, "   %seyedb::ObjectPeer::decrRefCount(__o);\n", ctx->get());
01105           
01106                 if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01107                   RETURN_ERROR(fd, ctx, cls, "   ");
01108               
01109                 ctx->pop();
01110                 fprintf(fd, "   %s }\n", ctx->get());
01111 
01112                 if (attr_cache)
01113                   {
01114                     ctx->push();
01115                     genAttrCacheGetEpilogue(ctx, optype);
01116                     ctx->pop();
01117                   }
01118               }
01119 
01120             fprintf(fd, "   %sreturn (%s%s)__o;\n", ctx->get(),
01121                     classname, pure_ref);
01122             fprintf(fd, "%s  }\n\n", ctx->get());
01123 
01124             fprintf(fd, "%seyedb::Bool wasnull = (!__o ? eyedb::True : eyedb::False);\n", ctx->get());
01125             fprintf(fd, "%sif (!__o && db)\n", ctx->get());
01126             fprintf(fd, "%s  {\n", ctx->get());
01127             fprintf(fd, "%s    eyedb::Oid toid;\n", ctx->get());
01128             if (odl_dynamic_attr)
01129               fprintf(fd, "%s    %s%s->getOid(this, &toid, 1, %s);\n",
01130                       ctx->get(), psret, __agrdyn, (ndims ? "from" : "0"));
01131             else
01132               fprintf(fd, "%s    %s%s[%d]->getOid(this, &toid, 1, %s);\n",
01133                       ctx->get(), psret, __agritems, num, (ndims ? "from" : "0"));
01134             if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01135               RETURN_ERROR(fd, ctx, cls, "    ");
01136 
01137             fprintf(fd, "%s    if (toid.isValid())\n", ctx->get());
01138             fprintf(fd, "%s      {\n", ctx->get());
01139             fprintf(fd, "%s        %sdb->loadObject(&toid, &__o);\n",
01140                     ctx->get(), psret);
01141             if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01142               RETURN_ERROR(fd, ctx, cls, "        ");
01143 
01144             // ---- added the 4/05/99
01145             if (!cls->asCollectionClass()) // added the 23/08/99
01146               {
01147                 fprintf(fd, "%s        if (!eyedb::ObjectPeer::isGRTObject(__o))\n",
01148                         ctx->get());
01149                 fprintf(fd, "%s         {\n", ctx->get());
01150                 fprintf(fd, "%s           __go = (%s *)make_object"
01151                         "(__o, eyedb::False);\n", ctx->get(), classname);
01152                 fprintf(fd, "%s           if (__go) __o = __go;\n", ctx->get());
01153                 fprintf(fd, "%s         }\n", ctx->get());
01154               }
01155             // ----
01156             fprintf(fd, "%s      }\n", ctx->get());
01157             fprintf(fd, "%s  }\n", ctx->get());
01158           
01159             fprintf(fd, "\n%sif (__o && wasnull)\n", ctx->get());
01160             fprintf(fd, "%s  {\n", ctx->get());
01161             if (odl_dynamic_attr)
01162               fprintf(fd, "   %s%s%s->setValue((eyedb::Agregat *)this, (eyedb::Data)&__o, 1, %s);\n",
01163                       ctx->get(), psret, __agrdyn, (ndims ? "from" : "0"));
01164             else
01165               fprintf(fd, "   %s%s%s[%d]->setValue((eyedb::Agregat *)this, (eyedb::Data)&__o, 1, %s);\n",
01166                       ctx->get(), psret, __agritems, num, (ndims ? "from" : "0"));
01167             if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01168               RETURN_ERROR(fd, ctx, cls, "   ");
01169 
01170             // change the 23/08/99
01171             fprintf(fd, "   %s__o->release();\n", ctx->get());
01172             fprintf(fd, "%s  }\n", ctx->get());
01173           }
01174         else if (!cls->asCollectionClass()) // added the 25/11/99
01175           {
01176             fprintf(fd, "\n%sif (__o)\n", ctx->get());
01177             fprintf(fd, "%s  {\n", ctx->get());
01178             fprintf(fd, "   %sif (eyedb::ObjectPeer::isGRTObject(__o)) {\n", ctx->get());
01179             if (attr_cache)
01180               {
01181                 ctx->push();
01182                 ctx->push();
01183                 genAttrCacheGetEpilogue(ctx, optype);
01184                 ctx->pop();
01185                 ctx->pop();
01186               }
01187 
01188             fprintf(fd, "     %sreturn (%s *)__o;\n", ctx->get(),
01189                     classname);
01190             fprintf(fd, "   %s}\n", ctx->get());
01191             fprintf(fd, "   %s__go = (%s *)make_object(__o, eyedb::False);\n", ctx->get(), classname);
01192             fprintf(fd, "   %sif (__go)\n", ctx->get());
01193             fprintf(fd, "   %s {\n", ctx->get());
01194             ctx->push();
01195             fprintf(fd, "   %s__o = __go;;\n", ctx->get());
01196             if (odl_dynamic_attr)
01197               fprintf(fd, "   %s%s%s->setValue((eyedb::Agregat *)this, (eyedb::Data)&__o, 1, %s);\n",
01198                       ctx->get(), psret, __agrdyn, (ndims ? "from" : "0"));
01199             else
01200               fprintf(fd, "   %s%s%s[%d]->setValue((Agregat *)this, (eyedb::Data)&__o, 1, %s);\n",
01201                       ctx->get(), psret, __agritems, num, (ndims ? "from" : "0"));
01202             fprintf(fd, "   %seyedb::ObjectPeer::decrRefCount(__o);\n", ctx->get());
01203           
01204             if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01205               RETURN_ERROR(fd, ctx, cls, "   ");
01206 
01207             ctx->pop();
01208             fprintf(fd, "   %s }\n", ctx->get());
01209             fprintf(fd, "%s  }\n", ctx->get());
01210           }
01211       }
01212 
01213     if (attr_cache)
01214       genAttrCacheGetEpilogue(ctx, optype);
01215 
01216     if (const_obj)
01217       fprintf(fd, "%sreturn (%s%s)__o;\n", ctx->get(),
01218               classname, pure_ref);
01219     else if (cls->asEnumClass())
01220       fprintf(fd, "%sreturn (%s)__tmp;\n", ctx->get(), className(cls, True));
01221     else
01222       fprintf(fd, "%sreturn __tmp;\n", ctx->get());
01223 
01224     fprintf(fd, "}\n\n");
01225 
01226     // WARNING: changed '*_const || IS_RAW()' to
01227     // '!isoid && !IS_STRING()' the 11/1/99
01228     if (isVarDim() && !isoid && !*_const && !IS_STRING())
01229       {
01230         fprintf(fd, "unsigned int %s::%s(%s) const\n{\n", className(own),
01231                 ATTRNAME(name, tGetCount, hints), starg);
01232 
01233         if (attr_cache)
01234           genAttrCacheGetPrologue(ctx, GenCodeHints::tGetCount);
01235 
01236         if (odl_dynamic_attr)
01237           dynamic_attr_gen(fd, ctx, this, op_OTHER, isoid);
01238 
01239         gbx_suspend(ctx);
01240 
01241         fprintf(fd, "%seyedb::Size size;\n", ctx->get());
01242         if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01243           {
01244             /*
01245               fprintf(fd, "%seyedb::Status s, *ps;\n", ctx->get());
01246               fprintf(fd, "%sps = (rs ? rs : &s);\n", ctx->get());
01247             */
01248             fprintf(fd, "%seyedb::Status s;\n", ctx->get());
01249           }
01250         if (odl_dynamic_attr)
01251           fprintf(fd, "%s%s%s->getSize(this, size);\n", ctx->get(), psret,
01252                   __agrdyn);
01253         else
01254           fprintf(fd, "%s%s%s[%d]->getSize(this, size);\n", ctx->get(), psret,
01255                   __agritems, num);
01256         if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01257           fprintf(fd, "%sif (s) {if (rs) *rs = s; return 0;}\n", ctx->get());
01258 
01259         if (attr_cache)
01260           genAttrCacheGetEpilogue(ctx, GenCodeHints::tGetCount);
01261 
01262         fprintf(fd, "%sreturn (int)size;\n", ctx->get());
01263         fprintf(fd, "}\n\n");
01264       }
01265 
01266     if (cls->asCollectionClass())
01267       return generateCollGetMethod_C(own, ctx, isoid,
01268                                      hints, _const);
01269     return Success;
01270   }
01271   
01272   Status Attribute::generateBody_C(Class *own,
01273                                    GenContext *ctx,
01274                                    const GenCodeHints &hints)
01275   {
01276     FILE *fd = ctx->getFile();
01277     int ndims = typmod.ndims, i;
01278     int maxdims = typmod.maxdims;
01279     int not_basic = NOT_BASIC();
01280     const char *ref = (not_basic ? getPtrRet() : " ");
01281     int is_string = IS_STRING();
01282     int is_raw = IS_RAW();
01283     const char *starg    = STATUS_ARG(hints, False);
01284     const char *stargcom = STATUS_ARG(hints, True);
01285     const char *psret = "";
01286 
01287     // set methods
01288     if (is_string || is_raw)
01289       {
01290         const char *sclass = SCLASS();
01291         const char *sarg = SARGIN();
01292 #ifdef ODL_STD_STRING
01293         if (is_string)
01294           fprintf(fd, "eyedb::Status %s::%s(const std::string &_%s%s)\n{\n",
01295                   className(own), ATTRNAME(name, tSet, hints), name,
01296                   sarg);
01297         else
01298           fprintf(fd, "eyedb::Status %s::%s(const %s *_%s%s)\n{\n",
01299                   className(own), ATTRNAME(name, tSet, hints), sclass, name,
01300                   sarg);
01301 #else
01302         fprintf(fd, "eyedb::Status %s::%s(const %s *_%s%s)\n{\n",
01303                 className(own), ATTRNAME(name, tSet, hints), sclass, name,
01304                 sarg);
01305 #endif
01306 
01307         if (attr_cache)
01308           genAttrCacheSetPrologue(ctx, GenCodeHints::tSet, True);
01309 
01310         if (odl_dynamic_attr)
01311           dynamic_attr_gen(fd, ctx, this, op_SET);
01312 
01313         gbx_suspend(ctx);
01314         fprintf(fd, "%seyedb::Status status;\n", ctx->get());
01315       
01316         if (isVarDim())
01317           {
01318             fprintf(fd, "%seyedb::Size size;\n", ctx->get());
01319 
01320 #ifdef ODL_STD_STRING
01321             if (is_string)
01322               fprintf(fd, "%seyedb::Size len = _%s.size() + 1;\n\n", ctx->get(), name);
01323 #else
01324             if (is_string)
01325               fprintf(fd, "%seyedb::Size len = ::strlen(_%s) + 1;\n\n", ctx->get(), name);
01326 #endif
01327             if (odl_dynamic_attr)
01328               fprintf(fd, "%sstatus = %s->getSize(this, size);\n", ctx->get(),
01329                       __agrdyn);
01330             else
01331               fprintf(fd, "%sstatus = %s[%d]->getSize(this, size);\n", ctx->get(),
01332                       __agritems, num);
01333             fprintf(fd, "%sif (status)\n%s  return status;\n\n", ctx->get(),
01334                     ctx->get());
01335             fprintf(fd, "%sif (size != len)\n", ctx->get());
01336             ctx->push();
01337             if (odl_dynamic_attr)
01338               fprintf(fd, "%sstatus = %s->setSize(this, len);\n", ctx->get(),
01339                       __agrdyn);
01340             else
01341               fprintf(fd, "%sstatus = %s[%d]->setSize(this, len);\n", ctx->get(),
01342                       __agritems, num);
01343             ctx->pop();
01344             fprintf(fd, "%sif (status)\n%s  return status;\n\n", ctx->get(),
01345                     ctx->get());
01346 
01347 #ifdef ODL_STD_STRING
01348             if (odl_dynamic_attr) {
01349               if (is_string)
01350                 fprintf(fd, "%sstatus = %s->setValue(this, (eyedb::Data)_%s.c_str(), len, 0);\n",
01351                         ctx->get(), __agrdyn, name);
01352               else
01353                 fprintf(fd, "%sstatus = %s->setValue(this, (eyedb::Data)_%s., len, 0);\n",
01354                         ctx->get(), __agrdyn, name);
01355             }
01356             else {
01357               if (is_string)
01358                 fprintf(fd, "%sstatus = %s[%d]->setValue(this, (eyedb::Data)_%s.c_str(), len, 0);\n",
01359                         ctx->get(), __agritems, num, name);
01360               else
01361                 fprintf(fd, "%sstatus = %s[%d]->setValue(this, (eyedb::Data)_%s, len, 0);\n",
01362                         ctx->get(), __agritems, num, name);
01363             }
01364 #else
01365             if (odl_dynamic_attr)
01366               fprintf(fd, "%sstatus = %s->setValue(this, (eyedb::Data)_%s, len, 0);\n",
01367                       ctx->get(), __agrdyn, name);
01368             else
01369               fprintf(fd, "%sstatus = %s[%d]->setValue(this, (eyedb::Data)_%s, len, 0);\n",
01370                       ctx->get(), __agritems, num, name);
01371 #endif
01372 
01373             if (attr_cache)
01374               genAttrCacheSetEpilogue(ctx, GenCodeHints::tSet, True);
01375             fprintf(fd, "%sreturn status;\n\n", ctx->get());
01376           }
01377         else
01378           {
01379             if (is_string) {
01380               fprintf(fd, "%sunsigned char data[%d];\n", ctx->get(), maxdims);
01381 #ifdef ODL_STD_STRING
01382               fprintf(fd, "%seyedb::Size len = _%s.size();\n", ctx->get(), name);
01383 #else
01384               fprintf(fd, "%seyedb::Size len = ::strlen(_%s);\n", ctx->get(), name);
01385 #endif
01386             }
01387             fprintf(fd, "%sif (len >= %d)\n", ctx->get(), maxdims);
01388 #ifdef ODL_STD_STRING
01389             if (is_string)
01390               fprintf(fd, "%s  return eyedb::Exception::make(eyedb::IDB_ERROR, "
01391                       "\"string `%%s' [%%d] too long for attribute %s::%s, maximum "
01392                       "is %d\\n\", _%s.c_str(), len);\n", ctx->get(),
01393                       class_owner->getName(), name, maxdims, name);
01394             else
01395               fprintf(fd, "%s  return eyedb::Exception::make(eyedb::IDB_ERROR, "
01396                       "\"string `%%s' [%%d] too long for attribute %s::%s, maximum "
01397                       "is %d\\n\", _%s, len);\n", ctx->get(),
01398                       class_owner->getName(), name, maxdims, name);
01399 #else
01400             fprintf(fd, "%s  return eyedb::Exception::make(eyedb::IDB_ERROR, "
01401                     "\"string `%%s' [%%d] too long for attribute %s::%s, maximum "
01402                     "is %d\\n\", _%s, len);\n", ctx->get(),
01403                     class_owner->getName(), name, maxdims, name);
01404 #endif
01405             if (is_string) {
01406               fprintf(fd, "%smemset(data, 0, %d);\n", ctx->get(), maxdims);
01407 #ifdef ODL_STD_STRING
01408               fprintf(fd, "%sstrncpy((char *)data, _%s.c_str(), min(%d, len));\n",
01409                       ctx->get(), name, maxdims-1);
01410 #else
01411               fprintf(fd, "%sstrncpy((char *)data, _%s, min(%d, len));\n",
01412                       ctx->get(), name, maxdims-1);
01413 #endif
01414               if (odl_dynamic_attr)
01415                 fprintf(fd, "%sstatus = %s->setValue(this, data, %d, 0);\n",
01416                         ctx->get(), __agrdyn, maxdims);
01417               else
01418                 fprintf(fd, "%sstatus = %s[%d]->setValue(this, data, %d, 0);\n",
01419                         ctx->get(), __agritems, num, maxdims);
01420             }
01421             else {
01422 #ifdef ODL_STD_STRING
01423               if (odl_dynamic_attr) {
01424                 if (is_string)
01425                   fprintf(fd, "%sstatus = %s->setValue(this, (eyedb::Data)_%s.c_str(), len, 0);\n",
01426                           ctx->get(), __agrdyn, name);
01427                 else
01428                   fprintf(fd, "%sstatus = %s->setValue(this, (eyedb::Data)_%s, len, 0);\n",
01429                           ctx->get(), __agrdyn, name);
01430               }
01431               else {
01432                 if (is_string)
01433                   fprintf(fd, "%sstatus = %s[%d]->setValue(this, (eyedb::Data)_%s.c_str(), len, 0);\n",
01434                           ctx->get(), __agritems, num, name);
01435                 else
01436                   fprintf(fd, "%sstatus = %s[%d]->setValue(this, (eyedb::Data)_%s, len, 0);\n",
01437                           ctx->get(), __agritems, num, name);
01438               }
01439 #else
01440               if (odl_dynamic_attr)
01441                 fprintf(fd, "%sstatus = %s->setValue(this, (eyedb::Data)_%s, len, 0);\n",
01442                         ctx->get(), __agrdyn, name);
01443               else
01444                 fprintf(fd, "%sstatus = %s[%d]->setValue(this, (eyedb::Data)_%s, len, 0);\n",
01445                         ctx->get(), __agritems, num, name);
01446 #endif
01447             }
01448 
01449             if (attr_cache)
01450               genAttrCacheSetEpilogue(ctx, GenCodeHints::tSet, True);
01451             fprintf(fd, "%sreturn status;\n\n", ctx->get());
01452           }
01453         fprintf(fd, "}\n\n");
01454       }
01455 
01456     /* warning:
01457      * the methods setXxx() should be avoided when xxx is a non basic
01458      * and direct, because the direct Object.has already been allocated
01459      * in the object construction.
01460      * The problem is for the vardim: the setXxx(int w, Xxx *x) method sets
01461      * the size and sets the `x' object.
01462      * So if we suppress the setXxx() method, one should had a method for
01463      * vardim: setXxx_cnt() or setXxx_size to set the size.
01464      */
01465 
01466 #ifdef NO_DIRECT_SET
01467     if (isIndirect() || !not_basic) // added 22/09/98
01468 #endif
01469       generateSetMethod_C(own, ctx, False, hints);
01470 #ifdef NO_DIRECT_SET
01471     else
01472 #endif
01473 #if defined(SET_COUNT_DIRECT) || defined(NO_DIRECT_SET)
01474       // 23/05/06: suppressed !isIndirect()
01475       //      if (isVarDim() && !isIndirect() && !is_string) /*&& not_basic*/
01476       if (isVarDim() && !is_string) /*&& not_basic*/
01477         {
01478           fprintf(fd, "eyedb::Status %s::%s(", className(own),
01479                   ATTRNAME(name, tSetCount, hints));
01480       
01481           dimArgsGen(fd, ndims, True);
01482       
01483           fprintf(fd, ")\n{\n");
01484 
01485           if (attr_cache)
01486             genAttrCacheSetPrologue(ctx, GenCodeHints::tSetCount);
01487 
01488           if (odl_dynamic_attr)
01489             dynamic_attr_gen(fd, ctx, this, op_SET);
01490 
01491           gbx_suspend(ctx);
01492 
01493           fprintf(fd, "%seyedb::Status status;\n", ctx->get());
01494 
01495           fprintf(fd, "%seyedb::Size from = a%d;\n", ctx->get(), ndims-1);
01496           for (int i = ndims - 2 ; i >= 0; i--)
01497             fprintf(fd, "%sfrom += a%d * %d;\n", ctx->get(), i, typmod.dims[i]);
01498 
01499           // disconnected the 3/09/01: it is not useful to forbid to
01500           // decrement count!
01501 #if 0
01502           fprintf(fd, "\n%seyedb::Size size;\n", ctx->get());
01503           if (odl_dynamic_attr)
01504             fprintf(fd, "%sstatus = %s->getSize(this, size);\n",
01505                     ctx->get(), __agrdyn);
01506           else
01507             fprintf(fd, "%sstatus = %s[%d]->getSize(this, size);\n",
01508                     ctx->get(), __agritems, num);
01509           fprintf(fd, "%sif (status)\n%s  return status;\n\n", ctx->get(),
01510                   ctx->get());
01511           // changed the 24/08/99
01512           fprintf(fd, "%sif (size < from)\n", ctx->get());
01513           ctx->push();
01514 #endif
01515           if (odl_dynamic_attr)
01516             fprintf(fd, "%sstatus = %s->setSize(this, from);\n",
01517                     ctx->get(), __agrdyn);
01518           else
01519             fprintf(fd, "%sstatus = %s[%d]->setSize(this, from);\n",
01520                     ctx->get(), __agritems, num);
01521 
01522 #if 0
01523           ctx->pop();
01524 #endif
01525 
01526           if (attr_cache)
01527             genAttrCacheSetEpilogue(ctx, GenCodeHints::tSetCount);
01528 
01529           fprintf(fd, "%sreturn status;\n", ctx->get(),
01530                   ctx->get());
01531 
01532           fprintf(fd, "}\n\n");
01533         }
01534 #endif
01535 
01536     // get methods
01537     if (is_string || is_raw)
01538       {
01539         const char *sclass = SCLASS();
01540         const char *sarg = SARGOUT();
01541         
01542 #ifdef ODL_STD_STRING
01543         if (is_string)
01544           fprintf(fd, "std::string %s::%s(%seyedb::Bool *isnull%s) const\n{\n", 
01545                   className(own), ATTRNAME(name, tGet, hints), sarg,
01546                   stargcom);
01547         else
01548           fprintf(fd, "const %s *%s::%s(%seyedb::Bool *isnull%s) const\n{\n", 
01549                   sclass, className(own), ATTRNAME(name, tGet, hints), sarg,
01550                   stargcom);
01551 #else
01552         fprintf(fd, "const %s *%s::%s(%seyedb::Bool *isnull%s) const\n{\n", 
01553                 sclass, className(own), ATTRNAME(name, tGet, hints), sarg,
01554                 stargcom);
01555 #endif
01556 
01557         if (attr_cache)
01558           genAttrCacheGetPrologue(ctx, GenCodeHints::tGet, True);
01559 
01560         if (odl_dynamic_attr)
01561           dynamic_attr_gen(fd, ctx, this, op_GET, False, IDBBOOL(is_string));
01562 
01563         gbx_suspend(ctx);
01564 
01565         fprintf(fd, "%seyedb::Data data;\n", ctx->get());
01566         if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01567           {
01568             /*
01569               fprintf(fd, "%seyedb::Status s, *ps;\n", ctx->get());
01570               fprintf(fd, "%sps = (rs ? rs : &s);\n", ctx->get());
01571               psret = "*ps = ";
01572             */
01573             fprintf(fd, "%seyedb::Status s;\n", ctx->get());
01574             psret = "s = ";
01575           }
01576         if (odl_dynamic_attr)
01577           fprintf(fd, "\n%s%s%s->getValue(this, (eyedb::Data *)&data, eyedb::Attribute::directAccess, 0, isnull);\n",
01578                   ctx->get(), psret, __agrdyn);
01579         else
01580           fprintf(fd, "\n%s%s%s[%d]->getValue(this, (eyedb::Data *)&data, eyedb::Attribute::directAccess, 0, isnull);\n",
01581                   ctx->get(), psret, __agritems, num);
01582 
01583         if (hints.error_policy == GenCodeHints::StatusErrorPolicy)
01584           RETURN_ERROR(fd, ctx, cls, "");
01585 
01586         if (isVarDim())
01587           fprintf(fd, "%sif (!data) data = nulldata;\n", ctx->get());
01588 
01589         if (attr_cache)
01590           genAttrCacheGetEpilogue(ctx, GenCodeHints::tGet, True);
01591 
01592         if (is_raw && isVarDim())
01593           fprintf(fd, "%sif (len) *len = %s();\n", ctx->get(),
01594                   ATTRNAME(name, tGetCount, hints));
01595         //fprintf(fd, "%sif (s && rs) *rs = s;\n", ctx->get());
01596         if (attr_cache) {
01597 #ifdef ODL_STD_STRING
01598           fprintf(fd, "%sreturn %s;\n", ctx->get(),
01599                   atc_name(name));
01600 #else
01601           fprintf(fd, "%sreturn (const %s *)%s;\n", ctx->get(), sclass,
01602                   atc_name(name));
01603 #endif
01604         }
01605         else
01606           fprintf(fd, "%sreturn (const %s *)data;\n", ctx->get(), sclass);
01607         fprintf(fd, "}\n\n");
01608       }
01609     else if (not_basic)
01610       generateGetMethod_C(own, ctx, False, hints, "const ");
01611 
01612     generateGetMethod_C(own, ctx, False, hints, "");
01613 
01614     if (isIndirect())
01615       {
01616         generateSetMethod_C(own, ctx, True, hints);
01617         generateGetMethod_C(own, ctx, True, hints, "");
01618       }
01619     else if (cls->asCollectionClass())
01620       generateCollGetMethod_C(own, ctx, True, hints, "");
01621 
01622     generateSetMethod_C(own, ctx, hints);
01623 
01624     return Success;
01625   }
01626 
01627   //
01628   // Attribute Cache Methods
01629   //
01630   // on peut se limiter dans un premier temps à:
01631   //
01632   // - type de dimensions fixes:
01633   //   + get/set
01634   //   + getoid/setoid
01635   //
01636   // - type string:
01637   //   + get/set
01638   //
01639   // - type de dimension variable:
01640   //   + getcount/setcount
01641 
01642 #define ATC_NOVD // acronym for ATtribute Cache NO VarDim
01643 
01644   void
01645   Attribute::genAttrCacheDecl(GenContext *ctx)
01646   {
01647     if (isNative()) return;
01648 
01649 #ifdef ATC_NOVD
01650     //  if (isVarDim() && !IS_STRING()) return;
01651 #endif
01652     FILE *fd = ctx->getFile();
01653 
01654     int is_string = IS_STRING();
01655     int is_raw = IS_RAW();
01656     int i;
01657 
01658     if (isVarDim())
01659       fprintf(fd, "%sunsigned int %s;\n", ctx->get(), atc_cnt(name));
01660 #ifdef ATC_NOVD
01661     if (isVarDim() && !(is_string || is_raw))
01662       return;
01663 #endif
01664 
01665     fprintf(fd, "%sunsigned char ", ctx->get());
01666 
01667 #ifndef ATC_NOVD
01668     if (isVarDim())
01669       fprintf(fd, getPtrRet());
01670 #endif
01671 
01672     fprintf(fd, atc_set(name));
01673     if (!is_string && !is_raw)
01674       {
01675         for (i = 0; i < typmod.ndims; i++)
01676           if (typmod.dims[i] > 0)
01677             fprintf(fd, "[%d]", typmod.dims[i]);
01678       }
01679     fprintf(fd, ";\n");
01680 
01681     if (is_string || is_raw)
01682       {
01683 #ifdef ODL_STD_STRING
01684 #ifdef ATTR_CACHE_DIRECT
01685         if (is_string)
01686           fprintf(fd, "%sstd::string %s;\n", ctx->get(), atc_name(name));
01687         else
01688           fprintf(fd, "%sconst %s *%s;\n", ctx->get(), SCLASS(), atc_name(name));
01689 #else
01690         if (is_string)
01691           fprintf(fd, "%sstd::string %s;\n", ctx->get(), atc_name(name));
01692         else
01693           fprintf(fd, "%s%s *%s;\n", ctx->get(), SCLASS(), atc_name(name));
01694 #endif
01695 #else
01696 #ifdef ATTR_CACHE_DIRECT
01697         fprintf(fd, "%sconst %s *%s;\n", ctx->get(), SCLASS(), atc_name(name));
01698 #else
01699         fprintf(fd, "%s%s *%s;\n", ctx->get(), SCLASS(), atc_name(name));
01700 #endif
01701 #endif
01702         return;
01703       }
01704     else
01705       fprintf(fd, "%s%s%s%s%s",
01706               ctx->get(), className(cls, (isIndirect() ? True : False)),
01707               (isVarDim() ? getPtrRet() : " "), (NOT_BASIC() ? getPtrRet() : " "), atc_name(name));
01708 
01709     for (i = 0; i < typmod.ndims; i++)
01710       if (typmod.dims[i] > 0)
01711         fprintf(fd, "[%d]", typmod.dims[i]);
01712 
01713     fprintf(fd, ";\n");
01714   }
01715 
01716   void
01717   Attribute::genAttrCacheEmpty(GenContext *ctx)
01718   {
01719     if (isNative())
01720       return;
01721 
01722 #ifdef ATC_NOVD
01723     //  if (isVarDim() && !IS_STRING()) return;
01724 #endif
01725 
01726     int is_string = IS_STRING();
01727     int is_raw = IS_RAW();
01728 
01729     FILE *fd = ctx->getFile();
01730     if (isVarDim())
01731       fprintf(fd, "%s%s = ~0;\n", ctx->get(), atc_cnt(name));
01732 
01733 #ifdef ATC_NOVD
01734     if (isVarDim() && !(is_string || is_raw)) return;
01735 #endif
01736 
01737     if (!typmod.ndims || is_string || is_raw) {
01738 #ifdef ODL_STD_STRING
01739       /*
01740       if (is_string)
01741         fprintf(fd, "%s%s = "";\n", ctx->get(), atc_set(name));
01742       else
01743       */
01744       fprintf(fd, "%s%s = 0;\n", ctx->get(), atc_set(name));
01745 #else
01746       fprintf(fd, "%s%s = 0;\n", ctx->get(), atc_set(name));
01747 #endif
01748     }
01749     else
01750       fprintf(fd, "%smemset(%s, 0, %d);\n", ctx->get(), atc_set(name),
01751               typmod.pdims);
01752   }
01753 
01754   void
01755   Attribute::genAttrCacheGarbage(GenContext *ctx)
01756   {
01757     if (isNative()) return;
01758 #ifdef ATC_NOVD
01759     if (isVarDim() && !(IS_STRING() || IS_RAW())) return;
01760 #endif
01761 
01762     //  if (isNative() || !isVarDim()) return;
01763     FILE *fd = ctx->getFile();
01764 
01765     if (IS_STRING() || IS_RAW())
01766       {
01767 #ifndef ATTR_CACHE_DIRECT
01768         fprintf(fd, "%sif (%s) free(%s);\n", ctx->get(), atc_set(name),
01769                 atc_name(name));
01770 #endif
01771         return;
01772       }
01773 
01774     if (!isVarDim()) return;
01775 
01776     // TODO: NOTE: si les precedents malloc() sont bons pour les vardim, alors
01777     // les free qui suivent ne sont pas corrects; en effet, il faut
01778     // liberer tous les pointeurs d'un tableau. -> il me semble qu'il y a
01779     // un peu de confusion!
01780 
01781     fprintf(fd, "%sif (%s) {free(%s); free(%s);}\n", ctx->get(), atc_cnt(name),
01782             atc_set(name), atc_name(name));
01783   }
01784 
01785   void
01786   Attribute::genAttrCacheGetPrologue(GenContext *ctx, int optype,
01787                                      Bool is_raw_string)
01788   {
01789 #ifdef ATC_NOVD
01790     if (optype != GenCodeHints::tGetCount)
01791       {
01792         if (isVarDim() && !is_raw_string)
01793           return;
01794         if ((IS_STRING() || IS_RAW()) && !is_raw_string)
01795           return;
01796       }
01797 #endif
01798 
01799     if (optype == GenCodeHints::tGetOid && !isIndirect()) return;
01800 
01801     if (optype == GenCodeHints::tGetOid) return;
01802 
01803     FILE *fd = ctx->getFile();
01804 
01805     if (optype == GenCodeHints::tGetCount)
01806       {
01807         fprintf(fd, "%sif (%s != (unsigned int)~0) return %s;\n", ctx->get(), atc_cnt(name),
01808                 atc_cnt(name));
01809         return;
01810       }
01811 
01812     // TODO: WARNING: must check dimensions before returning from cache!
01813 
01814     if (is_raw_string)
01815       {
01816         if (IS_RAW() && isVarDim())
01817           {
01818             fprintf(fd, "%sif (%s) {if (len) *len = %s; return %s;}\n",
01819                     ctx->get(), atc_set(name), atc_cnt(name), atc_name(name));
01820           }
01821         else
01822           fprintf(fd, "%sif (%s) return %s;\n", ctx->get(), atc_set(name),
01823                   atc_name(name));
01824         return;
01825       }
01826 
01827     if (isVarDim())
01828       fprintf(fd, "%sif (%s > a%d && %s",
01829               ctx->get(), atc_cnt(name), typmod.ndims-1, atc_set(name));
01830     else
01831       fprintf(fd, "%sif (%s", ctx->get(), atc_set(name));
01832 
01833     int i;
01834     for (i = 0; i < typmod.ndims; i++)
01835       fprintf(fd, "[a%d]", i);
01836     fprintf(fd, ") return %s", atc_name(name));
01837 
01838     for (i = 0; i < typmod.ndims; i++)
01839       fprintf(fd, "[a%d]", i);
01840     fprintf(fd, ";\n\n");
01841   }
01842 
01843   void
01844   Attribute::genAttrCacheGetEpilogue(GenContext *ctx, int optype,
01845                                      Bool is_raw_string)
01846   {
01847 #ifdef ATC_NOVD
01848     if (optype != GenCodeHints::tGetCount)
01849       {
01850         if (isVarDim() && !is_raw_string)
01851           return;
01852         if ((IS_STRING() || IS_RAW()) && !is_raw_string)
01853           return;
01854       }
01855 #endif
01856 
01857     if (optype == GenCodeHints::tGetOid && !isIndirect()) return;
01858 
01859     if (optype == GenCodeHints::tGetOid) return;
01860 
01861     FILE *fd = ctx->getFile();
01862 
01863     const char *classname = className(class_owner);
01864 
01865     if (optype == GenCodeHints::tGetCount)
01866       {
01867         fprintf(fd, "%s%s->%s = size;\n", ctx->get(), atc_this(classname),
01868                 atc_cnt(name));
01869         return;
01870       }
01871 
01872     if (is_raw_string)
01873       {
01874         fprintf(fd, "%s%s->%s = 1;\n", ctx->get(), atc_this(classname),
01875                 atc_set(name));
01876         // TODO: faux dans le cas d'un raw data.
01877         if (IS_RAW())
01878           {
01879 #ifdef ATTR_CACHE_DIRECT
01880             if (isVarDim())
01881               {
01882                 const char *scnt = ATTRNAME(name, tGetCount, *phints);
01883                 fprintf(fd, "%s%s->%s = %s();\n", ctx->get(),
01884                         atc_this(classname), atc_cnt(name), scnt);
01885               }
01886 
01887             fprintf(fd, "%s%s->%s = data;\n", ctx->get(),
01888                     atc_this(classname), atc_name(name));
01889 #else
01890             if (isVarDim())
01891               {
01892                 const char *scnt = ATTRNAME(name, tGetCount, *phints);
01893                 fprintf(fd, "%s%s->%s = rawdup(data, %s());\n", ctx->get(),
01894                         atc_this(classname), atc_name(name), scnt);
01895                 fprintf(fd, "%s%s->%s = %s();\n", ctx->get(),
01896                         atc_this(classname), atc_cnt(name), scnt);
01897 
01898               }
01899             else
01900               fprintf(fd, "%s%s->%s = rawdup(data, %d);\n", ctx->get(),
01901                       atc_this(classname), atc_name(name), typmod.pdims);
01902 #endif
01903           }
01904 #ifdef ATTR_CACHE_DIRECT
01905         else
01906           fprintf(fd, "%s%s->%s = (const char *)data;\n", ctx->get(),
01907                   atc_this(classname), atc_name(name));
01908 #else
01909         else
01910           fprintf(fd, "%s%s->%s = strdup((const char *)data);\n", ctx->get(),
01911                   atc_this(classname), atc_name(name));
01912 #endif
01913         return;
01914       }
01915 
01916     if (isVarDim())
01917       {
01918         // TODO: FAUX: on doit plutot faire un realloc dans le cas ou
01919         // le _cnt n'etait pas null!
01920         fprintf(fd, "%sif (%s) {free(%s->%s); free(%s->%s);}\n",
01921                 ctx->get(), atc_cnt(name), atc_this(classname), atc_set(name),
01922                 atc_this(classname), atc_name(name));
01923         fprintf(fd, "%s%s->%s = a%d+1;\n", ctx->get(), atc_this(classname), atc_cnt(name),
01924                 typmod.ndims-1);
01925         fprintf(fd, "%s%s->%s",
01926                 ctx->get(), atc_this(classname), atc_set(name));
01927         int i;
01928         for (i = 0; i < typmod.ndims; i++)
01929           if (typmod.dims[i] > 0) fprintf(fd, "[a%d]", i);
01930 
01931         fprintf(fd, " = (unsigned char *)malloc(a%d+1);\n", typmod.ndims-1);
01932 
01933         fprintf(fd, "%s%s->%s",
01934                 ctx->get(), atc_this(classname), atc_name(name));
01935         for (i = 0; i < typmod.ndims; i++)
01936           if (typmod.dims[i] > 0) fprintf(fd, "[a%d]", i);
01937         fprintf(fd, " = (%s *%s)malloc((a%d+1)*sizeof(%s *));\n",
01938                 className(cls, (isIndirect() ? True : False)),
01939                 (NOT_BASIC() ? getPtrRet() : " "),
01940                 typmod.ndims-1, className(cls, True));
01941       }
01942 
01943     fprintf(fd, "%s%s->%s", ctx->get(), atc_this(classname), atc_set(name));
01944     int i;
01945     for (i = 0; i < typmod.ndims; i++)
01946       fprintf(fd, "[a%d]", i);
01947 
01948     fprintf(fd, " = 1;\n");
01949     fprintf(fd, "%s%s->%s", ctx->get(), atc_this(classname), atc_name(name));
01950     for (i = 0; i < typmod.ndims; i++)
01951       fprintf(fd, "[a%d]", i);
01952 
01953     fprintf(fd, " = ");
01954 
01955     if (NOT_BASIC())
01956       fprintf(fd, "(%s *)__o", className(cls, True));
01957     else
01958       fprintf(fd, "(%s)__tmp", className(cls, False));
01959     fprintf(fd, ";\n");
01960   }
01961 
01962   void
01963   Attribute::genAttrCacheSetPrologue(GenContext *ctx, int optype,
01964                                      Bool is_raw_string)
01965   {
01966     // nothing to do!
01967   }
01968 
01969   void
01970   Attribute::genAttrCacheSetEpilogue(GenContext *ctx, int optype,
01971                                      Bool is_raw_string)
01972   {
01973 #ifdef ATC_NOVD
01974     if (optype != GenCodeHints::tSetCount)
01975       {
01976         if (isVarDim() && !is_raw_string)
01977           return;
01978         if ((IS_STRING() || IS_RAW()) && !is_raw_string)
01979           return;
01980       }
01981 #endif
01982     if (optype == GenCodeHints::tSetOid && !isIndirect()) return;
01983 
01984     if (optype == GenCodeHints::tSetOid) return;
01985 
01986     FILE *fd = ctx->getFile();
01987 
01988     if (optype == GenCodeHints::tSetCount)
01989       {
01990         //EV : 5/03/06: should be 'size' but 'from' or another variable !
01991         //fprintf(fd, "%sif (!status) %s = size;\n", ctx->get(), atc_cnt(name));
01992         return;
01993       }
01994 
01995     const char *classname = className(class_owner);
01996 
01997     fprintf(fd, "%sif (!status) {\n", ctx->get());
01998     ctx->push();
01999 
02000     if (is_raw_string)
02001       {
02002         if (IS_RAW() && !isVarDim())
02003           {
02004             fprintf(fd, "%sif (len == %d) {\n", ctx->get(), typmod.pdims);
02005             ctx->push();
02006           }
02007 
02008 #ifndef ATTR_CACHE_DIRECT
02009         fprintf(fd, "%sif (%s) free(%s->%s);\n", ctx->get(), atc_set(name),
02010                 atc_this(classname), atc_name(name));
02011 #endif
02012         fprintf(fd, "%s%s->%s = 1;\n", ctx->get(), atc_this(classname),
02013                 atc_set(name));
02014 
02015         if (IS_RAW())
02016           {
02017 #ifdef ATTR_CACHE_DIRECT
02018             fprintf(fd, "%s%s->%s = %s(%s);\n", ctx->get(),
02019                     atc_this(classname), atc_name(name),
02020                     ATTRNAME(name, tGet, *phints),
02021                     (isVarDim() ? "(unsigned int *)0" : ""));
02022 #else
02023             fprintf(fd, "%s%s->%s = rawdup(_%s, len);\n", ctx->get(),
02024                     atc_this(classname), atc_name(name), name);
02025 #endif
02026             if (isVarDim())
02027               fprintf(fd, "%s%s->%s = len;\n", ctx->get(),
02028                       atc_this(classname), atc_cnt(name));
02029             else
02030               {
02031                 ctx->pop();
02032                 fprintf(fd, "%s}\n", ctx->get());
02033               }
02034           }
02035         else
02036           {
02037 #ifdef ATTR_CACHE_DIRECT
02038             fprintf(fd, "%s%s->%s = %s();\n", ctx->get(),
02039                     atc_this(classname), atc_name(name),
02040                     ATTRNAME(name, tGet, *phints));
02041 #else
02042             if (isVarDim())
02043               fprintf(fd, "%s%s->%s = strdup((const char *)_%s);\n", ctx->get(),
02044                       atc_this(classname), atc_name(name), name);
02045             else
02046               fprintf(fd, "%s%s->%s = strdup((const char *)data);\n", ctx->get(),
02047                       atc_this(classname), atc_name(name));
02048 #endif
02049           }
02050         ctx->pop();
02051         fprintf(fd, "%s}\n", ctx->get());
02052         return;
02053       }
02054 
02055     fprintf(fd, "%s%s->%s", ctx->get(), atc_this(classname), atc_set(name));
02056     int i;
02057     for (i = 0; i < typmod.ndims; i++)
02058       fprintf(fd, "[a%d]", i);
02059 
02060     fprintf(fd, " = 1;\n");
02061     fprintf(fd, "%s%s->%s", ctx->get(), atc_this(classname), atc_name(name));
02062     for (i = 0; i < typmod.ndims; i++)
02063       fprintf(fd, "[a%d]", i);
02064 
02065     fprintf(fd, " = ");
02066 
02067     /*
02068       if (NOT_BASIC())
02069       fprintf(fd, "(%s *)__o", className(cls, True));
02070       else
02071       fprintf(fd, "(%s)__tmp", className(cls, False));
02072     */
02073 
02074     if (NOT_BASIC())
02075       fprintf(fd, "(%s *)_%s", className(cls, True), name);
02076     else
02077       fprintf(fd, "(%s)_%s", className(cls, False), name);
02078 
02079     fprintf(fd, ";\n");
02080     ctx->pop();
02081     fprintf(fd, "%s}\n", ctx->get());
02082   }
02083 
02084   Status Attribute::generateCode_C(Class *own,
02085                                    const GenCodeHints &hints,
02086                                    GenContext *ctxH,
02087                                    GenContext *ctxC)
02088   {
02089     FILE *fdh = ctxH->getFile();
02090     int ndims = typmod.ndims, i;
02091     int not_basic = NOT_BASIC();
02092     const char *ref1 = (not_basic ? getPtrSet() : " ");
02093     //    const char *ref2 = (not_basic ? " *" : " ");
02094     const char *ref2 = (not_basic ? getPtrRet() : " ");
02095     const char *comma = (ndims ? ", " : "");
02096     int is_string = IS_STRING();
02097     int is_raw = IS_RAW();
02098     const char *starg    = STATUS_PROTO(hints, False);
02099     const char *stargcom = STATUS_PROTO(hints, True);
02100     const char *classname = isIndirect() ?
02101       className(cls, True) : className(cls, False);
02102 
02103     // set method
02104     fprintf(fdh, "\n");
02105     if (is_string || is_raw) {
02106 #ifdef ODL_STD_STRING
02107       if (is_string)
02108         fprintf(fdh, "%seyedb::Status %s(const std::string &%s);\n", ctxH->get(),
02109                 ATTRNAME(name, tSet, hints), SARGIN());
02110       else
02111         fprintf(fdh, "%seyedb::Status %s(const %s *%s);\n", ctxH->get(),
02112                 ATTRNAME(name, tSet, hints), SCLASS(), SARGIN());
02113 #else
02114       fprintf(fdh, "%seyedb::Status %s(const %s *%s);\n", ctxH->get(),
02115               ATTRNAME(name, tSet, hints), SCLASS(), SARGIN());
02116 #endif
02117     }
02118 
02119 #ifdef NO_DIRECT_SET
02120     if (isIndirect() || !not_basic) // added 22/09/98
02121 #endif
02122       {
02123         fprintf(fdh, "%seyedb::Status %s(", ctxH->get(),
02124                 ATTRNAME_1(name, ATTRSET(cls), hints));
02125         dimArgsGen(fdh, ndims);
02126         if (cls->asEnumClass())
02127           fprintf(fdh, "%s%s%s, eyedb::Bool _check_value = eyedb::True);\n",
02128                   comma, classname, ref1);
02129         else
02130           fprintf(fdh, "%s%s%s);\n", comma, classname, ref1);
02131       }
02132 #ifdef NO_DIRECT_SET
02133     else
02134 #endif
02135 #if defined(SET_COUNT_DIRECT) || defined(NO_DIRECT_SET)
02136       // 23/05/06: suppressed !isIndirect()
02137       //      if (isVarDim() && !isIndirect() && !is_string) /*&& not_basic*/
02138       //if (isVarDim() && !isIndirect() && !is_string) /*&& not_basic*/
02139       if (isVarDim() && !is_string) /*&& not_basic*/
02140         {
02141           fprintf(fdh, "%seyedb::Status %s(",
02142                   ctxH->get(), ATTRNAME(name, tSetCount, hints));
02143 
02144           dimArgsGen(fdh, ndims);
02145           fprintf(fdh, ");\n");
02146         }
02147 #endif
02148 
02149     // get methods
02150     if (is_string || is_raw) {
02151 #ifdef ODL_STD_STRING
02152       if (is_string)
02153         fprintf(fdh, "%sstd::string %s(%seyedb::Bool *isnull = 0%s) const;\n",
02154                 ctxH->get(), ATTRNAME(name, tGet, hints), SARGOUT(),
02155                 stargcom);
02156       else
02157         fprintf(fdh, "%sconst %s *%s(%seyedb::Bool *isnull = 0%s) const;\n",
02158                 ctxH->get(), SCLASS(), ATTRNAME(name, tGet, hints), SARGOUT(),
02159                 stargcom);
02160 #else
02161       fprintf(fdh, "%sconst %s *%s(%seyedb::Bool *isnull = 0%s) const;\n",
02162               ctxH->get(), SCLASS(), ATTRNAME(name, tGet, hints), SARGOUT(),
02163               stargcom);
02164 #endif
02165     }
02166 
02167     fprintf(fdh, "%s%s%s%s(", ctxH->get(), classname, ref2,
02168             ATTRNAME_1(name, ATTRGET(cls), hints));
02169     dimArgsGen(fdh, ndims);
02170     fprintf(fdh, "%seyedb::Bool *isnull = 0%s) %s;\n", comma,
02171             stargcom, (!not_basic ? " const" : ""));
02172 
02173     if (cls->asCollectionClass()) {
02174       fprintf(fdh, "%sunsigned int %s(", ctxH->get(),
02175               ATTRNAME(name, tGetCount, hints));
02176       dimArgsGen(fdh, ndims);
02177       fprintf(fdh, "%seyedb::Bool *isnull = 0, eyedb::Status *rs = 0) const "
02178               "{const eyedb::Collection%s _coll = %s(", comma, getPtrRet(),ATTRNAME(name, tGetColl, hints));
02179       for (i = 0; i < ndims; i++)
02180         fprintf(fdh, "a%d, ", i);
02181       fprintf(fdh, "isnull, rs); ");
02182       fprintf(fdh, "return (!!_coll ? _coll->getCount() : 0);}\n");
02183     }
02184 
02185     if (not_basic) {
02186       fprintf(fdh, "%sconst %s%s%s(", ctxH->get(), classname, ref2,
02187               ATTRNAME_1(name, ATTRGET(cls), hints));
02188   
02189       dimArgsGen(fdh, ndims);
02190       fprintf(fdh, "%seyedb::Bool *isnull = 0%s) const;\n", comma,
02191               stargcom);
02192     }
02193 
02194     if (isIndirect()) {
02195       fprintf(fdh, "%seyedb::Oid %s(",
02196               ctxH->get(), ATTRNAME(name, tGetOid, hints));
02197       dimArgsGen(fdh, ndims);
02198       fprintf(fdh, "%s) const;\n", (ndims ? stargcom : starg));
02199       fprintf(fdh, "%seyedb::Status %s(",
02200               ctxH->get(), ATTRNAME(name, tSetOid, hints));
02201       dimArgsGen(fdh, ndims);
02202       fprintf(fdh, "%sconst eyedb::Oid &);\n", comma);
02203     }
02204 
02205     if (cls->asCollectionClass()) {
02206       Bool _isref;
02207       eyedblib::int16 _dim;
02208       Class *cl = const_cast<Class *>
02209         (cls->asCollectionClass()->getCollClass(&_isref, &_dim));
02210       const char *oclassname = _isref ?
02211         className(cl, True) : className(cl, False);
02212       Bool ordered;
02213 
02214       if (cls->asCollSetClass() || cls->asCollBagClass())
02215         ordered = False;
02216       else
02217         ordered = True;
02218 
02219       const char *where = (ordered ? "int where, " : "");
02220 
02221       if (_dim == 1) {
02222         fprintf(fdh, "%seyedb::Status %s(%s", ctxH->get(),
02223                 ATTRNAME_1(name, (ordered ? GenCodeHints::tSetItemInColl : GenCodeHints::tAddItemToColl), hints), where);
02224         dimArgsGen(fdh, ndims);
02225         fprintf(fdh, "%s%s%s%s, const eyedb::IndexImpl * = 0);\n", comma,
02226                 oclassname, (_isref || !cl->asBasicClass() ? getPtrRet() : " "),
02227                 (!*where ? ", eyedb::Bool noDup = eyedb::False" : ""));
02228 
02229         if (ordered) {
02230           fprintf(fdh, "%seyedb::Status %s(int where%s", ctxH->get(),
02231                   ATTRNAME(name, tUnsetItemInColl, hints),
02232                   (ndims >= 1 ? ", " : ""));
02233           dimArgsGen(fdh, ndims);
02234           fprintf(fdh, ");\n");
02235         }
02236         else
02237           {
02238             fprintf(fdh, "%seyedb::Status %s(%s", ctxH->get(),
02239                     ATTRNAME(name, tRmvItemFromColl, hints), where);
02240             dimArgsGen(fdh, ndims);
02241             fprintf(fdh, "%s%s%s%s);\n", comma, oclassname,
02242                     (_isref || !cl->asBasicClass() ? getPtrRet() : " "),
02243                     (!*where ? ", eyedb::Bool checkFirst = eyedb::False" : ""));
02244           }
02245       }
02246       else if (!strcmp(cl->getName(), char_class_name) && _dim > 1) {
02247         fprintf(fdh, "%seyedb::Status %s(%s", ctxH->get(),
02248                 ATTRNAME_1(name, (ordered ? GenCodeHints::tSetItemInColl : GenCodeHints::tAddItemToColl), hints), where);
02249 
02250         dimArgsGen(fdh, ndims);
02251         fprintf(fdh, "%sconst char *%s, const eyedb::IndexImpl * = 0);\n",
02252                 comma,
02253                 (!*where ? ", eyedb::Bool noDup = eyedb::False" : ""));
02254         if (ordered)
02255           fprintf(fdh, "%seyedb::Status %s(", ctxH->get(),
02256                   ATTRNAME(name, tUnsetItemInColl, hints));
02257         else
02258           fprintf(fdh, "%seyedb::Status %s(", ctxH->get(),
02259                   ATTRNAME(name, tRmvItemFromColl, hints));
02260 
02261         dimArgsGen(fdh, ndims);
02262         fprintf(fdh, "%sconst char *%s);\n", comma,
02263                 (!*where ? ", eyedb::Bool checkFirst = eyedb::False" : ""));
02264       }
02265 
02266       if (!cl->asBasicClass()) {
02267         fprintf(fdh, "%seyedb::Status %s(%s", ctxH->get(),
02268                 ATTRNAME_1(name, (ordered ? GenCodeHints::tSetItemInColl : GenCodeHints::tAddItemToColl), hints), where);
02269         dimArgsGen(fdh, ndims);
02270         fprintf(fdh, "%sconst eyedb::Oid &, const eyedb::IndexImpl * = 0);\n",
02271                 comma);
02272         fprintf(fdh, "%seyedb::Status %s(", ctxH->get(),
02273                 ATTRNAME_1(name, (ordered ? GenCodeHints::tUnsetItemInColl : GenCodeHints::tRmvItemFromColl), hints));
02274         dimArgsGen(fdh, ndims);
02275         fprintf(fdh, "%sconst eyedb::Oid &);\n", comma);
02276       }
02277 
02278       if (ordered) { // 24/09/05
02279         if (!strcmp(cl->getName(), char_class_name) && _dim > 1) {
02280           fprintf(fdh, "%sconst char *%s(unsigned int ind, ",
02281                   ctxH->get(),
02282                   ATTRNAME_1(name, (ordered ? GenCodeHints::tRetrieveItemAt : GenCodeHints::tGetItemAt), hints));
02283           dimArgsGen(fdh, ndims);
02284           fprintf(fdh, "%seyedb::Bool *isnull = 0, eyedb::Status *rs = 0) const;\n", comma);
02285         }
02286         else if (_dim == 1) {
02287           fprintf(fdh, "%sconst %s%s%s(unsigned int ind, ",
02288                   ctxH->get(),
02289                   oclassname, (_isref || !cl->asBasicClass() ? getPtrRet() : " "), 
02290                   ATTRNAME_1(name, (ordered ? GenCodeHints::tRetrieveItemAt : GenCodeHints::tGetItemAt), hints));
02291           dimArgsGen(fdh, ndims);
02292           fprintf(fdh, "%seyedb::Bool *isnull = 0, eyedb::Status *rs = 0) const;\n", comma);
02293           
02294           if (!cl->asBasicClass()) {
02295             fprintf(fdh, "%s%s%s%s(unsigned int ind, ",
02296                     ctxH->get(),
02297                     oclassname, (_isref || !cl->asBasicClass() ? getPtrRet() : " "),
02298                     ATTRNAME_1(name, (ordered ? GenCodeHints::tRetrieveItemAt : GenCodeHints::tGetItemAt), hints));
02299             dimArgsGen(fdh, ndims);
02300             fprintf(fdh, "%seyedb::Bool *isnull = 0, eyedb::Status *rs = 0);\n", comma);
02301           }
02302         }
02303       
02304         if (_isref) {
02305           fprintf(fdh, "%seyedb::Oid %s(unsigned int ind, ",
02306                   ctxH->get(),
02307                   ATTRNAME_1(name, (ordered ? GenCodeHints::tRetrieveOidItemAt : GenCodeHints::tGetOidItemAt) , hints));
02308           dimArgsGen(fdh, ndims);
02309           fprintf(fdh, "%seyedb::Status *rs = 0) const;\n", comma);
02310         }
02311       }
02312     }
02313 
02314     if (isVarDim() && !is_string)
02315       fprintf(fdh, "%sunsigned int %s(%s) const;\n", ctxH->get(),
02316               ATTRNAME(name, tGetCount, hints), starg);
02317 
02318     generateBody_C(own, ctxC, hints);
02319 
02320     return Success;
02321   }
02322 
02323   static void const_f0(FILE *fd, Class *parent, const char *var,
02324                        Bool fill = False)
02325   {
02326     if (!strcmp(parent->getName(), "struct"))
02327       fprintf(fd, "eyedb::Struct(%s)", var);
02328     else if (!strcmp(parent->getName(), "union"))
02329       fprintf(fd, "eyedb::Union(%s)", var);
02330     else
02331       fprintf(fd, "%s(%s, 1)", className(parent), var);
02332 
02333     if (fill)
02334       fprintf(fd, "\n{\n");
02335   }
02336 
02337   static void const_f01(FILE *fd, Class *parent, const char *var,
02338                         Bool fill = False)
02339   {
02340     if (!strcmp(parent->getName(), "struct"))
02341       fprintf(fd, "eyedb::Struct(%s, share)", var);
02342     else if (!strcmp(parent->getName(), "union"))
02343       fprintf(fd, "eyedb::Union(%s, share)", var);
02344     else
02345       fprintf(fd, "%s(%s, share, 1)", className(parent), var);
02346 
02347     if (fill)
02348       fprintf(fd, "\n{\n");
02349   }
02350 
02351   static void const_f1(FILE *fd, GenContext *ctx, const char *name, Bool share)
02352   {
02353     if (share)
02354       fprintf(fd, "%sif (!share)\n%s  {\n", ctx->get(), ctx->get());
02355 
02356     fprintf(fd, "%s%sheaderCode(eyedb::_Struct_Type, idr_psize, IDB_XINFO_LOCAL_OBJ);\n",
02357             ctx->get(), (share ? "    " : ""), name);
02358 
02359     fprintf(fd, "%s%seyedb::ClassPeer::newObjRealize(getClass(), this);\n", ctx->get(), (share ? "    " : ""));
02360     if (share)
02361       fprintf(fd, "%s  }\n\n", ctx->get());
02362 
02363     fprintf(fd, "%seyedb::ObjectPeer::setGRTObject(this, eyedb::True);\n", ctx->get());
02364   }
02365 
02366   Status AgregatClass::generateConstructors_C(GenContext *ctx)
02367   {
02368     FILE *fd = ctx->getFile();
02369 
02370     fprintf(fd, "%s::%s(eyedb::Database *_db, const eyedb::Dataspace *_dataspace) : ", name, name);
02371 
02372     const_f0(fd, parent, "_db, _dataspace", eyedb::True);
02373 
02374     if (attr_cache && !isRootClass())
02375       fprintf(fd, "%sattrCacheEmpty();\n", ctx->get());
02376     fprintf(fd, "%sinitialize(_db);\n", ctx->get());
02377     fprintf(fd, "}\n\n");
02378 
02379     if (attr_cache && !isRootClass())
02380       {
02381         fprintf(fd, "void %s::attrCacheEmpty()\n{\n", name);
02382         if (strcmp(getParent()->getName(), "struct") &&
02383             !getParent()->isRootClass())
02384           fprintf(fd, "%s%s::attrCacheEmpty();\n", ctx->get(),
02385                   getParent()->getCName());
02386 
02387         int i;
02388         for (i = 0; i < items_cnt; i++)
02389           if (items[i]->getClassOwner()->compare(this))
02390             items[i]->genAttrCacheEmpty(ctx);
02391         fprintf(fd, "}\n\n");
02392 
02393         fprintf(fd, "void %s::garbage()\n{\n", name);
02394         for (i = 0; i < items_cnt; i++)
02395           if (items[i]->getClassOwner()->compare(this))
02396             items[i]->genAttrCacheGarbage(ctx);
02397         fprintf(fd, "%s%s::garbage();\n", ctx->get(), getParent()->getCName());
02398         fprintf(fd, "}\n\n");
02399       }
02400 
02401     // changed the 12/10/00 because of a memory leaks
02402     /*
02403       fprintf(fd, "%s::%s(const Class *_cls, Data _idr)\n{\n",
02404       name, name);
02405     */
02406     fprintf(fd, "%s::%s(const eyedb::Class *_cls, eyedb::Data _idr)", name, name);
02407     if (strcmp(parent->getName(), "struct"))
02408       fprintf(fd, ": %s((eyedb::Database *)0, (const eyedb::Dataspace *)0, 1)", className(parent));
02409     fprintf(fd, "\n{\n");
02410     fprintf(fd, "%ssetClass((eyedb::Class *)_cls);\n\n", ctx->get());
02411 
02412     fprintf(fd, "%seyedb::Size idr_psize;\n", ctx->get());
02413     fprintf(fd, "%seyedb::Size idr_tsize = getClass()->getIDRObjectSize(&idr_psize);\n", ctx->get(), name);
02414     fprintf(fd, "%sif (_idr)\n", ctx->get());
02415     fprintf(fd, "%s  idr->setIDR(idr_tsize, _idr);\n", ctx->get());
02416     fprintf(fd, "%selse\n", ctx->get());
02417     fprintf(fd, "%s  {\n", ctx->get());
02418     // changed the 5/02/01
02419     //  fprintf(fd, "%s    idr->setIDR(idr->getSize());\n", ctx->get());
02420     fprintf(fd, "%s    idr->setIDR(idr_tsize);\n", ctx->get());
02421     fprintf(fd, "%s    memset(idr->getIDR() + IDB_OBJ_HEAD_SIZE, 0, idr->getSize() - IDB_OBJ_HEAD_SIZE);\n", ctx->get());
02422     fprintf(fd, "%s  }\n", ctx->get());
02423 
02424     fprintf(fd, "%sheaderCode(eyedb::_Struct_Type, idr_psize, IDB_XINFO_LOCAL_OBJ);\n", ctx->get(), name);
02425     fprintf(fd, "%seyedb::ClassPeer::newObjRealize(getClass(), this);\n", ctx->get());
02426     fprintf(fd, "%seyedb::ObjectPeer::setGRTObject(this, eyedb::True);\n", ctx->get());
02427     fprintf(fd, "%suserInitialize();\n", ctx->get());
02428     fprintf(fd, "}\n\n");
02429 
02430     fprintf(fd, "void %s::initialize(eyedb::Database *_db)\n{\n",
02431             name);
02432     fprintf(fd, "%ssetClass((_db ? _db->getSchema()->getClass(\"%s\") : %s%s));\n\n", ctx->get(), getAliasName(), name, classSuffix);
02433     fprintf(fd, "%seyedb::Size idr_psize;\n", ctx->get());
02434     //fprintf(fd, "%sidr->idr_sz = getClass()->getIDRObjectSize(&idr_psize);\n", ctx->get(), name);
02435     fprintf(fd, "%sidr->setIDR(getClass()->getIDRObjectSize(&idr_psize));\n",
02436             ctx->get(), name);
02437   
02438     //fprintf(fd, "%sidr->idr = (unsigned char *)malloc(idr->idr_sz * sizeof(unsigned char));\n\n", ctx->get());
02439     fprintf(fd, "%smemset(idr->getIDR() + IDB_OBJ_HEAD_SIZE, 0, idr->getSize() - IDB_OBJ_HEAD_SIZE);\n",
02440             ctx->get());
02441 
02442     const_f1(fd, ctx, name, False);
02443     if (attr_cache && !isRootClass())
02444       fprintf(fd, "%sattrCacheEmpty();\n", ctx->get());
02445     fprintf(fd, "%suserInitialize();\n", ctx->get());
02446     fprintf(fd, "}\n\n");
02447 
02448     fprintf(fd, "%s::%s(const %s& x) : %s(x)\n{\n",
02449             name, name, name, parent->getCName(), ctx->get());
02450     if (attr_cache && !isRootClass())
02451       fprintf(fd, "%sattrCacheEmpty();\n", ctx->get());
02452     fprintf(fd, "%suserCopy(x);\n", ctx->get());
02453     fprintf(fd, "}\n\n");
02454     fprintf(fd, "%s& %s::operator=(const %s& x)\n{\n", name, name, name);
02455     fprintf(fd, "%s*(%s *)this = %s::operator=((const %s &)x);\n",
02456             ctx->get(), parent->getCName(), parent->getCName(),  parent->getCName());
02457     if (attr_cache && !isRootClass())
02458       fprintf(fd, "%sattrCacheEmpty();\n", ctx->get());
02459     fprintf(fd, "%suserCopy(x);\n", ctx->get());
02460     fprintf(fd, "%sreturn *this;\n", ctx->get());
02461     fprintf(fd, "}\n\n", ctx->get());
02462 
02463     fprintf(fd, "%s::%s(const eyedb::Struct *x, eyedb::Bool share) : ",
02464             name, name, className(parent));
02465 
02466     const_f01(fd, parent, "x", True);
02467 
02468     fprintf(fd, "%ssetClass((db ? db->getSchema()->getClass(\"%s\") : %s%s));\n\n", ctx->get(), getAliasName(), name, classSuffix);
02469     fprintf(fd, "%seyedb::Size idr_psize;\n", ctx->get());
02470     fprintf(fd, "%sgetClass()->getIDRObjectSize(&idr_psize);\n", ctx->get(), name);
02471 
02472     const_f1(fd, ctx, name, True);
02473     if (attr_cache && !isRootClass())
02474       fprintf(fd, "%sattrCacheEmpty();\n", ctx->get());
02475     fprintf(fd, "%suserCopy(*x);\n", ctx->get());
02476     fprintf(fd, "}\n\n");
02477 
02478     fprintf(fd, "%s::%s(const %s *x, eyedb::Bool share) : ", name, name,
02479             name, className(parent));
02480 
02481     const_f01(fd, parent, "x", True);
02482 
02483     fprintf(fd, "%ssetClass((db ? db->getSchema()->getClass(\"%s\") : %s%s));\n\n", ctx->get(), getAliasName(), name, classSuffix);
02484 
02485     fprintf(fd, "%seyedb::Size idr_psize;\n", ctx->get());
02486     fprintf(fd, "%sgetClass()->getIDRObjectSize(&idr_psize);\n", ctx->get(), name);
02487     const_f1(fd, ctx, name, True);
02488     if (attr_cache && !isRootClass())
02489       fprintf(fd, "%sattrCacheEmpty();\n", ctx->get());
02490     fprintf(fd, "%suserCopy(*x);\n", ctx->get());
02491 
02492     fprintf(fd, "}\n\n");
02493     return Success;
02494   }
02495 
02496   Status AgregatClass::generateDownCasting_C(GenContext *ctx,
02497                                              Schema *m)
02498   {
02499     const LinkedList *list = m->getClassList();
02500     LinkedListCursor *curs = list->startScan();
02501     FILE *fd = ctx->getFile();
02502 
02503     Class *cl;
02504 
02505     while (list->getNextObject(curs, (void *&)cl))
02506       {
02507         Bool is;
02508         if (isSuperClassOf(cl, &is) == Success && is)
02509           {
02510             const char *s = className(cl);
02511             char body[128], body_const[128];
02512 
02513             if (cl == this)
02514               {
02515                 sprintf(body, " {return this;}\n");
02516                 strcpy(body_const, body);
02517               }
02518             else
02519               {
02520                 sprintf(body, " {return (%s *)0;}\n", s);
02521                 sprintf(body_const, " {return (const %s *)0;}\n", s);
02522               }
02523 
02524             fprintf(fd, "%svirtual %s *%s%s()%s", ctx->get(),
02525                     s, downCastPrefix, cl->getCanonicalName(), body);
02526           
02527             fprintf(fd, "%svirtual const %s *%s%s() const%s", ctx->get(),
02528                     s, downCastPrefix, cl->getCanonicalName(), body_const);
02529           }
02530       }
02531 
02532     return Success;
02533   }
02534 
02535   static int
02536   true_items_count(const Class *cls, Attribute **items, int items_cnt)
02537   {
02538     for (int i = 0; i < items_cnt; i++)
02539       if (items[i]->getClassOwner() == cls && !items[i]->isNative())
02540         return items_cnt - i;
02541 
02542     return 0;
02543   }
02544 
02545   Status
02546   AgregatClass::generateClassDesc_C(GenContext *ctx,
02547                                     const char *)
02548   {
02549     FILE *fd = ctx->getFile();
02550     Status status;
02551     const char *_type = (asStructClass() ? "Struct" : "Union");
02552 
02553     fprintf(fd, "static const eyedb::Attribute **%s_agritems;\n", name);
02554     fprintf(fd, "static eyedb::Size %s_idr_objsz, %s_idr_psize;\n\n", name, name);
02555 
02556     fprintf(fd, "static eyedb::%sClass *%s_make(eyedb::%sClass *%s_class = 0, eyedb::Schema *m = 0)\n{\n", _type, name, _type, name);
02557     ctx->push();
02558 
02559     fprintf(fd, "%sif (!%s_class)\n", ctx->get(), name);
02560     Class *parent_cl = parent->isRootClass() ? parent->getParent() : parent;
02561     fprintf(fd,"%s  return new eyedb::%sClass(\"%s\", (m ? m->getClass(\"%s\") : %s%s));\n", ctx->get(), _type, getAliasName(),
02562             (parent_cl->getAliasName() ?  parent_cl->getAliasName() : parent_cl->getName()),
02563             className(parent_cl), classSuffix);
02564     // changed the 30/05/01: was:
02565     // className(parent_cl, True, True), className(parent_cl), classSuffix);
02566 
02567     if (items_cnt)
02568       {
02569         fprintf(fd, "%seyedb::Attribute *attr[%d];\n", ctx->get(), items_cnt);
02570         int dims_declare = 0;
02571       
02572         int i;
02573         for (i = 0; i < items_cnt; i++)
02574           if (items[i]->class_owner == (void *)this && !items[i]->isNative())
02575             {
02576               if (!dims_declare)
02577                 {
02578                   dims_declare = 1;
02579                   fprintf(fd, "%sint *dims;\n", ctx->get());
02580                 }
02581               status = items[i]->generateClassDesc_C(ctx);
02582               if (status)
02583                 return status;
02584             }
02585       
02586         int count = true_items_count(this, items, items_cnt);
02587         fprintf(fd, "\n%s%s_class->setAttributes(&attr[%d], %d);\n", ctx->get(),
02588                 name, items_cnt - count, count);
02589 
02590         fprintf(fd, "\n");
02591 
02592         for (i = items_cnt - count; i < items_cnt; i++)
02593           fprintf(fd, "%sdelete attr[%d];\n", ctx->get(), i);
02594 
02595         fprintf(fd, "\n");
02596       }
02597     else
02598       fprintf(fd, "\n%s%s_class->setAttributes(0, 0);\n", ctx->get(), name);
02599 
02600     // should set implementation. Really necessary ?? Bof.
02601     /*
02602       if (idximpl->getType() == IndexImpl::Hash)
02603       fprintf(fd, "%sidximpl = new IndexImpl(IndexImpl::Hash, 0, "
02604       "%d, idximp
02605     */
02606 
02607     if (isSystem() || odl_system_class)
02608       fprintf(fd, "%seyedb::ClassPeer::setMType(%s_class, eyedb::Class::System);\n",
02609               ctx->get(), name);
02610 
02611     fprintf(fd, "\n%sreturn %s_class;\n}\n\n", ctx->get(),
02612             name);
02613 
02614     fprintf(fd, "eyedb::Object *%s_construct_x(const eyedb::Class *cls, eyedb::Data idr)\n{\n", name);
02615     fprintf(fd, "%sreturn new %s(cls, idr);\n", ctx->get(), name);
02616     fprintf(fd, "}\n\n");
02617 
02618     fprintf(fd, "eyedb::Object *%s_construct(const eyedb::Object *o, eyedb::Bool share)\n{\n", name);
02619     fprintf(fd, "%sreturn new %s((const eyedb::Struct *)o, share);\n", ctx->get(), name);
02620     fprintf(fd, "}\n\n");
02621 
02622     fprintf(fd, "static void %s_init_p()\n{\n", name);
02623     fprintf(fd, "%s%s%s = %s_make();\n", ctx->get(), name, classSuffix, name);
02624     fprintf(fd, "%sconstructors_x[class_ind] = %s_construct_x;\n", ctx->get(),
02625             name);
02626     fprintf(fd, "%sconstructors[class_ind] = %s_construct;\n", ctx->get(),
02627             name);
02628     fprintf(fd, "%shash->insert(\"%s\", class_ind++);\n", ctx->get(),
02629             getAliasName());
02630     fprintf(fd, "}\n\n");
02631 
02632     fprintf(fd, "static void %s_init()\n{\n", name);
02633     fprintf(fd, "%s%s_make(%s%s);\n\n", ctx->get(), name, name, classSuffix);
02634     fprintf(fd, "%s%s_agritems = %s%s->getAttributes();\n", ctx->get(),
02635             name, name, classSuffix);
02636     fprintf(fd, "%s%s_idr_objsz = %s%s->getIDRObjectSize(&%s_idr_psize, 0);\n\n",
02637             ctx->get(), name, name, classSuffix, name);
02638 
02639     fprintf(fd, "%seyedb::ObjectPeer::setUnrealizable(%s%s, eyedb::True);\n",
02640             ctx->get(), name, classSuffix);
02641     fprintf(fd, "}\n\n");
02642     ctx->pop();
02643     return Success;
02644   }
02645 
02646 #define NEW_ARGTYPE
02647 
02648   static inline void
02649   argTypeDump(GenContext *ctx, ArgType *argtype, const char *str)
02650   {
02651     FILE *fd = ctx->getFile();
02652 
02653 #ifdef NEW_ARGTYPE
02654     fprintf(fd, "%sargtype = %s;\n", ctx->get(), str);
02655 #else
02656     fprintf(fd, "%sargtype = new eyedb::ArgType();\n", ctx->get());
02657 #endif
02658 
02659     fprintf(fd, "%sargtype->setType((eyedb::ArgType_Type)%d, eyedb::False);\n",
02660             ctx->get(), argtype->getType());
02661 
02662     /*
02663       if ((argtype->getType() & ~(INOUT_ARG_TYPE|ARRAY_TYPE)) == OBJ_TYPE)
02664     */
02665     fprintf(fd, "%sargtype->setClname(\"%s\");\n", ctx->get(),
02666             argtype->getClname().c_str());
02667   }
02668 
02669   static void
02670   sign_declare_realize(FILE *fd, GenContext *ctx)
02671   {
02672     fprintf(fd, "%seyedb::Signature *sign;\n", ctx->get());
02673     fprintf(fd, "%seyedb::ArgType *argtype;\n\n", ctx->get());
02674   }
02675 
02676 #define dataspace_prologue(ctx, fd, x) \
02677 do { \
02678   Bool isnull; \
02679   short dspid = x->getDspid(&isnull); \
02680   if (!isnull) { \
02681     fprintf(fd, "%sstatus = db->getDataspace(%d, dataspace);\n", \
02682             ctx->get(), dspid); \
02683     fprintf(fd, "%sif (status) return status;\n", ctx->get()); \
02684   } \
02685   else \
02686     fprintf(fd, "%sdataspace = 0;;\n", ctx->get()); \
02687 } while(0)
02688 
02689 #define hints_prologue(ctx, fd, x) \
02690 do { \
02691   int cnt = x->getImplHintsCount(); \
02692   if (cnt) { \
02693     fprintf(fd, "%simpl_hints = new int[%d];\n", \
02694             ctx->get(), cnt); \
02695     for (int i = 0; i < cnt; i++) \
02696       fprintf(fd, "%simpl_hints[%d] = %d;\n", ctx->get(), i, \
02697               x->getImplHints(i)); \
02698   } \
02699 } while(0)
02700 
02701 
02702 #define hints_epilogue(ctx, fd, x) \
02703 do { \
02704   int cnt = x->getImplHintsCount(); \
02705   if (cnt) { \
02706     fprintf(fd, ", impl_hints, %d);\n", cnt); \
02707     fprintf(fd, "%sdelete [] impl_hints;\n", ctx->get());\
02708   } \
02709   else \
02710     fprintf(fd, "0, 0);\n"); \
02711 } while(0)
02712 
02713   void
02714   Class::compAddGenerate(GenContext *ctx, FILE *fd)
02715   {
02716     if (asAgregatClass()) {
02717       /*
02718         fprintf(fd, "%sif (cls->getOid().isValid()) {\n", ctx->get());
02719         fprintf(fd, "%s  if (status = comp->realize()) return status;\n", ctx->get());
02720         fprintf(fd, "%s} else\n", ctx->get());
02721       */
02722       fprintf(fd, "%scls->add(comp->getInd(), comp);\n\n", ctx->get());
02723     }
02724     else
02725       fprintf(fd, "%sif (status = comp->realize()) return status;\n\n", ctx->get());
02726   }
02727 
02728   Status Class::generateAttrComponent_C(GenContext *ctx)
02729   {
02730     if (!getUserData(odlGENCODE) && !getUserData(odlGENCOMP)) {
02731       printf("generateAttrComponent_C -> is system %s %p\n", name, this);
02732       return Success;
02733     }
02734 
02735     const LinkedList *list;
02736     Status s = getAttrCompList(list);
02737     if (s) return s;
02738 
02739     FILE *fd = ctx->getFile();
02740 
02741     fprintf(fd, "static eyedb::Status %s_attrcomp_realize(eyedb::Database *db, eyedb::Class *cls)\n{\n", name);
02742 
02743     ctx->push();
02744     if (list->getCount()) {
02745       fprintf(fd, "%seyedb::AttributeComponent *comp;\n", ctx->get());
02746       fprintf(fd, "%sconst eyedb::Dataspace *dataspace;\n", ctx->get());
02747       fprintf(fd, "%seyedb::ClassComponent *clcomp;\n", ctx->get());
02748       fprintf(fd, "%seyedb::Status status;\n", ctx->get());
02749       fprintf(fd, "%sint *impl_hints;\n", ctx->get());
02750     }
02751 
02752     LinkedListCursor c(list);
02753 
02754     AttributeComponent *comp;
02755     Bool setup_done = False;
02756     while (c.getNext((void *&)comp)){
02757       if (comp->asNotNullConstraint()) {
02758         NotNullConstraint *notnull = comp->asNotNullConstraint();
02759         fprintf(fd, "%scomp = new eyedb::NotNullConstraint(db, cls, \"%s\", %s);\n",
02760                 ctx->get(), notnull->getAttrpath().c_str(),
02761                 IDBBOOL_STR(notnull->getPropagate()));
02762       }
02763       else if (comp->asUniqueConstraint()) {
02764         UniqueConstraint *unique = comp->asUniqueConstraint();
02765         fprintf(fd, "%scomp = new eyedb::UniqueConstraint(db, cls, \"%s\", %s);\n",
02766                 ctx->get(), unique->getAttrpath().c_str(),
02767                 IDBBOOL_STR(unique->getPropagate()));
02768       }
02769       /*
02770         else if (comp->asCardinalityConstraint()) {
02771         CardinalityConstraint *card = comp->asCardinalityConstraint();
02772         CardinalityDescription *card_desc = card->getCardDesc();
02773         fprintf(fd, "%scomp = new CardinalityConstraint(db, cls, \"%s\", %d, %d, %d, %d);\n",
02774         ctx->get(), card->getAttrname(), card_desc->getBottom(),
02775         card_desc->getBottomExcl(),
02776         card_desc->getTop(), card_desc->getTopExcl());
02777         }
02778       */
02779       else if (comp->asBTreeIndex()) {
02780         BTreeIndex *idx = comp->asBTreeIndex();
02781         hints_prologue(ctx, fd, idx);
02782         dataspace_prologue(ctx, fd, idx);
02783         fprintf(fd, "%scomp = new eyedb::BTreeIndex(db, cls, \"%s\", %s, %s, dataspace, %d",
02784                 ctx->get(), idx->getAttrpath().c_str(),
02785                 IDBBOOL_STR(idx->getPropagate()),
02786                 IDBBOOL_STR(idx->getIsString()),
02787                 idx->getDegree());
02788         hints_epilogue(ctx, fd, idx);
02789       }
02790       else if (comp->asHashIndex()) {
02791         HashIndex *idx = comp->asHashIndex();
02792         if (idx->getHashMethod()) {
02793           // hack
02794           if (!setup_done) {
02795             fprintf(fd, "%sgetClass()->setSetupComplete(eyedb::True);\n", ctx->get());
02796             setup_done = True;
02797           }
02798           fprintf(fd, "%sstatus = getClass()->getComp(\"%s\", clcomp);\n",
02799                   ctx->get(), idx->getHashMethod()->getName().c_str());
02800           fprintf(fd, "%sif (status) return status;\n", ctx->get());
02801         }
02802         hints_prologue(ctx, fd, idx);
02803         dataspace_prologue(ctx, fd, idx);
02804         fprintf(fd, "%scomp = new eyedb::HashIndex(db, cls, \"%s\", %s, %s, dataspace, %d",
02805                 ctx->get(), idx->getAttrpath().c_str(),
02806                 IDBBOOL_STR(idx->getPropagate()),
02807                 IDBBOOL_STR(idx->getIsString()),
02808                 idx->getKeyCount());
02809       
02810         if (idx->getHashMethod())
02811           fprintf(fd, ", clcomp->asBEMethod_C()");
02812         else
02813           fprintf(fd, ", 0");
02814         hints_epilogue(ctx, fd, idx);
02815       }
02816       else if (comp->asCollAttrImpl()) {
02817         CollAttrImpl *collimpl = comp->asCollAttrImpl();
02818         if (collimpl->getHashMethod()) {
02819           // hack
02820           if (!setup_done) {
02821             fprintf(fd, "%sgetClass()->setSetupComplete(eyedb::True);\n", ctx->get());
02822             setup_done = True;
02823           }
02824           fprintf(fd, "%sstatus = getClass()->getComp(\"%s\", clcomp);\n",
02825                   ctx->get(), collimpl->getHashMethod()->getName().c_str());
02826           fprintf(fd, "%sif (status) return status;\n", ctx->get());
02827         }
02828         hints_prologue(ctx, fd, collimpl);
02829         dataspace_prologue(ctx, fd, collimpl);
02830         fprintf(fd, "%scomp = new eyedb::CollAttrImpl(db, cls, \"%s\", %s, dataspace, %s, %d",
02831                 ctx->get(), collimpl->getAttrpath().c_str(),
02832                 IDBBOOL_STR(collimpl->getPropagate()),
02833                 (collimpl->getIdxtype() == IndexImpl::Hash ?
02834                  "eyedb::IndexImpl::Hash" : "eyedb::IndexImpl::BTree"),
02835                 collimpl->getKeyCountOrDegree());
02836       
02837         if (collimpl->getHashMethod())
02838           fprintf(fd, ", clcomp->asBEMethod_C()");
02839         else
02840           fprintf(fd, ", 0");
02841         hints_epilogue(ctx, fd, collimpl);
02842       }
02843       else
02844         abort();
02845     
02846       compAddGenerate(ctx, fd);
02847     }
02848 
02849     fprintf(fd, "%sreturn eyedb::Success;\n", ctx->get());
02850 
02851     ctx->pop();
02852     fprintf(fd, "}\n\n");
02853     return Success;
02854   }
02855 
02856   Status Class::generateClassComponent_C(GenContext *ctx)
02857   {
02858     if (!getCompList() || !getCompList()->getCount())
02859       return Success;
02860 
02861     if (!getUserData(odlGENCODE) && !getUserData(odlGENCOMP)) {
02862       printf("generateClassComponent_C -> is system %s %p\n", name, this);
02863       return Success;
02864     }
02865 
02866     FILE *fd = ctx->getFile();
02867 
02868     Status status;
02869     //const char *_type = (asStructClass() ? "Struct" : "Union");
02870 
02871     fprintf(fd, "static eyedb::Status %s_comp_realize(eyedb::Database *db, eyedb::Class *cls)\n{\n", name);
02872 
02873     ctx->push();
02874     if (complist->getCount())
02875       {
02876         fprintf(fd, "%seyedb::ClassComponent *comp;\n", ctx->get());
02877         fprintf(fd, "%seyedb::Status status;\n", ctx->get());
02878       }
02879 
02880     int sign_declare = 0;
02881 
02882     LinkedListCursor c(complist);
02883 
02884     ClassComponent *comp;
02885     while (complist->getNextObject(&c, (void *&)comp))
02886       {
02887         if (comp->asCardinalityConstraint())
02888           {
02889             CardinalityConstraint *card = comp->asCardinalityConstraint();
02890             CardinalityDescription *card_desc = card->getCardDesc();
02891             fprintf(fd, "%scomp = new eyedb::CardinalityConstraint(db, cls, \"%s\", %d, %d, %d, %d);\n",
02892                     ctx->get(), card->getAttrname().c_str(), card_desc->getBottom(),
02893                     card_desc->getBottomExcl(),
02894                     card_desc->getTop(), card_desc->getTopExcl());
02895           }
02896         else if (comp->asTrigger())
02897           {
02898             Trigger *trig = comp->asTrigger();
02899             char *x = purge(trig->getEx()->getExtrefBody().c_str());
02900             fprintf(fd, "%scomp = new eyedb::Trigger(db, cls, (eyedb::TriggerType)%d, (eyedb::ExecutableLang)%d, %s, \"%s\", %s, \"%s\");\n",
02901                     ctx->get(), trig->getType(),
02902                     (trig->getEx()->getLang() & ~SYSTEM_EXEC),
02903                     STRBOOL(trig->getEx()->getLang() & SYSTEM_EXEC),
02904                     trig->getSuffix().c_str(),
02905                     trig->getLight() ? "eyedb::True" : "eyedb::False",
02906                     x);
02907             free(x);
02908           }
02909         else if (comp->asMethod())
02910           {
02911             Method *mth = comp->asMethod();
02912             Executable *ex = mth->getEx();
02913 
02914             if ((ex->getLang() & (C_LANG|SYSTEM_EXEC)) ==
02915                 (C_LANG|SYSTEM_EXEC) && !odl_system_class)
02916               continue;
02917 
02918             if (!sign_declare)
02919               {
02920                 sign_declare = 1;
02921                 sign_declare_realize(fd, ctx);
02922               }
02923 
02924             fprintf(fd, "%ssign = new eyedb::Signature();\n",
02925                     ctx->get());
02926             Signature *sign = ex->getSign();
02927             const char *prefix = ((ex->getLoc()&~STATIC_EXEC) == FRONTEND ? "FE" : "BE");
02928             const char *lang = ((ex->getLang() & C_LANG) ? "C"  : "OQL");
02929             char *extref = purge(ex->getExtrefBody().c_str());
02930 
02931 #ifdef NEW_ARGTYPE
02932             argTypeDump(ctx, sign->getRettype(), "sign->getRettype()");
02933 #else
02934             argTypeDump(ctx, sign->getRettype());
02935             fprintf(fd, "%ssign->setRettype(argtype);\n", ctx->get());
02936             fprintf(fd, "%sargtype->release();\n\n", ctx->get());
02937 #endif
02938 
02939             int nargs = sign->getNargs();
02940             fprintf(fd, "%ssign->setNargs(%d);\n", ctx->get(), nargs);
02941             fprintf(fd, "%ssign->setTypesCount(%d);\n", ctx->get(), nargs);
02942             int i;
02943             for (i = 0; i < nargs; i++)
02944               {
02945 #ifdef NEW_ARGTYPE
02946                 char tok[128];
02947                 sprintf(tok, "sign->getTypes(%d)", i);
02948                 argTypeDump(ctx, sign->getTypes(i), tok);
02949 #else
02950                 argTypeDump(ctx, sign->getTypes(i));
02951                 fprintf(fd, "%ssign->setTypes(%d, argtype);\n", ctx->get(),
02952                         i);
02953                 fprintf(fd, "%sargtype->release();\n\n", ctx->get());
02954 #endif
02955               }
02956 
02957             fprintf(fd,
02958                     "%scomp = new eyedb::%sMethod_%s(db, cls, \"%s\", sign, %s, %s, \"%s\");\n",
02959                     ctx->get(), prefix, lang, ex->getExname().c_str(),
02960                     STRBOOL(ex->isStaticExec()),
02961                     STRBOOL(ex->getLang() & SYSTEM_EXEC),
02962                     extref);
02963             free(extref);
02964           }
02965         else
02966           abort();
02967 
02968         compAddGenerate(ctx, fd);
02969 
02970         if (comp->asMethod())
02971           fprintf(fd, "%ssign->release();\n\n", ctx->get());
02972       }
02973 
02974     fprintf(fd, "%sreturn eyedb::Success;\n", ctx->get());
02975 
02976     ctx->pop();
02977     fprintf(fd, "}\n\n");
02978     return Success;
02979   }
02980 
02981   Status AgregatClass::generateConstructors_C(GenContext *ctxH,
02982                                               GenContext *ctxC)
02983   {
02984     FILE *fdh = ctxH->getFile();
02985 
02986     fprintf(fdh, "%s%s(eyedb::Database * = 0, const eyedb::Dataspace * = 0);\n", ctxH->get(), name);
02987 
02988     fprintf(fdh, "%s%s(const %s& x);\n\n", ctxH->get(), name, name);
02989 
02990     if (isRootClass()) {
02991       fprintf(fdh, "%svirtual eyedb::Object *clone() const "
02992               "{return _clone();};\n", ctxH->get(), name);
02993       fprintf(fdh, "%svirtual eyedb::Object *_clone() const "
02994               "{return new %s(*this);};\n\n", ctxH->get(), name);
02995     }
02996     else if (odl_rootclass) { // ctxC->getRootclass()) {
02997       fprintf(fdh, "%svirtual eyedb::Object *_clone() const "
02998               "{return new %s(*this);};\n\n", ctxH->get(), name);
02999     }
03000     else {
03001       fprintf(fdh, "%svirtual eyedb::Object *clone() const "
03002               "{return new %s(*this);};\n\n", ctxH->get(), name);
03003     }
03004 
03005     fprintf(fdh, "%s%s& operator=(const %s& x);\n\n", ctxH->get(), name, name);
03006 
03007     generateConstructors_C(ctxC);
03008 
03009     return Success;
03010   }
03011 
03012   Status
03013   AgregatClass::generateMethodDecl_C(Schema *m, GenContext *ctx)
03014   {
03015     FILE *fd = ctx->getFile();
03016     LinkedListCursor c(complist);
03017 
03018     ClassComponent *comp;
03019 
03020     while (c.getNext((void *&)comp))
03021       if (comp->asMethod())
03022         {
03023           Method *mth = comp->asMethod();
03024           Executable *ex = mth->getEx();
03025 
03026           if (!(ex->getLang() & C_LANG))
03027             continue;
03028 
03029           if (!mth->getUserData())
03030             continue;
03031 
03032           Signature *sign = ex->getSign();
03033         
03034           if (sign->getUserData()) {
03035             odlMethodHints *mth_hints = ((odlSignUserData *)sign->getUserData())->mth_hints;
03036             if (mth_hints->calledFrom != odlMethodHints::ANY_HINTS &&
03037                 mth_hints->calledFrom != odlMethodHints::C_HINTS)
03038               continue;
03039           }
03040 
03041           if (ex->isStaticExec()) {
03042             fprintf(fd, "%sstatic eyedb::Status %s(eyedb::Database *db", ctx->get(),
03043                     ex->getExname().c_str());
03044             if (sign->getNargs() || !Signature::isVoid(sign->getRettype()))
03045               fprintf(fd, ", ");
03046           }
03047           else
03048             fprintf(fd, "%svirtual eyedb::Status %s(", ctx->get(), ex->getExname().c_str());
03049 
03050           sign->declArgs(fd, m);
03051           fprintf(fd, ");\n\n");
03052         }
03053 
03054     return Success;
03055   }
03056 
03057   Status
03058   AgregatClass::generateMethodFetch_C(GenContext *ctx, Method *mth)
03059   {
03060     FILE *fd = ctx->getFile();
03061     fprintf(fd, "%sif (!mth)\n", ctx->get());
03062     fprintf(fd, "%s{\n", ctx->get());
03063     ctx->push();
03064     fprintf(fd, "%sstatus = eyedb::Method::get(db, "
03065             "db->getSchema()->getClass(\"%s\"), \"%s\", %s, mth);\n",
03066             ctx->get(), (getAliasName() ? getAliasName() : getName()),
03067             mth->getPrototype(False),
03068             STRBOOL(mth->getEx()->isStaticExec()));
03069 
03070     fprintf(fd, "%sif (status) return status;\n", ctx->get());
03071 
03072     fprintf(fd, "%sif (!mth)\n", ctx->get());
03073     fprintf(fd, "%s  return eyedb::Exception::make(eyedb::IDB_ERROR, "
03074             "\"method '%s' not found\");\n", ctx->get(), mth->getPrototype());
03075     ctx->pop();
03076     fprintf(fd, "%s}\n\n", ctx->get());
03077 
03078     return Success;
03079   }
03080 
03081   Status
03082   AgregatClass::generateMethodBodyFE_C(Schema *m,
03083                                        GenContext *ctx, Method *mth)
03084   {
03085     FILE *fd = ctx->getFile();
03086     Executable *ex = mth->getEx();
03087     Signature *sign = ex->getSign();
03088 
03089     fprintf(fd, "eyedb::Status %s::%s(", name, ex->getExname().c_str());
03090     if (ex->isStaticExec()) {
03091       fprintf(fd, "eyedb::Database *db");
03092       if (sign->getNargs() || !Signature::isVoid(sign->getRettype()))
03093         fprintf(fd, ", ");
03094     }
03095     sign->declArgs(fd, m);
03096     fprintf(fd, ")\n{\n");
03097     ctx->push();
03098 
03099     fprintf(fd, "%sstatic eyedb::Method *mth;\n", ctx->get());
03100     fprintf(fd, "%seyedb::Status status;\n", ctx->get());
03101 
03102     generateMethodFetch_C(ctx, mth);
03103 
03104 #ifdef NEW_ARGARR
03105     fprintf(fd, "%sstatic eyedb::ArgArray *argarr = new eyedb::ArgArray(%d, eyedb::Argument::AutoFullGarbage);\n\n",
03106             ctx->get(), sign->getNargs());
03107     sign->setArgs(fd, m, IN_ARG_TYPE, "(*argarr)[%d]->", "retarg.", ctx->get());
03108     fprintf(fd, "\n%seyedb::Argument __retarg;\n", ctx->get());
03109     fprintf(fd, "%sstatus = mth->applyTo(db, %s, *argarr, __retarg, eyedb::False);\n\n",
03110             ctx->get(), (mth->getEx()->isStaticExec() ? "0" : "this"));
03111     fprintf(fd, "%sif (status) return status;\n\n", ctx->get());
03112     sign->retArgs(fd, m, "(*argarr)[%d]->", "__retarg.", ctx->get());
03113 #else
03114     fprintf(fd, "%seyedb::ArgArray argarr(%d, eyedb::Argument::AutoFullGarbage);\n\n",
03115             ctx->get(), sign->getNargs());
03116     sign->setArgs(fd, m, IN_ARG_TYPE, "argarr[%d]->", "retarg.", ctx->get());
03117     fprintf(fd, "\n%seyedb::Argument __retarg;\n", ctx->get());
03118     fprintf(fd, "%sstatus = mth->applyTo(db, %s, argarr, __retarg, eyedb::False);\n\n",
03119             ctx->get(), (mth->getEx()->isStaticExec() ? "0" : "this"));
03120     fprintf(fd, "%sif (status) return status;\n\n", ctx->get());
03121     sign->retArgs(fd, m, "argarr[%d]->", "__retarg.", ctx->get());
03122 #endif
03123 
03124     fprintf(fd, "%sreturn eyedb::Success;\n}\n\n", ctx->get());
03125     ctx->pop();
03126 
03127     return Success;
03128   }
03129 
03130   static void
03131   userImpl(FILE *fd)
03132   {
03133     fprintf(fd, "  _packageInit(_db);\n");
03134     fprintf(fd, "\n  //\n  // User Implementation\n  //\n\n");
03135     fprintf(fd, "  return eyedb::Success;\n");
03136   }
03137 
03138   Status
03139   Class::generateMethodBodyFE_C(Schema *m,
03140                                 GenContext *ctx, Method *mth)
03141   {
03142     return Success;
03143   }
03144 
03145   Status
03146   Class::generateMethodBodyBE_C(Schema *m,
03147                                 GenContext *ctxStubs,
03148                                 GenContext *ctxMth,
03149                                 Method *mth)
03150   {
03151     FILE *fdstubs = ctxStubs->getFile();
03152     FILE *fdmth = ctxMth->getFile();
03153     Executable *ex = mth->getEx();
03154 
03155     Signature *sign = ex->getSign();
03156     const char *intname =
03157       Executable::makeInternalName(ex->getExname().c_str(),
03158                                    sign,
03159                                    (mth->getEx()->isStaticExec() ? True:
03160                                     False),
03161                                    (getAliasName() ?
03162                                     getAliasName() : getName()));
03163   
03164     //const char *prefix = (mth->asFEMethod_C() ? "FE" : "BE");
03165     const char *prefix = ((ex->getLoc()&~STATIC_EXEC) == FRONTEND ? "FE" : "BE");
03166     const char *lang = ((ex->getLang() & C_LANG) ? "C"  : "OQL");
03167 
03168     fprintf(fdmth, "//\n// %s [%s.cc]\n//\n\n", mth->getPrototype(),
03169             mth->getEx()->getExtrefBody().c_str());
03170     fprintf(fdmth, "Status\n");
03171     fprintf(fdmth, "__%s(eyedb::Database *_db, eyedb::%sMethod_%s *_m%s",
03172             intname,
03173             prefix, lang,
03174             (ex->isStaticExec() ? "" : ", eyedb::Object *_o"));
03175     
03176     if (sign->getNargs() || !Signature::isVoid(sign->getRettype()))
03177       fprintf(fdmth, ", ");
03178 
03179     sign->declArgs(fdmth, m);
03180 
03181     fprintf(fdmth, ")\n{\n");
03182     userImpl(fdmth);
03183     fprintf(fdmth, "}\n\n");
03184 
03185     fprintf(fdstubs, "extern eyedb::Status __%s(eyedb::Database *_db, "
03186             "eyedb::%sMethod_%s *_m%s",
03187             intname,
03188             prefix, lang,
03189             (ex->isStaticExec() ? "" : ", eyedb::Object *_o"));
03190 
03191     if (sign->getNargs() || !Signature::isVoid(sign->getRettype()))
03192       fprintf(fdstubs, ", ");
03193 
03194     sign->declArgs(fdstubs, m);
03195     fprintf(fdstubs, ");\n\n");
03196   
03197     fprintf(fdstubs, "extern \"C\" eyedb::Status\n");
03198     fprintf(fdstubs, "%s(eyedb::Database *_db, eyedb::%sMethod_%s *_m, "
03199             "eyedb::Object *_o, eyedb::ArgArray &_array, eyedb::Argument &__retarg)\n{\n",
03200             intname,
03201             prefix, lang);
03202 
03203     ctxStubs->push();
03204     fprintf(fdstubs, "%seyedb::Status status;\n\n", ctxStubs->get());
03205 
03206     sign->initArgs(fdstubs, m, "_array[%d]->", "_retarg", ctxStubs->get());
03207 
03208     fprintf(fdstubs, "\n%sstatus = __%s(_db, _m%s", ctxStubs->get(), intname,
03209             (ex->isStaticExec() ? "" : ", _o"));
03210 
03211     if (sign->getNargs() || !Signature::isVoid(sign->getRettype()))
03212       fprintf(fdstubs, ", ");
03213 
03214     sign->listArgs(fdstubs, m);
03215 
03216     fprintf(fdstubs, ");\n");
03217 
03218     fprintf(fdstubs, "%sif (status) return status;\n\n", ctxStubs->get());
03219 
03220     sign->setArgs(fdstubs, m, OUT_ARG_TYPE, "_array[%d]->", "__retarg.",
03221                   ctxStubs->get());
03222 
03223     fprintf(fdstubs, "%sreturn eyedb::Success;\n}\n\n", ctxStubs->get());
03224     ctxStubs->pop();
03225 
03226     return Success;
03227   }
03228 
03229   Status
03230   Class::generateTriggerBody_C(Schema *m,
03231                                GenContext *ctxMth,
03232                                Trigger *trig)
03233   {
03234     FILE *fdmth = ctxMth->getFile();
03235 
03236     fprintf(fdmth, "//\n// %s\n//\n\n", trig->getPrototype());
03237     fprintf(fdmth, "extern \"C\"\n");
03238     fprintf(fdmth, "eyedb::Status %s(eyedb::TriggerType type, eyedb::Database *_db, "
03239             "const eyedb::Oid &oid, eyedb::Object *o)\n{\n",
03240             trig->getCSym());
03241     userImpl(fdmth);
03242     fprintf(fdmth, "}\n\n");
03243     return Success;
03244   }
03245 
03246   Status
03247   Class::generateMethodBody_C(Schema *m,
03248                               GenContext *ctx,
03249                               GenContext *ctxStubsFe,
03250                               GenContext *ctxStubsBe,
03251                               GenContext *ctxMthFe,
03252                               GenContext *ctxMthBe)
03253   {
03254     if (!getUserData(odlGENCODE) && !getUserData(odlGENCOMP))
03255       return Success;
03256 
03257     LinkedListCursor c(complist);
03258 
03259     ClassComponent *comp;
03260 
03261     while (c.getNext((void *&)comp))
03262       if (comp->asMethod()) {
03263         Method *mth = comp->asMethod();
03264         if (!(mth->getEx()->getLang() & C_LANG))
03265           continue;
03266 
03267         Signature *sign = mth->getEx()->getSign();
03268 
03269         if (mth->asBEMethod())
03270           generateMethodBodyBE_C(m, ctxStubsBe, ctxMthBe, mth);
03271         else
03272           generateMethodBodyBE_C(m, ctxStubsFe, ctxMthFe, mth);
03273 
03274         if (!mth->getUserData())
03275           continue;
03276 
03277         if (sign->getUserData()) {
03278           odlMethodHints *mth_hints = ((odlSignUserData *)sign->getUserData())->mth_hints;
03279           if (mth_hints->calledFrom != odlMethodHints::ANY_HINTS &&
03280               mth_hints->calledFrom != odlMethodHints::C_HINTS)
03281             continue;
03282         }
03283         generateMethodBodyFE_C(m, ctx, mth);
03284       }
03285       else if (comp->asTrigger())
03286         generateTriggerBody_C(m, ctxMthBe, comp->asTrigger());
03287 
03288     return Success;
03289   }
03290 
03291   Status
03292   Class::generateCode_C(Schema *m,
03293                         const char *prefix,
03294                         const GenCodeHints &hints,
03295                         const char *stubs,
03296                         FILE *fdh,
03297                         FILE *fdc, FILE *fdstubsfe,
03298                         FILE *fdstubsbe,
03299                         FILE *fdmthfe,
03300                         FILE *fdmthbe)
03301   {
03302     GenContext ctxH(fdh), ctxC(fdc), ctxStubsFe(fdstubsfe),
03303       ctxStubsBe(fdstubsbe), ctxMthFe(fdmthfe), ctxMthBe(fdmthbe);
03304 
03305     ctxC.push();
03306     generateMethodBody_C(m, &ctxC, &ctxStubsFe, &ctxStubsBe,
03307                          &ctxMthFe, &ctxMthBe);
03308     ctxC.pop();
03309 
03310     generateClassComponent_C(&ctxC);
03311     generateAttrComponent_C(&ctxC);
03312 
03313     return Success;
03314   }
03315 
03316   Status
03317   AgregatClass::generateCode_C(Schema *m,
03318                                const char *prefix,
03319                                const GenCodeHints &hints,
03320                                const char *stubs,
03321                                FILE *fdh,
03322                                FILE *fdc, FILE *fdstubsfe,
03323                                FILE *fdstubsbe,
03324                                FILE *fdmthfe,
03325                                FILE *fdmthbe)
03326   {
03327     GenContext ctxH(fdh), ctxC(fdc), ctxStubsFe(fdstubsfe),
03328       ctxStubsBe(fdstubsbe), ctxMthFe(fdmthfe), ctxMthBe(fdmthbe);
03329 
03330     int i;
03331     Status status;
03332 
03333     phints = &hints;
03334     class_enums = hints.class_enums;
03335     attr_cache  = hints.attr_cache;
03336 
03337     if (getUserData(odlGENCODE))
03338       generateClassDesc_C(&ctxC, "");
03339 
03340     generateClassComponent_C(&ctxC);
03341     generateAttrComponent_C(&ctxC);
03342 
03343     if (!getUserData(odlGENCODE))
03344       return Success;
03345 
03346     fprintf(fdh, "class %s : public %s {\n", name, className(parent));
03347 
03348     ctxH.push();
03349 
03350     if (stubs)
03351       fprintf(fdh, "#include \"%s\"\n", stubs);
03352 
03353 #ifndef NO_COMMENTS
03354     fprintf(fdh, "\n%s// ----------------------------------------------------------------------\n", ctxH.get());
03355     fprintf(fdh, "%s// %s Interface\n", ctxH.get(), name);
03356     fprintf(fdh, "%s// ----------------------------------------------------------------------\n", ctxH.get());
03357 #else
03358     fprintf(fdh, "\n");
03359 #endif
03360     fprintf(fdh, " public:\n");
03361   
03362     ctxC.push();
03363 
03364     generateConstructors_C(&ctxH, &ctxC);
03365 
03366     if (hints.gen_down_casting)
03367       generateDownCasting_C(&ctxH, m);
03368 
03369     for (i = 0; i < items_cnt; i++)
03370       {
03371         if (items[i]->class_owner == (void *)this)
03372           {
03373             status = items[i]->generateCode_C(this, hints, &ctxH, &ctxC);
03374             if (status)
03375               return status;
03376           }
03377       }
03378 
03379     ctxC.pop();
03380     generateMethodBody_C(m, &ctxC, &ctxStubsFe, &ctxStubsBe,
03381                          &ctxMthFe, &ctxMthBe);
03382     ctxC.push();
03383 
03384     /* include file */
03385 
03386     generateMethodDecl_C(m, &ctxH);
03387 
03388     fprintf(fdh, "%svirtual ~%s() {garbageRealize();}\n", ctxH.get(),
03389             name);
03390 
03391     if (attr_cache)
03392       fprintf(fdh, "\n%svoid attrCacheEmpty();\n", ctxH.get());
03393 
03394     if (getTiedCode())
03395       {
03396 #ifndef NO_COMMENTS
03397         fprintf(fdh, "\n%s// ----------------------------------------------------------------------\n", ctxH.get());
03398 #endif
03399         fprintf(fdh, "%s// %s User Part\n", ctxH.get(), name);
03400 #ifndef NO_COMMENTS
03401         fprintf(fdh, "%s// ----------------------------------------------------------------------\n", ctxH.get());
03402 #endif
03403         fprintf(fdh, "%s\n", getTiedCode());
03404       }
03405 
03406 #ifndef NO_COMMENTS
03407     fprintf(fdh, "\n%s// ----------------------------------------------------------------------\n", ctxH.get());
03408     fprintf(fdh, "%s// %s Protected Part\n", ctxH.get(), name);
03409     fprintf(fdh, "%s// ----------------------------------------------------------------------\n", ctxH.get());
03410 #else
03411     fprintf(fdh, "\n");
03412 #endif
03413     fprintf(fdh, " protected:\n");
03414 
03415     if (attr_cache && !isRootClass())
03416       fprintf(fdh, "%svirtual void garbage();\n", ctxH.get());
03417 
03418     //  fprintf(fdh, "%s%s(Database *_db, int) : ", ctxH.get(), name);
03419     fprintf(fdh, "%s%s(eyedb::Database *_db, const eyedb::Dataspace *_dataspace, int) : ", ctxH.get(), name);
03420 
03421     const_f0(fdh, parent, "_db, _dataspace");
03422 
03423     fprintf(fdh, " {}\n");
03424     fprintf(fdh, "%s%s(const eyedb::Struct *x, eyedb::Bool share, int) : ",
03425             ctxH.get(), name);
03426     const_f01(fdh, parent, "x");
03427     fprintf(fdh, " {}\n");
03428 
03429     fprintf(fdh, "%s%s(const %s *x, eyedb::Bool share, int) : ", ctxH.get(), name, name);
03430     const_f01(fdh, parent, "x");
03431 
03432     fprintf(fdh, " {}\n");
03433 
03434 #ifndef NO_COMMENTS
03435     fprintf(fdh, "\n%s// ----------------------------------------------------------------------\n", ctxH.get());
03436     fprintf(fdh, "%s// %s Private Part\n", ctxH.get(), name);
03437     fprintf(fdh, "%s// ----------------------------------------------------------------------\n", ctxH.get());
03438 #else
03439     fprintf(fdh, "\n");
03440 #endif
03441 
03442     fprintf(fdh, " private:\n", ctxH.get());
03443   
03444     fprintf(fdh, "%svoid initialize(eyedb::Database *_db);\n", ctxH.get());
03445 
03446     if (attr_cache)
03447       {
03448         fprintf(fdh, "\n");
03449         int i;
03450         for (i = 0; i < items_cnt; i++)
03451           if (items[i]->getClassOwner()->compare(this))
03452             items[i]->genAttrCacheDecl(&ctxH);
03453       }
03454 
03455     fprintf(fdh, "\n public: /* restricted */\n", ctxH.get());
03456     fprintf(fdh, "%s%s(const eyedb::Struct *, eyedb::Bool = eyedb::False);\n",
03457             ctxH.get(), name);
03458     fprintf(fdh, "%s%s(const %s *, eyedb::Bool = eyedb::False);\n",
03459             ctxH.get(), name, name);
03460     fprintf(fdh, "%s%s(const eyedb::Class *, eyedb::Data);\n", ctxH.get(), name);
03461 
03462     fprintf(fdh, "};\n\n");
03463 
03464     ctxH.pop();
03465     ctxC.pop();
03466 
03467     return Success;
03468   }
03469 
03470   Status EnumClass::generateClassDesc_C(GenContext *ctx)
03471   {
03472     FILE *fd = ctx->getFile();
03473     Status status;
03474 
03475     fprintf(fd, "static eyedb::Size %s_idr_objsz, %s_idr_psize;\n\n", name, name);
03476 
03477     fprintf(fd, "static eyedb::EnumClass *%s_make(eyedb::EnumClass *%s_class = 0, eyedb::Schema *m = 0)\n{\n", name, name);
03478 
03479     ctx->push();
03480     fprintf(fd, "%sif (!%s_class)\n", ctx->get(), name);
03481     fprintf(fd, "%s  return new eyedb::EnumClass(\"%s\");\n", ctx->get(), getAliasName());
03482 
03483     fprintf(fd, "%seyedb::EnumItem *en[%d];\n", ctx->get(), items_cnt);
03484 
03485     int i;
03486     for (i = 0; i < items_cnt; i++)
03487       fprintf(fd, "%sen[%d] = new eyedb::EnumItem(\"%s\", \"%s\", (unsigned int)%d);\n",
03488               ctx->get(),
03489               i, items[i]->getName(), items[i]->getAliasName(),
03490               items[i]->getValue());
03491   
03492     fprintf(fd, "\n%s%s_class->setEnumItems(en, %d);\n", ctx->get(),
03493             name, items_cnt);
03494 
03495     fprintf(fd, "\n");
03496     for (i = 0; i < items_cnt; i++)
03497       fprintf(fd, "%sdelete en[%d];\n", ctx->get(), i);
03498     fprintf(fd, "\n");
03499 
03500     if (isSystem() || odl_system_class)
03501       fprintf(fd, "%seyedb::ClassPeer::setMType(%s_class, eyedb::Class::System);\n",
03502               ctx->get(), name);
03503 
03504     fprintf(fd, "\n%sreturn %s_class;\n}\n\n", ctx->get(), name);
03505 
03506     fprintf(fd, "static void %s_init_p()\n{\n", name);
03507     fprintf(fd, "%s%s%s = %s_make();\n", ctx->get(), name, classSuffix, name);
03508     fprintf(fd, "}\n\n");
03509 
03510     fprintf(fd, "static void %s_init()\n{\n", name);
03511     fprintf(fd, "%s%s_make(%s%s);\n\n", ctx->get(), name, name, classSuffix);
03512 
03513     fprintf(fd, "%s%s_idr_objsz = %s%s->getIDRObjectSize(&%s_idr_psize, 0);\n\n",
03514             ctx->get(), name, name, classSuffix, name);
03515 
03516     fprintf(fd, "%seyedb::ObjectPeer::setUnrealizable(%s%s, eyedb::True);\n",
03517             ctx->get(), name, classSuffix);
03518     fprintf(fd, "}\n\n");
03519     ctx->pop();
03520 
03521     return Success;
03522   }
03523 
03524   Status
03525   EnumClass::generateCode_C(Schema *,
03526                             const char *prefix,
03527                             const GenCodeHints &hints,
03528                             const char *stubs,
03529                             FILE *fdh, FILE *fdc, FILE *,
03530                             FILE *, FILE *, FILE *)
03531   {
03532     GenContext ctxH(fdh), ctxC(fdc);
03533     int i;
03534     Status status;
03535 
03536     phints = &hints;
03537     class_enums = hints.class_enums;
03538     attr_cache  = hints.attr_cache;
03539 
03540     generateClassDesc_C(&ctxC);
03541 
03542     ctxH.push();
03543     ctxC.push();
03544 
03545     //  fprintf(fdh, "\n");
03546 
03547     const char *indent_str;
03548 
03549     if (class_enums) {
03550       fprintf(fdh, "class %s {\n", name);
03551       fprintf(fdh, "\npublic:\n");
03552       fprintf(fdh, "  enum %s {\n", enum_type);
03553       indent_str = "    ";
03554     }
03555     else {
03556       fprintf(fdh, "enum %s {\n", name);
03557       indent_str = "  ";
03558     }
03559 
03560     EnumItem **it;
03561     for (i = 0, it = items; i < items_cnt; i++, it++)
03562       {
03563         if (i) fprintf(fdh, ",\n");
03564         fprintf(fdh, "%s%s = %d", indent_str, 
03565                 (*it)->getAliasName(), (*it)->getValue());
03566       }
03567 
03568     if (class_enums)
03569       fprintf(fdh, "\n  };");
03570 
03571     fprintf(fdh, "\n};\n\n");
03572 
03573     ctxH.pop();
03574     ctxC.pop();
03575 
03576     return Success;
03577   }
03578 
03579   Status CollectionClass::generateCode_C(Schema *,
03580                                          const char *prefix,
03581                                          const GenCodeHints &hints,
03582                                          const char *stubs,
03583                                          FILE *fdh,
03584                                          FILE *fdc, FILE *, FILE *,
03585                                          FILE *, FILE *)
03586   {
03587     GenContext ctxH(fdh), ctxC(fdc);
03588     int i;
03589     Status status;
03590     const char *c_name = getCName();
03591     const char *_type = getCSuffix();
03592 
03593     phints = &hints;
03594     class_enums = hints.class_enums;
03595     attr_cache  = hints.attr_cache;
03596 
03597     fprintf(fdc, "static eyedb::%sClass *%s_make(eyedb::%sClass *cls = 0, eyedb::Schema *m = 0)\n{\n", _type, c_name, _type);
03598     ctxC.push();
03599 
03600     fprintf(fdc, "%sif (!cls)\n%s  {\n", ctxC.get(), ctxC.get());
03601 
03602     fprintf(fdc, "%s    cls = new eyedb::%sClass((m ? m->getClass(\"%s\") : %s%s), ",
03603             ctxC.get(), _type, coll_class->getAliasName(), // changed 27/04/00
03604             (coll_class->asCollectionClass() ? coll_class->getCName() :
03605              className(coll_class)), classSuffix);
03606 
03607     if (dim > 1)
03608       fprintf(fdc, "%d);\n", dim);
03609     else
03610       fprintf(fdc, "%s);\n", (isref ? "eyedb::True" : "eyedb::False"));
03611 
03612     fprintf(fdc, "%s    eyedb::ClassPeer::setMType(cls, eyedb::Class::System);\n",
03613             ctxC.get());
03614     fprintf(fdc, "%s  }\n", ctxC.get());
03615 
03616     fprintf(fdc, "%sreturn cls;\n", ctxC.get());
03617     fprintf(fdc, "}\n\n");
03618 
03619     fprintf(fdc, "static void %s_init_p()\n{\n", c_name);
03620     fprintf(fdc, "%s%s%s = %s_make();\n", ctxC.get(), c_name, classSuffix, c_name);
03621     fprintf(fdc, "}\n\n");
03622 
03623     return Success;
03624   }
03625 }
03626   

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