2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: eltutil.c /main/3 1995/11/08 09:27:46 rswiston $ */
25 Copyright 1986 Tandem Computers Incorporated.
26 This product and information is proprietary of Tandem Computers Incorporated.
27 Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
30 /* Eltutil.c contains procedures for program ELTDEF */
51 /* Output indicated action pointer array to if.h */
52 void actptrout(array, name)
58 fprintf(ifh, "M_IFEXTERN int %s[%d]\n#if defined(M_IFDEF)\n = {\n",
60 for (i = 0 ; i < m_elcount ; i++) {
61 if (i > 0) fprintf(ifh, ",\n");
62 fprintf(ifh, " %d", array[i] ? array[i]->count : M_NULLVAL);
64 fprintf(ifh, "}\n#endif\n ;\n");
68 /* Close a code file and write jump table at the end */
70 void closeiffile(LOGICAL flag, FILE *file, int count, char *table, char *proto)
72 void closeiffile(flag, file, count, table, proto)
85 "void (*m_%stable[])(\n#if defined(M_PROTO)\n %s\n#endif\n ) = {\n",
87 fprintf(file, " m_%s1, /* Place holder for 1-based indexing */\n",
89 for (i = 1 ; i <= count ; i++) {
90 fprintf(file, " m_%s%d", table, i);
91 if (i != count) fputs(",\n", file);
97 "void (*m_%stable[1])(\n#if defined(M_PROTO)\n %s\n#endif\n ) ;\n",
102 /* Called when the C identifier to be #define'd to a parameter value is
108 new = (PARVAL *) m_malloc(sizeof(PARVAL), "parameter value");
109 if (pval = (PARVAL *) m_ntrtrie(name, &parval, (M_TRIE *) new))
110 m_free(new, "parameter value");
114 new->cname = (M_WCHAR *) m_malloc(w_strlen(name) + 1, "C name");
115 w_strcpy(new->cname, name);
121 /* Called after last input character is read to place closing punctuation
122 at end of output files and close them */
130 closeiffile(inent, entfile, codeent, "c", nopar);
131 closeiffile(intext, tfile, tactions, "t", tproto);
132 closeiffile(inpc, pfile, pactions, "p", pproto);
133 closeiffile(insc, sfile, sactions, "s", nopar);
134 closeiffile(inec, efile, eactions, "e", nopar);
135 closeiffile(instc, stfile, stactions, "st", stproto);
140 /* Write if.h (which was opened for sign-on message) */
141 fprintf(ifh, "M_IFEXTERN int m_gss M_IFINIT(%d) ;\n", gss);
142 fprintf(ifh, "M_IFEXTERN int m_ges M_IFINIT(%d) ;\n", ges);
143 fputs("M_IFEXTERN struct {\n", ifh);
144 fputs(" int data ;\n", ifh);
145 fputs(" M_ELEMENT element ;\n", ifh);
146 fputs(" int son ;\n", ifh);
147 fputs(" int next ;\n", ifh);
150 " } m_action[%d]\n#if defined(M_IFDEF)\n = {\n",
154 for (actp = firstact ; actp ; actp = actp->nextact) {
155 if (first) first = FALSE;
156 else fprintf(ifh, ",\n");
157 fprintf(ifh, " %d, %d, %d, %d",
158 actp->data, actp->element,
159 actp->son ? actp->son->count : M_NULLVAL,
160 actp->next ? actp->next->count : M_NULLVAL);
162 fprintf(ifh, "}\n#endif\n ;\n");
164 else fputs(" } m_action[1] ;\n", ifh);
166 actptrout(starray, "m_starray");
167 actptrout(etarray, "m_etarray");
168 actptrout(scarray, "m_scarray");
169 actptrout(ecarray, "m_ecarray");
170 actptrout(tcarray, "m_tcarray");
171 actptrout(pcarray, "m_pcarray");
172 actptrout(stcarray, "m_stcarray");
175 m_openchk(&pvalh, "pval.h", "w");
176 fputs("/* Parameter values specified in the interface */\n", pvalh);
177 if (parval.data) outpval(parval.data);
181 /* Report any elements and entities left undefined */
182 for (i = 0 ; i < m_elcount ; i++)
184 warning1("Warning: No specification for element %s",
185 &m_ename[m_element[i].enptr]);
187 for (ent = firstent ; ent ; ent = ent->next)
189 warning1("Warning: Entity %s undefined", ent->name);
195 /* Called when finished reading a section of code from the input file */
197 void endcode(LOGICAL flag, FILE *file)
199 void endcode(flag, file)
204 if (flag) fprintf(file, "}}\n\n");
207 /* Called at the end of all initial fields in the interface definition */
211 fputs(" putc(m_textchar, m_outfile);\n", tfile);
213 fputs(" fputs(m_pi, m_outfile) ;\n", pfile);
216 fputs(" {\n", stfile);
217 fputs(" char *mb_string;\n", stfile);
218 fputs(" mb_string = MakeMByteString(m_string);\n", stfile);
219 fputs(" fputs(mb_string, m_outfile) ;\n", stfile);
220 fputs(" m_free(mb_string,\"multi-byte string\");;\n", stfile);
221 fputs(" }\n", stfile);
225 /* End the sign-on message */
227 void endsignon(M_NOPAR)
232 static char signon1[] = "Interface generated from ";
233 static char signon2[] = " on ";
239 /* Discard a trailing carriage return in the sign-on message */
243 timeofday = ctime(&storetime);
246 sochar+strlen(signon1)+strlen(signon2)+strlen(iffile)+strlen(timeofday)
247 /* a byte for end of string marker */
249 /* a byte for a carriage return after any user-supplied message */
251 m_openchk(&sgfile, "signonx.h", "w");
252 fprintf(sgfile, "extern char m_signon[%d] ;\n", len);
254 m_openchk(&sgfile, "signon.h", "w");
255 fprintf(sgfile, "char m_signon[%d] = {\n", len);
257 for (i = 0 ; i <sochar ; i++)
258 fprintf(sgfile, " %d,\n", signonmsg[i]);
259 if (sochar) fputs(" 10,\n", sgfile);
260 for (p = signon1 ; *p ; p++)
261 fprintf(sgfile, " %d,\n", *p);
262 for (p = iffile ; *p ; p++)
263 fprintf(sgfile, " %d,\n", *p);
264 for (p = signon2 ; *p ; p++)
265 fprintf(sgfile, " %d,\n", *p);
266 for (p = timeofday ; *p ; p++)
267 fprintf(sgfile, " %d,\n", *p);
268 fputs(" 0} ;\n", sgfile);
272 /* Closes a start-string or end-string */
273 void endstring(M_NOPAR)
276 if (stringstart) stringstart = FALSE;
277 else fprintf(string, ",\n");
280 fprintf(string, " 0");
282 /* If called after ENDFILE, ensure at least one character in output file*/
283 else if (stringstart) fprintf(string, " 0");
286 /* Set the type of an entity and check if different than declaration in
291 if ((entity->type == M_PI && type == M_CODEPI) ||
292 (entity->type == M_SDATA && type == M_CODESDATA));
293 else if (entity->type != M_GENERAL &&
294 entity->type != (unsigned char) type)
295 warning1("Redefining type of entity %s", name);
296 entity->type = (unsigned char) type;
299 /* Free storage used for a context-specification chain */
300 void freechain(M_NOPAR)
302 CHAIN *chainp, *dchainp;
304 for (chainp = firstchain ; chainp ;) {
306 chainp = chainp->next;
307 m_free(dchainp, "chain");
310 nextchain = &firstchain;
313 /* Returns pointer to data field in action node for current chain of
315 int *getaction(array)
318 ACTION *start, *node;
321 if (! array[openelt - 1]) {
322 array[openelt - 1] = getactstruct();
323 array[openelt - 1]->element = openelt + 1;
325 start = array[openelt - 1];
326 for (chainp = firstchain ; chainp ; chainp = chainp->next) {
328 for ( ; chainp ; chainp = chainp->next) {
329 start->son = getactstruct();
330 start->son->element = chainp->elt;
334 return(&start->data);
336 for (node = start->son ; node ; start = node, node = node->next)
337 if (node->element == chainp->elt) break;
339 start->next = getactstruct();
340 start->next->element = chainp->elt;
345 if (start->data) m_error("Duplicate specification");
347 return(&start->data);
350 /* Allocate new action structure */
351 ACTION *getactstruct(M_NOPAR)
355 new = (ACTION *) m_malloc(sizeof(ACTION), "action");
356 new->count = ++actlen;
357 new->data = M_NULLVAL;
358 new->son = new->next = new->nextact = NULL;
360 nextact = &new->nextact;
364 /* Program initialization */
365 void initialize(M_NOPAR)
370 fprintf(stderr, "MARKUP System - ELTDEF %s\n", M_VERSION);
371 fprintf(stderr, "Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.\n");
373 m_openchk(&ifh, "if.h", "w");
374 m_openchk(&globdef, "globdef.h", "w");
375 m_openchk(&globdec, "globdec.h", "w");
376 m_openchk(&pfile, "pfile.c", "w");
377 /* ELTDEF opens too many files for use with CodeView debugger. If
378 this option is set, all code segments are written to one file */
390 m_openchk(&tfile, "tfile.c", "w");
391 m_openchk(&sfile, "sfile.c", "w");
392 m_openchk(&efile, "efile.c", "w");
393 m_openchk(&stfile, "stfile.c", "w");
394 m_openchk(&entfile, "entfile.c", "w");
396 m_openchk(&string, "estring.h", "w");
397 m_openchk(&m_errfile, "error", "w");
398 m_openchk(&ifile, iffile, "r");
400 mb_delims = mb_dlmptr;
401 wc_delims = m_dlmptr;
405 *wc_delims++ = MakeWideCharString(*mb_delims);
410 /* Start array for sign-on message on globals.h. Also,
411 make sure there is at least one line in globals.h, because
412 DOS copy does not copy an empty file */
414 fputs("/* Global definitions specified by interface designer*/\n",
416 fputs("/* Global declarations specified by interface designer*/\n",
419 fputs("#if defined(M_IFDEF)\n", ifh);
420 fputs("#define M_IFEXTERN\n", ifh);
421 fputs("#define M_IFINIT(a) = a\n", ifh);
422 fputs("#else\n", ifh);
423 fputs("#define M_IFEXTERN extern\n", ifh);
424 fputs("#define M_IFINIT(a)\n", ifh);
425 fputs("#endif\n", ifh);
427 startcode(pactions, &inpc, pfile, "p", pproto, pformal, pftype);
428 startcode(tactions, &intext, tfile, "t", tproto, tformal, tftype);
429 startcode(sactions, &insc, sfile, "s", nopar, nopar, "");
430 startcode(eactions, &inec, efile, "e", nopar, nopar, "");
431 startcode(stactions, &instc, stfile, "st", stproto, stformal, stft);
434 /* Output definitions for strings */
435 void outstring(M_NOPAR)
439 m_openchk(&string, "estring.h", "r");
440 fprintf(ifh, "M_IFEXTERN char m_string[%d]\n",
441 stringcnt > 1 ? stringcnt - 1 : 1);
443 fputs("#if defined(M_IFDEF)\n = {\n", ifh);
444 while ((c = getc(string)) != EOF) putc(c, ifh);
445 fputs("}\n#endif\n", ifh);
451 /* Output #define's for parameter values */
457 for ( ; p ; p = p->next)
458 if (p->symbol) outpval(p->data);
463 mb_cname = MakeMByteString(((PARVAL *) p->data)->cname);
465 "/* line %d \"%s\" */\n",
466 ((PARVAL *) p->data)->line,
468 fprintf(pvalh, "#define %s \"", mb_cname);
469 m_free(mb_cname,"multi-byte string");
470 if (q = ((PARVAL *) p->data)->value)
473 char mbq[32]; /* larger than largest possible mbyte char */
476 length = wctomb(mbq, *q);
484 fputs("\\\"", pvalh);
493 fputs("\"\n", pvalh);
497 /* Skip rest of statement after an error */
498 void skiptoend(M_NOPAR)
502 CVARSTRUCT *cvarp, *dvarp;
504 for (cvarp = cvarlist ; cvarp ;) {
506 m_free(cvarp->cvarptr, "C variable name");
508 m_free(dvarp, "C variable");
516 if (i == ENDFILE) break;
518 if (restart <= RSIGNON) endsignon();
523 else if (i == GDEF && restart < RGLOBDEF) {
524 if (restart <= RSIGNON) endsignon();
529 else if (i == GDEC && restart < RGLOBDEC) {
530 if (restart <= RSIGNON) endsignon();
535 else if (i == SIGNON && restart < RSIGNON) {
540 else if (i == ENTSTART && restart == RENTITY) {
546 } /* end if ! errlev */
550 /* Starts processing a code segment from the input file */
551 void startcode(caseno, flag, file, prefix, proto, formal, formtype)
562 endcode(*flag, file);
566 "void m_%s%d(\n#if defined(M_PROTO)\n %s\n#endif\n ) ;\n",
572 fputs("#if defined(M_PROTO)\n", file);
573 fprintf(file, "void m_%s%d(%s)\n", prefix, caseno, proto);
574 fputs("#else\n", file);
576 "void m_%s%d(%s)\n%s\n#endif\n {\n", /* balance the "}" */
582 for (cvarp = cvarlist ; cvarp ; cvarp = cvarp->next)
586 mb_cvarptr = MakeMByteString(cvarp->cvarptr);
587 fprintf(file, " M_WCHAR *%s ;\n", mb_cvarptr);
588 m_free(mb_cvarptr,"multi-byte string");
591 for (cvarp = cvarlist ; cvarp ; cvarp = cvarp->next)
595 mb_cvarptr = MakeMByteString(cvarp->cvarptr);
597 " m_setparam(&%s, %d) ;\n",
600 m_free(mb_cvarptr,"multi-byte string");
602 fprintf(file, "{\n/* line %d \"%s\" */\n", m_line, iffile); /* balance "}" */
605 /* Begins processing a new element */
606 void startelement(M_NOPAR)
611 for (cvarp = cvarlist ; cvarp ; ) {
613 m_free(cvarp->cvarptr, "C variable name");
615 m_free(discard, "C variable");
618 if (openelt = m_packedlook(m_entree, name)) {
619 if (processed[openelt - 1])
620 warning1("Warning: Element %s already processed", name);
621 processed[openelt - 1] = TRUE;
623 else m_err1("Undefined element: %s", name);
626 /* Stores the name of a C variable read from the input file */
627 void storecvar(M_NOPAR)
631 new = (CVARSTRUCT *) m_malloc(sizeof(CVARSTRUCT), "C variable");
632 new->cvarptr = (M_WCHAR *) m_malloc(w_strlen(name) + 1,
634 w_strcpy(new->cvarptr, name);
635 new->next = cvarlist;
639 /* Compares the parameter name associated with a C variable in the input
640 file with the names of all parameters of the current element. Stores
641 result for later output with code segments */
642 void storepname(M_NOPAR)
646 for (i = 0, par = m_element[openelt - 1].parptr;
647 i < m_element[openelt - 1].parcount;
649 if (! w_strcmp(&m_pname[m_parameter[par - 1].paramname], name))
651 if (i >= m_element[openelt - 1].parcount) {
652 m_err2("%s: No such parameter for element %s", name,
653 &m_ename[m_element[openelt - 1].enptr]);
659 /* Called when a possible parameter value to be defined is encountered */
665 if (m_partype(cvarlist->param + m_element[openelt - 1].parptr, p))
669 if (w_strcmp(pval->value, p))
673 sprintf(buffer, "%d", pval->line);
674 w_buffer = MakeWideCharString(buffer);
675 m_err5("Can't #define %s to %s. %s #define'd to %s on line %s",
681 m_free(w_buffer, "wide character string");
685 pval->value = (M_WCHAR *) m_malloc(w_strlen(p) + 1, "pval value");
686 w_strcpy(pval->value, p);
690 else m_err3("\"%s\" illegal value for parameter %s of %s",
692 &m_pname[m_parameter[cvarlist->param +
693 m_element[openelt - 1].parptr - 1].paramname],
694 &m_ename[m_element[openelt-1].enptr]);