home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / IDIOMS.ZIP / ETOP.C < prev    next >
C/C++ Source or Header  |  1991-12-04  |  5KB  |  146 lines

  1. /* Copyright (c) 1992 by AT&T Bell Laboratories. */
  2. /* Advanced C++ Programming Styles and Idioms */
  3. /* James O. Coplien */
  4. /* All rights reserved. */
  5.  
  6. //************************************************************//
  7. //                                                            //
  8. //     F I L E :    E T O P . C                               //
  9. //                                                            //
  10. //         Code for class Top                                 //
  11. //                                                            //
  12. //************************************************************//
  13.  
  14. #include "ek.h"
  15. #include <sys/types.h>
  16.  
  17. Top *
  18. Top::doit() {
  19.     // unused function provided as a handy,
  20.     // user-loadable hook to help orchestrate
  21.     // class update
  22.     return 0;
  23. }
  24.  
  25. int
  26. Top::compareFuncs(int vtblindex, vptp, vptp fptr) {
  27.     // this compares two function pointer abstractions
  28.     // for equality.  The first function pointer is
  29.     // characterized by its vtbl index and a function
  30.     // pointer;  the second, by just a function pointer.
  31.     // The use of these parameters may be system dependent;
  32.     // here the first pointer's function address is
  33.     // unused
  34.     return vtblindex == (int)fptr;
  35. }
  36.  
  37. mptr *
  38. Top::findVtblEntry(vptp f) {
  39.     // Look in "this" object's virtual function table
  40.     // for a function pointer equal to the f parameter,
  41.     // and return the address of its mptr structure
  42.     // (the full contents of the virtual function table
  43.     // entry)
  44.  
  45.     // mpp will be the address of the vtbl pointer;  we
  46.     // are guaranteed by the inheritance structure that
  47.     // the vtbl pointer will be at the beginning of
  48.     // every object of interest (all objects are derived
  49.     // from Top)
  50.     mptr ** mpp = (mptr**) this;
  51.  
  52.     // dereference the pointer address to get the
  53.     // vtbl address which is sitting in the beginning
  54.     // of this object
  55.     mptr * vtbl = *mpp;
  56.  
  57.     printf("Top::findVtblEntry(%d):  vtbl = 0x%x\n", f, vtbl);
  58.  
  59.     // go through my own vtbl;  a zero entry is an end
  60.     // sentinel, and the zeroth entry is unused.  Look
  61.     // for the requested function
  62.     for(int i = 1; vtbl[i].f; ++i ) {
  63.         if (compareFuncs(i, vtbl[i].f, f)) {
  64.             return vtbl + i;
  65.         }
  66.     }
  67.     return 0;
  68. }
  69.  
  70. // declaration of external "load" function from C land
  71. extern "C" vptp load(const char *);
  72.  
  73. void
  74. Top::update(    String filename,
  75.                 String fname,
  76.                 const char *const TypedefSpec) {
  77.  
  78.     // Get function fname from file filename and
  79.     // load it into memory.  The last parameter
  80.     // optionally specifies the type of a pointer
  81.     // to the function;  it is necessary if the
  82.     // function is overloaded.  The virtual function
  83.     // table is updated accordingly.  Only virtual
  84.     // functions can be updated.
  85.  
  86.     const String temp = "/tmp";
  87.  
  88.     printf("Top::update(\"%s\", \"%s\", \"%s\")\n",
  89.         (const char *)filename, (const char *)fname,
  90.         (const char *)TypedefSpec);
  91.     String prepname = temp + "/" + "t.c";
  92.     String Typedef, cast = "";
  93.     if (strlen(TypedefSpec)) {
  94.         Typedef = String("// TYPE used to disambiguate\
  95.         overloaded function\n\t\t\ttypedef ") + TypedefSpec;
  96.     } else {
  97.         Typedef = "typedef vptp TYPE";
  98.         cast = "(vptp)";
  99.     }
  100.     // make prepname:  helper function to return address
  101.     // of the function being updated
  102.     FILE *tempFile = fopen(prepname, "w");
  103.     fprintf(tempFile, "#\
  104.         include \"includes.h\"\n\
  105.         extern vptp functionAddress() {\n\
  106.             %s;\n\
  107.             TYPE retval = %s&%s;\n\
  108.             return (vptp)retval;\n\
  109.         }\n",
  110.         (const char*)Typedef,
  111.         (const char *)cast,
  112.         (const char*)fname);
  113.     fclose(tempFile);
  114.  
  115.     // Compile the helper function
  116.     String command = String("DIR=`pwd`; cd ") + temp + ";\
  117.         CC +e0 -I$DIR -c -g " + prepname;
  118.     system(command);
  119.     unlink(prepname);
  120.     String objectname =
  121.             prepname(0, prepname.length() - 2) + ".o";
  122.  
  123.     // Load the helper function.  Recall that load
  124.     // returns the new function's address
  125.     vvptp findfunc = (vvptp)load(objectname);
  126.     unlink(objectname);
  127.     printf("Top::update: calling findVtblEntry(%d)\n",
  128.                     (*findfunc)());
  129.  
  130.     // Now find the correct vtbl entry within this
  131.     // class vtbl. The helper function is called to
  132.     // tell findVtblEntry which function it is
  133.     // looking for
  134.     mptr *vtblEntry = findVtblEntry((*findfunc)());
  135.  
  136.     // Now load the new version of the function and store
  137.     // its address in the vtbl entry
  138.     printf("Top::update: old vtblEntry->f = 0x%x\n",
  139.         vtblEntry->f);
  140.     printf("Top::update: calling load(\"%s\")\n",
  141.         (const char *) filename);
  142.     vtblEntry->f = load(filename);
  143.     printf("Top::update: complete, new vtblEntry->f = 0x%x\n",
  144.         vtblEntry->f);
  145. }
  146.