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, "%s", 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, "%s", endif);
87 fprintf(context, "%s", 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;
131 ret = mbtowc(&wlb, "{", 1); /* keep the "}" balanced */
132 ret = mbtowc(&wcm, ",", 1);
133 ret = mbtowc(&wnl, "\n", 1);
134 ret = mbtowc(&wsl, "/", 1);
135 ret = mbtowc(&wst, "*", 1);
139 while (m_whitespace((M_WCHAR) (c = readchar(FALSE))));
140 if (c != wlb && c != wcm)
150 mb_dname = MakeMByteString(dname);
152 fprintf(fcase, " case %s:\n", mb_dname);
153 fprintf(fcase, " switch (m_prevcon) {\n") ; /* balance the } */
154 m_free(mb_dname,"multi-byte string");
157 mb_context = MakeMByteString(contexts[n]);
158 fprintf(fcase, " case %s:\n", mb_context);
159 m_free(mb_context,"multi-byte string");
161 if (c == wcm) return;
163 fprintf(fcase, "/* line %d \"context.dat\" */\n", m_line);
167 char mb_c[32]; /* arbitrarily large */
173 warning("Unexpected EOF");
177 length = wctomb(mb_c, c);
184 if (! comment) nested++;
190 fprintf(fcase,"\n break ;\n");
199 if (c == wst) comment = TRUE;
200 length = wctomb(mb_c, c);
209 if (c == wsl) comment = FALSE;
210 length = wctomb(mb_c, c);
215 fprintf(fcase, "%s", mb_c);
218 fprintf(fcase, "#line %d \"context.dat\"\n", m_line);
221 } /* End proc getcode() */
223 /* Read the colon separating the two states in a transition pair */
224 void getcolon(M_NOPAR)
226 int c ; /* c is int instead of char for use with ungetc */
228 char unexp[32]; /* arbitraily large */
231 int ret = mbtowc(&wcl, ":", 1);
237 if (! m_whitespace((M_WCHAR) c)) break;
241 length = wctomb(unexp, (M_WCHAR) c);
243 warning1("Expecting : instead of '%s'\n", unexp);
247 /* Read a context name from an input line */
248 int getContext(M_NOPAR)
250 M_WCHAR name[CNAMELEN + 1];
251 int c ; /* c is int instead of char for use with ungetc */
253 M_WCHAR wsm = 0, wcl, wcm;
259 ret = mbtowc(&wsm, ";", 1);
260 ret = mbtowc(&wcl, ":", 1);
261 ret = mbtowc(&wcm, ",", 1);
268 if (c == EOF) return(NOMORE);
270 if (*name == wsm) return(NOMORE);
271 if (! m_whitespace(*name)) break;
279 while (! m_whitespace((M_WCHAR) (c = readchar(TRUE)))
288 if (m_whitespace((M_WCHAR) c) ||
297 name[i] = (M_WCHAR) c;
301 for (i = 0 ; i < ccount ; i++)
302 if (! w_strcmp(name, contexts[i])) return(i);
305 i = w_strlen(name) + 1;
306 contexts[ccount - 1] = (M_WCHAR *) m_malloc(i, "context name");
307 memcpy(contexts[ccount - 1], name, i * sizeof(M_WCHAR));
309 mb_name = MakeMByteString(name);
310 fprintf(context, "#define %s %d\n", mb_name, ccount);
311 m_free(mb_name,"multi-byte string");
316 /* Read a delimiter name from the input line */
317 LOGICAL getdname(M_NOPAR)
322 /* Skip leading blanks */
326 if (c == EOF) return(FALSE);
327 if (! m_whitespace((M_WCHAR) c)) break;
330 ! m_whitespace((M_WCHAR) c) && c != EOF;
333 if (p - dname >= DNAMELEN)
335 while (! m_whitespace((M_WCHAR) c) && c != EOF) c = readchar(TRUE);
341 if ((dstruct = (struct dstruct *) m_lookfortrie(dname, &delimtrie)))
344 curdelim = dstruct->count - 1;
353 mb_dname = MakeMByteString(dname);
354 fprintf(delim, "#define %s %d\n", mb_dname, dcount);
355 m_free(mb_dname,"multi-byte string");
360 /* Out of context space. Increase. */
363 M_TRIE **newtrie = NULL;
364 int *newtransit = NULL;
365 M_WCHAR **newcontexts = NULL;
369 if (ccount < NUMCON) {
373 trysize = m_plus10p(NUMCON);
374 newtrie = (M_TRIE **) calloc(trysize, sizeof(M_TRIE *));
375 newtransit = (int *) calloc(trysize * NUMDELIM, sizeof(int));
376 newcontexts = (M_WCHAR **) calloc(trysize, sizeof(M_WCHAR *));
377 if (! newtrie || ! newtransit || ! newcontexts) {
378 trysize = NUMCON + 1;
379 if (newtrie) free((M_POINTER) newtrie);
380 if (newtransit) free((M_POINTER) newtransit);
381 if (newcontexts) free((M_POINTER) newcontexts);
382 newtrie = (M_TRIE **) calloc(trysize, sizeof(M_TRIE *));
383 newtransit = (int *) calloc(trysize * NUMDELIM, sizeof(int));
384 newcontexts = (M_WCHAR **) calloc(trysize, sizeof(M_WCHAR *));
386 if (! newtrie || ! newtransit || ! newcontexts) {
387 m_error("Out of memory for contexts");
390 for (i = 0 ; i < ccount ; i++)
391 for (j = 0 ; j < dcount ; j++)
392 newtransit[i * NUMDELIM + j] = transit(i, j);
394 free((M_POINTER) xtransit);
395 xtransit = newtransit;
396 memcpy((M_POINTER) newtrie, (M_POINTER) contree,
397 ccount * sizeof(M_TRIE **));
398 memcpy((M_POINTER) newcontexts, (M_POINTER) contexts,
399 ccount * sizeof(M_WCHAR **));
400 free((M_POINTER) contree);
401 free((M_POINTER) contexts);
403 contexts = newcontexts;
407 /* Increase delimiter space. */
408 void incdelim(M_NOPAR)
410 int *newtransit = NULL;
411 char **newdlm = NULL;
415 if (dcount < NUMDELIM)
421 trysize = m_plus10p(NUMDELIM);
422 newtransit = (int *) calloc(NUMCON * trysize, sizeof(int));
423 if (loading) newdlm = (char **) calloc(trysize, sizeof(M_WCHAR *));
424 if (! newtransit || (loading && ! newdlm))
426 trysize = NUMDELIM + 1;
428 newtransit = (int *) calloc(NUMCON * trysize, sizeof(int));
431 newdlm = (char **) calloc(trysize, sizeof(M_WCHAR *));
434 if (! newtransit || (loading && ! newdlm))
436 m_error("Out of memory for delimiters");
439 for (i = 0 ; i < ccount ; i++)
440 for (j = 0 ; j < dcount ; j++)
441 newtransit[i * trysize + j] = transit(i, j);
442 free((M_POINTER) xtransit);
445 memcpy((M_POINTER) newdlm, (M_POINTER) dlmptr, dcount * sizeof(M_TRIE **));
446 free((M_POINTER) dlmptr);
450 xtransit = newtransit;
454 /* Read delimiter definitions from delim.dat */
455 void loaddelim(M_NOPAR)
461 char *mb_dname, *mb_dstring;
463 int ret = mbtowc(&wnl, "\n", 1);
467 while ((c = getc(ddat)) != EOF)
469 /* Skip leading white space */
470 if (c == wnl) continue;
471 if (m_whitespace((M_WCHAR) c))
473 while ((c = getc(ddat)) != wnl)
474 if (c == EOF) return;
477 /* Delimiter name into dname */
478 for (p = dname ; ! m_whitespace((M_WCHAR) c) ; c = getc(ddat))
482 warning("Unexpected EOF");
485 if (p - dname >= DNAMELEN)
487 while (! m_whitespace((M_WCHAR) c) && c != EOF) c = getc(ddat);
490 warning("Unexpected EOF");
498 /* Skip intervening white space */
499 while (m_whitespace((M_WCHAR) c) && c != EOF) c = getc(ddat);
502 warning("Unexpected EOF");
505 /* Delimiter string into dstring */
507 ! m_whitespace((M_WCHAR) c) && c != EOF;
510 if (p - dstring >= DELIMLEN)
512 m_error("Delimiter string too long");
518 if (w_strlen(dstring) > maxd) maxd = w_strlen(dstring);
519 /* Write definitions to output file. Save data for later. */
521 dstruct = (struct dstruct *)
522 m_malloc(sizeof(struct dstruct), "delimiter structure");
523 dstruct->string = (M_WCHAR *) m_malloc(w_strlen(dstring) + 1, "delimiter");
524 w_strcpy(dstruct->string, dstring);
525 dstruct->count = dcount;
527 mb_dname = MakeMByteString(dname);
528 fprintf(delim, "#define %s %d\n", mb_dname, dcount);
529 m_free(mb_dname,"multi-byte string");
531 for (i = 0 ; dname[i] ; i++)
532 dname[i] = m_lower(dname[i]);
533 mb_dname = MakeMByteString(dname);
535 mb_dstring = MakeMByteString(dstring);
537 "M_DELIMEXTERN char %s[%d] M_DELIMINIT(\"",
539 (int)strlen(mb_dstring) + 1);
541 for (p = dstring ; *p ; p++)
544 char mb_p[32]; /* arbitrarily large */
547 length = wctomb(mb_p, *p);
553 if (*pc == '"' || *pc == '\\') putc('\\', delim);
558 fputs("\") ;\n", delim);
560 dlmptr[dcount - 1] = MakeMByteString(dname);
561 if (m_ntrtrie(dname, &delimtrie, dstruct))
562 m_err1("Duplicate definition of %s", mb_dname);
568 m_free(mb_dname,"multi-byte string");
569 m_free(mb_dstring,"multi-byte string");
575 /* Output transition matrix */
577 void nextcon(LOGICAL sparse)
587 for (i = 0 ; i < ccount ; i++) {
588 for (j = 0 ; j < dcount ; j++)
589 if (transit(i, j)) nonzero++;
593 "M_DELIMEXTERN struct {\n %s context ;\n %s nextcon ;\n",
595 fprintf(delim, " } m_trnsit [%d]\n", nonzero);
598 fprintf(delim, "#if defined(M_DELIMDEF)\n = {\n");
599 fprintf(context, "M_CONEXTERN int m_trnsptr[%d]\n", ccount);
600 fprintf(context, "#if defined(M_CONDEF)\n = {\n");
601 for (i = 0 ; i < ccount ; i++) {
603 for (j = 0 ; j < dcount ; j++) {
604 if (! transit(i, j)) continue;
605 prtctxt(j, transit(i, j));
606 if (! firstinrow) firstinrow = nonzero;
609 if (i > 0) fprintf(context, ",\n");
610 fprintf(context, " %d", firstinrow);
612 fprintf(delim, "%s", endif);
613 fprintf(context, "%s", endif);
617 "M_CONEXTERN %s m_nextcon[%d][%d]\n#if defined(M_CONDEF)\n = {\n",
618 contype, ccount, dcount);
619 for (i = 0 ; i < ccount ; i++) {
620 fprintf(context, " {\n");
621 for (j = 0 ; j < dcount ; j++) {
622 fprintf(context, " %d", transit(i, j));
623 if (j < dcount - 1) fprintf(context, ",\n");
625 fprintf(context, "}");
626 if (i < ccount - 1) fprintf(context, ",");
627 fprintf(context, "\n");
629 fprintf(context, "%s", endif);
633 /* If sparse matrix output option, generate a single element of transit
635 void prtctxt(column, value)
638 static LOGICAL first = TRUE;
640 if (! first) fprintf(delim, ",\n");
642 fprintf(delim, " {%d, %d}", column, value);
647 /* Read the next input character */
649 int readchar(LOGICAL cap)
658 int ret = mbtowc(&wnl, "\n", 1);
661 c = mb_getwc(cdat); /* use mb_getwc so we read multi-byte chars */
662 if (cap && c != EOF) c = m_upper(c);
664 if (c == wnl) m_line++;
669 /* Called by utility procedure m_error() -- has content in other programs
670 that use m_error() */
671 void skiptoend(M_NOPAR)
675 /* Return a character to the input stream for re-reading */
681 int ret = mbtowc(&wnl, "\n", 1);
685 if (c == wnl) m_line--;