|
From: <set...@us...> - 2006-04-07 21:25:13
|
Revision: 1226 Author: sethdill Date: 2006-04-07 14:24:58 -0700 (Fri, 07 Apr 2006) ViewCVS: http://svn.sourceforge.net/frontierkernel/?rev=1226&view=rev Log Message: ----------- Adding Conversant-specific files. I hope this go into my branch... Added Paths: ----------- Frontier/branches/Conversant/Common/headers/conversantverbs.h Frontier/branches/Conversant/Common/resources/Mac/conversantverbs.r Frontier/branches/Conversant/Common/resources/Win32/conversantverbs.rc Frontier/branches/Conversant/Common/source/conversantverbs.c Added: Frontier/branches/Conversant/Common/headers/conversantverbs.h =================================================================== --- Frontier/branches/Conversant/Common/headers/conversantverbs.h (rev 0) +++ Frontier/branches/Conversant/Common/headers/conversantverbs.h 2006-04-07 21:24:58 UTC (rev 1226) @@ -0,0 +1 @@ +/****************************************************************************** Conversant Verbs Conversant-related verbs and functions for the Frontier Kernel Created by Seth Dillingham on 12/31/04. Copyright (C) 2004, 2005, 2006 Macrobyte Resources. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ #ifndef conversantinclude #define conversantinclude #define conversanterrorlist 270 #define notimplementederror 1 #define STR_textname ("\x05" "\ttext") #define STR_rezname ("\x09" "\trezdelim") #define STR_macroname ("\x06" "\tmacro") #define STR_paramname ("\x06" "\tparam") #define STR_rezdelim ("\x01" "|") #define STR_macro ("\x05" "macro") #define STR_ifmacro ("\x02" "if") #define STR_elseifmacro ("\x06" "elseif") #define STR_elsemacro ("\x04" "else") #define STR_endifmacro ("\x05" "endif") #define STR_conditional ("\x0b" "conditional") #define STR_endconditional ("\x0f" "end conditional") #define STR_name ("\x04" "name") #define STR_type ("\x04" "type") #define STR_condblock ("\x10" "conditionalBlock") #define STR_macrotype ("\x09" "macroType") #define STR_parenthetical ("\x0d" "parenthetical") #define STR_parameterless ("\x0d" "parameterless") #define STR_attvaluepairs ("\x13" "attributeValuePairs") #define STR_params ("\x06" "params") #define STR_convcompileerror ("\x39" "Error compiling string (^0). Problem seems to be here: ^1") #define STR_nearcharacteroffset ("\x16" " (Near character #^0.)") #define STR_badcharinmacroname ("\x26" "Illegal character found in macro name.") #define STR_badcharinparamname ("\x26" "Illegal character found in param name.") #define STR_badcharunquoted ("\x29" "Illegal character found in unquoted param") #define STR_seekingparamname ("\x19" "Searching for param name.") #define STR_endfoundseekingparamname ("\x33" "Reached end of string while seeking parameter name.") #define STR_missingequalsign ("\x14" "Missing equals sign.") #define STR_badparametervalue ("\x4c" "Bad parameter value. Only macros, resources, and quoted strings are allowed.") #define STR_illegalparamstart ("\x2f" "Illegal start of param value after equals sign.") #define STR_endfoundprocmacro ("\x2d" "Reached end of string while processing macro.") #define STR_endfoundquoteparam ("\x37" "Reached end of string while processing quoted parameter.") #define STR_endfoundrezparam ("\x39" "Reached end of string while processing resource parameter.") #define STR_missingcomma ("\x26" "Missing comma between parameter values") #define STR_extracomma ("\x11" "Found extra comma") typedef enum tyconversanttoken { /* verbs that are processed by conversantverbs.c */ compilestringfunc, cconversantverbs } tyconversanttoken; typedef enum tyconvitemtype { /* types that are found when looking for the next macro or resource */ CONV_NOTYPE, /* no macro or resource was found */ CONV_MACRO, /* macro was found */ CONV_RESOURCE, /* resource was found */ /* types of macros */ CONV_MACROTYPE_NOPARAM, /* regular macro */ CONV_MACROTYPE_COND_IF, /* if macro */ CONV_MACROTYPE_COND_ELSE, /* else macro */ CONV_MACROTYPE_COND_ELSEIF, /* elseif macro */ CONV_MACROTYPE_COND_ENDIF, /* endif macro */ CONV_MACROTYPE_AV, /* attribute-value pairs */ CONV_MACROTYPE_PAREN /* parenthetical macros */ } tyconvitemtype; typedef struct convaddress { /* name and table of an xml item */ long tblsize; hdlhashtable ht; bigstring bs; } convaddress, *ptrconvaddress; /* function declarations */ static void extractstringfromhandle( Handle, long, long, bigstring ); static boolean conv_addrezdelim( hdlhashtable ); static boolean conv_compilemacro( hdlhashtable *, Handle, long *, long, long * ); #endif /* conversantinclude */ \ No newline at end of file Added: Frontier/branches/Conversant/Common/resources/Mac/conversantverbs.r =================================================================== --- Frontier/branches/Conversant/Common/resources/Mac/conversantverbs.r (rev 0) +++ Frontier/branches/Conversant/Common/resources/Mac/conversantverbs.r 2006-04-07 21:24:58 UTC (rev 1226) @@ -0,0 +1,36 @@ +/****************************************************************************** + + Conversant Verbs + + Conversant-related verbs and functions for the Frontier Kernel + + Created by Seth Dillingham on 12/31/04. + + Copyright (C) 2004, 2005, 2006 Macrobyte Resources. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +******************************************************************************/ + + +resource 'EFP#' (idconversantverbs, "conv") { /*2004-12-31 SMD: conversant verbs*/ + + { + "conv", false, { + + "compilestring" + } + } +}; Added: Frontier/branches/Conversant/Common/resources/Win32/conversantverbs.rc =================================================================== --- Frontier/branches/Conversant/Common/resources/Win32/conversantverbs.rc (rev 0) +++ Frontier/branches/Conversant/Common/resources/Win32/conversantverbs.rc 2006-04-07 21:24:58 UTC (rev 1226) @@ -0,0 +1,31 @@ + +/****************************************************************************** + + Conversant. + + Copyright (C) 2004, 2005 Macrobyte Resources + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +******************************************************************************/ + +1026 /*conversantverbs*/ EFP DISCARDABLE + BEGIN + 1, //Number of "blocks" in this resource + "conv\0", //Function Processor name + false, //Window required + 1, //Count of verbs + "compilestring\0" + END Added: Frontier/branches/Conversant/Common/source/conversantverbs.c =================================================================== --- Frontier/branches/Conversant/Common/source/conversantverbs.c (rev 0) +++ Frontier/branches/Conversant/Common/source/conversantverbs.c 2006-04-07 21:24:58 UTC (rev 1226) @@ -0,0 +1,1089 @@ +/****************************************************************************** + + Conversant Verbs + + Conversant-related verbs and functions for the Frontier Kernel + + Created by Seth Dillingham on 12/31/04. + + Copyright (C) 2004, 2005, 2006 Macrobyte Resources. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +******************************************************************************/ + +#ifdef flconversantverbs + #if (flconversantverbs==1) + +#include <ctype.h> + +#include "frontier.h" +#include "standard.h" + +#include "error.h" +#include "memory.h" +#include "strings.h" +#include "ops.h" +#include "resources.h" +#include "lang.h" +#include "langinternal.h" +#include "langexternal.h" +#include "langsystem7.h" +#include "tablestructure.h" +#include "tableverbs.h" +#include "kernelverbs.h" +#include "kernelverbdefs.h" +#include "shell.rsrc.h" +#include "conversantverbs.h" + +#define scriptError(act, hsrc, ix, len) do {langparamerrormessage (act, hsrc, ix, len);} while (0) + + +/* report error and position */ +/* "Error compiling string (^0). Problem seems to be here: ^1" + ( extraction of area near ixPos ) */ +static void langparamerrormessage( const bigstring bsaction, const Handle src, const long ixPos, const long slen ) +{ + bigstring bserrmsg, bsactsafe, bsextract; + long extractstart, extractlength; + + copystring( bsaction, bsactsafe ); + + extractstart = max( 1, ixPos - 16 ); + + extractlength = min( 32, slen - extractstart ); + + extractstringfromhandle( src, extractstart, extractlength, bsextract ); + + parsedialogstring( STR_convcompileerror, bsactsafe, bsextract, nil, nil, bserrmsg ); + + langerrormessage( bserrmsg ); +} /*langparamerrormessage*/ + + +static void extractstringfromhandle( const Handle src, const long ixStart, const long length, bigstring dest ) +{ + ptrbyte s = (ptrbyte) *src; + + if ( length > 0 ) + moveleft( &s[ ixStart ], &dest[ 1 ], length ); + + setstringlength( dest, length ); +} + + +static long skipwhitespace( Handle src, long ixpos, long slen ) +{ + ptrbyte s = (ptrbyte) *src; + long ix = ixpos; + + while ( ix <= slen ) + { + if ( ( s[ ix ] == ' ' ) || + ( s[ ix ] == '\t' ) || + ( s[ ix ] == '\r' ) || + ( s[ ix ] == '\n' ) + ) + ix++; + else + return ix; + } + + return ix; +} + + +/* +there are currently just five possible results from this question: + 1. CONV_MACROTYPE_COND_IF + 2. CONV_MACROTYPE_COND_ELSE + 3. CONV_MACROTYPE_COND_ELSEIF + 4. CONV_MACROTYPE_COND_ENDIF + 5. CONV_MACRO +*/ +static short getmacrotypefromname( bigstring macroname ) +{ + if ( equalstrings( STR_ifmacro, macroname ) ) + return ( CONV_MACROTYPE_COND_IF ); + + if ( equalstrings( STR_elseifmacro, macroname ) ) + return ( CONV_MACROTYPE_COND_ELSEIF ); + + if ( equalstrings( STR_elsemacro, macroname ) ) + return ( CONV_MACROTYPE_COND_ELSE ); + + if ( equalstrings( STR_endifmacro, macroname ) ) + return ( CONV_MACROTYPE_COND_ENDIF ); + + return ( CONV_MACRO ); /* all we know from the name is that it's not a conditional */ +} + + +static long nextserialnum( ptrconvaddress adrtbl ) +{ + long ctitems; + + if ( (*adrtbl).tblsize == 0 ) + { + hashcountitems ((*adrtbl).ht, &ctitems); + (*adrtbl).tblsize = ctitems; + } + + return ( ctitems + 1 ); +} + +static void makenewitemname( ptrconvaddress adrtbl, bigstring basename, bigstring deststring ) +{ + long ct = nextserialnum( adrtbl ); + + numbertostring( ct, deststring ); + + while ( stringlength( deststring ) < 4 ) + insertchar( '0', deststring ); + + pushstring( basename, deststring ); +} + +static void getnewplainaddress( hdlhashtable ht, bigstring newname, ptrconvaddress adr ) +{ + (*adr).ht = ht; + + (*adr).tblsize = 0; + + copystring( newname, (*adr).bs ); + /* pushstring( newname, (*adr).bs ); */ +} + +static void getnewitemaddress( hdlhashtable ht, bigstring basename, ptrconvaddress adr ) +{ + (*adr).ht = ht; + + (*adr).tblsize = 0; + + makenewitemname( adr, basename, (*adr).bs ); +} + + +static boolean createsubtable( hdlhashtable parenttable, bigstring newname, ptrconvaddress newtable, boolean flserialname ) +{ + if ( flserialname ) + getnewitemaddress( parenttable, newname, newtable ); + else + getnewplainaddress( parenttable, newname, newtable ); + + if ( !langassignnewtablevalue( (*newtable).ht, (*newtable).bs, &(*newtable).ht ) ) + return ( false ); + + return ( true ); +} + + +static boolean assignchar( ptrconvaddress newitemdest, byte ch ) +{ + if ( !langassigncharvalue( (*newitemdest).ht, (*newitemdest).bs, ch ) ) + return ( false ); + + (*newitemdest).tblsize++; + + return ( true ); +} + +static boolean assignstringhandle( ptrconvaddress newitemdest, Handle newtextvalue ) +{ + if ( !langassigntextvalue( (*newitemdest).ht, (*newitemdest).bs, newtextvalue ) ) + { + disposehandle( newtextvalue ); + return ( false ); + } + + (*newitemdest).tblsize++; + + return ( true ); +} + +static boolean assignstring( ptrconvaddress adrdest, const bigstring itemname, const bigstring itemvalue ) +{ + if ( !langassignstringvalue( (*adrdest).ht, itemname, itemvalue ) ) + return ( false ); + + (*adrdest).tblsize++; + + return ( true ); +} + +static boolean assignstringvalue( ptrconvaddress adrdest, bigstring itemname, bigstring itemvalue ) +{ + tyvaluerecord val; + convaddress adrnewitem; + + getnewitemaddress( (*adrdest).ht, itemname, &adrnewitem ); + + if ( !setstringvalue( itemvalue, &val ) ) + return ( false ); + + if ( !hashtableassign( adrnewitem.ht, adrnewitem.bs, val ) ) + return ( false ); + + exemptfromtmpstack( &val ); + + (*adrdest).tblsize++; + + return ( true ); +} + +static boolean conv_addtextrange( hdlhashtable tbldest, Handle s, long ixStart, long ix ) +{ + Handle htextrange; + convaddress adrnewitem; + + if ( ixStart < ix ) + { + if ( !loadfromhandletohandle( s, &ixStart, ix - ixStart, true, &htextrange ) ) + { + disposehandle( htextrange ); + return ( false ); + } + + getnewitemaddress( tbldest, STR_textname, &adrnewitem ); + + if ( !assignstringhandle( &adrnewitem, htextrange ) ) + { + disposehandle( htextrange ); + return ( false ); + } + } + + return ( true ); +} + + +static boolean parseunquotedstring( const Handle src, long * ixpos, const long slen, const bigstring bsextrachars, bigstring result, const bigstring badcharerr, const boolean flallowpuncs ) +{ + ptrbyte s = (ptrbyte) *src; + long ct = slen; + long ix = *ixpos; + long ixstart = ix; + long i; + char ch; + boolean flfoundend = false; + + while ( ix < ct ) + { + ch = s[ ix ]; + + if ( ( ! isalnum( ch ) ) && + ( ( ( ch != '.' ) && ( ch != '_' ) ) || !flallowpuncs ) /* this line is glad it doesn't have a mirror, it's ugly */ + ) + { + if ( ( ch == ' ' ) || /* these characters all _legally_ end any unquoted string */ + ( ch == '\r' ) || + ( ch == '\n' ) || + ( ch == '\t' ) + ) + { + flfoundend = true; + } + else + { + for ( i = 1; i <= stringlength( bsextrachars ); i++ ) /* check for other legal "endings" */ + { + if ( bsextrachars[ i ] == ch ) + { + flfoundend = true; + break; + } + } + } + + if ( flfoundend ) /* found a legal end of the unquoted string */ + { + extractstringfromhandle( src, ixstart, ix - ixstart, result ); + + *ixpos = ix; + + return ( true ); + } + else /* found an illegal character in an unquoted string */ + { + scriptError( badcharerr, src, ix, ct ); + + return ( false ); + } + } + + ++ix; + } + + *ixpos = ix; + + return ( false ); +} + +static boolean parseunquotedstringparam( ptrconvaddress adrparam, const Handle src, long * ixpos, const long slen ) +{ + bigstring param; + long ixstart = *ixpos; + + if ( !parseunquotedstring( src, ixpos, slen, "\x02,)", param, STR_badcharunquoted, false ) ) + return ( false ); + + if ( !conv_addtextrange( (*adrparam).ht, src, ixstart, *ixpos ) ) + return ( false ); + + return ( true ); +} + + +static boolean getmacroname( const Handle src, long * ixpos, const long slen, bigstring macroname ) +{ + boolean fl; + + fl = parseunquotedstring( src, ixpos, slen, "\x02-(", macroname, STR_badcharinmacroname, true ); + + if ( fl ) + alllower( macroname ); + + return ( fl ); +} + + +static boolean getparamname( Handle src, long * ixpos, long slen, bigstring paramname ) +{ + long ixstart = *ixpos; + + if ( ! parseunquotedstring( src, ixpos, slen, "\x01=", paramname, STR_badcharinparamname, false ) ) + { + if ( *ixpos == ixstart ) /* we ran out of string */ + { + *ixpos = ixstart; + scriptError( STR_endfoundseekingparamname, src, ixstart, slen ); + } + else + scriptError( STR_seekingparamname, src, *ixpos, slen ); /* generic error */ + + return ( false ); + } + + alllower( paramname ); + + return ( true ); +} + + +static boolean parsestringuntilchar( ptrconvaddress adrdest, Handle src, long * ixpos, long slen, long * depth, char ch ) +{ + long ix = *ixpos; + long ct = slen; + ptrbyte s = (ptrbyte) *src; + long ixstart = ix; + boolean flcomplete = false; + + while ( ix < ct ) + { + if ( s[ ix ] == ch ) /* found the ending char */ + { + if ( !conv_addtextrange( (*adrdest).ht, src, ixstart, ix ) ) + break; + + flcomplete = true; + break; + } + else if ( s[ ix ] == '\\' ) + { + if ( ( s[ ix + 1 ] == '\\' ) || ( s[ ix + 1 ] == '"' ) ) /* skip the next char */ + ix++; + } + else if ( s[ ix ] == '<' ) /* macro delim? */ + { + if ( ( ix < slen - 4 ) && + ( s[ ix + 1 ] == '!' ) && + ( s[ ix + 2 ] == '-' ) && + ( s[ ix + 3 ] == '-' ) && + ( s[ ix + 4 ] == '#' ) + ) + { + if ( !conv_addtextrange( (*adrdest).ht, src, ixstart, ix ) ) + break; + + *ixpos = ix += 5; /* move pointer past delim */ + + if ( !conv_compilemacro( &(*adrdest).ht, src, ixpos, slen, depth ) ) + break; + + ix = ixstart = *ixpos; + + continue; /* avoid the increment */ + } + } + else if ( s[ ix ] == '|' ) /* rez delim */ + { + if ( !conv_addtextrange( (*adrdest).ht, src, ixstart, ix ) ) + break; + + if ( !conv_addrezdelim( (*adrdest).ht ) ) + break; + + ixstart = ++ix; + + continue; + } + + ++ix; + } /* while */ + + *ixpos = ix; + + return ( flcomplete ); +} + + +static boolean parsequotedstring( ptrconvaddress adrdest, Handle src, long * ixpos, long slen, long * depth ) +{ + boolean fl; + + fl = parsestringuntilchar( adrdest, src, ixpos, slen, depth, '"' ); + + if ( fl ) + ++(*ixpos); /* increment past the closing quotes */ + else + scriptError( STR_missingequalsign, src, *ixpos, slen ); + + return ( fl ); +} + +static boolean parseresource( ptrconvaddress adrdest, Handle src, long * ixpos, long slen, long * depth ) +{ + boolean fl = true; + + /* add rez delim */ + fl = conv_addrezdelim( (*adrdest).ht ); + + ++(*ixpos); + + if ( fl ) /* pass to general param parser */ + { + fl = parsestringuntilchar( adrdest, src, ixpos, slen, depth, '|' ); + } + + if ( fl ) /* add rez delim */ + { + fl = conv_addrezdelim( (*adrdest).ht ); + + ++(*ixpos); /* increment past the closing resource delim */ + } + + return ( fl ); +} + + +static boolean commaneeded_commafound( boolean * flcommafound, long ctparams ) +{ + if ( *flcommafound ) + { + *flcommafound = false; + return ( true ); + } + + return ( ctparams == 0 ); +} + +/* + parenthetical macros suck. + they're an anachronism in Conversant that will probably never go away + they look like this: <!--#macroname ( "param1", param2, <!--#param3-->, |param4| )--> + + syntax rules: + 1. all white space is optional + 2. white space can appear after the macro name, before the opening paren + 3. white space to either side of any parameter is legal + 4. commas are required between parameters + 5. commas are illegal before the first param and after the last param + 6. parameters come in four fruity flavors: + a. quoted (actually, double-quoted), this is the easy and obvious type, containing anything + (they can even contain escaped double-quotes) + b. unquoted params can contain only letters and numbers + c. macro params can be any legal macro (following the same syntax rules as all other macros) + d. resource params are identical to string params, except the delimiter is the vertical pipe + (also, resource params are evaluated as resources by the macro processor) + resource params can not contain escaped resource delimiters. Wrap the param in quotes, instead. +*/ +static boolean conv_parseparentheticalmacro( ptrconvaddress adrparams, Handle src, long * ixpos, long slen, long * depth ) +{ + convaddress adrparam; + long ix; + long ixstart; + long ct = slen; + long ixmacrostart; + long ctparams = 0; + boolean flcommafound = false; + boolean flmacrocomplete = false; + ptrbyte s = (ptrbyte) *src; + + ixmacrostart = ixstart = ix = *ixpos; + + while ( ix < ct ) + { + *ixpos = ix = skipwhitespace( src, ix, slen ); + + if ( s[ ix ] == ')' ) /* end of macro */ + { + if ( flcommafound ) + { + scriptError( STR_extracomma, src, *ixpos, slen ); + + return ( false ); + } + + *ixpos = skipwhitespace( src, ++ix, slen ); /* move past the closing parens, we're done */ + + flmacrocomplete = true; + + break; + } + + /* set up the new subtable for the param */ + if ( !createsubtable( (*adrparams).ht, STR_paramname, &adrparam, true ) ) + break; + + if ( s[ ix ] == '<' ) /* macro param */ + { + if ( !commaneeded_commafound( &flcommafound, ctparams ) ) + { + scriptError( STR_missingcomma, src, ix, slen ); + + return ( false ); + } + + /* parameters that start with '<' must be macros, period */ + if ( ( ix > slen - 4 ) || + ( s[ ix + 1 ] != '!' ) || + ( s[ ix + 2 ] != '-' ) || + ( s[ ix + 3 ] != '-' ) || + ( s[ ix + 4 ] != '#' ) + ) + { + scriptError( STR_badparametervalue, src, ix, slen ); + break; + } + else + { + /* position the pointer to right after the macro delim */ + *ixpos = ixstart = ix + 5; + + if ( !conv_compilemacro( &adrparam.ht, src, ixpos, slen, depth ) ) + break; + + ++ctparams; + + ix = skipwhitespace( src, *ixpos, slen ); + + if ( s[ ix ] == ',' ) + { + flcommafound = true; + + ++ix; /* skip it */ + } + + continue; + } + } + else if ( s[ ix ] == '|' ) /* rez param */ + { + if ( !commaneeded_commafound( &flcommafound, ctparams ) ) + { + scriptError( STR_missingcomma, src, *ixpos, slen ); + + return ( false ); + } + + *ixpos = ixstart = ix; /* skip the pipe */ + + if ( !parseresource( &adrparam, src, ixpos, slen, depth ) ) + break; + + ++ctparams; + + ix = skipwhitespace( src, *ixpos, slen ); + + if ( s[ ix ] == ',' ) + { + flcommafound = true; + + ++ix; /* skip it */ + } + } + else if ( s[ ix ] == '"' ) /* quoted param */ + { + if ( !commaneeded_commafound( &flcommafound, ctparams ) ) + { + scriptError( STR_missingcomma, src, *ixpos, slen ); + + return ( false ); + } + + *ixpos = ixstart = ++ix; /* skip the quote */ + + if ( !parsequotedstring( &adrparam, src, ixpos, slen, depth ) ) + break; + + ix = skipwhitespace( src, *ixpos, slen ); + + if ( s[ ix ] == ',' ) + { + flcommafound = true; + + ++ix; /* skip it */ + } + } + else /* unquoted param */ + { + if ( !commaneeded_commafound( &flcommafound, ctparams ) ) + { + scriptError( STR_missingcomma, src, *ixpos, slen ); + + return ( false ); + } + + if ( !parseunquotedstringparam( &adrparam, src, ixpos, slen ) ) + break; + + ix = skipwhitespace( src, *ixpos, slen ); + + if ( s[ ix ] == ',' ) + { + flcommafound = true; + + ++ix; /* skip it */ + } + } + } + + if ( ! flmacrocomplete ) + { + scriptError( STR_endfoundprocmacro, src, ixmacrostart, slen ); + return ( false ); + } + else + { + *ixpos += 3; + + return ( true ); + } +} + +static boolean conv_parsemacro( ptrconvaddress adrdest, Handle src, long * ixpos, long slen, long * depth ) +{ + convaddress adrparams; + bigstring paramname; + convaddress adrparam; + long ix, ixstart; + boolean flmacrocomplete = false; + ptrbyte s = (ptrbyte) *src; + + if ( !createsubtable( (*adrdest).ht, STR_params, &adrparams, false ) ) + return ( false ); + + ix = skipwhitespace( src, *ixpos, slen ); + + if ( s[ ix ] == '(' ) /* parenthetical() macro */ + { + assignstring( adrdest, STR_macrotype, STR_parenthetical ); + ix++; + *ixpos = ix; + + return conv_parseparentheticalmacro( &adrparams, src, ixpos, slen, depth ); + } + else if ( s[ ix ] == '-' ) /* end of macro */ /* perhaps we assume too much? */ + { + assignstring( adrdest, STR_macrotype, STR_parameterless ); + + // *ixpos += 3; + *ixpos = ix + 3; // ixpos is now [whitespace] + '-->' + + return ( true ); + } + else /* if neither of the above, this must be a attribute=valuepairs macro */ + { + assignstring( adrdest, STR_macrotype, STR_attvaluepairs ); + } + + while ( ix < slen ) /* extract parameters */ + { + ix = skipwhitespace( src, *ixpos, slen ); + + if ( ( s[ ix ] == '-' ) && /* macro done? look for --> */ + ( ix <= ( slen - 2 ) ) && + ( s[ ix + 1 ] == '-' ) && + ( s[ ix + 2 ] == '>' ) + ) + { + flmacrocomplete = true; + break; + } + + /* param name */ + (*ixpos) = ix; + if ( !getparamname( src, ixpos, slen, paramname ) ) + break; + + if ( !insertchar( '\t', paramname ) ) + break; + + if ( !createsubtable( adrparams.ht, paramname, &adrparam, true ) ) + break; + + ix = skipwhitespace( src, *ixpos, slen ); + + /* equals */ + if ( s[ ix ] != '=' ) + { + scriptError( STR_missingequalsign, src, ix, slen ); + break; + } + ix++; /* skip the equals sign */ + ix = skipwhitespace( src, ix, slen ); + + /* param value */ + if ( s[ ix ] == '"' ) /* quoted string param */ + { + *ixpos = ixstart = ++ix; /* skip the quote */ + + if ( !parsequotedstring( &adrparam, src, ixpos, slen, depth ) ) + break; + } + else if ( s[ ix ] == '<' ) /* macro param */ + { + /* parameters that start with '<' must be macros, period */ + if ( ( ix > slen - 4 ) || + ( s[ ix + 1 ] != '!' ) || + ( s[ ix + 2 ] != '-' ) || + ( s[ ix + 3 ] != '-' ) || + ( s[ ix + 4 ] != '#' ) + ) + { + scriptError( STR_badparametervalue, src, ix, slen ); + break; + } + else + { + /* position the pointer to right after the macro delim */ + *ixpos = ixstart = ix + 5; + + if ( !conv_compilemacro( &adrparam.ht, src, ixpos, slen, depth ) ) + break; + + ix = *ixpos; + + continue; + } + } + else if ( s[ ix ] == '|' ) /* resource param */ + { + *ixpos = ixstart = ix; /* skip the pipe */ + + if ( !parseresource( &adrparam, src, ixpos, slen, depth ) ) + break; + } + else + { + scriptError( STR_badparametervalue, src, ix, slen ); + break; + } + } + + if ( flmacrocomplete ) + { + // *ixpos += 3; + *ixpos = ix + 3; // ixpos is now [whitespace] + '-->' + } + else + { + ; /* is anything needed here, to clean up in the event of failure? */ + } + + return ( flmacrocomplete ); +} + + +static boolean conv_compilemacro( hdlhashtable * tbldest, const Handle s, long * ixpos, const long slen, long * depth ) +{ + bigstring macroname; + short macrotype; + convaddress adrnewitem, adrconditionalblock; + + if ( !getmacroname( s, ixpos, slen, macroname ) ) + return ( false ); + + macrotype = getmacrotypefromname( macroname ); + + if ( macrotype == CONV_MACROTYPE_COND_IF ) + { + if ( !createsubtable( *tbldest, STR_macroname, &adrnewitem, true ) ) /* adrMacro = xmlAddTable( adrParent, "macro" ) */ + return ( false ); + + if ( !assignstring( &adrnewitem, STR_name, macroname ) ) /* adrDest^.macroname = macroname */ + return ( false ); + + if ( !assignstring( &adrnewitem, STR_type, STR_conditional ) ) /* adrDest^.macrotype = "conditional" */ + return ( false ); + + if ( !conv_parsemacro( &adrnewitem, s, ixpos, slen, depth ) ) /* parsemacro( adrMaro ) */ + return ( false ); + + if ( !createsubtable( adrnewitem.ht, STR_condblock, &adrconditionalblock, false ) ) /* new( tabletype, @adrMacro^.conditionalBlock ) */ + return ( false ); + + ++(*depth); + + *tbldest = adrconditionalblock.ht; + } + else if ( ( macrotype == CONV_MACROTYPE_COND_ELSE ) || ( macrotype == CONV_MACROTYPE_COND_ELSEIF ) ) + { + if ( *depth > 1 ) + { + *tbldest = (***tbldest).parenthashtable; + *tbldest = (***tbldest).parenthashtable; + --(*depth); + } + + if ( !createsubtable( *tbldest, STR_macroname, &adrnewitem, true ) ) + return ( false ); + + if ( !assignstring( &adrnewitem, STR_name, macroname ) ) + return ( false ); + + if ( !assignstring( &adrnewitem, STR_type, STR_conditional ) ) + return ( false ); + + if ( !conv_parsemacro( &adrnewitem, s, ixpos, slen, depth ) ) + return ( false ); + + if ( !createsubtable( adrnewitem.ht, STR_condblock, &adrconditionalblock, false ) ) + return ( false ); + + ++(*depth); + + *tbldest = adrconditionalblock.ht; + } + else if ( macrotype == CONV_MACROTYPE_COND_ENDIF ) + { + if ( *depth > 1 ) + { + *tbldest = (***tbldest).parenthashtable; + *tbldest = (***tbldest).parenthashtable; + --(*depth); + } + + if ( !createsubtable( *tbldest, STR_macroname, &adrnewitem, true ) ) + return ( false ); + + if ( !assignstring( &adrnewitem, STR_name, macroname ) ) + return ( false ); + + if ( !assignstring( &adrnewitem, STR_type, STR_endconditional ) ) + return ( false ); + + if ( !conv_parsemacro( &adrnewitem, s, ixpos, slen, depth ) ) + return ( false ); + } + else + { + if ( !createsubtable( *tbldest, STR_macroname, &adrnewitem, true ) ) + return ( false ); + + if ( !assignstring( &adrnewitem, STR_name, macroname ) ) + return ( false ); + + if ( !assignstring( &adrnewitem, STR_type, STR_macro ) ) + return ( false ); + + if ( !conv_parsemacro( &adrnewitem, s, ixpos, slen, depth ) ) + return ( false ); + } + + return ( true ); +} + +static boolean conv_addrezdelim( hdlhashtable tbldest ) +{ + boolean fl = false; + byte delim = '|'; + convaddress adrnewitem; + + getnewitemaddress( tbldest, STR_rezname, &adrnewitem ); + + if ( !assignchar( &adrnewitem, delim ) ) + return ( false ); + + return ( true ); +} + +/* just finds the delimiters, doesn't actually identify the contents */ +static int conv_findnextmacroorresource( Handle src, long * ixpos, const long slen ) +{ + ptrbyte s = (ptrbyte) *src; + long maxlen = slen; + long ix = *ixpos; + + while ( ix < maxlen ) + { + if ( s[ ix ] == '|' ) + { + *ixpos = ix; + return CONV_RESOURCE; + } + else if ( ( s[ ix ] == '<' ) && ( ix <= maxlen - 4 ) ) + { + if ( ( ix < maxlen - 4 ) && + ( s[ ix + 1 ] == '!' ) && + ( s[ ix + 2 ] == '-' ) && + ( s[ ix + 3 ] == '-' ) && + ( s[ ix + 4 ] == '#' ) + ) + { + *ixpos = ix; + return CONV_MACRO; + } + } + + ++ix; + } /* while ix maxlen */ + + *ixpos = slen; + + return CONV_NOTYPE; +} + +static boolean conv_compilestringverb( hdltreenode hp1, tyvaluerecord *v, bigstring bserror ) +{ + Handle s; /* the string being parsed */ + convaddress adr; /* the table where the compiled output is to be stored */ + + hdlhashtable nomadtable; /* the table or subtable we're currently compiling to */ + + long ix = 0; /* current position in string */ + long ixStart = 0; /* start of current word */ + long slen; /* total size of string */ + long depth = 1; /* how deeply nested (in conditionals) are we? */ + + int nexttype; /* type of next item found by the scanner */ + boolean flcomplete = false; /* did parsing finish? */ + + + /* initialize */ + + if ( !getreadonlytextvalue( hp1, 1, &s ) ) + return false; + + slen = gethandlesize( s ); + + flnextparamislast = true; + + if ( !getvarparam( hp1, 2, &adr.ht, adr.bs ) ) /* initialize adr to info about the provided address */ + return (false); + + if ( langassignnewtablevalue( adr.ht, adr.bs, &nomadtable ) ) + { + assert ( (**nomadtable).parenthashtable == adr.ht ); + + /* start looping through the string, in "chunks" handled by other parts of the code */ + + while ( ix < slen ) + { + nexttype = conv_findnextmacroorresource( s, &ix, slen ); + + if ( nexttype == CONV_NOTYPE ) /* no more macros or resources */ + { + if ( !conv_addtextrange( nomadtable, s, ixStart, ix ) ) + break; + + flcomplete = true; + break; + } + else if ( nexttype == CONV_MACRO ) /* found a macro */ + { + if ( !conv_addtextrange( nomadtable, s, ixStart, ix ) ) + break; + + ix += 5; /* skip the maco delim */ + + /* may leave nomadtable pointing at something else, if macro is a conditional */ + if ( !conv_compilemacro( &nomadtable, s, &ix, slen, &depth ) ) + break; + + ixStart = ix; + } + else if ( nexttype == CONV_RESOURCE ) /* found a resource */ + { + if ( !conv_addtextrange( nomadtable, s, ixStart, ix ) ) + break; + + if ( !conv_addrezdelim( nomadtable ) ) + break; + + ixStart = ++ix; /* increment ix past the rez delim, and set ixStart to the new position */ + } + } /* while */ + + if ( ( !flcomplete ) && ( ix == slen ) ) + flcomplete = true; + } /* if langassignnewtablevalue */ + + if ( !flcomplete ) + ; /*hashtabledelete( nomadtable, bserror ); */ + else + setbooleanvalue( flcomplete, v ); + + return ( flcomplete ); +} /* conv_compilestringverb */ + + +static boolean conv_functionvalue ( short token, hdltreenode hp1, tyvaluerecord *v, bigstring bserror ) +{ + /* + 2004-120-31 smd: kernelized conversant verbs + */ + + short errornum = 0; + + setbooleanvalue (false, v); /* by default, conversant functions return false */ + + switch (token) + { + case compilestringfunc: /* 2004/12/31 smd */ + return ( conv_compilestringverb( hp1, v, bserror ) ); + + default: + errornum = notimplementederror; + + goto error; + } /*switch*/ + + error: + + if (errornum != 0) /*get error string*/ + getstringlist (conversanterrorlist, errornum, bserror); + + return (false); +} /*conv_functionvalue*/ + + +extern boolean conversantinitverbs (void) { + + return (loadfunctionprocessor (idconversantverbs, &conv_functionvalue)); + +} /*conversantinitverbs*/ + + #endif /* flconversantverbs==1 */ +#endif /* flconversantverbs */ \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |