cdesktopenv/cde/programs/dthelp/parser/pass2/parser/actutil.c

339 lines
9.1 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: actutil.c /main/3 1995/11/08 10:48:36 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Actutil.c contains utility procedures for processing actions specified
in the interface definition.*/
#include <stdio.h>
#include <stdlib.h>
#if defined(MSDOS)
#include <process.h>
#endif
#include <string.h>
#include "basic.h"
#include "trie.h"
#include "dtdext.h"
#include "parser.h"
#define M_IFDEF
#include "if.h"
#include "delim.h"
#include "context.h"
#include "signon.h"
/* When an explicit or implied end-tag occurs */
void m_endaction(m_elt)
M_ELEMENT m_elt;
{
M_ELEMENT m_action;
char buffer[2*MAXD+M_NAMELEN+1];
if (m_tagtrace) {
if (m_element[m_elt - 1].content != M_NONE) {
if (m_toptstat == M_OTHER) {
strcpy(buffer, "\n");
m_trace(buffer);
}
sprintf(buffer,
"%s%s%s",
m_etago,
m_nameofelt(m_elt),
m_tagc);
m_trace(buffer);
}
m_toptstat = M_OTHER;
}
if (m_action = m_findact(m_elt, m_ecarray)) {
m_stackpar = m_stacktop;
m_endcase(m_action);
}
if (m_action = m_findact(m_elt, m_etarray)) {
m_stackpar = m_stacktop->stparam;
m_textout(&m_string[m_action - 1], FALSE, TRUE);
}
}
/* Find appropriate action according to current stack */
int m_findact(elt, array)
M_ELEMENT elt;
int *array;
{
int chainlen = 0;
int index;
if (! array[elt - 1]) return(FALSE);
if (m_stacktop->element != elt) {
m_error("Program error in findact");
m_exit(TRUE);
}
/* There is an action for this element with no context specification */
if (m_action[array[elt - 1] - 1].data) {
chainlen = 1;
index = array[elt - 1];
}
/* Only actions for this element have context specified */
else {
chainlen = 0;
index = 0;
}
m_findchain(m_stacktop->oldtop, array[elt - 1], chainlen, &chainlen,
&index, FALSE);
return(index ? m_action[index - 1].data : FALSE);
}
/* Recursive procedure called by findact() to search m_action */
#if defined(M_PROTO)
void m_findchain(M_PARSE *stackptr, int start, int chainin, int *chainout, int *index, LOGICAL wild)
#else
void m_findchain(stackptr, start, chainin, chainout, index, wild)
M_PARSE *stackptr;
int start;
int chainin;
int *chainout;
int *index;
LOGICAL wild;
#endif
{
int node;
M_PARSE *stackp;
for (node = m_action[start - 1].son ; node;
node = m_action[node - 1].next) {
if (m_action[node - 1].element == 1)
m_findchain(stackptr, node, chainin, chainout, index, TRUE);
else for (stackp = stackptr;
stackp->oldtop;
stackp = stackp->oldtop) {
if (stackp->element == m_action[node - 1].element - 1) {
if (m_action[node - 1].data)
if (chainin + 1 > *chainout ||
(chainin + 1 == *chainout && node < *index)) {
*chainout = chainin + 1;
*index = node;
}
m_findchain(stackp->oldtop, node, chainin + 1, chainout,
index, FALSE);
}
if (! wild) break;
}
}
}
/* Process global end string. In separate procedure to keep all references
to if.h in one source file and minimize recompilation if interface
changes. */
void m_globes(M_NOPAR)
{
M_WCHAR *wc_string;
wc_string = MakeWideCharString(&m_string[m_ges]);
if (m_ges) m_stcaction(wc_string, FALSE, TRUE);
m_free(wc_string,"wide character string");
}
/* Process global start string. In separate procedure to keep all references
to if.h in one source file and minimize recompilation if interface
changes. */
void m_globss(M_NOPAR)
{
M_WCHAR *wc_string;
wc_string = MakeWideCharString(&m_string[m_gss]);
if (m_gss) m_stcaction(wc_string, TRUE, FALSE);
m_free(wc_string,"wide character string");
}
/* When an explicit or implied start-tag occurs */
void m_strtaction(m_elt)
M_ELEMENT m_elt;
{
int m_par, m_i;
M_WCHAR *m_p;
M_ELEMENT m_action;
static char newpar[] = "\n ";
static char quote[] = " = \"";
char buffer[M_NAMELEN + 1 +
(sizeof(quote) + sizeof(newpar) - 2 > MAXD ?
sizeof(quote) + sizeof(newpar) - 2 :
MAXD)
];
m_start = TRUE;
m_getline(&m_stacktop->file, &m_stacktop->line);
if (m_tagtrace) {
sprintf(buffer, "%s%s", m_stago, m_nameofelt(m_elt));
m_trace(buffer);
for (m_i = 0, m_par = m_element[m_elt - 1].parptr;
m_i < m_element[m_elt - 1].parcount;
m_i++, m_par++)
if (m_stacktop->param[m_i]) {
sprintf(buffer, "%s%s%s",
newpar, &m_pname[m_parameter[m_par - 1].paramname], quote);
m_trace(buffer);
buffer[1] = M_EOS;
for (m_p = m_stacktop->param[m_i] ; *m_p ; m_p++)
if (*m_p != '"') {
buffer[0] = *m_p;
m_trace(buffer);
}
else {
sprintf(buffer, "%s%d", m_cro, '"');
m_trace(buffer);
buffer[1] = M_EOS;
}
buffer[0] = '"';
m_trace(buffer);
}
if (m_element[m_elt - 1].parcount) {
buffer[0] = '\n';
buffer[1] = M_EOS;
m_trace(buffer);
}
sprintf(buffer, "%s\n", m_tagc);
m_trace(buffer);
m_toptstat = M_TOPTSTARTTAG;
}
if (m_action = m_findact(m_elt, m_scarray)) {
m_stackpar = m_stacktop;
m_strtcase(m_action);
}
if (m_action = m_findact(m_elt, m_stcarray)) {
m_stacktop->stccase = m_action;
m_stacktop->stparam = m_stacktop;
}
if (m_action = m_findact(m_elt, m_starray)) {
m_stackpar = m_stacktop->stparam;
m_textout(&m_string[m_action - 1], TRUE, FALSE);
}
if (m_action = m_findact(m_elt, m_tcarray)) {
m_stacktop->cdcase = m_action;
m_stacktop->cdparam = m_stacktop;
}
if (m_action = m_findact(m_elt, m_pcarray)) {
m_stacktop->picase = m_action;
m_stacktop->piparam = m_stacktop;
}
}
/* Output a start-string or end-string */
#if defined(M_PROTO)
void m_textout(char *format, LOGICAL start, LOGICAL end)
#else
void m_textout(format, start, end)
char *format;
LOGICAL start;
LOGICAL end;
#endif
{
M_WCHAR name[M_NAMELEN + 1];
int i, par;
LOGICAL found;
M_WCHAR *string;
M_WCHAR *p;
M_WCHAR *q;
M_WCHAR *r;
M_WCHAR *s;
M_WCHAR *new;
int stringlen;
int changelen;
int unused;
stringlen = strlen(format) + 1;
unused = 0;
string = (M_WCHAR *) m_malloc(stringlen, "string space");
for (p = string ; *format ; )
{
if (*format == M_ESCAPECHAR)
{
for (i = 0, format++ ; i < M_NAMELEN ; i++, format++)
{
mbtowc(&name[i], format, 1);
if (m_cttype(name[i]) == M_NONNAME ||
(m_cttype(name[i]) != M_NMSTART && i == 0)
) break;
}
if (! i)
{
char mb;
mb = M_ESCAPECHAR;
mbtowc(p, &mb, 1);
p++;
/* Double escape character used to insert a single escape character
in the output string */
if (*format == M_ESCAPECHAR) format++;
continue;
}
name[i] = M_EOS;
for (found = FALSE, i = 0,
par = m_element[m_stacktop->element - 1].parptr;
i < m_element[m_stacktop->element - 1].parcount;
i++, par++)
if (! m_wcupstrcmp(&m_pname[m_parameter[par - 1].paramname], name))
{
q = m_stacktop->param[i];
if (! q)
{
found = TRUE;
unused += w_strlen(name) + 1;
break;
}
changelen = w_strlen(q) - w_strlen(name) - 1 - unused;
if (changelen > 0)
{
new = (M_WCHAR *) m_malloc(stringlen + changelen,
"string space");
for (r = string, s = new ; r < p ; ) *s++ = *r++;
m_free(string, "string space");
string = new;
stringlen = stringlen + changelen;
p = s;
unused = 0;
}
else if (changelen < 0) unused = -changelen;
found = TRUE;
break;
}
if (! found)
{
char mb;
mb = M_ESCAPECHAR;
mbtowc(p, &mb, 1);
p++;
q = name;
}
if (q) while (*q) *p++ = *q++;
}
else *p++ = *format++;
}
*p = M_EOS;
m_stcaction(string, start, end);
m_free(string, "string space");
}