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: conutil.c /main/3 1995/11/08 11:03:16 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 /* Conutil has utility procedures for program CONTEXT. */
42 /* Output declaration of dlmptr */
43 void dumpdlmptr(M_NOPAR)
47 fprintf(delim, "M_DELIMEXTERN M_WCHAR *m_dlmptr[%d];\n", dcount+1);
48 fprintf(delim, "M_DELIMEXTERN char *mb_dlmptr[%d]\n", dcount+1);
49 fprintf(delim, "#if defined(M_DELIMDEF)\n = {\n");
50 for (n = 0 ; n < dcount ; n++) {
51 if (n) fputs(",\n", delim);
52 fprintf(delim, " %s", dlmptr[n]);
54 fprintf(delim, endif);
57 /* Output the generated data structures */
59 void dumptree(LOGICAL sparse)
67 for (i = 0 ; i < ccount ; i++)
69 countdown(contree[i], &count);
71 "M_DELIMEXTERN M_PTRIE m_delimtrie[%d]\n#if defined(M_DELIMDEF)\n = {\n",
74 "M_CONEXTERN int m_contree[%d]\n#if defined(M_CONDEF)\n = {\n ",
78 for (i = 0 ; i < ccount ; i++) {
80 fprintf(context, "%d", count + 1);
81 dumpnode(&first, delim, contree[i], &count, (void *)printval);
83 else fprintf(context, "0");
84 if (i < ccount - 1) fprintf(context, ",\n ");
86 fprintf(delim, endif);
87 fprintf(context, endif);
91 /* Enter a delimiter into the delimiter tree for a particular context */
97 contree[n] = m_gettrienode();
100 if (m_ntrtrie(dstruct->string,
102 (void *) (unsigned long) dstruct->count))
104 char *mb_dstring, *mb_contexts;
106 mb_dstring = MakeMByteString(dstring);
107 mb_contexts = MakeMByteString(contexts[n]);
109 warning2("Duplicate assignment to delimiter \"%s\" in context \"%s\"",
112 m_free(mb_dstring,"multi-byte string");
113 m_free(mb_contexts,"multi-byte string");
117 /* Read the code to be executed with a given state transition */
121 int c ; /* c is int instead of char for use with ungetc */
123 LOGICAL comment = FALSE;
125 M_WCHAR wlb = 0, wcm, wnl, wsl, wst;
130 mbtowc(&wlb, "{", 1); /* keep the "}" balanced */
131 mbtowc(&wcm, ",", 1);
132 mbtowc(&wnl, "\n", 1);
133 mbtowc(&wsl, "/", 1);
134 mbtowc(&wst, "*", 1);
137 while (m_whitespace((M_WCHAR) (c = readchar(FALSE))));
138 if (c != wlb && c != wcm)
148 mb_dname = MakeMByteString(dname);
150 fprintf(fcase, " case %s:\n", mb_dname);
151 fprintf(fcase, " switch (m_prevcon) {\n") ; /* balance the } */
152 m_free(mb_dname,"multi-byte string");
155 mb_context = MakeMByteString(contexts[n]);
156 fprintf(fcase, " case %s:\n", mb_context);
157 m_free(mb_context,"multi-byte string");
159 if (c == wcm) return;
161 fprintf(fcase, "/* line %d \"context.dat\" */\n", m_line);
165 char mb_c[32]; /* arbitrarily large */
171 warning("Unexpected EOF");
175 length = wctomb(mb_c, c);
182 if (! comment) nested++;
188 fprintf(fcase,"\n break ;\n");
197 if (c == wst) comment = TRUE;
198 length = wctomb(mb_c, c);
207 if (c == wsl) comment = FALSE;
208 length = wctomb(mb_c, c);
213 fprintf(fcase, "%s", mb_c);
216 fprintf(fcase, "#line %d \"context.dat\"\n", m_line);
219 } /* End proc getcode() */
221 /* Read the colon separating the two states in a transition pair */
222 void getcolon(M_NOPAR)
224 int c ; /* c is int instead of char for use with ungetc */
226 char unexp[32]; /* arbitraily large */
229 mbtowc(&wcl, ":", 1);
234 if (! m_whitespace((M_WCHAR) c)) break;
238 length = wctomb(unexp, (M_WCHAR) c);
240 warning1("Expecting : instead of '%s'\n", unexp);
244 /* Read a context name from an input line */
245 int getContext(M_NOPAR)
247 M_WCHAR name[CNAMELEN + 1];
248 int c ; /* c is int instead of char for use with ungetc */
250 M_WCHAR wsm = 0, wcl, wcm;
255 mbtowc(&wsm, ";", 1);
256 mbtowc(&wcl, ":", 1);
257 mbtowc(&wcm, ",", 1);
263 if (c == EOF) return(NOMORE);
265 if (*name == wsm) return(NOMORE);
266 if (! m_whitespace(*name)) break;
274 while (! m_whitespace((M_WCHAR) (c = readchar(TRUE)))
283 if (m_whitespace((M_WCHAR) c) ||
292 name[i] = (M_WCHAR) c;
296 for (i = 0 ; i < ccount ; i++)
297 if (! w_strcmp(name, contexts[i])) return(i);
300 i = w_strlen(name) + 1;
301 contexts[ccount - 1] = (M_WCHAR *) m_malloc(i, "context name");
302 memcpy(contexts[ccount - 1], name, i * sizeof(M_WCHAR));
304 mb_name = MakeMByteString(name);
305 fprintf(context, "#define %s %d\n", mb_name, ccount);
306 m_free(mb_name,"multi-byte string");
311 /* Read a delimiter name from the input line */
312 LOGICAL getdname(M_NOPAR)
317 /* Skip leading blanks */
321 if (c == EOF) return(FALSE);
322 if (! m_whitespace((M_WCHAR) c)) break;
325 ! m_whitespace((M_WCHAR) c) && c != EOF;
328 if (p - dname >= DNAMELEN)
330 while (! m_whitespace((M_WCHAR) c) && c != EOF) c = readchar(TRUE);
336 if (dstruct = (struct dstruct *) m_lookfortrie(dname, &delimtrie))
339 curdelim = dstruct->count - 1;
348 mb_dname = MakeMByteString(dname);
349 fprintf(delim, "#define %s %d\n", mb_dname, dcount);
350 m_free(mb_dname,"multi-byte string");
355 /* Out of context space. Increase. */
358 M_TRIE **newtrie = NULL;
359 int *newtransit = NULL;
360 M_WCHAR **newcontexts = NULL;
364 if (ccount < NUMCON) {
368 trysize = m_plus10p(NUMCON);
369 newtrie = (M_TRIE **) calloc(trysize, sizeof(M_TRIE *));
370 newtransit = (int *) calloc(trysize * NUMDELIM, sizeof(int));
371 newcontexts = (M_WCHAR **) calloc(trysize, sizeof(M_WCHAR *));
372 if (! newtrie || ! newtransit || ! newcontexts) {
373 trysize = NUMCON + 1;
374 if (newtrie) free((M_POINTER) newtrie);
375 if (newtransit) free((M_POINTER) newtransit);
376 if (newcontexts) free((M_POINTER) newcontexts);
377 newtrie = (M_TRIE **) calloc(trysize, sizeof(M_TRIE *));
378 newtransit = (int *) calloc(trysize * NUMDELIM, sizeof(int));
379 newcontexts = (M_WCHAR **) calloc(trysize, sizeof(M_WCHAR *));
381 if (! newtrie || ! newtransit || ! newcontexts) {
382 m_error("Out of memory for contexts");
385 for (i = 0 ; i < ccount ; i++)
386 for (j = 0 ; j < dcount ; j++)
387 newtransit[i * NUMDELIM + j] = transit(i, j);
389 free((M_POINTER) xtransit);
390 xtransit = newtransit;
391 memcpy((M_POINTER) newtrie, (M_POINTER) contree,
392 ccount * sizeof(M_TRIE **));
393 memcpy((M_POINTER) newcontexts, (M_POINTER) contexts,
394 ccount * sizeof(M_WCHAR **));
395 free((M_POINTER) contree);
396 free((M_POINTER) contexts);
398 contexts = newcontexts;
402 /* Increase delimiter space. */
403 void incdelim(M_NOPAR)
405 int *newtransit = NULL;
406 char **newdlm = NULL;
410 if (dcount < NUMDELIM)
416 trysize = m_plus10p(NUMDELIM);
417 newtransit = (int *) calloc(NUMCON * trysize, sizeof(int));
418 if (loading) newdlm = (char **) calloc(trysize, sizeof(M_WCHAR *));
419 if (! newtransit || (loading && ! newdlm))
421 trysize = NUMDELIM + 1;
422 newtransit = (int *) calloc(NUMCON * trysize, sizeof(int));
423 if (loading) newdlm = (char **) calloc(trysize, sizeof(M_WCHAR *));
425 if (! newtransit || (loading && ! newdlm))
427 m_error("Out of memory for delimiters");
430 for (i = 0 ; i < ccount ; i++)
431 for (j = 0 ; j < dcount ; j++)
432 newtransit[i * trysize + j] = transit(i, j);
433 free((M_POINTER) xtransit);
436 memcpy((M_POINTER) newdlm, (M_POINTER) dlmptr, dcount * sizeof(M_TRIE **));
437 free((M_POINTER) dlmptr);
441 xtransit = newtransit;
445 /* Read delimiter definitions from delim.dat */
446 void loaddelim(M_NOPAR)
452 char *mb_dname, *mb_dstring;
454 mbtowc(&wnl, "\n", 1);
457 while ((c = getc(ddat)) != EOF)
459 /* Skip leading white space */
460 if (c == wnl) continue;
461 if (m_whitespace((M_WCHAR) c))
463 while ((c = getc(ddat)) != wnl)
464 if (c == EOF) return;
467 /* Delimiter name into dname */
468 for (p = dname ; ! m_whitespace((M_WCHAR) c) ; c = getc(ddat))
472 warning("Unexpected EOF");
475 if (p - dname >= DNAMELEN)
477 while (! m_whitespace((M_WCHAR) c) && c != EOF) c = getc(ddat);
480 warning("Unexpected EOF");
488 /* Skip intervening white space */
489 while (m_whitespace((M_WCHAR) c) && c != EOF) c = getc(ddat);
492 warning("Unexpected EOF");
495 /* Delimiter string into dstring */
497 ! m_whitespace((M_WCHAR) c) && c != EOF;
500 if (p - dstring >= DELIMLEN)
502 m_error("Delimiter string too long");
508 if (w_strlen(dstring) > maxd) maxd = w_strlen(dstring);
509 /* Write definitions to output file. Save data for later. */
511 dstruct = (struct dstruct *)
512 m_malloc(sizeof(struct dstruct), "delimiter structure");
513 dstruct->string = (M_WCHAR *) m_malloc(w_strlen(dstring) + 1, "delimiter");
514 w_strcpy(dstruct->string, dstring);
515 dstruct->count = dcount;
517 mb_dname = MakeMByteString(dname);
518 fprintf(delim, "#define %s %d\n", mb_dname, dcount);
519 m_free(mb_dname,"multi-byte string");
521 for (i = 0 ; dname[i] ; i++)
522 dname[i] = m_lower(dname[i]);
523 mb_dname = MakeMByteString(dname);
525 mb_dstring = MakeMByteString(dstring);
527 "M_DELIMEXTERN char %s[%d] M_DELIMINIT(\"",
529 strlen(mb_dstring) + 1);
531 for (p = dstring ; *p ; p++)
534 char mb_p[32]; /* arbitrarily large */
537 length = wctomb(mb_p, *p);
543 if (*pc == '"' || *pc == '\\') putc('\\', delim);
548 fputs("\") ;\n", delim);
550 dlmptr[dcount - 1] = MakeMByteString(dname);
551 if (m_ntrtrie(dname, &delimtrie, dstruct))
552 m_err1("Duplicate definition of %s", mb_dname);
558 m_free(mb_dname,"multi-byte string");
559 m_free(mb_dstring,"multi-byte string");
565 /* Output transition matrix */
567 void nextcon(LOGICAL sparse)
577 for (i = 0 ; i < ccount ; i++) {
578 for (j = 0 ; j < dcount ; j++)
579 if (transit(i, j)) nonzero++;
583 "M_DELIMEXTERN struct {\n %s context ;\n %s nextcon ;\n",
585 fprintf(delim, " } m_trnsit [%d]\n", nonzero);
588 fprintf(delim, "#if defined(M_DELIMDEF)\n = {\n");
589 fprintf(context, "M_CONEXTERN int m_trnsptr[%d]\n", ccount);
590 fprintf(context, "#if defined(M_CONDEF)\n = {\n");
591 for (i = 0 ; i < ccount ; i++) {
593 for (j = 0 ; j < dcount ; j++) {
594 if (! transit(i, j)) continue;
595 prtctxt(j, transit(i, j));
596 if (! firstinrow) firstinrow = nonzero;
599 if (i > 0) fprintf(context, ",\n");
600 fprintf(context, " %d", firstinrow);
602 fprintf(delim, endif);
603 fprintf(context, endif);
607 "M_CONEXTERN %s m_nextcon[%d][%d]\n#if defined(M_CONDEF)\n = {\n",
608 contype, ccount, dcount);
609 for (i = 0 ; i < ccount ; i++) {
610 fprintf(context, " {\n");
611 for (j = 0 ; j < dcount ; j++) {
612 fprintf(context, " %d", transit(i, j));
613 if (j < dcount - 1) fprintf(context, ",\n");
615 fprintf(context, "}");
616 if (i < ccount - 1) fprintf(context, ",");
617 fprintf(context, "\n");
619 fprintf(context, endif);
623 /* If sparse matrix output option, generate a single element of transit
625 void prtctxt(column, value)
628 static LOGICAL first = TRUE;
630 if (! first) fprintf(delim, ",\n");
632 fprintf(delim, " %d, %d", column, value);
637 /* Read the next input character */
639 int readchar(LOGICAL cap)
648 mbtowc(&wnl, "\n", 1);
650 c = mb_getwc(cdat); /* use mb_getwc so we read multi-byte chars */
651 if (cap && c != EOF) c = m_upper(c);
653 if (c == wnl) m_line++;
658 /* Called by utility procedure m_error() -- has content in other programs
659 that use m_error() */
660 void skiptoend(M_NOPAR)
664 /* Return a character to the input stream for re-reading */
670 mbtowc(&wnl, "\n", 1);
673 if (c == wnl) m_line--;