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 César 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 */
37LispObj *
38Lisp_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
63LispObj *
64Lisp_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