Home | History | Annotate | Line # | Download | only in lisp
      1 /*
      2  * Copyright (c) 2001 by The XFree86 Project, Inc.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20  * SOFTWARE.
     21  *
     22  * Except as contained in this notice, the name of the XFree86 Project shall
     23  * not be used in advertising or otherwise to promote the sale, use or other
     24  * dealings in this Software without prior written authorization from the
     25  * XFree86 Project.
     26  *
     27  * Author: Paulo Csar Pereira de Andrade
     28  */
     29 
     30 /* $XFree86: xc/programs/xedit/lisp/require.c,v 1.17tsi Exp $ */
     31 
     32 #include "lisp/require.h"
     33 
     34 /*
     35  * Implementation
     36  */
     37 LispObj *
     38 Lisp_Load(LispBuiltin *builtin)
     39 /*
     40  load filename &key verbose print if-does-not-exist
     41  */
     42 {
     43     LispObj *filename, *verbose, *print, *if_does_not_exist;
     44 
     45     if_does_not_exist = ARGUMENT(3);
     46     print = ARGUMENT(2);
     47     verbose = ARGUMENT(1);
     48     filename = ARGUMENT(0);
     49 
     50     if (PATHNAMEP(filename))
     51 	filename = CAR(filename->data.pathname);
     52     else {
     53 	CHECK_STRING(filename);
     54     }
     55 
     56     return (LispLoadFile(filename,
     57 			 verbose != UNSPEC && verbose != NIL,
     58 			 print != UNSPEC && print != NIL,
     59 			 if_does_not_exist != UNSPEC &&
     60 			 if_does_not_exist != NIL));
     61 }
     62 
     63 LispObj *
     64 Lisp_Require(LispBuiltin *builtin)
     65 /*
     66  require module &optional pathname
     67  */
     68 {
     69     char filename[1024], *ext;
     70     int len;
     71 
     72     LispObj *obj, *module, *pathname;
     73 
     74     pathname = ARGUMENT(1);
     75     module = ARGUMENT(0);
     76 
     77     CHECK_STRING(module);
     78     if (pathname != UNSPEC) {
     79 	if (PATHNAMEP(pathname))
     80 	    pathname = CAR(pathname->data.pathname);
     81 	else {
     82 	    CHECK_STRING(pathname);
     83 	}
     84     }
     85     else
     86 	pathname = module;
     87 
     88     for (obj = MOD; CONSP(obj); obj = CDR(obj)) {
     89 	if (strcmp(THESTR(CAR(obj)), THESTR(module)) == 0)
     90 	    return (module);
     91     }
     92 
     93     if (THESTR(pathname)[0] != '/') {
     94 #ifdef LISPDIR
     95 	snprintf(filename, sizeof(filename), "%s", LISPDIR);
     96 #else
     97 	getcwd(filename, sizeof(filename));
     98 #endif
     99     }
    100     else
    101 	filename[0] = '\0';
    102     *(filename + sizeof(filename) - 5) = '\0';	/* make sure there is place for ext */
    103     len = strlen(filename);
    104     if (!len || filename[len - 1] != '/') {
    105 	strcat(filename, "/");
    106 	++len;
    107     }
    108 
    109     snprintf(filename + len, sizeof(filename) - len - 5, "%s", THESTR(pathname));
    110 
    111     ext = filename + strlen(filename);
    112 
    113 #ifdef SHARED_MODULES
    114     strcpy(ext, ".so");
    115     if (access(filename, R_OK) == 0) {
    116 	LispModule *lisp_module;
    117 	char data[64];
    118 	int len;
    119 
    120 	if (lisp__data.module == NULL) {
    121 	    /* export our own symbols */
    122 	    if (dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL) == NULL)
    123 		LispDestroy("%s: ", STRFUN(builtin), dlerror());
    124 	}
    125 
    126 	lisp_module = (LispModule*)LispMalloc(sizeof(LispModule));
    127 	if ((lisp_module->handle =
    128 	     dlopen(filename, RTLD_LAZY | RTLD_GLOBAL)) == NULL)
    129 	    LispDestroy("%s: dlopen: %s", STRFUN(builtin), dlerror());
    130 	snprintf(data, sizeof(data), "%sLispModuleData", THESTR(module));
    131 	if ((lisp_module->data =
    132 	     (LispModuleData*)dlsym(lisp_module->handle, data)) == NULL) {
    133 	    dlclose(lisp_module->handle);
    134 	    LispDestroy("%s: cannot find LispModuleData for %s",
    135 			STRFUN(builtin), STROBJ(module));
    136 	}
    137 	LispMused(lisp_module);
    138 	lisp_module->next = lisp__data.module;
    139 	lisp__data.module = lisp_module;
    140 	if (lisp_module->data->load)
    141 	    (lisp_module->data->load)();
    142 
    143 	if (MOD == NIL)
    144 	    MOD = CONS(module, NIL);
    145 	else {
    146 	    RPLACD(MOD, CONS(CAR(MOD), CDR(MOD)));
    147 	    RPLACA(MOD, module);
    148 	}
    149 	LispSetVar(lisp__data.modules, MOD);
    150 
    151 	return (module);
    152     }
    153 #endif
    154 
    155     strcpy(ext, ".lsp");
    156     (void)LispLoadFile(STRING(filename), 0, 0, 0);
    157 
    158     return (module);
    159 }
    160