1 /*
2 * Motif Tools Library, Version 3.1
3 * $Id: Include.c,v 1.2 2001/09/19 02:57:18 grmcdorman Exp $
4 *
5 * Written by David Flanagan.
6 * Copyright (c) 1992-2001 by David Flanagan.
7 * All Rights Reserved. See the file COPYRIGHT for details.
8 * This is open source software. See the file LICENSE for details.
9 * There is no warranty for this software. See NO_WARRANTY for details.
10 *
11 * $Log: Include.c,v $
12 * Revision 1.2 2001/09/19 02:57:18 grmcdorman
13 * This change makes the following modifications:
14 * A new program, printConfig, is provided. This is built by a
15 * simple rule in the Makefile and not installed. It prints
16 * significant defines from Xmt.tmpl.
17 *
18 * XmtP.h is now generated from XmtP.h.in using printConfig. As
19 * a result, code compiled outside of the Xmt Imakefiles will
20 * have all of the Xmt.tmpl defines.
21 *
22 * Source files are modified to use XmtP.h instead of Xmt.h.
23 *
24 * WorkingBox.c is modified to use the new Progress widget.
25 * It can be compiled in the old style if WORKINGBOX_USE_SCALE is
26 * defined at compile time.
27 *
28 * Because XmtP.h is generated dynamically, it is removed from CVS
29 * with this check-in.
30 *
31 * Revision 1.1.1.1 2001/02/10 13:44:08 motiftools
32 * Initial import of Xmt310 to CVS
33 *
34 *
35 */
36
37 #include <stdio.h>
38 #include <errno.h>
39 #ifdef VMS
40 #include <perror.h>
41 #endif
42 #include <Xmt/XmtP.h>
43 #include <Xmt/Include.h>
44 #include <Xmt/Hash.h>
45 #include <Xmt/Lexer.h>
46 #include <Xmt/AppResP.h>
47 #include <X11/IntrinsicP.h>
48
49 #if NeedFunctionPrototypes
load_file_error(String filename)50 static void load_file_error(String filename)
51 #else
52 static void load_file_error(filename)
53 String filename;
54 #endif
55 {
56 XmtWarningMsg("XmtLoadResourceFile", "io",
57 "can't load file '%s':\n\t%s.",
58 filename, strerror(errno));
59 }
60
61
62 /* forward declaration */
63 #if NeedFunctionPrototypes
64 static void LoadResourceFileList(XrmDatabase *, Widget, StringConst);
65 #else
66 static void LoadResourceFileList();
67 #endif
68
69
70 #if NeedFunctionPrototypes
LoadResourceFile(XrmDatabase * db,Widget w,StringConst filename,Boolean user,Boolean override)71 static Boolean LoadResourceFile(XrmDatabase *db, Widget w,StringConst filename,
72 Boolean user, Boolean override)
73 #else
74 static Boolean LoadResourceFile(db, w, filename, user, override)
75 XrmDatabase *db;
76 Widget w;
77 StringConst filename;
78 Boolean user;
79 Boolean override;
80 #endif
81 {
82 static XrmName required_names[2];
83 static XrmClass required_classes[2];
84 static required_quarks_inited = False;
85 XmtAppResources *app = XmtGetApplicationResources(w);
86 XrmRepresentation type;
87 XrmValue value;
88 XrmDatabase newdb = NULL;
89 XrmDatabase userdb = NULL;
90 String full_filename;
91 String user_filename;
92 Boolean found = False;
93 XrmQuark fileq;
94 XtPointer dummy;
95
96 if (!filename || filename[0] == '\0') return False;
97
98 /* find our application shell */
99 w = XmtGetApplicationShell(w);
100
101 /*
102 * one time initialization
103 */
104 if (required_quarks_inited == False) {
105 required_names[0] = XrmPermStringToQuark(XmtNxmtRequires);
106 required_names[1] = NULLQUARK;
107 required_classes[0] = XrmPermStringToQuark(XmtCXmtRequires);
108 required_classes[1] = NULLQUARK;
109 required_quarks_inited = True;
110 }
111
112 /* test that the file is not already included */
113 fileq = XrmStringToQuark(filename);
114 if (XmtHashTableLookup(app->loaded_files_table,
115 (XtPointer)fileq, &dummy))
116 return True;
117
118 /*
119 * If the filename begins with / or ./ or ../, then we don't search for it.
120 * Otherwise, we've got to deal with paths.
121 */
122 if ((filename[0] == '/') ||
123 ((filename[0] == '.') && (filename[1] == '/')) ||
124 ((filename[0]=='.') && (filename[1]=='.') && (filename[2]=='/'))) {
125 found = True;
126 newdb = XrmGetFileDatabase(filename);
127 if (!newdb) load_file_error((String)filename);
128 }
129 else {
130 /*
131 * go look for a application or system file by the specified name.
132 * This call searches resourceFilePath under the directory configDir.
133 * If resourceFilePath is undefined or if no file is found there, it
134 * searches configFilePath, if it differs from resourceFilePath, or
135 * if configFilePath is undefined it uses a default path under teh
136 * directory configDir.
137 * If still no file, it searches XFILESEARCHPATH or the /usr/lib/X11
138 * default path.
139 */
140 full_filename = XmtFindFile(w, "app-defaults", filename,
141 APPDEFAULTSSUFFIX,
142 NULL, app->resource_file_path,
143 XmtSearchAppPath | XmtSearchSysPath);
144
145 if (full_filename) {
146 newdb = XrmGetFileDatabase(full_filename);
147 if (!newdb) load_file_error(full_filename);
148 else found = True;
149 XtFree(full_filename);
150 }
151
152 /* if user is True, go look for a user resource file
153 * and override the application file with it.
154 */
155 if (user) {
156 user_filename = XmtFindFile(w, "app-defaults", filename,
157 APPDEFAULTSSUFFIX,
158 NULL, NULL, XmtSearchUserPath);
159 if (user_filename) {
160 userdb = XrmGetFileDatabase(user_filename);
161 if (!userdb) load_file_error(user_filename);
162 else {
163 XrmMergeDatabases(userdb, &newdb);
164 found = True;
165 }
166 XtFree(user_filename);
167 }
168 }
169 }
170
171 /*
172 * if no file was found, warn
173 */
174 if (!found)
175 XmtWarningMsg("XmtLoadResourceFile", "notFound",
176 "file '%s' not found.", filename);
177
178 /* if there's no db at this point, quit */
179 if (!newdb) return False;
180
181 /*
182 * remember that we loaded this file
183 */
184 XmtHashTableStore(app->loaded_files_table, (XtPointer)fileq, (XtPointer)1);
185
186 /*
187 * check the new db for recursive include files
188 */
189 if (XrmQGetResource(newdb, required_names, required_classes,
190 &type, &value) == True)
191 LoadResourceFileList(db, w, value.addr);
192
193 /*
194 * Finally, augment or override the db with the new db
195 * Note that this destroys newdb, so we don't have to do so explicitly.
196 */
197 #ifndef X11R5
198 if (!override)
199 XmtWarningMsg("XmtLoadResourceFile", "cantAugment",
200 "the #augment directive only works with X11R5\n\tand later releases. Overriding instead.");
201 XrmMergeDatabases(newdb, db);
202 #else
203 XrmCombineDatabase(newdb, db, override);
204 #endif
205
206 return True;
207 }
208
209
210 static String keywords[] = {
211 "augment",
212 "override"
213 };
214
215 #define AUGMENT 0
216 #define OVERRIDE 1
217
218 #if NeedFunctionPrototypes
LoadResourceFileList(XrmDatabase * db,Widget w,StringConst list)219 static void LoadResourceFileList(XrmDatabase *db, Widget w, StringConst list)
220 #else
221 static void LoadResourceFileList(db, w, list)
222 XrmDatabase *db;
223 Widget w;
224 StringConst list;
225 #endif
226 {
227 XmtLexer l;
228 XmtLexerToken tok;
229 Boolean override = True;
230
231 l = XmtLexerCreate(keywords, XtNumber(keywords));
232 XmtLexerInit(l, list);
233
234 /*
235 * Parse the following grammar:
236 * ((directive | file) [','])*
237 * directive: ("#augment" | "#override")
238 * file: STRING | '<'[^> \t]*'>'
239 */
240 while((tok = XmtLexerGetToken(l)) != XmtLexerEndOfString) {
241 switch(tok) {
242 case XmtLexerSharp:
243 if (XmtLexerNextToken(l) != XmtLexerKeyword) goto syntax;
244 if (XmtLexerKeyValue(l) == AUGMENT) override = False;
245 else override = True;
246 XmtLexerConsumeToken(l);
247 break;
248 case XmtLexerString:
249 (void)LoadResourceFile(db, w, XmtLexerStrValue(l), True, override);
250 XtFree(XmtLexerStrValue(l));
251 if (XmtLexerNextToken(l) == XmtLexerComma) XmtLexerConsumeToken(l);
252 break;
253 case XmtLexerLess:
254 XmtLexerConsumeToken(l);
255 XmtLexerSkipWhite(l);
256 if (XmtLexerScan(l, "> \t", False) != XmtLexerString) goto syntax;
257 (void)LoadResourceFile(db,w, XmtLexerStrValue(l), False, override);
258 XtFree(XmtLexerStrValue(l));
259 if (XmtLexerNextToken(l) != XmtLexerGreater) goto syntax;
260 if (XmtLexerNextToken(l) == XmtLexerComma) XmtLexerConsumeToken(l);
261 break;
262 default:
263 goto syntax;
264 }
265 }
266 XmtLexerDestroy(l);
267 return;
268
269 syntax:
270 XmtWarningMsg("XmtLoadResourceFileList", "syntax",
271 "syntax error in xmtRequires resource:\n\t%s",
272 list);
273 XmtLexerDestroy(l);
274 return;
275 }
276
277 #if NeedFunctionPrototypes
XmtLoadResourceFile(Widget w,StringConst filename,XmtWideBoolean user,XmtWideBoolean override)278 Boolean XmtLoadResourceFile(Widget w, StringConst filename,
279 XmtWideBoolean user, XmtWideBoolean override)
280 #else
281 Boolean XmtLoadResourceFile(w, filename, user, override)
282 Widget w;
283 StringConst filename;
284 int user;
285 int override;
286 #endif
287 {
288 XrmDatabase db;
289
290 w = XmtGetApplicationShell(w);
291 db = XmtDatabaseOfWidget(w);
292 return LoadResourceFile(&db, w, filename, user, override);
293 }
294
295 #if NeedFunctionPrototypes
XmtLoadResourceFileList(Widget w,StringConst list)296 void XmtLoadResourceFileList(Widget w, StringConst list)
297 #else
298 void XmtLoadResourceFileList(w, list)
299 Widget w;
300 StringConst list;
301 #endif
302 {
303 XrmDatabase db;
304
305 w = XmtGetApplicationShell(w);
306 db = XmtDatabaseOfWidget(w);
307 LoadResourceFileList(&db, w, list);
308 }
309