Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
652
cde/programs/dthelp/parser/pass2/util/conutil.c
Normal file
652
cde/programs/dthelp/parser/pass2/util/conutil.c
Normal file
@@ -0,0 +1,652 @@
|
||||
/* $XConsortium: conutil.c /main/3 1995/11/08 11:03:16 rswiston $ */
|
||||
/*
|
||||
Copyright 1986 Tandem Computers Incorporated.
|
||||
This product and information is proprietary of Tandem Computers Incorporated.
|
||||
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
|
||||
*/
|
||||
|
||||
/* Conutil has utility procedures for program CONTEXT. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#if defined(MSDOS)
|
||||
#include <process.h>
|
||||
#endif
|
||||
#include "basic.h"
|
||||
#include "trie.h"
|
||||
|
||||
#include "cont.h"
|
||||
|
||||
/* Output declaration of dlmptr */
|
||||
void dumpdlmptr(M_NOPAR)
|
||||
{
|
||||
int n;
|
||||
|
||||
fprintf(delim, "M_DELIMEXTERN M_WCHAR *m_dlmptr[%d];\n", dcount+1);
|
||||
fprintf(delim, "M_DELIMEXTERN char *mb_dlmptr[%d]\n", dcount+1);
|
||||
fprintf(delim, "#if defined(M_DELIMDEF)\n = {\n");
|
||||
for (n = 0 ; n < dcount ; n++) {
|
||||
if (n) fputs(",\n", delim);
|
||||
fprintf(delim, " %s", dlmptr[n]);
|
||||
}
|
||||
fprintf(delim, endif);
|
||||
}
|
||||
|
||||
/* Output the generated data structures */
|
||||
#if defined(M_PROTO)
|
||||
void dumptree(LOGICAL sparse)
|
||||
#else
|
||||
void dumptree(sparse)
|
||||
LOGICAL sparse;
|
||||
#endif
|
||||
{
|
||||
int i, count = 0;
|
||||
|
||||
for (i = 0 ; i < ccount ; i++)
|
||||
if (contree[i])
|
||||
countdown(contree[i], &count);
|
||||
fprintf(delim,
|
||||
"M_DELIMEXTERN M_PTRIE m_delimtrie[%d]\n#if defined(M_DELIMDEF)\n = {\n",
|
||||
count);
|
||||
fprintf(context,
|
||||
"M_CONEXTERN int m_contree[%d]\n#if defined(M_CONDEF)\n = {\n ",
|
||||
ccount);
|
||||
|
||||
count = 0;
|
||||
for (i = 0 ; i < ccount ; i++) {
|
||||
if (contree[i]) {
|
||||
fprintf(context, "%d", count + 1);
|
||||
dumpnode(&first, delim, contree[i], &count, (void *)printval);
|
||||
}
|
||||
else fprintf(context, "0");
|
||||
if (i < ccount - 1) fprintf(context, ",\n ");
|
||||
}
|
||||
fprintf(delim, endif);
|
||||
fprintf(context, endif);
|
||||
nextcon(sparse);
|
||||
}
|
||||
|
||||
/* Enter a delimiter into the delimiter tree for a particular context */
|
||||
void enterdelim(n)
|
||||
int n;
|
||||
{
|
||||
if (! contree[n])
|
||||
{
|
||||
contree[n] = m_gettrienode();
|
||||
}
|
||||
|
||||
if (m_ntrtrie(dstruct->string,
|
||||
contree[n],
|
||||
(void *) (unsigned long) dstruct->count))
|
||||
{
|
||||
char *mb_dstring, *mb_contexts;
|
||||
|
||||
mb_dstring = MakeMByteString(dstring);
|
||||
mb_contexts = MakeMByteString(contexts[n]);
|
||||
dcount--;
|
||||
warning2("Duplicate assignment to delimiter \"%s\" in context \"%s\"",
|
||||
mb_dstring,
|
||||
mb_contexts);
|
||||
m_free(mb_dstring,"multi-byte string");
|
||||
m_free(mb_contexts,"multi-byte string");
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the code to be executed with a given state transition */
|
||||
void getcode(n)
|
||||
int n;
|
||||
{
|
||||
int c ; /* c is int instead of char for use with ungetc */
|
||||
int nested = 1;
|
||||
LOGICAL comment = FALSE;
|
||||
char *mb_context;
|
||||
M_WCHAR wlb = 0, wcm, wnl, wsl, wst;
|
||||
|
||||
|
||||
if (!wlb)
|
||||
{
|
||||
mbtowc(&wlb, "{", 1); /* keep the "}" balanced */
|
||||
mbtowc(&wcm, ",", 1);
|
||||
mbtowc(&wnl, "\n", 1);
|
||||
mbtowc(&wsl, "/", 1);
|
||||
mbtowc(&wst, "*", 1);
|
||||
}
|
||||
|
||||
while (m_whitespace((M_WCHAR) (c = readchar(FALSE))));
|
||||
if (c != wlb && c != wcm)
|
||||
{
|
||||
unread(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (! casestarted)
|
||||
{
|
||||
char *mb_dname;
|
||||
|
||||
mb_dname = MakeMByteString(dname);
|
||||
casestarted = TRUE;
|
||||
fprintf(fcase, " case %s:\n", mb_dname);
|
||||
fprintf(fcase, " switch (m_prevcon) {\n") ; /* balance the } */
|
||||
m_free(mb_dname,"multi-byte string");
|
||||
}
|
||||
|
||||
mb_context = MakeMByteString(contexts[n]);
|
||||
fprintf(fcase, " case %s:\n", mb_context);
|
||||
m_free(mb_context,"multi-byte string");
|
||||
|
||||
if (c == wcm) return;
|
||||
|
||||
fprintf(fcase, "/* line %d \"context.dat\" */\n", m_line);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
char mb_c[32]; /* arbitrarily large */
|
||||
int length;
|
||||
|
||||
c = readchar(FALSE);
|
||||
if (c == EOF)
|
||||
{
|
||||
warning("Unexpected EOF");
|
||||
exit(TRUE);
|
||||
}
|
||||
|
||||
length = wctomb(mb_c, c);
|
||||
mb_c[length] = 0;
|
||||
if (length == 1)
|
||||
{
|
||||
switch (mb_c[0])
|
||||
{
|
||||
case '{':
|
||||
if (! comment) nested++;
|
||||
break;
|
||||
case '}':
|
||||
if (! comment)
|
||||
if (! --nested)
|
||||
{
|
||||
fprintf(fcase,"\n break ;\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if (! comment)
|
||||
{
|
||||
fprintf(fcase, "/");
|
||||
c = readchar(FALSE);
|
||||
if (c == wst) comment = TRUE;
|
||||
length = wctomb(mb_c, c);
|
||||
mb_c[length] = 0;
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
if (comment)
|
||||
{
|
||||
fprintf(fcase, "*");
|
||||
c = readchar(FALSE);
|
||||
if (c == wsl) comment = FALSE;
|
||||
length = wctomb(mb_c, c);
|
||||
mb_c[length] = 0;
|
||||
}
|
||||
} /* End case */
|
||||
}
|
||||
fprintf(fcase, "%s", mb_c);
|
||||
#if 0
|
||||
if (c == wnl)
|
||||
fprintf(fcase, "#line %d \"context.dat\"\n", m_line);
|
||||
#endif
|
||||
} /* End while */
|
||||
} /* End proc getcode() */
|
||||
|
||||
/* Read the colon separating the two states in a transition pair */
|
||||
void getcolon(M_NOPAR)
|
||||
{
|
||||
int c ; /* c is int instead of char for use with ungetc */
|
||||
M_WCHAR wcl;
|
||||
char unexp[32]; /* arbitraily large */
|
||||
int length;
|
||||
|
||||
mbtowc(&wcl, ":", 1);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
c = readchar(FALSE);
|
||||
if (! m_whitespace((M_WCHAR) c)) break;
|
||||
}
|
||||
if (c != wcl)
|
||||
{
|
||||
length = wctomb(unexp, (M_WCHAR) c);
|
||||
unexp[length] = 0;
|
||||
warning1("Expecting : instead of '%s'\n", unexp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a context name from an input line */
|
||||
int getContext(M_NOPAR)
|
||||
{
|
||||
M_WCHAR name[CNAMELEN + 1];
|
||||
int c ; /* c is int instead of char for use with ungetc */
|
||||
int i = 0;
|
||||
M_WCHAR wsm = 0, wcl, wcm;
|
||||
char *mb_name;
|
||||
|
||||
if (!wsm)
|
||||
{
|
||||
mbtowc(&wsm, ";", 1);
|
||||
mbtowc(&wcl, ":", 1);
|
||||
mbtowc(&wcm, ",", 1);
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
c = readchar(TRUE);
|
||||
if (c == EOF) return(NOMORE);
|
||||
*name = (M_WCHAR) c;
|
||||
if (*name == wsm) return(NOMORE);
|
||||
if (! m_whitespace(*name)) break;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
i++;
|
||||
if (i >= CNAMELEN)
|
||||
{
|
||||
while (! m_whitespace((M_WCHAR) (c = readchar(TRUE)))
|
||||
&& c != wcl
|
||||
&& c != wcm
|
||||
&& c != EOF
|
||||
&& c != wsm);
|
||||
unread(c);
|
||||
break;
|
||||
}
|
||||
c = readchar(TRUE);
|
||||
if (m_whitespace((M_WCHAR) c) ||
|
||||
c == wsm ||
|
||||
c == wcl ||
|
||||
c == wcm ||
|
||||
c == EOF)
|
||||
{
|
||||
unread(c);
|
||||
break;
|
||||
}
|
||||
name[i] = (M_WCHAR) c;
|
||||
}
|
||||
name[i] = M_EOS;
|
||||
|
||||
for (i = 0 ; i < ccount ; i++)
|
||||
if (! w_strcmp(name, contexts[i])) return(i);
|
||||
|
||||
inccon() ;
|
||||
i = w_strlen(name) + 1;
|
||||
contexts[ccount - 1] = (M_WCHAR *) m_malloc(i, "context name");
|
||||
memcpy(contexts[ccount - 1], name, i * sizeof(M_WCHAR));
|
||||
|
||||
mb_name = MakeMByteString(name);
|
||||
fprintf(context, "#define %s %d\n", mb_name, ccount);
|
||||
m_free(mb_name,"multi-byte string");
|
||||
|
||||
return(ccount - 1);
|
||||
}
|
||||
|
||||
/* Read a delimiter name from the input line */
|
||||
LOGICAL getdname(M_NOPAR)
|
||||
{
|
||||
int c;
|
||||
M_WCHAR *p;
|
||||
|
||||
/* Skip leading blanks */
|
||||
while (TRUE)
|
||||
{
|
||||
c = readchar(TRUE);
|
||||
if (c == EOF) return(FALSE);
|
||||
if (! m_whitespace((M_WCHAR) c)) break;
|
||||
}
|
||||
for (p = dname;
|
||||
! m_whitespace((M_WCHAR) c) && c != EOF;
|
||||
c = readchar(TRUE))
|
||||
{
|
||||
if (p - dname >= DNAMELEN)
|
||||
{
|
||||
while (! m_whitespace((M_WCHAR) c) && c != EOF) c = readchar(TRUE);
|
||||
break;
|
||||
}
|
||||
*p++ = (M_WCHAR) c;
|
||||
}
|
||||
*p = M_EOS;
|
||||
if (dstruct = (struct dstruct *) m_lookfortrie(dname, &delimtrie))
|
||||
{
|
||||
withdelim = TRUE;
|
||||
curdelim = dstruct->count - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *mb_dname;
|
||||
|
||||
curdelim = dcount;
|
||||
incdelim();
|
||||
withdelim = FALSE;
|
||||
mb_dname = MakeMByteString(dname);
|
||||
fprintf(delim, "#define %s %d\n", mb_dname, dcount);
|
||||
m_free(mb_dname,"multi-byte string");
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/* Out of context space. Increase. */
|
||||
void inccon(M_NOPAR)
|
||||
{
|
||||
M_TRIE **newtrie = NULL;
|
||||
int *newtransit = NULL;
|
||||
M_WCHAR **newcontexts = NULL;
|
||||
int trysize;
|
||||
int i, j;
|
||||
|
||||
if (ccount < NUMCON) {
|
||||
ccount++;
|
||||
return;
|
||||
}
|
||||
trysize = m_plus10p(NUMCON);
|
||||
newtrie = (M_TRIE **) calloc(trysize, sizeof(M_TRIE *));
|
||||
newtransit = (int *) calloc(trysize * NUMDELIM, sizeof(int));
|
||||
newcontexts = (M_WCHAR **) calloc(trysize, sizeof(M_WCHAR *));
|
||||
if (! newtrie || ! newtransit || ! newcontexts) {
|
||||
trysize = NUMCON + 1;
|
||||
if (newtrie) free((M_POINTER) newtrie);
|
||||
if (newtransit) free((M_POINTER) newtransit);
|
||||
if (newcontexts) free((M_POINTER) newcontexts);
|
||||
newtrie = (M_TRIE **) calloc(trysize, sizeof(M_TRIE *));
|
||||
newtransit = (int *) calloc(trysize * NUMDELIM, sizeof(int));
|
||||
newcontexts = (M_WCHAR **) calloc(trysize, sizeof(M_WCHAR *));
|
||||
}
|
||||
if (! newtrie || ! newtransit || ! newcontexts) {
|
||||
m_error("Out of memory for contexts");
|
||||
exit(TRUE);
|
||||
}
|
||||
for (i = 0 ; i < ccount ; i++)
|
||||
for (j = 0 ; j < dcount ; j++)
|
||||
newtransit[i * NUMDELIM + j] = transit(i, j);
|
||||
NUMCON = trysize;
|
||||
free((M_POINTER) xtransit);
|
||||
xtransit = newtransit;
|
||||
memcpy((M_POINTER) newtrie, (M_POINTER) contree,
|
||||
ccount * sizeof(M_TRIE **));
|
||||
memcpy((M_POINTER) newcontexts, (M_POINTER) contexts,
|
||||
ccount * sizeof(M_WCHAR **));
|
||||
free((M_POINTER) contree);
|
||||
free((M_POINTER) contexts);
|
||||
contree = newtrie;
|
||||
contexts = newcontexts;
|
||||
ccount++;
|
||||
}
|
||||
|
||||
/* Increase delimiter space. */
|
||||
void incdelim(M_NOPAR)
|
||||
{
|
||||
int *newtransit = NULL;
|
||||
char **newdlm = NULL;
|
||||
int trysize;
|
||||
int i, j;
|
||||
|
||||
if (dcount < NUMDELIM)
|
||||
{
|
||||
dcount++;
|
||||
return;
|
||||
}
|
||||
|
||||
trysize = m_plus10p(NUMDELIM);
|
||||
newtransit = (int *) calloc(NUMCON * trysize, sizeof(int));
|
||||
if (loading) newdlm = (char **) calloc(trysize, sizeof(M_WCHAR *));
|
||||
if (! newtransit || (loading && ! newdlm))
|
||||
{
|
||||
trysize = NUMDELIM + 1;
|
||||
newtransit = (int *) calloc(NUMCON * trysize, sizeof(int));
|
||||
if (loading) newdlm = (char **) calloc(trysize, sizeof(M_WCHAR *));
|
||||
}
|
||||
if (! newtransit || (loading && ! newdlm))
|
||||
{
|
||||
m_error("Out of memory for delimiters");
|
||||
exit(TRUE);
|
||||
}
|
||||
for (i = 0 ; i < ccount ; i++)
|
||||
for (j = 0 ; j < dcount ; j++)
|
||||
newtransit[i * trysize + j] = transit(i, j);
|
||||
free((M_POINTER) xtransit);
|
||||
if (loading)
|
||||
{
|
||||
memcpy((M_POINTER) newdlm, (M_POINTER) dlmptr, dcount * sizeof(M_TRIE **));
|
||||
free((M_POINTER) dlmptr);
|
||||
dlmptr = newdlm;
|
||||
}
|
||||
NUMDELIM = trysize;
|
||||
xtransit = newtransit;
|
||||
dcount++;
|
||||
}
|
||||
|
||||
/* Read delimiter definitions from delim.dat */
|
||||
void loaddelim(M_NOPAR)
|
||||
{
|
||||
int c;
|
||||
M_WCHAR *p;
|
||||
int i;
|
||||
M_WCHAR wnl;
|
||||
char *mb_dname, *mb_dstring;
|
||||
|
||||
mbtowc(&wnl, "\n", 1);
|
||||
|
||||
loading = TRUE;
|
||||
while ((c = getc(ddat)) != EOF)
|
||||
{
|
||||
/* Skip leading white space */
|
||||
if (c == wnl) continue;
|
||||
if (m_whitespace((M_WCHAR) c))
|
||||
{
|
||||
while ((c = getc(ddat)) != wnl)
|
||||
if (c == EOF) return;
|
||||
continue;
|
||||
}
|
||||
/* Delimiter name into dname */
|
||||
for (p = dname ; ! m_whitespace((M_WCHAR) c) ; c = getc(ddat))
|
||||
{
|
||||
if (c == EOF)
|
||||
{
|
||||
warning("Unexpected EOF");
|
||||
exit(TRUE);
|
||||
}
|
||||
if (p - dname >= DNAMELEN)
|
||||
{
|
||||
while (! m_whitespace((M_WCHAR) c) && c != EOF) c = getc(ddat);
|
||||
if (c == EOF)
|
||||
{
|
||||
warning("Unexpected EOF");
|
||||
exit(TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
*p++ = m_upper(c);
|
||||
}
|
||||
*p = M_EOS;
|
||||
/* Skip intervening white space */
|
||||
while (m_whitespace((M_WCHAR) c) && c != EOF) c = getc(ddat);
|
||||
if (c == EOF)
|
||||
{
|
||||
warning("Unexpected EOF");
|
||||
exit(TRUE);
|
||||
}
|
||||
/* Delimiter string into dstring */
|
||||
for (p = dstring;
|
||||
! m_whitespace((M_WCHAR) c) && c != EOF;
|
||||
c = getc(ddat))
|
||||
{
|
||||
if (p - dstring >= DELIMLEN)
|
||||
{
|
||||
m_error("Delimiter string too long");
|
||||
exit(TRUE);
|
||||
}
|
||||
*p++ = c;
|
||||
}
|
||||
*p = M_EOS;
|
||||
if (w_strlen(dstring) > maxd) maxd = w_strlen(dstring);
|
||||
/* Write definitions to output file. Save data for later. */
|
||||
incdelim();
|
||||
dstruct = (struct dstruct *)
|
||||
m_malloc(sizeof(struct dstruct), "delimiter structure");
|
||||
dstruct->string = (M_WCHAR *) m_malloc(w_strlen(dstring) + 1, "delimiter");
|
||||
w_strcpy(dstruct->string, dstring);
|
||||
dstruct->count = dcount;
|
||||
|
||||
mb_dname = MakeMByteString(dname);
|
||||
fprintf(delim, "#define %s %d\n", mb_dname, dcount);
|
||||
m_free(mb_dname,"multi-byte string");
|
||||
|
||||
for (i = 0 ; dname[i] ; i++)
|
||||
dname[i] = m_lower(dname[i]);
|
||||
mb_dname = MakeMByteString(dname);
|
||||
|
||||
mb_dstring = MakeMByteString(dstring);
|
||||
fprintf(delim,
|
||||
"M_DELIMEXTERN char %s[%d] M_DELIMINIT(\"",
|
||||
mb_dname,
|
||||
strlen(mb_dstring) + 1);
|
||||
|
||||
for (p = dstring ; *p ; p++)
|
||||
{
|
||||
char *pc;
|
||||
char mb_p[32]; /* arbitrarily large */
|
||||
int length, i;
|
||||
|
||||
length = wctomb(mb_p, *p);
|
||||
mb_p[length] = 0;
|
||||
|
||||
pc = mb_p;
|
||||
while (*pc)
|
||||
{
|
||||
if (*pc == '"' || *pc == '\\') putc('\\', delim);
|
||||
putc(*pc, delim);
|
||||
pc++;
|
||||
}
|
||||
}
|
||||
fputs("\") ;\n", delim);
|
||||
|
||||
dlmptr[dcount - 1] = MakeMByteString(dname);
|
||||
if (m_ntrtrie(dname, &delimtrie, dstruct))
|
||||
m_err1("Duplicate definition of %s", mb_dname);
|
||||
while (c != wnl)
|
||||
{
|
||||
if (c == EOF) break;
|
||||
c = getc(ddat);
|
||||
}
|
||||
m_free(mb_dname,"multi-byte string");
|
||||
m_free(mb_dstring,"multi-byte string");
|
||||
}
|
||||
dumpdlmptr();
|
||||
loading = FALSE;
|
||||
}
|
||||
|
||||
/* Output transition matrix */
|
||||
#if defined(M_PROTO)
|
||||
void nextcon(LOGICAL sparse)
|
||||
#else
|
||||
void nextcon(sparse)
|
||||
LOGICAL sparse;
|
||||
#endif
|
||||
{
|
||||
int i, j;
|
||||
int firstinrow;
|
||||
|
||||
if (sparse) {
|
||||
for (i = 0 ; i < ccount ; i++) {
|
||||
for (j = 0 ; j < dcount ; j++)
|
||||
if (transit(i, j)) nonzero++;
|
||||
nonzero++;
|
||||
}
|
||||
fprintf(delim,
|
||||
"M_DELIMEXTERN struct {\n %s context ;\n %s nextcon ;\n",
|
||||
contype, contype);
|
||||
fprintf(delim, " } m_trnsit [%d]\n", nonzero);
|
||||
|
||||
nonzero = 0;
|
||||
fprintf(delim, "#if defined(M_DELIMDEF)\n = {\n");
|
||||
fprintf(context, "M_CONEXTERN int m_trnsptr[%d]\n", ccount);
|
||||
fprintf(context, "#if defined(M_CONDEF)\n = {\n");
|
||||
for (i = 0 ; i < ccount ; i++) {
|
||||
firstinrow = 0;
|
||||
for (j = 0 ; j < dcount ; j++) {
|
||||
if (! transit(i, j)) continue;
|
||||
prtctxt(j, transit(i, j));
|
||||
if (! firstinrow) firstinrow = nonzero;
|
||||
}
|
||||
prtctxt(0, 0);
|
||||
if (i > 0) fprintf(context, ",\n");
|
||||
fprintf(context, " %d", firstinrow);
|
||||
}
|
||||
fprintf(delim, endif);
|
||||
fprintf(context, endif);
|
||||
}
|
||||
else {
|
||||
fprintf(context,
|
||||
"M_CONEXTERN %s m_nextcon[%d][%d]\n#if defined(M_CONDEF)\n = {\n",
|
||||
contype, ccount, dcount);
|
||||
for (i = 0 ; i < ccount ; i++) {
|
||||
fprintf(context, " {\n");
|
||||
for (j = 0 ; j < dcount ; j++) {
|
||||
fprintf(context, " %d", transit(i, j));
|
||||
if (j < dcount - 1) fprintf(context, ",\n");
|
||||
}
|
||||
fprintf(context, "}");
|
||||
if (i < ccount - 1) fprintf(context, ",");
|
||||
fprintf(context, "\n");
|
||||
}
|
||||
fprintf(context, endif);
|
||||
}
|
||||
}
|
||||
|
||||
/* If sparse matrix output option, generate a single element of transit
|
||||
array */
|
||||
void prtctxt(column, value)
|
||||
int column, value;
|
||||
{
|
||||
static LOGICAL first = TRUE;
|
||||
|
||||
if (! first) fprintf(delim, ",\n");
|
||||
first = FALSE;
|
||||
fprintf(delim, " %d, %d", column, value);
|
||||
nonzero++;
|
||||
}
|
||||
|
||||
|
||||
/* Read the next input character */
|
||||
#if defined(M_PROTO)
|
||||
int readchar(LOGICAL cap)
|
||||
#else
|
||||
int readchar(cap)
|
||||
LOGICAL cap;
|
||||
#endif
|
||||
{
|
||||
int c;
|
||||
M_WCHAR wnl;
|
||||
|
||||
mbtowc(&wnl, "\n", 1);
|
||||
|
||||
c = mb_getwc(cdat); /* use mb_getwc so we read multi-byte chars */
|
||||
if (cap && c != EOF) c = m_upper(c);
|
||||
|
||||
if (c == wnl) m_line++;
|
||||
|
||||
return(c);
|
||||
}
|
||||
|
||||
/* Called by utility procedure m_error() -- has content in other programs
|
||||
that use m_error() */
|
||||
void skiptoend(M_NOPAR)
|
||||
{
|
||||
}
|
||||
|
||||
/* Return a character to the input stream for re-reading */
|
||||
void unread(c)
|
||||
int c;
|
||||
{
|
||||
M_WCHAR wnl;
|
||||
|
||||
mbtowc(&wnl, "\n", 1);
|
||||
|
||||
ungetc(c, cdat);
|
||||
if (c == wnl) m_line--;
|
||||
}
|
||||
Reference in New Issue
Block a user