123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809 |
- /*
- * 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 libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /******************************<+>*************************************
- **********************************************************************
- **
- ** File: WmParse.c
- **
- ** Project: HP/Motif Workspace Manager (dtwm)
- **
- ** Description:
- ** -----------
- ** This file contains the generic parsing routines
- **
- **
- *********************************************************************
- **
- ** (c) Copyright 1987, 1988, 1989, 1990, 1991 HEWLETT-PACKARD COMPANY
- ** ALL RIGHTS RESERVED
- **
- **********************************************************************
- **********************************************************************
- **
- **
- **********************************************************************
- ******************************<+>*************************************/
- /* ANSI C definitions, This should be the first thing in WmGlobal.h */
- #ifdef __STDC__
- #define Const const
- #else
- #define Const /**/
- #endif
- /*
- * Included Files:
- */
- #include <stdio.h>
- #include <X11/Intrinsic.h>
- #include "WmGlobal.h"
- #include "WmParse.h"
- #include "WmParseP.h"
- #include <stdlib.h>
- #include <ctype.h>
- /*
- * Internal routines
- */
- static DtWmpParseBuf * _DtWmpIncBuf (
- DtWmpParseBuf *pWmPB);
- #ifndef MAXLINE
- #define MAXLINE (MAXWMPATH+1)
- #endif
- #define MAX_QUOTE_DEPTH 10
- /*
- * This flags non-OSF code in those sections that were lifted
- * from mwm.
- */
- #define PARSE_LIB
- /*
- * Defines used to maintain code similarity between OSF/mwm source
- * routines and these routines.
- */
- #define cfileP ((pWmPB)->pFile)
- #define linec ((pWmPB)->lineNumber)
- #define line ((pWmPB)->pchLine)
- #define parseP ((pWmPB)->pchNext)
- #define ScanWhitespace(s) (_DtWmParseSkipWhitespaceC(s))
- #define PeekAhead(s,l) (_DtWmParsePeekAhead(s,l))
- /*************************************<->*************************************
- *
- * _DtWmParseSkipWhitespace(pWmPB)
- *
- *
- * Description:
- * -----------
- * Scan the current string, skipping over all white space characters.
- *
- *
- * Inputs:
- * ------
- * pWmPB = ptr to parse buffer
- *
- *
- * Outputs:
- * -------
- * pWmPB = parse buffer modified; current line ptr may be moved.
- *
- *
- * Comments:
- * --------
- * Assumes there's a current line in the parse buffer
- *
- *************************************<->***********************************/
- void _DtWmParseSkipWhitespace(DtWmpParseBuf *pWmPB)
- {
- _DtWmParseSkipWhitespaceC (&(pWmPB->pchNext));
- } /* END OF FUNCTION _DtWmParseSkipWhitespace */
- /*************************************<->*************************************
- *
- * _DtWmParseNextToken (pWmPB)
- *
- *
- * Description:
- * -----------
- * Returns the next quoted or whitespace-terminated nonquoted string in the
- * current line buffer.
- *
- *
- * Inputs:
- * ------
- * pWmPB = ptr to parse buffer
- *
- *
- * Outputs:
- * -------
- * Return = ptr to null terminated string.
- * pWmPB = current line modified internally.
- *
- *
- * Comments:
- * --------
- * May alter the line buffer contents.
- * Handles quoted strings and characters, removing trailing whitespace from
- * quoted strings.
- * Returns NULL string if the line is empty or is a comment.
- * Does not use session manager style algorithm for dealing with
- * quoted strings.
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseNextToken (
- DtWmpParseBuf *pWmPB
- )
- {
- return (_DtWmParseNextTokenC (&(pWmPB->pchNext), False));
- }
- /*************************************<->*************************************
- *
- * _DtWmParseNextTokenExpand (pWmPB)
- *
- *
- * Description:
- * -----------
- * Returns the next quoted or whitespace-terminated nonquoted string in the
- * current line buffer. Environment variables found in the are expanded.
- * Characters quoted by '\' are passed through unaffected with the
- * quoting '\' removed.
- *
- *
- * Inputs:
- * ------
- * pWmPB = ptr to parse buffer
- *
- *
- * Outputs:
- * -------
- * Return = ptr to null terminated string.
- * Free this string with XtFree().
- * pWmPB = current line modified internally.
- *
- *
- * Comments:
- * --------
- * May alter the line buffer contents.
- * Handles quoted strings and characters, removing trailing whitespace from
- * quoted strings.
- * Returns NULL string if the line is empty or is a comment.
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseNextTokenExpand (
- DtWmpParseBuf *pWmPB
- )
- {
- unsigned char *pch;
- unsigned char *pchReturn = NULL;
- /* isolate the next token */
- pch = _DtWmParseNextTokenC (&(pWmPB->pchNext), False);
- /* expand environment variables, a copy of the string is returned */
- pchReturn = _DtWmParseExpandEnvironmentVariables (pch, NULL);
- /*
- * If a token was found, but no copy returned, there were no
- * environment variables. This routine needs to return a copy,
- * so make one now.
- */
- if (pch && !pchReturn)
- pchReturn = (unsigned char *) XtNewString ((String) pch);
- return (pchReturn);
- }
- /*************************************<->*************************************
- *
- * _DtWmParseBackUp (pWmPB, pchTok)
- *
- *
- * Description:
- * -----------
- * Backs up to the previous token (the one before pchTok)
- *
- *
- * Inputs:
- * ------
- * pWmPB = ptr to parse buffer
- * pchTok = ptr to a token in the parse buffer
- *
- *
- * Outputs:
- * -------
- * Returns = ptr to prev token
- *
- *
- * Comments:
- * --------
- * Operates on the line buffer in the pWmPB structure. Backs up
- * the next pointer and writes a space over the interpolated
- * NULL (if any).
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseBackUp (
- DtWmpParseBuf *pWmPB,
- unsigned char *pchTok
- )
- {
- if ((pchTok > pWmPB->pchLine) &&
- (pchTok < (pWmPB->pchLine + pWmPB->cLineSize)))
- {
- unsigned char *pch;
- unsigned char *pchLast;
- int chlen;
- pch = pchLast = pWmPB->pchLine;
- /*
- * Search from beginning (because of multibyte chars) to
- * find the token before the string we're interested in.
- */
- while ((pch < pchTok))
- {
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- if (*pch == '\0')
- {
- pch++;
- if (pch == pchTok)
- {
- /*
- * Found the NULL preceding the string passed in!
- * Replace it with a blank and return the previous
- * token (pointed to by pchLast).
- */
- *(pch - 1) = DTWM_CHAR_SPACE;
- break;
- }
- else
- {
- /*
- * Remember the beginning of this token.
- */
- pchLast = pch;
- }
- }
- else if (chlen < 1)
- {
- break;
- }
- else
- {
- pch += chlen;
- }
- }
- pWmPB->pchNext = pchLast;
- }
- return (pWmPB->pchNext);
- }
- /*************************************<->*************************************
- *
- * _DtWmParseSkipWhitespaceC(linePP)
- *
- *
- * Description:
- * -----------
- * Scan the string, skipping over all white space characters.
- *
- *
- * Inputs:
- * ------
- * linePP = nonNULL pointer to current line buffer pointer
- *
- *
- * Outputs:
- * -------
- * linePP = nonNULL pointer to revised line buffer pointer
- *
- *
- * Comments:
- * --------
- * Assumes linePP is nonNULL
- *
- *************************************<->***********************************/
- void _DtWmParseSkipWhitespaceC(unsigned char **linePP)
- {
- while (*linePP &&
- (mblen ((char *)*linePP, MB_CUR_MAX) == 1) &&
- isspace (**linePP))
- {
- (*linePP)++;
- }
- } /* END OF FUNCTION _DtWmParseSkipWhitespaceC */
- /*************************************<->*************************************
- *
- * _DtWmParseNextTokenC (linePP, SmBehavior)
- *
- *
- * Description:
- * -----------
- * Returns the next quoted or whitespace-terminated nonquoted string in the
- * line buffer.
- * Additional functionality added to GetString in that anything in a
- * quoted string is considered sacred and nothing will be stripped from
- * the middle of a quoted string.
- *
- *
- * Inputs:
- * ------
- * linePP = pointer to current line buffer pointer.
- * SmBehavior = flag that enables parsing session manager hints if True.
- * If False, this behaves as the normal OSF mwm GetString
- * routine.
- *
- *
- * Outputs:
- * -------
- * linePP = pointer to revised line buffer pointer.
- * Return = string
- *
- *
- * Comments:
- * --------
- * May alter the line buffer contents.
- * Handles quoted strings and characters, removing trailing whitespace from
- * quoted strings.
- * Returns NULL string if the line is empty or is a comment.
- * Code stolen from dtmwm.
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseNextTokenC (
- unsigned char **linePP,
- Boolean SmBehavior
- )
- {
- /***********************************************************************
- *
- * The following code is duplicated from WmResParse.c (GetStringC)
- * GetStringC is the HP DT version of GetString.
- *
- * It works here through the magic of #defines.
- *
- ***********************************************************************/
- unsigned char *lineP = *linePP;
- unsigned char *endP;
- unsigned char *curP;
- unsigned char *lnwsP;
- unsigned int level = 0, checkLev, i, quoteLevel[MAX_QUOTE_DEPTH];
- int chlen;
- /* get rid of leading white space */
- ScanWhitespace (&lineP);
- /*
- * Return NULL if line is empty, whitespace, or begins with a comment.
- */
- if (
- *lineP == '\0' ||
- ((chlen = mblen ((char *)lineP, MB_CUR_MAX)) < 1) ||
- ((chlen == 1) && ((*lineP == '!') ||
- ((!SmBehavior) && (*lineP == '#'))))
- )
- {
- *linePP = lineP;
- return (NULL);
- }
- if ((chlen == 1) && (*lineP == '"'))
- /* Quoted string */
- {
- quoteLevel[level] = 1;
- /*
- * Start beyond double quote and find the end of the quoted string.
- * '\' quotes the next character.
- * Otherwise, matching double quote or NULL terminates the string.
- *
- * We use lnwsP to point to the last non-whitespace character in the
- * quoted string. When we have found the end of the quoted string,
- * increment lnwsP and if lnwsP < endP, write NULL into *lnwsP.
- * This removes any trailing whitespace without overwriting the
- * matching quote, needed later. If the quoted string was all
- * whitespace, then this will write a NULL at the beginning of the
- * string that will be returned -- OK.
- */
- lnwsP = lineP++; /* lnwsP points to first '"' */
- curP = endP = lineP; /* other pointers point beyond */
- while ((*endP = *curP) &&
- ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0) &&
- ((chlen > 1) || (*curP != '"')))
- /* Haven't found matching quote yet.
- * First byte of next character has been copied to endP.
- */
- {
- curP++;
- if ((chlen == 1) && (*endP == '\\') &&
- ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0))
- /* character quote:
- * copy first byte of quoted nonNULL character down.
- * point curP to next byte
- */
- {
- if (SmBehavior)
- {
- /*
- * Check to see if this is a quoted quote - if it is
- * strip off a level - if not - it's sacred leave it alone
- */
- checkLev = PeekAhead((curP - 1), quoteLevel[level]);
- if(checkLev > 0)
- {
- if(quoteLevel[level] >= checkLev)
- {
- if (level > 0) level--;
- }
- else if (level < MAX_QUOTE_DEPTH)
- {
- level++;
- quoteLevel[level] = checkLev;
- }
-
- for(i = 0;i < (checkLev - 2);i++)
- {
- *endP++ = *curP++;curP++;
- }
- *endP = *curP++;
- }
- }
- else
- {
- *endP = *curP++;
- }
- }
- if (chlen == 1)
- /* Singlebyte character: character copy finished. */
- {
- if (isspace (*endP))
- /* whitespace character: leave lnwsP unchanged. */
- {
- endP++;
- }
- else
- /* non-whitespace character: point lnwsP to it. */
- {
- lnwsP = endP++;
- }
- }
- else if (chlen > 1)
- /* Multibyte (nonwhitespace) character: point lnwsP to it.
- * Finish character byte copy.
- */
- {
- lnwsP = endP++;
- while (--chlen)
- {
- *endP++ = *curP++;
- lnwsP++;
- }
- }
- }
- /*
- * Found matching quote or NULL.
- * NULL out any trailing whitespace.
- */
- lnwsP++;
- if (lnwsP < endP)
- {
- *lnwsP = '\0';
- }
- }
- else
- /* Unquoted string */
- {
- /*
- * Find the end of the nonquoted string.
- * '\' quotes the next character.
- * Otherwise, whitespace, NULL, or '#' terminates the string.
- */
- curP = endP = lineP;
- while ((*endP = *curP) &&
- ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0) &&
- ((chlen > 1) || (!isspace (*curP) &&
- (SmBehavior || (*curP != '#')))))
- /* Haven't found whitespace or '#' yet.
- * First byte of next character has been copied to endP.
- */
- {
- curP++;
- if ((chlen == 1) && (*endP == '\\') &&
- ((chlen = mblen ((char *)curP, MB_CUR_MAX)) > 0))
- /* character quote:
- * copy first byte of quoted nonNULL character down.
- * point curP to next byte
- */
- {
- *endP = *curP++;
- }
- endP++;
- if (chlen > 1)
- /* Multibyte character: finish character copy. */
- {
- while (--chlen)
- {
- *endP++ = *curP++;
- }
- }
- }
- }
- /*
- * Three cases for *endP:
- * '#' --> write NULL over # and point to NULL
- * whitespace or
- * matching quote -> write NULL over char and point beyond
- * NULL -> point to NULL
- */
- if (!SmBehavior && (*endP == '#'))
- {
- *endP = '\0'; /* write NULL over '#' */
- *linePP = endP; /* point to NULL */
- }
- else if (*endP != '\0')
- {
- *endP = '\0'; /* write NULL over terminator */
- *linePP = ++curP; /* point beyond terminator */
- }
- else
- {
- *linePP = endP;
- }
- return ((unsigned char *)lineP);
- } /* END OF FUNCTION _DtWmParseNextTokenC */
- /*************************************<->*************************************
- *
- * (DtWmParseBuf *) _DtWmParseNewBuf (void)
- *
- *
- * Description:
- * -----------
- * Allocates a new parse record for parsing.
- *
- * Inputs:
- * ------
- * none
- *
- *
- * Outputs:
- * -------
- * Return = ptr to parse buffer record, NULL if memory allocation
- * error.
- *
- *
- * Comments:
- * --------
- * Call this first before using the other DtWmp routines that require
- * a parse buffer. Treat this as an opaque type; use the provided
- * routines to create, access, and destroy this structure.
- *
- *************************************<->***********************************/
- DtWmpParseBuf *
- _DtWmParseNewBuf ( void )
- {
- DtWmpParseBuf *pWmPB;
- pWmPB = (DtWmpParseBuf *) XtMalloc (sizeof (DtWmpParseBuf));
- if (pWmPB)
- {
- pWmPB->pchLine = (unsigned char *) XtMalloc (MAXLINE+1);
- if (!pWmPB->pchLine)
- {
- XtFree ((char *)pWmPB);
- pWmPB = NULL;
- }
- }
- if (pWmPB)
- {
- pWmPB->lineNumber = 0;
- pWmPB->pchNext = pWmPB->pchLine;
- pWmPB->cLineSize = MAXLINE+1;
- pWmPB->pFile = NULL;
- *(pWmPB->pchLine) = '\0';
- }
- return (pWmPB);
- } /* END OF FUNCTION _DtWmParseNewBuf */
- /*************************************<->*************************************
- *
- * (DtWmParseBuf *) _DtWmpIncBuf (pWmPB)
- *
- *
- * Description:
- * -----------
- * Increases the size of the line buffer in the parse buffer
- *
- * Inputs:
- * ------
- * pWmPB = pointer to a parse buffer
- *
- *
- * Outputs:
- * -------
- * Return = ptr to parse buffer record, NULL if memory allocation
- * error.
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
- static DtWmpParseBuf *
- _DtWmpIncBuf (
- DtWmpParseBuf *pWmPB)
- {
- if (pWmPB)
- {
- int ix;
- if (pWmPB->pFile)
- {
- /* save index into old string */
- ix = pWmPB->pchNext - pWmPB->pchLine;
- }
- pWmPB->pchLine = (unsigned char *)
- XtRealloc ((char *)pWmPB->pchLine, (pWmPB->cLineSize + MAXLINE));
- if (pWmPB->pchLine)
- {
- pWmPB->cLineSize += MAXLINE;
- if (pWmPB->pFile)
- {
- /* restore index into new string */
- pWmPB->pchNext = pWmPB->pchLine + ix;
- }
- }
- }
- return (pWmPB);
- } /* END OF FUNCTION _DtWmpIncBuf */
- /*************************************<->*************************************
- *
- * _DtWmParseDestroyBuf (pWmPB)
- *
- *
- * Description:
- * -----------
- * Destroys a parse buffer record, freeing any allocated memory.
- *
- *
- * Inputs:
- * ------
- * pWmPB = ptr to previously allocated parse buffer
- *
- *
- * Outputs:
- * -------
- * none
- *
- *
- * Comments:
- * --------
- * Destroys parse buffers allocated by _DtWmParseNewBuf.
- *
- *************************************<->***********************************/
- void
- _DtWmParseDestroyBuf (
- DtWmpParseBuf *pWmPB
- )
- {
- if (pWmPB)
- {
- if (pWmPB->pchLine)
- {
- XtFree ((char *) pWmPB->pchLine);
- }
- XtFree ((char *) pWmPB);
- }
- } /* END OF FUNCTION _DtWmParseDestroyBuf */
- /*************************************<->*************************************
- *
- * (unsigned char *) _DtWmParseSetLine (pWmPB, pch)
- *
- *
- * Description:
- * -----------
- * Sets a line into the parse buffer structure. This is used in cases
- * where parsing of an embedded string, usually a default, is done
- * instead of parsing out of a file.
- *
- *
- * Inputs:
- * ------
- * pWmPB = previously allocated parse buffer
- * pch = ptr to unsigned char string (zero terminated)
- *
- * Outputs:
- * -------
- * Return = pch
- *
- *
- * Comments:
- * --------
- * This resets any previous setting of the file pointer. EOF wil be
- * returned when the string pointed to by pch is exhausted.
- *
- * Resets line number count.
- *
- *************************************<->***********************************/
- void
- _DtWmParseSetLine (
- DtWmpParseBuf *pWmPB,
- unsigned char *pch
- )
- {
- if (pWmPB)
- {
- pWmPB->pchLine = pch;
- pWmPB->pchNext = pWmPB->pchLine;
- pWmPB->pFile = NULL;
- pWmPB->lineNumber = 0;
- }
- } /* END OF FUNCTION _DtWmParseSetLine */
- /*************************************<->*************************************
- *
- * (FILE *) _DtWmParseSetFile (pWmPB, pFile)
- *
- *
- * Description:
- * -----------
- * Sets the file pointer in a parse buffer. This is used when parsing
- * from a file is required.
- *
- *
- * Inputs:
- * ------
- * pWmPB = pointer to a parse buffer
- * pFile = pointer to an opened FILE
- *
- * Outputs:
- * -------
- * Return = pFile
- *
- *
- * Comments:
- * --------
- * You fopen the file first, then pass in the FILE * returned to this
- * routine.
- *
- * Resets line number count.
- *
- *************************************<->***********************************/
- void
- _DtWmParseSetFile (
- DtWmpParseBuf *pWmPB,
- FILE *pFile
- )
- {
- if (pWmPB)
- {
- pWmPB->pchLine[0] = '\0';
- pWmPB->pchNext = NULL;
- pWmPB->pFile = pFile;
- pWmPB->lineNumber = 0;
- }
- } /* END OF FUNCTION _DtWmParseSetFile */
- /*************************************<->*************************************
- *
- * (unsigned char *) _DtWmParseNextLine ( pWmPB )
- *
- *
- * Description:
- * -----------
- * Returns a pointer to the next line to parse.
- *
- *
- * Inputs:
- * ------
- * pWmPB = pointer to a parse buffer
- *
- *
- * Outputs:
- * -------
- * Return = pointer to next line to parse or NULL on EOF.
- *
- *
- * Comments:
- * --------
- *
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseNextLine (
- DtWmpParseBuf *pWmPB
- )
- {
- /***********************************************************************
- *
- * The following code is duplicated from WmResParse.c (GetNextLine)
- * It works here through the magic of #defines.
- *
- ***********************************************************************/
- unsigned char *string;
- int len;
- int chlen;
- wchar_t last;
- wchar_t wdelim;
- char delim;
- int lastlen;
- if (cfileP != NULL)
- /* read fopened file */
- {
- if ((string = (unsigned char *)
- fgets ((char *)line, MAXLINE, cfileP)) != NULL)
- {
- #ifdef PARSE_LIB
- if (strlen((char *)string) > (size_t)pWmPB->cLineSize)
- {
- /*
- * Bump size of destination buffer
- */
- pWmPB->cLineSize = 1 + strlen((char *)string);
- pWmPB->pchLine = (unsigned char *)
- XtRealloc ((char *)pWmPB->pchLine,
- (pWmPB->cLineSize));
- }
- #endif /* PARSE_LIB */
- lastlen = 0;
- while (*string &&
- ((len = mblen((char *)string, MB_CUR_MAX)) > 0))
- {
- mbtowc(&last, (char *)string, MB_CUR_MAX);
- lastlen = len;
- string += len;
- }
- delim = '\\';
- mbtowc(&wdelim, &delim, MB_CUR_MAX);
- if (lastlen == 1 && last == wdelim)
- {
- do
- {
- if (!fgets((char *)string, MAXLINE - (string - line), cfileP))
- break;
- lastlen = 0;
- while (*string &&
- ((len = mblen((char *)string, MB_CUR_MAX)) > 0))
- {
- mbtowc(&last, (char *)string, MB_CUR_MAX);
- lastlen = len;
- string += len;
- }
- linec++;
- }
- while (lastlen == 1 && last == wdelim);
- }
- string = line;
- }
- }
- else if ((parseP != NULL) && (*parseP != '\0'))
- /* read parse string */
- {
- #ifdef PARSE_LIB
- if (strlen((char *)parseP) > (size_t)pWmPB->cLineSize)
- {
- /*
- * Bump size of destination buffer
- */
- pWmPB->cLineSize = 1 + strlen((char *)parseP);
- pWmPB->pchLine = (unsigned char *)
- XtRealloc ((char *)pWmPB->pchLine,
- (pWmPB->cLineSize));
- }
- #endif /* PARSE_LIB */
- string = line;
- while ((*parseP != '\0') &&
- ((chlen = mblen ((char *)parseP, MB_CUR_MAX)) != 0) &&
- (*parseP != '\n'))
- /* copy all but end-of-line and newlines to line buffer */
- {
- if (chlen == -1)
- parseP++;
- else
- {
- while (chlen--)
- {
- *(string++) = *(parseP++);
- }
- }
- }
- *string = '\0';
- if (*parseP == '\n')
- {
- parseP++;
- }
- }
- else
- {
- string = NULL;
- }
- linec++;
- #ifdef PARSE_LIB
- if (cfileP)
- {
- /* update pchNext to get next line */
- pWmPB->pchNext = string;
- }
- #endif /* PARSE_LIB */
- return (string);
- } /* END OF FUNCTION _DtWmParseNextLine */
- /*************************************<->*************************************
- *
- * (unsigned char *) _DtWmParseCurrentChar (pWmPB)
- *
- *
- * Description:
- * -----------
- * Returns a pointer to the rest of the current line.
- *
- *
- * Inputs:
- * ------
- * pWmPB = pointer to a parse buffer
- *
- *
- * Outputs:
- * -------
- * Return = pointer to the rest of the current line
- *
- *
- * Comments:
- * --------
- * Useful in cases where you want to look at a char before getting the
- * next token or if you want to treat the rest of the line as a
- * single token.
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseCurrentChar (
- DtWmpParseBuf *pWmPB
- )
- {
- return (pWmPB ? pWmPB->pchNext : (unsigned char *)NULL);
- } /* END OF FUNCTION _DtWmParseCurrentChar */
- /*************************************<->*************************************
- *
- * (unsigned char *) _DtWmParseNextChar (pWmPB)
- *
- *
- * Description:
- * -----------
- * Advances the pointer to the next char and returns a pointer
- * to the new current char.
- *
- *
- * Inputs:
- * ------
- * pWmPB = pointer to a parse buffer
- *
- *
- * Outputs:
- * -------
- * Return = pointer to the rest of the current line
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseNextChar (
- DtWmpParseBuf *pWmPB
- )
- {
- unsigned char *pch = NULL;
- int chlen;
- if (pWmPB &&
- pWmPB->pchNext &&
- (chlen = mblen((char *)pWmPB->pchNext, MB_CUR_MAX) > 0))
- {
- pch = (pWmPB->pchNext += chlen);
- }
- return (pch);
- }
- /*************************************<->*************************************
- *
- * (int) _DtWmParseLineNumber (pWmPB)
- *
- *
- * Description:
- * -----------
- * Returns the number of the current line of what's being parsed.
- *
- *
- * Inputs:
- * ------
- * pWmPB = ptr to parse buffer
- *
- *
- * Outputs:
- * -------
- * Return = number of current line
- *
- *
- * Comments:
- * --------
- * Used for error reporting.
- *
- * The line number is computed by counting '\n' characters.
- *
- *************************************<->***********************************/
- int
- _DtWmParseLineNumber (
- DtWmpParseBuf *pWmPB
- )
- {
- return (pWmPB ? pWmPB->lineNumber : 0);
- } /* END OF FUNCTION _DtWmParseLineNumber */
- /*************************************<->*************************************
- *
- * _DtWmParseToLower (string)
- *
- *
- * Description:
- * -----------
- * Lower all characters in a string.
- *
- *
- * Inputs:
- * ------
- * string = NULL-terminated character string or NULL
- *
- *
- * Outputs:
- * -------
- * string = NULL-terminated lower case character string or NULL
- *
- *
- * Comments:
- * --------
- * Can handle multi-byte characters
- *
- *************************************<->***********************************/
- void _DtWmParseToLower (char *string)
- {
- char *pch = string;
- int chlen;
- while ((chlen = mblen (pch, MB_CUR_MAX)) > 0)
- {
- if ((chlen == 1) && (isupper (*pch)))
- {
- *pch = tolower(*pch);
- }
- pch += chlen;
- }
- } /* END OF FUNCTION _DtWmParseToLower */
- /*************************************<->*************************************
- *
- * _DtWmParsePeekAhead (currentChar, currentLev)
- *
- *
- * Description:
- * -----------
- * Returns a new level value if this is a new nesting level of quoted string
- * Otherwise it returns a zero
- *
- *
- * Inputs:
- * ------
- * currentChar = current position in the string
- * currentLev = current level of nesting
- *
- *
- * Outputs:
- * -------
- * Returns either a new level of nesting or zero if the character is copied in
- *
- *
- * Comments:
- * --------
- *
- *************************************<->***********************************/
- unsigned int _DtWmParsePeekAhead(unsigned char *currentChar,
- unsigned int currentLev)
- {
- Boolean done = False;
- unsigned int tmpLev = 1;
- unsigned int chlen;
- while (((chlen = mblen ((char *)currentChar, MB_CUR_MAX)) > 0) &&
- (chlen == 1) && ((*currentChar == '"') || (*currentChar == '\\'))
- && (done == False))
- {
- currentChar++;
- if(((chlen = mblen ((char *)currentChar, MB_CUR_MAX)) > 0) &&
- (chlen == 1) &&
- ((*currentChar == '"') || (*currentChar == '\\')))
- {
- tmpLev++;
- if(*currentChar == '"')
- {
- done = True;
- }
- else
- {
- currentChar++;
- }
- }
- }
- /*
- * Figure out if this is truly a new level of nesting - else ignore it
- * This section probably could do some error checking and return -1
- * If so, change type of routine from unsigned int to int
- */
- if(done == True)
- {
- return(tmpLev);
- }
- else
- {
- return(0);
- }
- } /* END OF FUNCTION _DtWmParsePeekAhead */
- /*************************************<->*************************************
- *
- * (unsigned char *) _DtWmParseFilenameExpand (pchFilename)
- *
- *
- * Description:
- * -----------
- * Returns a copy of a file name with environment variables
- * expanded.
- *
- *
- * Inputs:
- * ------
- * pchFilename = ptr to a zero terminated character string (filename)
- *
- *
- * Outputs:
- * -------
- * Return = ptr to a new file name with environment variables
- * expanded.
- *
- *
- * Comments:
- * --------
- * The passed in string is temporarily modified inside here.
- *
- * Free the returned string with XtFree().
- *
- * Returns NULL on a memory allocation error.
- *
- * Environment variables that can't be expanded are removed from
- * the returned copy.
- *
- * If no environment variables, you get a copy of the string back.
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseFilenameExpand (
- unsigned char *pchFilename
- )
- {
- unsigned char *pchN, *pchNew, *pchO;
- unsigned char *pchEnv, *pchEnv0, *pchEnv1;
- unsigned char chSave;
- int len, n, nx, ix;
- unsigned char pchBrk[] = { DTWM_CHAR_ENVIRONMENT,
- DTWM_CHAR_DIRECTORY,
- '\0'
- };
- len = strlen ((char *)pchFilename);
- pchNew = (unsigned char *) XtMalloc (1+len);
- pchO = pchFilename;
- chSave = '\0';
- ix = 0;
- while (pchNew && pchO && *pchO)
- {
- /* find next environment variable */
- pchEnv0 = (unsigned char *)
- strchr ((char *)pchO, (int) DTWM_CHAR_ENVIRONMENT);
- if (pchEnv0)
- {
- /* length to this point */
- n = pchEnv0 - pchO;
- /* copy up to environment character */
- if (n)
- {
- memcpy (&pchNew[ix], pchO, n);
- ix += n;
- }
- /* skip environment character */
- pchEnv0++;
- /* end of variable is at one of:
- * start of next variable,
- * start of next directory,
- * end of string
- */
- pchEnv1 = (unsigned char *)
- strpbrk ((char *)pchEnv0, (char *)pchBrk);
- if (pchEnv1)
- {
- /* next string starts after this one */
- pchO = pchEnv1;
- n = pchEnv1 - pchEnv0 + 1;
- /* replace this char with NULL for now */
- chSave = *pchEnv1;
- *pchEnv1 = '\0';
- }
- else
- {
- /* This environment variable is the last thing on
- * the line. Signal all done.
- */
- n = strlen ((char *) pchO);
- pchO += n;
- }
- pchEnv = (unsigned char *) getenv ((char *)pchEnv0);
- if (pchEnv)
- {
- nx = strlen ((char *) pchEnv);
- if (nx > n)
- {
- len += nx - n;
- pchNew = (unsigned char *)
- XtRealloc ((char *)pchNew, 1+len);
- }
- if (pchNew)
- {
- memcpy (&pchNew[ix], pchEnv, nx);
- ix += nx;
- }
- else
- {
- continue;
- }
- }
- if (chSave)
- {
- *pchO = chSave;
- chSave = '\0';
- }
- /* keep a kosher string */
- pchNew[ix] = '\0';
- }
- else
- {
- /* copy the rest of the string */
- n = strlen ((char *) pchO);
- memcpy (&pchNew[ix], pchO, n);
- pchO += n;
- /* remember the NULL! (a famous battle cry) */
- pchNew[ix + n] = '\0';
- }
- }
- return (pchNew);
- } /* END OF FUNCTION _DtWmParseFilenameExpand */
- /*************************************<->*************************************
- *
- * unsigned char * _DtWmParseExpandEnvironmentVariables (pch, pchBrk)
- *
- *
- * Description:
- * -----------
- * Expands environment variables in a string.
- *
- *
- * Inputs:
- * ------
- * pch = ptr to a zero terminated character string
- * pchBrk = array of "break" characters (see strpbrk()).
- * defaults are used if this is NULL.
- *
- * Outputs:
- * -------
- * Return = string with expanded environment variables. (free with XtFree)
- * NULL string if no environment variables or backslashes
- * found in the string passed in.
- *
- *
- * Comments:
- * --------
- * Free returned string with XtFree()
- *
- * Environment variables that can't be expanded are removed from
- * the returned copy.
- *
- * Default delimiter set is [Space], [Tab], '$', [Newline], '\', '/'.
- *
- * Variables of form $(..) and ${..} supported.
- *
- * A backslash '\' in front of any character quotes it. The backslash
- * is removed in the returned string. A literal backslash needs to be
- * quoted with a backslash.
- *
- *************************************<->***********************************/
- unsigned char *
- _DtWmParseExpandEnvironmentVariables (
- unsigned char *pch,
- unsigned char *pchBrk
- )
- {
- int chlen;
- unsigned char *pchStart;
- unsigned char chSave;
- unsigned char *pchEnvStart;
- unsigned char *pchEnvValue;
- unsigned char *pchReturn = NULL;
- unsigned char *pchNext;
- unsigned char *pchBreak;
- Boolean bEatBreak;
- Boolean bAlreadyAdvanced;
- int lenOriginal;
- int lenNonEnv;
- int lenEnvVar;
- int lenEnvValue;
- int lenReturn;
- int lenSave;
- static unsigned char pchDefaultBrk[] = {
- DTWM_CHAR_ENVIRONMENT,
- DTWM_CHAR_SPACE,
- DTWM_CHAR_TAB,
- DTWM_CHAR_NEW_LINE,
- DTWM_CHAR_BACKSLASH,
- DTWM_CHAR_DIRECTORY,
- '\0' };
- unsigned char pchParenBrk[] = {
- DTWM_CHAR_R_PAREN,
- '\0' };
- unsigned char pchBraceBrk[] = {
- DTWM_CHAR_R_BRACE,
- '\0' };
- /* There needs to be something to look at */
- if (!pch)
- return (NULL);
- pchStart = pch;
- lenOriginal = strlen ((char *)pch);
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- chSave = '\0';
- while (*pch && (chlen > 0))
- {
- if (chlen == 1)
- {
- bAlreadyAdvanced = False;
- switch (*pch)
- {
- case DTWM_CHAR_BACKSLASH:
- /*
- * Copy up to start of quoted char
- */
- if (!pchReturn)
- {
- lenReturn = lenOriginal + 1;
- pchReturn = (unsigned char *)
- XtMalloc (lenReturn * sizeof (unsigned char));
- pchReturn[0] = '\0';
- }
- chSave = *pch;
- *pch = '\0';
- strcat ((char *) pchReturn, (char *)pchStart);
- *pch = chSave;
- chSave = '\0';
- /*
- * The next character is "escaped", skip over it.
- */
- pchStart = pch += chlen;
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- break;
- case DTWM_CHAR_ENVIRONMENT:
- /* save start of environment variable */
- pchEnvStart = pch;
- pch += chlen;
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- /*
- * Copy up to start of environment variable
- */
- if (!pchReturn)
- {
- lenReturn = lenOriginal + 1;
- pchReturn = (unsigned char *)
- XtMalloc (lenReturn * sizeof (unsigned char));
- pchReturn[0] = '\0';
- lenSave = 0;
- }
- else
- {
- lenSave = strlen ((char *)pchReturn);
- }
- lenNonEnv = pchEnvStart - pchStart;
- memcpy (&pchReturn[lenSave], pchStart, lenNonEnv);
- pchReturn[lenSave+lenNonEnv] = '\0';
- /*
- * Determine how we find the end of this
- * environment variable.
- */
- bEatBreak = False;
- if ((chlen == 1) &&
- (*pch == DTWM_CHAR_L_PAREN))
- {
- pch += chlen;
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- pchBreak = pchParenBrk;
- bEatBreak = True;
- }
- else if ((chlen == 1) &&
- (*pch == DTWM_CHAR_L_BRACE))
- {
- pch += chlen;
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- pchBreak = pchBraceBrk;
- bEatBreak = True;
- }
- else if (pchBrk && *pchBrk)
- {
- pchBreak = pchBrk;
- }
- else
- {
- pchBreak = pchDefaultBrk;
- }
- /*
- * Look for end of environment variable
- */
- pchNext = (unsigned char *)
- strpbrk ((char *)pch, (char *)pchBreak);
- if (!pchNext)
- {
- /* it's the rest of the string */
- chSave = '\0';
- bEatBreak = False;
- pchNext = pch + strlen ((char *) pch);
- }
- else
- {
- /* temporarily put a string terminator here */
- chSave = *pchNext;
- *pchNext = '\0';
- }
- /*
- * Lookup environment variable
- */
- lenEnvVar = strlen ((char *)pch);
- pchEnvValue = (unsigned char *) getenv ((char *)pch);
- if (pchEnvValue)
- {
- /*
- * Insure there's enough room in the return string
- */
- lenEnvValue = strlen ((char *)pchEnvValue);
- if (!pchReturn)
- {
- lenReturn = lenOriginal + 1 - lenEnvVar +
- lenEnvValue;
- pchReturn = (unsigned char *)
- XtMalloc (lenReturn * sizeof (unsigned char));
- pchReturn[0] = '\0';
- }
- else
- {
- lenReturn = lenReturn + 1 - lenEnvVar +
- lenEnvValue;
- pchReturn = (unsigned char *)
- XtRealloc ((char *)pchReturn,
- lenReturn * sizeof (unsigned char));
- }
- /*
- * Tack it onto the return string
- */
- strcat ((char *)pchReturn, (char *)pchEnvValue);
- }
- /*
- * Advance the pointer for the next pass
- */
- if (chSave)
- {
- /* restore saved character */
- *pchNext = chSave;
- chSave = '\0';
- /*
- * If this was a closing paren, then skip it
- */
- if (bEatBreak)
- {
- chlen = mblen ((char *)pchNext, MB_CUR_MAX);
- pchNext += chlen;
- }
- }
- pchStart = pch = pchNext;
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- /*
- * We're already pointing at the next character
- * to process, don't advance again!
- */
- bAlreadyAdvanced = True;
- break;
- default:
- /* this character is not interesting */
- break;
- }
- /*
- * Move to the next character if we're not already
- * there.
- */
- if (!bAlreadyAdvanced)
- {
- pch += chlen;
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- }
- }
- else
- {
- pch += chlen;
- chlen = mblen ((char *)pch, MB_CUR_MAX);
- }
- }
- if (pchReturn && *pchStart)
- {
- /*
- * Copy remaining parts of the string
- */
- strcat ((char *)pchReturn, (char *)pchStart);
- }
- return (pchReturn);
- } /* END OF FUNCTION _DtWmParseExpandEnvironmentVariables */
- /******************************<->*************************************
- *
- * _DtWmParseMakeQuotedString (pchLine)
- *
- *
- * Description:
- * -----------
- * Encapsulates the passed in "line" into a string argument quoted
- * by double quotes. Special characters are "escaped" as needed.
- *
- * Inputs:
- * ------
- * pchLine = ptr to string to enclose in quotes
- *
- * Outputs:
- * -------
- * Return = ptr to quoted string
- *
- * Comment:
- * -------
- * Returned string should be freed with XtFree().
- *
- ******************************<->***********************************/
- unsigned char *
- _DtWmParseMakeQuotedString (unsigned char *pchLine)
- {
- unsigned char *pchRet;
- int iLen0, iLen1;
- int cSpecial;
- int i,j;
- int chlen;
- iLen0 = strlen ((char *)pchLine);
- iLen1 = iLen0 + 2; /* for starting, ending quotes */
- for (i=0; i < iLen0; i++)
- {
- /*
- * Count special chars to get estimate of new length
- */
- chlen = mblen ((char *) &pchLine[i], MB_CUR_MAX);
- if ((chlen == 1) &&
- ((pchLine[i] == '\\') ||
- (pchLine[i] == '"')))
- {
- iLen1++;
- }
- else if (chlen < 1)
- {
- break;
- }
- else
- {
- i += chlen-1;
- }
- }
- pchRet = (unsigned char *) XtMalloc (1+iLen1);
- if (pchRet)
- {
- pchRet[0] = '"'; /* starting quote */
- /*
- * Copy chars from old string to new one
- */
- for (i=0, j=1; i < iLen0; i++, j++)
- {
- chlen = mblen ((char *) &pchLine[i], MB_CUR_MAX);
- if ((chlen == 1) &&
- ((pchLine[i] == '\\') ||
- (pchLine[i] == '"')))
- {
- /* quote next char */
- pchRet[j++] = '\\';
- }
- else if (chlen < 1)
- {
- break;
- }
- else while (chlen > 1)
- {
- /* copy first bytes of multibyte char */
- pchRet[j++] = pchLine[i++];
- chlen--;
- }
- /* copy char */
- pchRet[j] = pchLine[i];
- }
- pchRet[j++] = '"'; /* ending quote */
- pchRet[j] = '\0'; /* end of string */
- }
- return (pchRet);
- } /* END OF FUNCTION _DtWmParseMakeQuotedString */
- /*==================== END OF FILE WmParse.c ====================*/
|