home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v92.tgz / v92.tar / v92 / src / runtime / extcall.r < prev    next >
Text File  |  1996-03-22  |  5KB  |  218 lines

  1. /*
  2.  * extcall.r
  3.  */
  4.  
  5. /*  NOTE:  This file is considerably different for OS/2 than for other
  6.  *  systems.  In the future, differences for other systems may appear.
  7.  *  At present, all versions are being kept together in one file with
  8.  *  conditionals.
  9.  */
  10.  
  11. #if OS2
  12. #if !COMPILER
  13. #ifdef ExternalFunctions
  14. /*
  15.  */
  16.  
  17. struct os2xfunc {
  18.     struct os2xfunc *next;
  19.     unsigned long modhandle;
  20.     char *funcname;
  21.     char *modname;
  22.     void (*func)();
  23. };
  24.  
  25. static struct os2xfunc *xfunchead = NULL, *curxfunc;
  26.  
  27.  
  28. #define compare(a,b) (StrLen(a) != sizeof(b) - 1 || \
  29.               memcmp(StrLoc(a), (b), sizeof(b) - 1))
  30.  
  31. #define comparev(a,b) (StrLen(a) != strlen((b)) || \
  32.                memcmp(StrLoc(a), (b), StrLen(a)))
  33.  
  34. static dptr loadfnc(dptr dargv, int argc, int *ip);
  35. static dptr unloadfunc(dptr dargv, int argc, int *ip);
  36.  
  37. dptr extcall(dptr dargv, int argc, int *ip)
  38. {
  39. #passthru dptr (* _System func)(dptr dargv, int argc, int *ip);
  40.     *ip = -1;
  41.  
  42.     if (!cnv_str(dargv, dargv) ) {  /* 1st argument must be a string */
  43.     *ip = 103;            /* "String expected" error */
  44.     return dargv;
  45.     }
  46.  
  47.     if (!compare(*dargv, "loadfunc"))   return loadfnc(dargv, argc,ip);
  48.     if (!compare(*dargv, "unloadfunc")) return unloadfunc(dargv,argc,ip);
  49.  
  50.     for( curxfunc = xfunchead; curxfunc; curxfunc = curxfunc->next) {
  51.  
  52.     if (!comparev(*dargv,curxfunc->funcname)) {
  53.         func = curxfunc->func;
  54.         return (*func)(dargv, argc, ip);
  55.     }
  56.  
  57.     }
  58.  
  59.     *ip = 216;               /* external function not found */
  60.     return NULL;
  61. }
  62.  
  63. static dptr loadfnc(dptr dargv, int argc, int *ip)
  64. {
  65.  
  66.     char modname[MaxCvtLen];
  67.     char funcname[MaxCvtLen];
  68.  
  69.     unsigned long modhandle;
  70.     struct os2xfunc *modptr = NULL;
  71.     int rc;
  72. #passthru dptr (* _System funcaddr)(dptr dargv, int argc, int *ip);
  73.  
  74.  
  75.     if( argc < 3) {
  76.     *ip = 103;
  77.     return NULL;
  78.     }
  79.  
  80.     ++dargv;
  81.     if (!cnv_str(dargv,dargv)) {
  82.     *ip = 103;
  83.     return dargv;
  84.     }
  85.     if (!cnv_str(dargv+1,dargv+1)) {
  86.     *ip = 103;
  87.     return dargv+1;
  88.     }
  89.     strncpy(modname,StrLoc(*dargv),StrLen(*dargv));
  90.     strncpy(funcname,StrLoc(*(dargv+1)),StrLen(*(dargv+1)));
  91.  
  92.     for( curxfunc = xfunchead; curxfunc; curxfunc->next ) {
  93.     if( !comparev(*dargv,curxfunc->modname) ) {
  94.         modptr = curxfunc;
  95.         if ( !comparev(*(dargv+1),curxfunc->funcname )) break;
  96.     }
  97.     }
  98.     if (curxfunc) {
  99.     return &nulldesc;   /* Already loaded... */
  100.     }
  101.     if (!modptr) {
  102.     rc = _loadmod(modname,&modhandle);
  103.     if (rc) {
  104.         *ip = 216;
  105.         return dargv;
  106.     }
  107.     }
  108.     else modhandle = modptr->modhandle;
  109.  
  110.     rc = DosQueryProcAddr( modhandle, 0, funcname, &funcaddr );
  111.     if( rc ) {
  112.     if( !modptr )
  113.         _freemod(modhandle);
  114.     *ip = 216;
  115.     return dargv+1;
  116.     }
  117.  
  118.     modptr = malloc( sizeof(struct os2xfunc) );
  119.  
  120.     modptr->next = NULL;
  121.     modptr->modhandle = modhandle;
  122.     modptr->func = funcaddr;
  123.     modptr->modname = strdup(modname);
  124.     modptr->funcname = strdup(funcname);
  125.     if( !xfunchead ) xfunchead = modptr;
  126.     else {
  127.     for(curxfunc=xfunchead; curxfunc->next; curxfunc=curxfunc->next);
  128.     curxfunc->next = modptr;
  129.     }
  130.     return &nulldesc;
  131. }
  132.  
  133. static dptr unloadfunc(dptr dargv, int argc, int *ip)
  134. {
  135.     char modname[MaxCvtLen];
  136.     char funcname[MaxCvtLen];
  137.  
  138.     unsigned long modhandle;
  139.     struct os2xfunc *modptr = NULL;
  140.     int rc;
  141.  
  142.  
  143.     if( argc < 2) {
  144.     *ip = 103;
  145.     return NULL;
  146.     }
  147.  
  148.     ++dargv;
  149.     if (!cnv_str(dargv,dargv)) {
  150.     *ip = 103;
  151.     return dargv;
  152.     }
  153.  
  154.     for( curxfunc = xfunchead; curxfunc; curxfunc = curxfunc->next) {
  155.  
  156.     if (!comparev(*dargv,curxfunc->funcname)) break;
  157.  
  158.     }
  159.  
  160.     if (!curxfunc) return &nulldesc;    /* Just ignore not found */
  161.  
  162.     modptr = curxfunc;
  163.  
  164.     if( xfunchead == modptr )
  165.     xfunchead = modptr->next;
  166.     else {
  167.     for( curxfunc = xfunchead; curxfunc; curxfunc = curxfunc->next) {
  168.         if(curxfunc->next = modptr) {
  169.         curxfunc->next = modptr->next;
  170.         break;
  171.         }
  172.     }
  173.     if(!curxfunc) return &nulldesc; /* ?? didn't find it 2nd time?? */
  174.     }
  175.  
  176.     /* At this point the function has been removed from the chain */
  177.     /* Run the chain one last time to see if we can free the module */
  178.  
  179.     for( curxfunc = xfunchead; curxfunc; curxfunc = curxfunc->next) {
  180.     if(modptr->modhandle == curxfunc->modhandle) break;
  181.     }
  182.     if (curxfunc)
  183.     _freemod(modptr->modhandle);
  184.  
  185.     free(modptr->modname);
  186.     free(modptr->funcname);
  187.     free(modptr);
  188.     return &nulldesc;
  189.  
  190. }
  191. #else                    /* ExternalFunctions */
  192. static char x;            /* prevent empty module */
  193. #endif                    /* ExternalFunctions */
  194. #endif                    /* !COMPILER */
  195.  
  196. #else                    /* OS2 */
  197.  
  198. #if !COMPILER
  199. #ifdef ExternalFunctions
  200.  
  201. /*
  202.  * extcall - stub procedure for external call interface.
  203.  */
  204. dptr extcall(dargv, argc, ip)
  205. dptr dargv;
  206. int argc;
  207. int *ip;
  208.    {
  209.    *ip = 216;            /* no external function to find */
  210.    return (dptr)NULL;
  211.    }
  212.  
  213. #else                    /* ExternalFunctions */
  214. static char x;            /* prevent empty module */
  215. #endif                     /* ExternalFunctions */
  216. #endif                    /* !COMPILER */
  217. #endif                    /* OS2 */
  218.