/* * 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 #include #if defined(MSDOS) #include #endif #include #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"); }