mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 14:45:29 +00:00
0908487b46
Thanks to: Paul Chek <pchek@ziplink.net> for the fix
1615 lines
68 KiB
C
1615 lines
68 KiB
C
|
|
/* W3 Copyright statement
|
|
Copyright 1995 by: Massachusetts Institute of Technology (MIT), INRIA</H2>
|
|
|
|
This W3C software is being provided by the copyright holders under the
|
|
following license. By obtaining, using and/or copying this software,
|
|
you agree that you have read, understood, and will comply with the
|
|
following terms and conditions:
|
|
|
|
Permission to use, copy, modify, and distribute this software and its
|
|
documentation for any purpose and without fee or royalty is hereby
|
|
granted, provided that the full text of this NOTICE appears on
|
|
<EM>ALL</EM> copies of the software and documentation or portions
|
|
thereof, including modifications, that you make.
|
|
|
|
<B>THIS SOFTWARE IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO
|
|
REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE,
|
|
BUT NOT LIMITATION, COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR
|
|
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
|
|
THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY
|
|
THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
|
|
COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE
|
|
OR DOCUMENTATION.
|
|
|
|
The name and trademarks of copyright holders may NOT be used
|
|
in advertising or publicity pertaining to the software without
|
|
specific, written prior permission. Title to copyright in this
|
|
software and any associated documentation will at all times remain
|
|
with copyright holders.
|
|
*/
|
|
|
|
/* --- BEGIN added by mharmsen@netscape.com on 7/9/97 --- */
|
|
#include "xp.h"
|
|
/* --- END added by mharmsen@netscape.com on 7/9/97 --- */
|
|
/* #include "sysdep.h" jhines--7/9/97 */
|
|
/*#include "HTUtils.h" */
|
|
#include "htlist.h"
|
|
#include "htstring.h"
|
|
#include "csparse.h"
|
|
#include "csll.h"
|
|
#include "csllst.h"
|
|
|
|
#define GetCSLabel(A) ((A)->target.pCSLabel)
|
|
#define SETNEXTSTATE(target, subState) \
|
|
pCSParse->pTargetObject = target; \
|
|
pCSParse->currentSubState = subState;
|
|
|
|
|
|
/* C H A R A C T E R S E T V A L I D A T I O N */
|
|
/* The BNF for PICS labels describes the valid character ranges for each of
|
|
* the label fields. Defining NO_CHAR_TEST will disable the tedious checking
|
|
* of these ranges for a slight performance increase.
|
|
*/
|
|
#ifdef NO_CHAR_TEST
|
|
#define charSetOK(A, B, C)
|
|
#define CHECK_CAR_SET(A)
|
|
#define SET_CHAR_SET(A)
|
|
#else /* !NO_CHAR_TEST */
|
|
typedef enum {CharSet_ALPHAS = 1, CharSet_DIGITS = 2, CharSet_PLUSMINUS = 4, CharSet_FORSLASH = 8,
|
|
CharSet_EXTENS = 0x10, CharSet_BASE64_EXTRAS = 0x20, CharSet_DATE_EXTRAS = 0x40, CharSet_URL_EXTRAS = 0x80,
|
|
/* ------------------ BNF names are combinations of the above ------------------- */
|
|
CharSet_NUMBER = CharSet_DIGITS | CharSet_PLUSMINUS,
|
|
CharSet_ALPHANUMPM = CharSet_ALPHAS | CharSet_DIGITS | CharSet_PLUSMINUS,
|
|
CharSet_TRANSMIT_NAME = CharSet_ALPHANUMPM | CharSet_URL_EXTRAS,
|
|
CharSet_EXT_ALPHANUM = CharSet_ALPHANUMPM | CharSet_EXTENS,
|
|
CharSet_BASE64 = CharSet_ALPHAS | CharSet_DIGITS | CharSet_BASE64_EXTRAS,
|
|
CharSet_URL = CharSet_ALPHAS | CharSet_DIGITS | CharSet_URL_EXTRAS,
|
|
CharSet_DATE = CharSet_DIGITS | CharSet_DATE_EXTRAS,
|
|
CharSet_EXT_DATA = CharSet_DATE | CharSet_URL | CharSet_NUMBER | CharSet_EXT_ALPHANUM
|
|
} CharSet_t;
|
|
|
|
PRIVATE BOOL charSetOK(CSParse_t * pCSParse, char * checkMe, CharSet_t set);
|
|
#define CHECK_CAR_SET(A) \
|
|
if (!charSetOK(pCSParse, token, A)) \
|
|
return StateRet_ERROR_BAD_CHAR;
|
|
#define SET_CHAR_SET(A) pCSLabel->targetCharSet = A;
|
|
#endif /* !NO_CHAR_TEST */
|
|
|
|
/* C S L L S t a t e */
|
|
/* This holds label list data and the methods to view it. All application
|
|
* interface is intended to go through these methods. See User/Parsing.html
|
|
*/
|
|
struct CSLabel_s {
|
|
CSLLData_t * pCSLLData;
|
|
|
|
LabelError_t * pCurrentLabelError;
|
|
LabelOptions_t * pCurrentLabelOptions;
|
|
Extension_t * pCurrentExtension;
|
|
ExtensionData_t * pCurrentExtensionData;
|
|
|
|
ServiceInfo_t * pCurrentServiceInfo;
|
|
Label_t * pCurrentLabel;
|
|
int currentLabelNumber;
|
|
HTList * pCurrentLabelTree;
|
|
SingleLabel_t * pCurrentSingleLabel;
|
|
LabelRating_t * pCurrentLabelRating;
|
|
Range_t * pCurrentRange;
|
|
#ifndef NO_CHAR_TEST
|
|
CharSet_t targetCharSet;
|
|
#endif
|
|
|
|
LabelTargetCallback_t * pLabelTargetCallback;
|
|
LLErrorHandler_t * pLLErrorHandler;
|
|
};
|
|
|
|
/* forward references to parser functions */
|
|
PRIVATE TargetObject_t LabelList_targetObject;
|
|
PRIVATE TargetObject_t ServiceInfo_targetObject;
|
|
PRIVATE TargetObject_t ServiceNoRat_targetObject;
|
|
PRIVATE TargetObject_t ServiceError_targetObject;
|
|
PRIVATE TargetObject_t Label_targetObject;
|
|
PRIVATE TargetObject_t LabelError_targetObject;
|
|
PRIVATE TargetObject_t LabelTree_targetObject;
|
|
PRIVATE TargetObject_t SingleLabel_targetObject;
|
|
PRIVATE TargetObject_t LabelRating_targetObject;
|
|
PRIVATE TargetObject_t LabelRatingRange_targetObject;
|
|
PRIVATE TargetObject_t Extension_targetObject;
|
|
PRIVATE TargetObject_t ExtensionData_targetObject;
|
|
PRIVATE TargetObject_t Awkward_targetObject;
|
|
PRIVATE Check_t hasToken;
|
|
PRIVATE Check_t LabelList_getVersion;
|
|
PRIVATE Check_t ServiceInfo_getServiceId;
|
|
PRIVATE Check_t error_getExpl;
|
|
PRIVATE Check_t getOption;
|
|
PRIVATE Check_t getOptionValue;
|
|
PRIVATE Check_t LabelRating_getId;
|
|
PRIVATE Check_t LabelRating_getValue;
|
|
PRIVATE Check_t LabelRatingRange_get;
|
|
PRIVATE Check_t isQuoted;
|
|
PRIVATE Check_t Extension_getURL;
|
|
PRIVATE Check_t ExtensionData_getData;
|
|
PRIVATE Open_t LabelList_open;
|
|
PRIVATE Open_t ServiceInfo_open;
|
|
PRIVATE Open_t error_open;
|
|
PRIVATE Open_t Label_open;
|
|
PRIVATE Open_t LabelTree_open;
|
|
PRIVATE Open_t SingleLabel_open;
|
|
PRIVATE Open_t LabelRating_open;
|
|
PRIVATE Open_t LabelRatingRange_open;
|
|
PRIVATE Open_t Awkward_open;
|
|
PRIVATE Open_t Extension_open;
|
|
PRIVATE Open_t ExtensionData_open;
|
|
PRIVATE Close_t LabelList_close;
|
|
PRIVATE Close_t ServiceInfo_close;
|
|
PRIVATE Close_t error_close;
|
|
PRIVATE Close_t Label_close;
|
|
PRIVATE Close_t LabelTree_close;
|
|
PRIVATE Close_t SingleLabel_close;
|
|
PRIVATE Close_t LabelRating_close;
|
|
PRIVATE Close_t LabelRatingRange_close;
|
|
PRIVATE Close_t Awkward_close;
|
|
PRIVATE Close_t Extension_close;
|
|
PRIVATE Close_t ExtensionData_close;
|
|
PRIVATE Destroy_t LabelList_destroy;
|
|
PRIVATE Destroy_t ServiceInfo_destroy;
|
|
PRIVATE Destroy_t Label_destroy;
|
|
PRIVATE Destroy_t LabelTree_destroy;
|
|
PRIVATE Destroy_t SingleLabel_destroy;
|
|
PRIVATE Destroy_t LabelRating_destroy;
|
|
PRIVATE Destroy_t LabelRatingRange_destroy;
|
|
PRIVATE Destroy_t Awkward_destroy;
|
|
PRIVATE Destroy_t error_destroy;
|
|
PRIVATE Destroy_t Extension_destroy;
|
|
PRIVATE Destroy_t ExtensionData_destroy;
|
|
PRIVATE Prep_t ServiceInfo_clearOpts;
|
|
PRIVATE Prep_t LabelRating_next;
|
|
PRIVATE Prep_t Extension_mandatory;
|
|
PRIVATE Prep_t Extension_next;
|
|
PRIVATE Prep_t ExtensionData_next;
|
|
PRIVATE Prep_t SingleLabel_doClose;
|
|
PRIVATE Prep_t Label_doClose;
|
|
|
|
PRIVATE TargetChangeCallback_t targetChangeCallback;
|
|
PRIVATE ParseErrorHandler_t parseErrorHandler;
|
|
|
|
/* CSParse_doc states */
|
|
/* L A B E L L I S T P A R S E R S T A T E S */
|
|
/* This contains all the states in the BNF for PICS labels.
|
|
* See User/Parsing.html for details.
|
|
*/
|
|
PRIVATE StateToken_t LabelList_stateTokens[] = {
|
|
/* A: fresh LabelList
|
|
C: expect end */
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &LabelList_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{"get version", SubState_A, Punct_WHITE, &LabelList_getVersion, 0, 0, 0, &ServiceInfo_targetObject, SubState_N, Command_NONE, 0},
|
|
{"end of list", SubState_C, Punct_RPAREN, 0, 0, 0, 0, &LabelList_targetObject, SubState_A, Command_MATCHANY_CLOSE, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t ServiceInfo_stateTokens[] = {
|
|
/* A: fresh ServiceInfo
|
|
B: has service id
|
|
C: needs option value
|
|
D: call from Awkward or NoRat to close
|
|
E: call from Awkward to re-enter
|
|
F: call from Awkward to handle no-ratings error */
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &ServiceInfo_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "error w/o id", SubState_A, Punct_LPAREN, 0, "error", 0, 0, &ServiceNoRat_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "service id", SubState_A, Punct_WHITE, &ServiceInfo_getServiceId, 0, 0, 0, &ServiceInfo_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "service error", SubState_B, Punct_LPAREN, 0, "error", 0, 0, &ServiceError_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "service option", SubState_B, Punct_WHITE, &getOption, 0, 0, 0, &ServiceInfo_targetObject, SubState_C, Command_NONE, 0},
|
|
{"service extension", SubState_B, Punct_LPAREN, 0, "extension", 0, 0, &Extension_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "label-mark close", SubState_B, Punct_RPAREN, 0, "l", "labels", 0, &LabelList_targetObject, SubState_C, Command_CLOSE_CHAIN, 0},
|
|
{ "label-mark", SubState_B, Punct_WHITE_LPAREN, 0, "l", "labels", 0, &Label_targetObject, SubState_N, Command_CHAIN, &ServiceInfo_clearOpts},
|
|
{ "option value", SubState_C, Punct_WHITE, &getOptionValue, 0, 0, 0, &ServiceInfo_targetObject, SubState_B, Command_NONE, 0},
|
|
|
|
{ "close", SubState_D, Punct_ALL, 0, 0, 0, 0, &LabelList_targetObject, SubState_C, Command_MATCHANY_CLOSE_CHAIN, 0},
|
|
{ "re-enter", SubState_E, Punct_ALL, 0, 0, 0, 0, &ServiceInfo_targetObject, SubState_N, Command_MATCHANY_CLOSE_CHAIN, 0},
|
|
{ "to no-rat", SubState_F, Punct_ALL, 0, 0, 0, 0, &ServiceInfo_targetObject, SubState_G, Command_MATCHANY_CLOSE_CHAIN, 0},
|
|
{ "no-rat opener", SubState_G, Punct_ALL, 0, 0, 0, 0, &ServiceNoRat_targetObject, SubState_N, Command_MATCHANY_OPEN_CHAIN, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t Label_stateTokens[] = {
|
|
/* A: fresh SingleLabel
|
|
C: route to Awkward from LabelTree and LabelError
|
|
D: from Awkward to LabelError */
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &Label_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "single label mark", SubState_A, Punct_WHITE, 0, "l", "labels", 0, &Label_targetObject, SubState_A, Command_NONE, 0}, /* stick around */
|
|
{ "tree label mark", SubState_A, Punct_LPAREN, 0, "l", "labels", 0, &LabelTree_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "start tree", SubState_A, Punct_LPAREN, 0, 0, 0, 0, &LabelTree_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "label error", SubState_A, Punct_LPAREN, 0, "error", 0, 0, &LabelError_targetObject, SubState_N, Command_NONE, 0},
|
|
{"SingleLabel option", SubState_A, Punct_WHITE, &getOption, 0, 0, 0, &SingleLabel_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "label extension", SubState_A, Punct_LPAREN, 0, "extension", 0, 0, &SingleLabel_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "ratings", SubState_A, Punct_LPAREN, 0, "r", "ratings", 0, &SingleLabel_targetObject, SubState_N, Command_CHAIN, 0},
|
|
|
|
{ "to awkward", SubState_C, Punct_ALL, 0, 0, 0, 0, &Awkward_targetObject, SubState_A, Command_MATCHANY_CLOSE, 0},
|
|
{ "awkward to error", SubState_D, Punct_ALL, 0, 0, 0, 0, &LabelError_targetObject, SubState_N, Command_MATCHANY_OPEN_CHAIN, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t LabelTree_stateTokens[] = {
|
|
/* A: LabelTrees have no state */
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &LabelTree_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "label error", SubState_A, Punct_LPAREN, 0, "error", 0, 0, &LabelError_targetObject, SubState_N, Command_NONE, 0},
|
|
{"SingleLabel option", SubState_A, Punct_WHITE, &getOption, 0, 0, 0, &SingleLabel_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "ratingword", SubState_A, Punct_LPAREN, 0, "r", "ratings", 0, &SingleLabel_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "end of tree", SubState_A, Punct_RPAREN, 0, 0, 0, 0, &Label_targetObject, SubState_C, Command_CLOSE_CHAIN, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t SingleLabel_stateTokens[] = {
|
|
/* A: fresh SingleLabel
|
|
B: needs option value */
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &SingleLabel_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{"label extension", SubState_A, Punct_LPAREN, 0, "extension", 0, 0, &Extension_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "label option", SubState_A, Punct_WHITE, &getOption, 0, 0, 0, &SingleLabel_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "ratingword", SubState_A, Punct_LPAREN, 0, "r", "ratings", 0, &LabelRating_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "option value", SubState_B, Punct_WHITE, &getOptionValue, 0, 0, 0, &SingleLabel_targetObject, SubState_A, Command_NONE, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t LabelRating_stateTokens[] = {
|
|
/* A: looking for transmit name
|
|
B: looking for value
|
|
C: return from range (either creates a new rating or ends)
|
|
D: close and re-open */
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &LabelRating_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "id before value", SubState_A, Punct_WHITE, &LabelRating_getId, 0, 0, 0, &LabelRating_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "id before range", SubState_A, Punct_LPAREN, &LabelRating_getId, 0, 0, 0, &LabelRatingRange_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "value next", SubState_B, Punct_WHITE, &LabelRating_getValue, 0, 0, 0, &LabelRating_targetObject, SubState_D, Command_NONE, 0}, /* opener must close last rating first */
|
|
{ "value close", SubState_B, Punct_RPAREN, &LabelRating_getValue, 0, 0, 0, 0, SubState_X, Command_CLOSE, &LabelRating_next},
|
|
{ "close", SubState_C, Punct_RPAREN, 0, 0, 0, 0, 0, SubState_X, Command_CLOSE, &LabelRating_next},
|
|
{"value after range", SubState_C, Punct_WHITE_LPAREN, &hasToken, 0, 0, 0, &LabelRating_targetObject, SubState_D, Command_CHAIN, 0}, /* opener must close last rating first */
|
|
|
|
{ "re-enter", SubState_D, Punct_ALL, 0, 0, 0, 0, &LabelRating_targetObject, SubState_N, Command_MATCHANY_CLOSE_CHAIN, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t LabelRatingRange_stateTokens[] = {
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &LabelRatingRange_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "range data", SubState_A, Punct_WHITE, &LabelRatingRange_get, 0, 0, 0, &LabelRatingRange_targetObject, SubState_A, Command_NONE, 0},
|
|
{"range close", SubState_A, Punct_RPAREN, &LabelRatingRange_get, 0, 0, 0, &LabelRating_targetObject, SubState_C, Command_CLOSE, 0}
|
|
};
|
|
|
|
/* Awkward assumes that the current Label has been closed. It decides whether to chain to LabelTree, Label, or ServiceInfo */
|
|
PRIVATE StateToken_t Awkward_stateTokens[] = {
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &Awkward_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "start tree", SubState_A, Punct_LPAREN, 0, 0, 0, 0, &LabelTree_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "label error", SubState_A, Punct_LPAREN, 0, "error", 0, 0, &Awkward_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "label option", SubState_A, Punct_WHITE, &getOption, 0, 0, 0, &Label_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{"label extension", SubState_A, Punct_LPAREN, 0, "extension", 0, 0, &Label_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "rating", SubState_A, Punct_LPAREN, 0, "r", "ratings", 0, &Label_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "new service id", SubState_A, Punct_WHITE, &isQuoted, 0, 0, 0, &ServiceInfo_targetObject, SubState_E, Command_CHAIN, 0},
|
|
{ "close", SubState_A, Punct_RPAREN, 0, 0, 0, 0, &ServiceInfo_targetObject, SubState_D, Command_CHAIN, 0}, /* close of LabelList */
|
|
|
|
{ "req-denied", SubState_B, Punct_WHITE, 0, "request-denied", 0, 0, &Label_targetObject, SubState_D, Command_CHAIN, 0},
|
|
{ "req-denied close", SubState_B, Punct_RPAREN, 0, "request-denied", 0, 0, &Label_targetObject, SubState_D, Command_CHAIN, 0},
|
|
{ "not-labeled", SubState_B, Punct_WHITE, 0, "not-labeled", 0, 0, &Label_targetObject, SubState_D, Command_CHAIN, 0},
|
|
{"not-labeled close", SubState_B, Punct_RPAREN, 0, "not-labeled", 0, 0, &Label_targetObject, SubState_D, Command_CHAIN, 0},
|
|
{ "no-ratings", SubState_B, Punct_WHITE, 0, "no-ratings", 0, 0, &ServiceInfo_targetObject, SubState_F, Command_CHAIN, 0},
|
|
{ "no-ratings close", SubState_B, Punct_RPAREN, 0, "no-ratings", 0, 0, &ServiceInfo_targetObject, SubState_F, Command_CHAIN, 0}
|
|
};
|
|
|
|
/* error parsing states */
|
|
PRIVATE StateToken_t ServiceNoRat_stateTokens[] = {
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &ServiceNoRat_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "no-ratings", SubState_A, Punct_WHITE, 0, "no-ratings", 0, 0, &ServiceNoRat_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "no-ratings close", SubState_A, Punct_RPAREN, 0, "no-ratings", 0, 0, &ServiceInfo_targetObject, SubState_D, Command_CLOSE_CHAIN, 0},
|
|
{ "explanation", SubState_B, Punct_WHITE, &error_getExpl, 0, 0, 0, &ServiceNoRat_targetObject, SubState_B, Command_NONE, 0},
|
|
{"explanation close", SubState_B, Punct_RPAREN, &error_getExpl, 0, 0, 0, &ServiceInfo_targetObject, SubState_D, Command_CLOSE_CHAIN, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t ServiceError_stateTokens[] = {
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &ServiceError_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "req-denied", SubState_A, Punct_WHITE, 0, "request-denied", 0, 0, &ServiceError_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "req-denied close", SubState_A, Punct_RPAREN, 0, "request-denied", 0, 0, &ServiceInfo_targetObject, SubState_D, Command_CLOSE_CHAIN, 0},
|
|
{ "service-unavail", SubState_A, Punct_WHITE, 0,"service-unavailable", 0, 0, &ServiceError_targetObject, SubState_B, Command_NONE, 0},
|
|
{"service-unavail close", SubState_A, Punct_RPAREN, 0,"service-unavailable", 0, 0, &ServiceInfo_targetObject, SubState_D, Command_CLOSE_CHAIN, 0},
|
|
{ "explanation", SubState_B, Punct_WHITE, &error_getExpl, 0, 0, 0, &ServiceError_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "explanation close", SubState_B, Punct_RPAREN, &error_getExpl, 0, 0, 0, &ServiceInfo_targetObject, SubState_D, Command_CLOSE_CHAIN, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t LabelError_stateTokens[] = {
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &LabelError_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "req-denied", SubState_A, Punct_WHITE, 0, "request-denied", 0, 0, &LabelError_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "req-denied close", SubState_A, Punct_RPAREN, 0, "request-denied", 0, 0, &Label_targetObject, SubState_C, Command_CLOSE_CHAIN, 0},
|
|
{ "not-labeled", SubState_A, Punct_WHITE, 0, "not-labeled", 0, 0, &LabelError_targetObject, SubState_B, Command_NONE, 0},
|
|
{"not-labeled close", SubState_A, Punct_RPAREN, 0, "not-labeled", 0, 0, &Label_targetObject, SubState_C, Command_CLOSE_CHAIN, 0},
|
|
{ "explanation", SubState_B, Punct_WHITE, &error_getExpl, 0, 0, 0, &LabelError_targetObject, SubState_B, Command_NONE, 0},
|
|
{"explanation close", SubState_B, Punct_RPAREN, &error_getExpl, 0, 0, 0, &Label_targetObject, SubState_C, Command_CLOSE_CHAIN, 0}
|
|
};
|
|
|
|
PRIVATE StateToken_t Extension_stateTokens[] = {
|
|
/* A: looking for mand/opt
|
|
B: looking for URL
|
|
C: back from ExtensionData */
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &Extension_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "mandatory", SubState_A, Punct_WHITE, 0, "mandatory", 0, 0, &Extension_targetObject, SubState_B, Command_NONE, &Extension_mandatory},
|
|
{ "optional", SubState_A, Punct_WHITE, 0, "optional", 0, 0, &Extension_targetObject, SubState_B, Command_NONE, 0},
|
|
{ "URL", SubState_B, Punct_WHITE, &Extension_getURL, 0, 0, 0, &ExtensionData_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "URL open", SubState_B, Punct_LPAREN, &Extension_getURL, 0, 0, 0, &ExtensionData_targetObject, SubState_N, Command_CHAIN_NOTOKEN, 0},
|
|
{ "URL close", SubState_B, Punct_RPAREN, &Extension_getURL, 0, 0, 0, 0, SubState_X, Command_CLOSE, &Extension_next},
|
|
|
|
{ "more data", SubState_C, Punct_WHITE_LPAREN_RPAREN, &hasToken, 0, 0, 0, &ExtensionData_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "nest", SubState_C, Punct_LPAREN, 0, 0, 0, 0, &ExtensionData_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "close", SubState_C, Punct_RPAREN, 0, 0, 0, 0, 0, SubState_X, Command_CLOSE, &Extension_next}
|
|
};
|
|
|
|
PRIVATE StateToken_t ExtensionData_stateTokens[] = {
|
|
/* A: looking for data
|
|
B: back from recursive ExtensionData (identical to Extension B) */
|
|
{ "open", SubState_N, Punct_ALL, 0, 0, 0, 0, &ExtensionData_targetObject, SubState_A, Command_MATCHANY_OPEN_CHAIN, 0},
|
|
{ "lparen", SubState_A, Punct_LPAREN, 0, 0, 0, 0, &ExtensionData_targetObject, SubState_N, Command_NONE, 0},
|
|
{ "close", SubState_A, Punct_RPAREN, 0, 0, 0, 0, 0, SubState_X, Command_CLOSE, &ExtensionData_next},
|
|
{ "data", SubState_A, Punct_WHITE, &ExtensionData_getData, 0, 0, 0, 0, SubState_X, Command_CLOSE, &ExtensionData_next},
|
|
{"data punct", SubState_A, Punct_LPAREN_RPAREN, &ExtensionData_getData, 0, 0, 0, 0, SubState_X, Command_CLOSE_CHAIN_NOTOKEN, &ExtensionData_next},
|
|
|
|
{ "more data", SubState_B, Punct_WHITE_LPAREN_RPAREN, &hasToken, 0, 0, 0, &ExtensionData_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "nest", SubState_B, Punct_LPAREN, 0, 0, 0, 0, &ExtensionData_targetObject, SubState_N, Command_CHAIN, 0},
|
|
{ "close", SubState_B, Punct_RPAREN, 0, 0, 0, 0, 0, SubState_X, Command_CLOSE, &ExtensionData_next}
|
|
};
|
|
|
|
|
|
PRIVATE void init_target_obj(TargetObject_t *obj, char *note, Open_t *pOpen, Close_t *pClose, Destroy_t *pDestroy, StateToken_t *stateToken, int stateTokenCount, CSParseTC_t targetChange)
|
|
{
|
|
obj->note = note;
|
|
obj->pOpen = pOpen;
|
|
obj->pClose = pClose;
|
|
obj->pDestroy = pDestroy;
|
|
obj->stateTokens = stateToken;
|
|
obj->stateTokenCount = stateTokenCount;
|
|
obj->targetChange = targetChange;
|
|
}
|
|
|
|
PRIVATE void CSinitialize_global_data(void)
|
|
{
|
|
static XP_Bool first_time=TRUE;
|
|
|
|
if(first_time)
|
|
{
|
|
first_time = FALSE;
|
|
|
|
init_target_obj(&LabelList_targetObject, "LabelList", &LabelList_open, &LabelList_close, &LabelList_destroy, LabelList_stateTokens, raysize(LabelList_stateTokens), CSLLTC_LIST);
|
|
init_target_obj(&ServiceInfo_targetObject, "ServiceInfo", ServiceInfo_open, &ServiceInfo_close, &ServiceInfo_destroy, ServiceInfo_stateTokens, raysize(ServiceInfo_stateTokens), CSLLTC_SERVICE);
|
|
init_target_obj(&Label_targetObject, "Label", &Label_open, &Label_close, &Label_destroy, Label_stateTokens, raysize(Label_stateTokens), CSLLTC_LABEL);
|
|
init_target_obj(&LabelTree_targetObject, "LabelTree", &LabelTree_open, &LabelTree_close, &LabelTree_destroy, LabelTree_stateTokens, raysize(LabelTree_stateTokens), CSLLTC_LABTREE);
|
|
init_target_obj(&SingleLabel_targetObject, "SingleLabel", &SingleLabel_open, &SingleLabel_close, &SingleLabel_destroy, SingleLabel_stateTokens, raysize(SingleLabel_stateTokens), CSLLTC_SINGLE);
|
|
init_target_obj(&LabelRating_targetObject, "LabelRating", &LabelRating_open, &LabelRating_close, &LabelRating_destroy, LabelRating_stateTokens, raysize(LabelRating_stateTokens), CSLLTC_RATING);
|
|
init_target_obj(&LabelRatingRange_targetObject, "LabelRatingRange", &LabelRatingRange_open, &LabelRatingRange_close, &LabelRatingRange_destroy, LabelRatingRange_stateTokens, raysize(LabelRatingRange_stateTokens), CSLLTC_RANGE);
|
|
init_target_obj(&Awkward_targetObject, "Awkward", &Awkward_open, &Awkward_close, &Awkward_destroy, Awkward_stateTokens, raysize(Awkward_stateTokens), 0);
|
|
init_target_obj(&ServiceNoRat_targetObject, "ServiceNoRat", &error_open, &error_close, &error_destroy, ServiceNoRat_stateTokens, raysize(ServiceNoRat_stateTokens), CSLLTC_NORAT);
|
|
init_target_obj(&LabelError_targetObject, "LabelError", &error_open, &error_close, &error_destroy, LabelError_stateTokens, raysize(LabelError_stateTokens), CSLLTC_LABERR);
|
|
init_target_obj(&ServiceError_targetObject, "ServiceError", &error_open, &error_close, &error_destroy, ServiceError_stateTokens, raysize(ServiceError_stateTokens), CSLLTC_SRVERR);
|
|
init_target_obj(&Extension_targetObject, "Extension", &Extension_open, &Extension_close, &Extension_destroy, Extension_stateTokens, raysize(Extension_stateTokens), CSLLTC_EXTEN);
|
|
init_target_obj(&ExtensionData_targetObject, "ExtensionData", &ExtensionData_open, &ExtensionData_close, &ExtensionData_destroy, ExtensionData_stateTokens, raysize(ExtensionData_stateTokens), CSLLTC_EXTDATA);
|
|
}
|
|
}
|
|
|
|
/* CSParse_doc end */
|
|
/* S T A T E A S S O C I A T I O N - associate a CSLabel with the label list data
|
|
The label list data is kept around until all states referencing it are destroyed */
|
|
typedef struct {
|
|
CSLabel_t * pCSLabel;
|
|
CSLLData_t * pCSLLData;
|
|
} CSLabelAssoc_t;
|
|
|
|
PRIVATE HTList * CSLabelAssocs = 0;
|
|
|
|
PRIVATE void CSLabelAssoc_add(CSLabel_t * pCSLabel, CSLLData_t * pCSLLData)
|
|
{
|
|
CSLabelAssoc_t * pElement;
|
|
if ((pElement = (CSLabelAssoc_t *) HT_CALLOC(1, sizeof(CSLabelAssoc_t))) == NULL)
|
|
HT_OUTOFMEM("CSLabelAssoc_t");
|
|
pElement->pCSLabel = pCSLabel;
|
|
pElement->pCSLLData = pCSLLData;
|
|
if (!CSLabelAssocs)
|
|
CSLabelAssocs = HTList_new();
|
|
HTList_appendObject(CSLabelAssocs, (void *)pElement);
|
|
}
|
|
|
|
PRIVATE CSLabelAssoc_t * CSLabelAssoc_findByData(CSLLData_t * pCSLLData)
|
|
{
|
|
HTList * assocs = CSLabelAssocs;
|
|
CSLabelAssoc_t * pElement;
|
|
while ((pElement = (CSLabelAssoc_t *) HTList_nextObject(assocs)) != NULL)
|
|
if (pElement->pCSLLData == pCSLLData)
|
|
return pElement;
|
|
return 0;
|
|
}
|
|
|
|
PRIVATE CSLabelAssoc_t * CSLabelAssoc_findByState(CSLabel_t * pCSLabel)
|
|
{
|
|
HTList * assocs = CSLabelAssocs;
|
|
CSLabelAssoc_t * pElement;
|
|
while ((pElement = (CSLabelAssoc_t *) HTList_nextObject(assocs)) != NULL)
|
|
if (pElement->pCSLabel == pCSLabel)
|
|
return pElement;
|
|
return 0;
|
|
}
|
|
|
|
PRIVATE void CSLabelAssoc_removeByState(CSLabel_t * pCSLabel)
|
|
{
|
|
CSLabelAssoc_t * pElement = CSLabelAssoc_findByState(pCSLabel);
|
|
if (!pElement)
|
|
return;
|
|
HTList_removeObject(CSLabelAssocs, (void *)pElement);
|
|
HT_FREE(pElement);
|
|
}
|
|
|
|
/* P R I V A T E C O N S T R U C T O R S / D E S T R U C T O R S */
|
|
/* These serve the public constructors
|
|
*/
|
|
PRIVATE LabelError_t * LabelError_new(void)
|
|
{
|
|
LabelError_t * me;
|
|
if ((me = (LabelError_t *) HT_CALLOC(1, sizeof(LabelError_t))) == NULL)
|
|
HT_OUTOFMEM("LabelError_t");
|
|
me->explanations = HTList_new();
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void LabelError_free(LabelError_t * me)
|
|
{
|
|
char * explanation;
|
|
if (!me)
|
|
return;
|
|
while ((explanation = (char *) HTList_removeLastObject(me->explanations)) != NULL)
|
|
HT_FREE(explanation);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
PRIVATE LabelOptions_t * LabelOptions_new(LabelOptions_t * pParentLabelOptions)
|
|
{
|
|
LabelOptions_t * me;
|
|
if ((me = (LabelOptions_t *) HT_CALLOC(1, sizeof(LabelOptions_t))) == NULL)
|
|
HT_OUTOFMEM("LabelOptions_t");
|
|
me->pParentLabelOptions = pParentLabelOptions;
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void LabelOptions_free(LabelOptions_t * me)
|
|
{
|
|
char * comment;
|
|
DVal_clear(&me->at);
|
|
SVal_clear(&me->by);
|
|
SVal_clear(&me->complete_label);
|
|
BVal_clear(&me->generic);
|
|
SVal_clear(&me->fur);
|
|
SVal_clear(&me->MIC_md5);
|
|
DVal_clear(&me->on);
|
|
SVal_clear(&me->signature_PKCS);
|
|
DVal_clear(&me->until);
|
|
while ((comment = HTList_removeLastObject(me->comments)) != NULL)
|
|
HT_FREE(comment);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
PRIVATE ExtensionData_t * ExtensionData_new(void)
|
|
{
|
|
ExtensionData_t * me;
|
|
if ((me = (ExtensionData_t *) HT_CALLOC(1, sizeof(ExtensionData_t))) == NULL)
|
|
HT_OUTOFMEM("ExtensionData_t");
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void ExtensionData_free(ExtensionData_t * me)
|
|
{
|
|
ExtensionData_t * pExtensionData;
|
|
while ((pExtensionData = (ExtensionData_t *) HTList_removeLastObject(me->moreData)) != NULL)
|
|
ExtensionData_free(pExtensionData);
|
|
HT_FREE(me->text);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
PRIVATE Extension_t * Extension_new(void)
|
|
{
|
|
Extension_t * me;
|
|
if ((me = (Extension_t *) HT_CALLOC(1, sizeof(Extension_t))) == NULL)
|
|
HT_OUTOFMEM("Extension_t");
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void Extension_free(Extension_t * me)
|
|
{
|
|
ExtensionData_t * pExtensionData;
|
|
while ((pExtensionData = (ExtensionData_t *) HTList_removeLastObject(me->extensionData)) != NULL)
|
|
ExtensionData_free(pExtensionData);
|
|
SVal_clear(&me->url);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
PRIVATE LabelRating_t * LabelRating_new(void)
|
|
{
|
|
LabelRating_t * me;
|
|
if ((me = (LabelRating_t *) HT_CALLOC(1, sizeof(LabelRating_t))) == NULL)
|
|
HT_OUTOFMEM("LabelRating_t");
|
|
/* don't initialize HTList me->ranges as it may be just a value */
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void LabelRating_free(LabelRating_t * me)
|
|
{
|
|
Range_t * pRange;
|
|
while ((pRange = (Range_t *) HTList_removeLastObject(me->ranges)) != NULL)
|
|
HT_FREE(pRange);
|
|
SVal_clear(&me->identifier);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
PRIVATE SingleLabel_t * SingleLabel_new(LabelOptions_t * pLabelOptions, LabelOptions_t * pParentLabelOptions)
|
|
{
|
|
SingleLabel_t * me;
|
|
if ((me = (SingleLabel_t *) HT_CALLOC(1, sizeof(SingleLabel_t))) == NULL)
|
|
HT_OUTOFMEM("SingleLabel_t");
|
|
me->labelRatings = HTList_new();
|
|
me->pLabelOptions = pLabelOptions ? pLabelOptions : LabelOptions_new(pParentLabelOptions);
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void SingleLabel_free(SingleLabel_t * me)
|
|
{
|
|
LabelRating_t * pLabelRating;
|
|
while ((pLabelRating = (LabelRating_t *) HTList_removeLastObject(me->labelRatings)) != NULL)
|
|
LabelRating_free(pLabelRating);
|
|
LabelOptions_free(me->pLabelOptions);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
PRIVATE Label_t * Label_new(void)
|
|
{
|
|
Label_t * me;
|
|
if ((me = (Label_t *) HT_CALLOC(1, sizeof(Label_t))) == NULL)
|
|
HT_OUTOFMEM("Label_t");
|
|
/* dont initialize HTList me->singleLabels */
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void Label_free(Label_t * me)
|
|
{
|
|
SingleLabel_t * pSingleLabel;
|
|
if (me->pSingleLabel)
|
|
SingleLabel_free(me->pSingleLabel);
|
|
else /* if both of these are (erroneously) defined, mem checkers will pick it up */
|
|
while ((pSingleLabel = (SingleLabel_t *) HTList_removeLastObject(me->singleLabels)) != NULL)
|
|
SingleLabel_free(pSingleLabel);
|
|
LabelError_free(me->pLabelError);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
PRIVATE ServiceInfo_t * ServiceInfo_new()
|
|
{
|
|
ServiceInfo_t * me;
|
|
if ((me = (ServiceInfo_t *) HT_CALLOC(1, sizeof(ServiceInfo_t))) == NULL)
|
|
HT_OUTOFMEM("ServiceInfo_t");
|
|
me->labels = HTList_new();
|
|
me->pLabelOptions = LabelOptions_new(0);
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void ServiceInfo_free(ServiceInfo_t * me)
|
|
{
|
|
Label_t * pLabel;
|
|
while ((pLabel = (Label_t *) HTList_removeLastObject(me->labels)) != NULL)
|
|
Label_free(pLabel);
|
|
SVal_clear(&me->rating_service);
|
|
LabelOptions_free(me->pLabelOptions);
|
|
LabelError_free(me->pLabelError);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
PRIVATE CSLLData_t * CSLLData_new(void)
|
|
{
|
|
CSLLData_t * me;
|
|
if ((me = (CSLLData_t *) HT_CALLOC(1, sizeof(CSLLData_t))) == NULL)
|
|
HT_OUTOFMEM("CSLLData_t");
|
|
me->serviceInfos = HTList_new();
|
|
return me;
|
|
}
|
|
|
|
PRIVATE void CSLLData_free(CSLLData_t * me)
|
|
{
|
|
ServiceInfo_t * pServiceInfo;
|
|
if (CSLabelAssoc_findByData(me))
|
|
return;
|
|
while ((pServiceInfo = (ServiceInfo_t *) HTList_removeLastObject(me->serviceInfos)) != NULL)
|
|
ServiceInfo_free(pServiceInfo);
|
|
FVal_clear(&me->version);
|
|
LabelError_free(me->pLabelError);
|
|
HT_FREE(me);
|
|
}
|
|
|
|
/* P U B L I C C O N S T R U C T O R S / D E S T R U C T O R S */
|
|
PRIVATE CSLabel_t * CSLabel_new(CSLLData_t * pCSLLData, LabelTargetCallback_t * pLabelTargetCallback,
|
|
LLErrorHandler_t * pLLErrorHandler)
|
|
{
|
|
CSLabel_t * me;
|
|
if ((me = (CSLabel_t *) HT_CALLOC(1, sizeof(CSLabel_t))) == NULL)
|
|
HT_OUTOFMEM("CSLabel_t");
|
|
me->pCSLLData = pCSLLData;
|
|
me->pLabelTargetCallback = pLabelTargetCallback;
|
|
me->pLLErrorHandler = pLLErrorHandler;
|
|
CSLabelAssoc_add(me, pCSLLData);
|
|
return me;
|
|
}
|
|
|
|
PUBLIC CSLabel_t * CSLabel_copy(CSLabel_t * old)
|
|
{
|
|
CSLabel_t * me = CSLabel_new(old->pCSLLData, old->pLabelTargetCallback, old->pLLErrorHandler);
|
|
/* --- BEGIN converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
XP_MEMCPY(me, old, sizeof(CSLabel_t));
|
|
/* --- END converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
return me;
|
|
}
|
|
|
|
PUBLIC void CSLabel_free(CSLabel_t * me)
|
|
{
|
|
CSLLData_t * pCSLLData = me->pCSLLData;
|
|
CSLabelAssoc_removeByState(me);
|
|
HT_FREE(me);
|
|
CSLLData_free(pCSLLData);
|
|
}
|
|
|
|
PUBLIC CSLLData_t * CSLabel_getCSLLData(CSLabel_t * me)
|
|
{return me->pCSLLData;}
|
|
PUBLIC LabelError_t * CSLabel_getLabelError(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentLabelError;}
|
|
PUBLIC LabelOptions_t * CSLabel_getLabelOptions(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentLabelOptions;}
|
|
PUBLIC ServiceInfo_t * CSLabel_getServiceInfo(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentServiceInfo;}
|
|
PUBLIC char * CSLabel_getServiceName(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentServiceInfo ?
|
|
SVal_value(&pCSLabel->pCurrentServiceInfo->rating_service): 0;}
|
|
PUBLIC Label_t * CSLabel_getLabel(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentLabel;}
|
|
PUBLIC int CSLabel_getLabelNumber(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->currentLabelNumber;}
|
|
PUBLIC SingleLabel_t * CSLabel_getSingleLabel(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentSingleLabel;}
|
|
PUBLIC LabelRating_t * CSLabel_getLabelRating(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentLabelRating;}
|
|
PUBLIC char * CSLabel_getRatingName(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentLabelRating ?
|
|
SVal_value(&pCSLabel->pCurrentLabelRating->identifier): 0;}
|
|
PUBLIC Range_t * CSLabel_getLabelRatingRange(CSLabel_t * pCSLabel)
|
|
{return pCSLabel->pCurrentRange;}
|
|
PUBLIC char * CSLabel_getRatingStr(CSLabel_t * pCSLabel)
|
|
{
|
|
HTChunk * pChunk;
|
|
HTList * ranges;
|
|
Range_t * curRange;
|
|
FVal_t fVal;
|
|
int count = 0;
|
|
fVal = CSLabel_getLabelRating(pCSLabel)->value;
|
|
if (FVal_initialized(&fVal))
|
|
return FVal_toStr(&fVal);
|
|
pChunk = HTChunk_new(20);
|
|
ranges = CSLabel_getLabelRating(pCSLabel)->ranges;
|
|
while ((curRange = (Range_t *) HTList_nextObject(ranges)) != NULL) {
|
|
char * ptr;
|
|
count++;
|
|
ptr = Range_toStr(curRange);
|
|
if (count > 1)
|
|
HTChunk_puts(pChunk, " ");
|
|
HTChunk_puts(pChunk, ptr);
|
|
HT_FREE(ptr);
|
|
}
|
|
return HTChunk_toCString(pChunk);
|
|
}
|
|
|
|
PUBLIC CSParse_t * CSParse_newLabel(LabelTargetCallback_t * pLabelTargetCallback,
|
|
LLErrorHandler_t * pLLErrorHandler)
|
|
{
|
|
CSParse_t * me = CSParse_new();
|
|
|
|
CSinitialize_global_data();
|
|
|
|
me->pParseContext->engineOf = &CSParse_targetParser;
|
|
me->pParseContext->pTargetChangeCallback = &targetChangeCallback;
|
|
me->pParseContext->pParseErrorHandler = &parseErrorHandler;
|
|
me->target.pCSLabel = CSLabel_new(CSLLData_new(), pLabelTargetCallback, pLLErrorHandler);
|
|
me->pTargetObject = &LabelList_targetObject;
|
|
me->currentSubState = SubState_N;
|
|
return me;
|
|
}
|
|
|
|
PUBLIC CSLabel_t * CSParse_getLabel(CSParse_t * me)
|
|
{
|
|
return (me->target.pCSLabel);
|
|
}
|
|
|
|
PUBLIC BOOL CSParse_deleteLabel(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * me = GetCSLabel(pCSParse);
|
|
CSLLData_free(CSLabel_getCSLLData(me));
|
|
CSLabel_free(me);
|
|
CSParse_delete(pCSParse);
|
|
return YES;
|
|
}
|
|
|
|
/* D E F A U L T P A R S I N G H A N D L E R S */
|
|
PRIVATE StateRet_t targetChangeCallback(CSParse_t * pCSParse, TargetObject_t * pTargetObject, CSParseTC_t target, BOOL closed, void * pVoid)
|
|
{
|
|
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
if (pCSLabel->pLabelTargetCallback)
|
|
return (*pCSLabel->pLabelTargetCallback)(pCSLabel, pCSParse, (CSLLTC_t)target, closed, pVoid);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t parseErrorHandler(CSParse_t * pCSParse, const char * token, char demark, StateRet_t errorCode)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
if (pCSLabel->pLLErrorHandler)
|
|
return (*pCSLabel->pLLErrorHandler)(pCSLabel, pCSParse, token, demark, errorCode);
|
|
return errorCode;
|
|
}
|
|
|
|
/* CSParse_doc methods */
|
|
/* P A R S I N G S T A T E F U N C T I O N S */
|
|
#ifndef NO_CHAR_TEST
|
|
PRIVATE BOOL charSetOK(CSParse_t * pCSParse, char * checkMe, CharSet_t set)
|
|
{
|
|
if(!checkMe)
|
|
return FALSE;
|
|
|
|
for (;*checkMe;checkMe++) {
|
|
if (set & CharSet_ALPHAS &&
|
|
((*checkMe >= 'A' && *checkMe <= 'Z') ||
|
|
(*checkMe >= 'a' && *checkMe <= 'z')))
|
|
continue;
|
|
if (set & CharSet_DIGITS &&
|
|
((*checkMe >= '0' && *checkMe <= '9') || *checkMe == '.'))
|
|
continue;
|
|
if (set & CharSet_PLUSMINUS &&
|
|
((*checkMe == '+' || *checkMe == '-')))
|
|
continue;
|
|
if (set & CharSet_FORSLASH &&
|
|
*checkMe == '/')
|
|
continue;
|
|
if (set & CharSet_BASE64_EXTRAS &&
|
|
((*checkMe == '+' || *checkMe == '/' || *checkMe == '=')))
|
|
continue;
|
|
if (set & CharSet_DATE_EXTRAS &&
|
|
(*checkMe == '.' || *checkMe == ':' ||
|
|
*checkMe == '-' || *checkMe == 'T'))
|
|
continue;
|
|
/* RFC1738:2.1:"+.-","#%",";/"?:@=&" 2.2:"$-_.+!*'()," */
|
|
if (set & CharSet_URL_EXTRAS &&
|
|
(*checkMe == ':' || *checkMe == '?' ||
|
|
*checkMe == '#' || *checkMe == '%' ||
|
|
*checkMe == '/' || *checkMe == '.' ||
|
|
*checkMe == '-' || *checkMe == '_' ||
|
|
*checkMe == '~' || *checkMe == '\\'||
|
|
*checkMe == '@'))
|
|
continue;
|
|
/* '.' | ' ' | ',' | ';' | ':' | '&' | '=' | '?' | '!' | '*' | '~' | '@' | '#' */
|
|
if (set & CharSet_EXTENS &&
|
|
(*checkMe == '.' || *checkMe == ' ' ||
|
|
*checkMe == ',' || *checkMe == ';' ||
|
|
*checkMe == ':' || *checkMe == '&' ||
|
|
*checkMe == '=' || *checkMe == '?' ||
|
|
*checkMe == '!' || *checkMe == '*' ||
|
|
*checkMe == '~' || *checkMe == '@' ||
|
|
*checkMe == '#' || *checkMe == '\''||
|
|
*checkMe == '/' || *checkMe == '-'))
|
|
continue;
|
|
pCSParse->pParseContext->pTokenError = checkMe;
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
#endif /* !NO_CHAR_TEST */
|
|
|
|
PRIVATE StateRet_t isQuoted(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
ParseContext_t * pParseContext = pCSParse->pParseContext;
|
|
if (!pParseContext->observedQuotes)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t hasToken(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
return token ? StateRet_OK : StateRet_WARN_NO_MATCH;
|
|
}
|
|
#if 0
|
|
PRIVATE StateRet_t clearToken(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
HTChunk_clear(pCSParse->token);
|
|
return StateRet_OK;
|
|
}
|
|
#endif
|
|
/* getOption - see if token matches an option.
|
|
This may be called by:
|
|
ServiceInfo: add option to existent options, pCurrentLabelError is set by ServiceInfo_open
|
|
Label: kick off SingleLabel - SingleLabel_new(), pCurrentLabelError is 0
|
|
SingleLabel: add another option to existent options, pCurrentLabelError is set by SingleLabel_open
|
|
*/
|
|
#define CSOffsetOf(s,m) (size_t)&(((s *)0)->m)
|
|
/* --- BEGIN converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
#define CHECK_OPTION_TOKEN_BVAL1(text, pointer) \
|
|
if (!XP_STRCASECMP(token, text)) {\
|
|
pCSParse->pParseContext->valTarget.pTargetBVal = pointer;\
|
|
pCSParse->pParseContext->valType = ValType_BVAL;\
|
|
break;\
|
|
}
|
|
|
|
#define CHECK_OPTION_TOKEN_FVAL1(text, pointer) \
|
|
if (!XP_STRCASECMP(token, text)) {\
|
|
pCSParse->pParseContext->valTarget.pTargetFVal = pointer;\
|
|
pCSParse->pParseContext->valType = ValType_FVAL;\
|
|
break;\
|
|
}
|
|
|
|
#define CHECK_OPTION_TOKEN_SVAL1(text, pointer, charSet) \
|
|
if (!XP_STRCASECMP(token, text)) {\
|
|
pCSParse->pParseContext->valTarget.pTargetSVal = pointer;\
|
|
pCSParse->pParseContext->valType = ValType_SVAL;\
|
|
SET_CHAR_SET(charSet)\
|
|
break;\
|
|
}
|
|
|
|
#define CHECK_OPTION_TOKEN_DVAL1(text, pointer) \
|
|
if (!XP_STRCASECMP(token, text)) {\
|
|
pCSParse->pParseContext->valTarget.pTargetDVal = pointer;\
|
|
pCSParse->pParseContext->valType = ValType_DVAL;\
|
|
break;\
|
|
}
|
|
/* --- END converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
|
|
PRIVATE StateRet_t getOption(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
LabelOptions_t * me = pCSLabel->pCurrentLabelOptions;
|
|
if (!token)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (!me)
|
|
me = pCSLabel->pCurrentLabelOptions = LabelOptions_new(pCSLabel->pCurrentServiceInfo->pLabelOptions);
|
|
/* match token against legal options */
|
|
pCSParse->pParseContext->valType = ValType_NONE; /* use valType to flag a match */
|
|
/* --- BEGIN converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
do { /* fake do loop for break statements (to religiously avoid the goto) */
|
|
CHECK_OPTION_TOKEN_DVAL1("at", &me->at)
|
|
CHECK_OPTION_TOKEN_SVAL1("by", &me->by, CharSet_EXT_ALPHANUM)
|
|
CHECK_OPTION_TOKEN_SVAL1("complete_label", &me->complete_label, CharSet_URL)
|
|
CHECK_OPTION_TOKEN_SVAL1("full", &me->complete_label, CharSet_URL)
|
|
CHECK_OPTION_TOKEN_SVAL1("for", &me->fur, CharSet_URL)
|
|
CHECK_OPTION_TOKEN_BVAL1("generic", &me->generic)
|
|
CHECK_OPTION_TOKEN_BVAL1("gen", &me->generic)
|
|
CHECK_OPTION_TOKEN_SVAL1("MIC-md5", &me->MIC_md5, CharSet_BASE64)
|
|
CHECK_OPTION_TOKEN_SVAL1("md5", &me->MIC_md5, CharSet_BASE64)
|
|
CHECK_OPTION_TOKEN_DVAL1("on", &me->on)
|
|
CHECK_OPTION_TOKEN_SVAL1("signature-PKCS", &me->signature_PKCS, CharSet_BASE64)
|
|
CHECK_OPTION_TOKEN_DVAL1("until", &me->until)
|
|
CHECK_OPTION_TOKEN_DVAL1("exp", &me->until)
|
|
if (!XP_STRCASECMP(token, "comment")) {
|
|
pCSParse->pParseContext->valTarget.pTargetList = &me->comments;
|
|
pCSParse->pParseContext->valType = ValType_COMMENT;
|
|
break;
|
|
}
|
|
} while (0);
|
|
/* --- END converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
if (pCSParse->pParseContext->valType == ValType_NONE)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t getOptionValue(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
switch (pCSParse->pParseContext->valType) {
|
|
case ValType_BVAL:
|
|
BVal_readVal(pCSParse->pParseContext->valTarget.pTargetBVal, token);
|
|
pCSParse->pParseContext->valType = ValType_NONE;
|
|
break;
|
|
case ValType_FVAL:
|
|
CHECK_CAR_SET(CharSet_NUMBER)
|
|
FVal_readVal(pCSParse->pParseContext->valTarget.pTargetFVal, token);
|
|
pCSParse->pParseContext->valType = ValType_NONE;
|
|
break;
|
|
case ValType_SVAL:
|
|
CHECK_CAR_SET(pCSLabel->targetCharSet)
|
|
SVal_readVal(pCSParse->pParseContext->valTarget.pTargetSVal, token);
|
|
pCSParse->pParseContext->valType = ValType_NONE;
|
|
break;
|
|
case ValType_DVAL:
|
|
CHECK_CAR_SET(CharSet_DATE)
|
|
DVal_readVal(pCSParse->pParseContext->valTarget.pTargetDVal, token);
|
|
pCSParse->pParseContext->valType = ValType_NONE;
|
|
break;
|
|
case ValType_COMMENT:
|
|
CHECK_CAR_SET(CharSet_EXT_ALPHANUM)
|
|
{
|
|
char * ptr = 0;
|
|
StrAllocCopy(ptr, token);
|
|
HTList_appendObject(*pCSParse->pParseContext->valTarget.pTargetList, (void *)ptr);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelList_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelList_getVersion(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
static const char versionPrefix[] = "PICS-";
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
if (!token)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (strncasecomp(token, versionPrefix, sizeof(versionPrefix)-1))
|
|
return StateRet_WARN_NO_MATCH;
|
|
token += sizeof(versionPrefix)-1;
|
|
CHECK_CAR_SET(CharSet_NUMBER)
|
|
FVal_readVal(&pCSLabel->pCSLLData->version, token);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelList_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
return StateRet_DONE;
|
|
}
|
|
|
|
PRIVATE void LabelList_destroy(CSParse_t * pCSParse)
|
|
{
|
|
}
|
|
|
|
PRIVATE StateRet_t ServiceInfo_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentServiceInfo = ServiceInfo_new();
|
|
pCSLabel->currentLabelNumber = 0;
|
|
HTList_appendObject(pCSLabel->pCSLLData->serviceInfos, (void *)pCSLabel->pCurrentServiceInfo);
|
|
pCSLabel->pCurrentLabelOptions = pCSLabel->pCurrentServiceInfo->pLabelOptions;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t ServiceInfo_getServiceId(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
ParseContext_t * pParseContext = pCSParse->pParseContext;
|
|
|
|
if (!token || !pParseContext->observedQuotes)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
CHECK_CAR_SET(CharSet_URL)
|
|
SVal_readVal(&pCSLabel->pCurrentServiceInfo->rating_service, token);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t ServiceInfo_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentServiceInfo = 0;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void ServiceInfo_destroy(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
HTList_removeObject(pCSLabel->pCSLLData->serviceInfos, (void *)pCSLabel->pCurrentServiceInfo);
|
|
ServiceInfo_free(pCSLabel->pCurrentServiceInfo);
|
|
pCSLabel->pCurrentServiceInfo = 0;
|
|
}
|
|
|
|
PRIVATE StateRet_t ServiceInfo_clearOpts(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
pCSLabel->pCurrentLabelOptions = 0; /* needed to flag new SingleLabel started by option */
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t Label_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentLabel = Label_new();
|
|
pCSLabel->currentLabelNumber++;
|
|
HTList_appendObject(pCSLabel->pCurrentServiceInfo->labels, (void*)pCSLabel->pCurrentLabel);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t Label_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentLabel = 0;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void Label_destroy(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
HTList_removeObject(pCSLabel->pCurrentServiceInfo->labels, pCSLabel->pCurrentLabel);
|
|
Label_free(pCSLabel->pCurrentLabel);
|
|
pCSLabel->pCurrentLabel = 0;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelTree_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCSLLData->hasTree = 1;
|
|
pCSLabel->pCurrentLabelTree = pCSLabel->pCurrentLabel->singleLabels = HTList_new();
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelTree_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
/* Label_close(pCSParse, token, demark); */
|
|
pCSLabel->pCurrentLabelTree = 0;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void LabelTree_destroy(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
SingleLabel_t * pSingleLabel;
|
|
while ((pSingleLabel = (SingleLabel_t *) HTList_removeLastObject(pCSLabel->pCurrentLabel->singleLabels)) != NULL)
|
|
SingleLabel_free(pSingleLabel);
|
|
HTList_delete(pCSLabel->pCurrentLabel->singleLabels);
|
|
pCSLabel->pCurrentLabel->singleLabels = 0;
|
|
}
|
|
|
|
PRIVATE StateRet_t SingleLabel_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentSingleLabel = SingleLabel_new(pCSLabel->pCurrentLabelOptions, pCSLabel->pCurrentServiceInfo->pLabelOptions);
|
|
if (pCSLabel->pCurrentLabel->singleLabels)
|
|
HTList_appendObject(pCSLabel->pCurrentLabel->singleLabels, (void*)pCSLabel->pCurrentSingleLabel);
|
|
else
|
|
pCSLabel->pCurrentLabel->pSingleLabel = pCSLabel->pCurrentSingleLabel;
|
|
pCSLabel->pCurrentLabelOptions = pCSLabel->pCurrentSingleLabel->pLabelOptions;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t SingleLabel_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentSingleLabel = 0;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void SingleLabel_destroy(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
if (pCSLabel->pCurrentLabel->pSingleLabel)
|
|
pCSLabel->pCurrentLabel->pSingleLabel = 0;
|
|
else
|
|
HTList_removeObject(pCSLabel->pCurrentLabel->singleLabels, (void *)pCSLabel->pCurrentSingleLabel);
|
|
SingleLabel_free(pCSLabel->pCurrentSingleLabel);
|
|
pCSLabel->pCurrentSingleLabel = 0;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelRating_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
if (!pCSLabel->pCurrentSingleLabel) /* switched from label to rating on "r" rather than <option> */
|
|
SingleLabel_open(pCSParse, token, demark);
|
|
pCSLabel->pCurrentLabelRating = LabelRating_new();
|
|
HTList_appendObject(pCSLabel->pCurrentSingleLabel->labelRatings, (void*)pCSLabel->pCurrentLabelRating);
|
|
pCSLabel->pCurrentLabelOptions = 0;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelRating_getId(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
CHECK_CAR_SET(CharSet_TRANSMIT_NAME)
|
|
SVal_readVal(&pCSLabel->pCurrentLabelRating->identifier, token);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelRating_getValue(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
FVal_readVal(&pCSLabel->pCurrentLabelRating->value, token);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelRating_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentLabelRating = 0;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void LabelRating_destroy(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
HTList_removeObject(pCSLabel->pCurrentSingleLabel->labelRatings, (void *)pCSLabel->pCurrentLabelRating);
|
|
LabelRating_free(pCSLabel->pCurrentLabelRating);
|
|
pCSLabel->pCurrentLabelRating = 0;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelRating_next(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
SingleLabel_doClose(pCSParse, token, demark);
|
|
if (pCSLabel->pCurrentLabelTree) {
|
|
SETNEXTSTATE(&LabelTree_targetObject, SubState_A);
|
|
} else {
|
|
Label_doClose(pCSParse, token, demark);
|
|
SETNEXTSTATE(&Awkward_targetObject, SubState_A);
|
|
}
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelRatingRange_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentRange = 0;
|
|
pCSLabel->pCurrentLabelRating->ranges = HTList_new();
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelRatingRange_get(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
LabelRating_t * pLabelRating = pCSLabel->pCurrentLabelRating;
|
|
Range_t * me;
|
|
char * ptr, * backPtr;
|
|
if (!token)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
if ((me = (Range_t *) HT_CALLOC(1, sizeof(Range_t))) == NULL)
|
|
HT_OUTOFMEM("Range_t");
|
|
/* me = Range_new(); */
|
|
HTList_appendObject(pLabelRating->ranges, (void *)me);
|
|
backPtr = ptr = token;
|
|
while (*ptr) {
|
|
if (*ptr == ':') {
|
|
*ptr = 0;
|
|
ptr++;
|
|
break;
|
|
}
|
|
ptr++;
|
|
}
|
|
FVal_readVal(&me->min, backPtr);
|
|
if (*ptr)
|
|
FVal_readVal(&me->max, ptr);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t LabelRatingRange_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentRange = 0;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void LabelRatingRange_destroy(CSParse_t * pCSParse)
|
|
{
|
|
}
|
|
|
|
PRIVATE StateRet_t Awkward_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t Awkward_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void Awkward_destroy(CSParse_t * pCSParse)
|
|
{
|
|
}
|
|
|
|
PRIVATE StateRet_t error_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentLabelError = LabelError_new();
|
|
if (pCSLabel->pCurrentLabel)
|
|
pCSLabel->pCurrentLabel->pLabelError = pCSLabel->pCurrentLabelError;
|
|
else
|
|
pCSLabel->pCurrentServiceInfo->pLabelError = pCSLabel->pCurrentLabelError;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t error_getExpl(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
ParseContext_t * pParseContext = pCSParse->pParseContext;
|
|
char * explaination = 0;
|
|
|
|
if (!token || !pParseContext->observedQuotes)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
CHECK_CAR_SET(CharSet_EXT_ALPHANUM)
|
|
StrAllocCopy(explaination, token);
|
|
HTList_appendObject(pCSLabel->pCurrentLabelError->explanations, explaination);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t error_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
|
|
pCSLabel->pCurrentLabelError = 0;
|
|
if (pCSLabel->pCurrentLabel)
|
|
pCSLabel->pCurrentLabel->pLabelError = pCSLabel->pCurrentLabelError;
|
|
else
|
|
pCSLabel->pCurrentServiceInfo->pLabelError = pCSLabel->pCurrentLabelError;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void error_destroy(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
if (pCSLabel->pCurrentLabel)
|
|
pCSLabel->pCurrentLabel->pLabelError = 0;
|
|
else
|
|
pCSLabel->pCurrentServiceInfo->pLabelError = 0;
|
|
LabelError_free(pCSLabel->pCurrentLabelError);
|
|
}
|
|
|
|
PRIVATE StateRet_t Extension_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
Extension_t * me = Extension_new();
|
|
pCSLabel->pCurrentExtension = me;
|
|
if (!pCSLabel->pCurrentLabelOptions->extensions)
|
|
pCSLabel->pCurrentLabelOptions->extensions = HTList_new();
|
|
HTList_appendObject(pCSLabel->pCurrentLabelOptions->extensions, (void *)me);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t Extension_mandatory(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
pCSLabel->pCurrentExtension->mandatory = 1;
|
|
pCSLabel->pCSLLData->mandatoryExtensions++;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t Extension_getURL(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
if (!token || !pCSParse->pParseContext->observedQuotes)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
CHECK_CAR_SET(CharSet_URL)
|
|
SVal_readVal(&pCSLabel->pCurrentExtension->url, token);
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t Extension_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
pCSLabel->pCurrentExtension = 0;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void Extension_destroy(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
HTList_removeObject(pCSLabel->pCurrentLabelOptions->extensions, (void *)pCSLabel->pCurrentExtension);
|
|
if (!HTList_count(pCSLabel->pCurrentLabelOptions->extensions)) {
|
|
HTList_delete(pCSLabel->pCurrentLabelOptions->extensions);
|
|
pCSLabel->pCurrentLabelOptions->extensions = 0;
|
|
}
|
|
Extension_free(pCSLabel->pCurrentExtension);
|
|
pCSLabel->pCurrentExtension = 0;
|
|
}
|
|
|
|
PRIVATE StateRet_t Extension_next(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
if (pCSLabel->pCurrentSingleLabel) {
|
|
SETNEXTSTATE(&SingleLabel_targetObject, SubState_A);
|
|
} else {
|
|
SETNEXTSTATE(&ServiceInfo_targetObject, SubState_B);
|
|
}
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t ExtensionData_open(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
ExtensionData_t * me = ExtensionData_new();
|
|
|
|
me->pParentExtensionData = pCSLabel->pCurrentExtensionData;
|
|
if(pCSLabel->pCurrentExtensionData) {
|
|
if (!pCSLabel->pCurrentExtensionData->moreData)
|
|
pCSLabel->pCurrentExtensionData->moreData = HTList_new();
|
|
HTList_appendObject(pCSLabel->pCurrentExtensionData->moreData, (void *)me);
|
|
} else {
|
|
if (!pCSLabel->pCurrentExtension->extensionData)
|
|
pCSLabel->pCurrentExtension->extensionData = HTList_new();
|
|
HTList_appendObject(pCSLabel->pCurrentExtension->extensionData, (void *)me);
|
|
}
|
|
pCSLabel->pCurrentExtensionData = me;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t ExtensionData_next(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
/* close has already set recursed to the parentExtensionData */
|
|
if (pCSLabel->pCurrentExtensionData) {
|
|
SETNEXTSTATE(&ExtensionData_targetObject, SubState_B);
|
|
} else {
|
|
SETNEXTSTATE(&Extension_targetObject, SubState_C);
|
|
}
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE StateRet_t ExtensionData_close(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
pCSLabel->pCurrentExtensionData = pCSLabel->pCurrentExtensionData->pParentExtensionData;
|
|
return StateRet_OK;
|
|
}
|
|
|
|
PRIVATE void ExtensionData_destroy(CSParse_t * pCSParse)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
HTList ** pHolderList = pCSLabel->pCurrentExtensionData->pParentExtensionData ?
|
|
&pCSLabel->pCurrentExtensionData->pParentExtensionData->moreData :
|
|
&pCSLabel->pCurrentExtension->extensionData;
|
|
HTList_removeObject(*pHolderList, (void *)pCSLabel->pCurrentExtensionData);
|
|
if (!HTList_count(*pHolderList)) {
|
|
HTList_delete(*pHolderList);
|
|
*pHolderList = 0;
|
|
}
|
|
ExtensionData_free(pCSLabel->pCurrentExtensionData);
|
|
pCSLabel->pCurrentExtensionData = 0;
|
|
}
|
|
|
|
PRIVATE StateRet_t ExtensionData_getData(CSParse_t * pCSParse, StateToken_t * pStateToken, char * token, char demark)
|
|
{
|
|
CSLabel_t * pCSLabel = GetCSLabel(pCSParse);
|
|
ExtensionData_t * me;
|
|
if (!token)
|
|
return StateRet_WARN_NO_MATCH;
|
|
if (Punct_badDemark(pStateToken->validPunctuation, demark))
|
|
return StateRet_WARN_BAD_PUNCT;
|
|
CHECK_CAR_SET(CharSet_EXT_DATA)
|
|
me = pCSLabel->pCurrentExtensionData;
|
|
/* SVal_readVal(&me->text, token); */
|
|
StrAllocCopy(me->text, token);
|
|
me->quoted = pCSParse->pParseContext->observedQuotes;
|
|
return StateRet_OK;
|
|
}
|
|
#if 0
|
|
PRIVATE StateRet_t LabelRating_doClose(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
if (pCSParse->pParseContext->pTargetChangeCallback &&
|
|
(*pCSParse->pParseContext->pTargetChangeCallback)(pCSParse, &LabelRating_targetObject, CSLLTC_RATING, 2) == StateRet_ERROR)
|
|
return NowIn_ERROR;
|
|
return LabelRating_close(pCSParse, token, demark);
|
|
}
|
|
#endif
|
|
PRIVATE StateRet_t SingleLabel_doClose(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
if (pCSParse->pParseContext->pTargetChangeCallback &&
|
|
(*pCSParse->pParseContext->pTargetChangeCallback)(pCSParse, &SingleLabel_targetObject, CSLLTC_SINGLE, 2, 0) == StateRet_ERROR) /* !!! - pVoid */
|
|
return NowIn_ERROR;
|
|
return SingleLabel_close(pCSParse, token, demark);
|
|
}
|
|
#if 0
|
|
PRIVATE StateRet_t LabelTree_doClose(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
if (pCSParse->pParseContext->pTargetChangeCallback &&
|
|
(*pCSParse->pParseContext->pTargetChangeCallback)(pCSParse, &LabelTree_targetObject, CSLLTC_LABTREE, 2) == StateRet_ERROR)
|
|
return NowIn_ERROR;
|
|
return LabelTree_close(pCSParse, token, demark);
|
|
}
|
|
#endif
|
|
PRIVATE StateRet_t Label_doClose(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
if (pCSParse->pParseContext->pTargetChangeCallback &&
|
|
(*pCSParse->pParseContext->pTargetChangeCallback)(pCSParse, &Label_targetObject, CSLLTC_LABEL, 2, 0) == StateRet_ERROR) /* !!! - pVoid */
|
|
return NowIn_ERROR;
|
|
return Label_close(pCSParse, token, demark);
|
|
}
|
|
#if 0
|
|
PRIVATE StateRet_t ServiceInfo_doClose(CSParse_t * pCSParse, char * token, char demark)
|
|
{
|
|
if (pCSParse->pParseContext->pTargetChangeCallback &&
|
|
(*pCSParse->pParseContext->pTargetChangeCallback)(pCSParse, &ServiceInfo_targetObject, CSLLTC_SERVICE, 2) == StateRet_ERROR)
|
|
return NowIn_ERROR;
|
|
return ServiceInfo_close(pCSParse, token, demark);
|
|
}
|
|
#endif
|
|
/* CSParse_doc end */
|
|
/* I T E R A T O R S - scan through the CSLabel data structures for <identifier> */
|
|
/* --- BEGIN converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
/* CSLabel_iterateServices - look for rating service in a label list
|
|
(pCSLabel->pCurrentServiceInfo = (ServiceInfo_t *) HTList_nextObject(serviceInfos)) &&
|
|
SVal_initialized(&pCSLabel->pCurrentServiceInfo->rating_service))
|
|
if (!identifier || !XP_STRCASECMP(SVal_value(&pCSLabel->pCurrentServiceInfo->rating_service), identifier)) {
|
|
ret = (*pIteratorCB)(pCSLabel, pParms, identifier, pVoid);
|
|
count++;
|
|
*/
|
|
/* --- END converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
|
|
PUBLIC CSError_t CSLabel_iterateServices(CSLabel_t * pCSLabel, CSLabel_callback_t * pIteratorCB, State_Parms_t * pParms, const char * identifier, void * pVoid)
|
|
{
|
|
HTList * serviceInfos;
|
|
CSError_t ret = CSError_OK;
|
|
int count = 0;
|
|
if (!pIteratorCB ||
|
|
!pCSLabel ||
|
|
!pCSLabel->pCSLLData->serviceInfos)
|
|
return CSError_BAD_PARAM;
|
|
serviceInfos = pCSLabel->pCSLLData->serviceInfos;
|
|
while (ret == CSError_OK &&
|
|
(pCSLabel->pCurrentServiceInfo = (ServiceInfo_t *) HTList_nextObject(serviceInfos)) != NULL) {
|
|
/* --- BEGIN converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
if (identifier &&
|
|
(!SVal_initialized(&pCSLabel->pCurrentServiceInfo->rating_service) ||
|
|
XP_STRCASECMP(SVal_value(&pCSLabel->pCurrentServiceInfo->rating_service), identifier)))
|
|
continue;
|
|
/* --- END converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
ret = (*pIteratorCB)(pCSLabel, pParms, identifier, pVoid);
|
|
count++;
|
|
}
|
|
if (!count)
|
|
return CSError_SERVICE_MISSING;
|
|
return ret;
|
|
}
|
|
|
|
/* CSLabel_iterateLabels - look through all labels in current ServiceInfo
|
|
*/
|
|
PUBLIC CSError_t CSLabel_iterateLabels(CSLabel_t * pCSLabel, CSLabel_callback_t * pIteratorCB, State_Parms_t * pParms, const char * identifier, void * pVoid)
|
|
{
|
|
HTList * labels;
|
|
CSError_t ret= CSError_OK;
|
|
int count = 0;
|
|
if (!pIteratorCB ||
|
|
!pCSLabel ||
|
|
!pCSLabel->pCurrentServiceInfo ||
|
|
!pCSLabel->pCurrentServiceInfo->labels)
|
|
return CSError_BAD_PARAM;
|
|
labels = pCSLabel->pCurrentServiceInfo->labels;
|
|
while (ret == CSError_OK && (pCSLabel->pCurrentLabel = (Label_t *) HTList_nextObject(labels)) != NULL) {
|
|
ret = (*pIteratorCB)(pCSLabel, pParms, identifier, pVoid);
|
|
count++;
|
|
}
|
|
if (!count)
|
|
return CSError_LABEL_MISSING;
|
|
return ret;
|
|
}
|
|
|
|
/* CSLabel_iterateSingleLabels - look through all single labels in current label
|
|
*/
|
|
PUBLIC CSError_t CSLabel_iterateSingleLabels(CSLabel_t * pCSLabel, CSLabel_callback_t * pIteratorCB, State_Parms_t * pParms, const char * identifier, void * pVoid)
|
|
{
|
|
CSError_t ret= CSError_OK;
|
|
int count = 0;
|
|
if (!pIteratorCB ||
|
|
!pCSLabel ||
|
|
!pCSLabel->pCurrentServiceInfo ||
|
|
!pCSLabel->pCurrentServiceInfo->labels)
|
|
return CSError_BAD_PARAM;
|
|
{
|
|
if (pCSLabel->pCurrentLabel->pSingleLabel) {
|
|
pCSLabel->pCurrentSingleLabel = pCSLabel->pCurrentLabel->pSingleLabel;
|
|
ret = (*pIteratorCB)(pCSLabel, pParms, identifier, pVoid);
|
|
count++;
|
|
}
|
|
else {
|
|
HTList * singleLabels = pCSLabel->pCurrentLabel->singleLabels;
|
|
while (ret == CSError_OK && (pCSLabel->pCurrentSingleLabel = (SingleLabel_t *) HTList_nextObject(singleLabels)) != NULL) {
|
|
ret = (*pIteratorCB)(pCSLabel, pParms, identifier, pVoid);
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
if (!count)
|
|
return CSError_SINGLELABEL_MISSING;
|
|
return ret;
|
|
}
|
|
|
|
/* CSLabel_iterateLabelRatings - look for rating in current single label
|
|
*/
|
|
PUBLIC CSError_t CSLabel_iterateLabelRatings(CSLabel_t * pCSLabel, CSLabel_callback_t * pIteratorCB, State_Parms_t * pParms, const char * identifier, void * pVoid)
|
|
{
|
|
HTList * labelRatings;
|
|
CSError_t ret = CSError_OK;
|
|
int count = 0;
|
|
if (!pIteratorCB ||
|
|
!pCSLabel ||
|
|
!pCSLabel->pCurrentServiceInfo ||
|
|
!pCSLabel->pCurrentServiceInfo->labels ||
|
|
!pCSLabel->pCurrentLabel ||
|
|
!pCSLabel->pCurrentSingleLabel ||
|
|
!pCSLabel->pCurrentSingleLabel->labelRatings)
|
|
return CSError_BAD_PARAM;
|
|
labelRatings = pCSLabel->pCurrentSingleLabel->labelRatings;
|
|
while (ret == CSError_OK && (pCSLabel->pCurrentLabelRating = (LabelRating_t *) HTList_nextObject(labelRatings)) != NULL)
|
|
/* --- BEGIN converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
if (!identifier || !XP_STRCASECMP(SVal_value(&pCSLabel->pCurrentLabelRating->identifier), identifier)) {
|
|
ret = (*pIteratorCB)(pCSLabel, pParms, identifier, pVoid);
|
|
count++;
|
|
}
|
|
/* --- END converted by mharmsen@netscape.com on 7/9/97 --- */
|
|
if (!count)
|
|
return CSError_RATING_MISSING;
|
|
return ret;
|
|
}
|
|
|
|
/* R A N G E T E S T I N G - check that label values fall within acceptable user ranges */
|
|
/* CSLabel_ratingsIncludeFVal - find out if current rating in pCSLabel encompases userValue
|
|
* return: int stating how far it is from fitting.
|
|
*/
|
|
PUBLIC FVal_t CSLabel_ratingsIncludeFVal(CSLabel_t * pCSLabel, FVal_t * userValue)
|
|
{
|
|
Range_t parm = Range_NEW_UNINITIALIZED;
|
|
parm.min = *userValue;
|
|
return CSLabel_ratingsIncludeRange(pCSLabel, &parm);
|
|
}
|
|
|
|
PUBLIC FVal_t CSLabel_ratingsIncludeRange(CSLabel_t * pCSLabel, Range_t * pUserRange)
|
|
{
|
|
HTList * labelRanges = pCSLabel->pCurrentLabelRating->ranges;
|
|
FVal_t value = pCSLabel->pCurrentLabelRating->value;
|
|
FVal_t ret;
|
|
Range_t * pLabelRange;
|
|
if (FVal_initialized(&value)) {
|
|
Range_t parm = Range_NEW_UNINITIALIZED;
|
|
parm.min = value;
|
|
return Range_gap(&parm, pUserRange);
|
|
}
|
|
while ((pLabelRange = (Range_t *)HTList_nextObject(labelRanges)) != NULL) {
|
|
FVal_t thisOne = Range_gap(pLabelRange, pUserRange);
|
|
if (FVal_isZero(&thisOne))
|
|
return thisOne;
|
|
if (FVal_nearerZero(&thisOne, &ret))
|
|
ret = thisOne;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
PUBLIC FVal_t CSLabel_ratingsIncludeRanges(CSLabel_t * pCSLabel, HTList * userRanges)
|
|
{
|
|
FVal_t ret;
|
|
Range_t * pUserRange;
|
|
BOOL retInitialized = NO;
|
|
while ((pUserRange = (Range_t *)HTList_nextObject(userRanges)) != NULL) {
|
|
FVal_t thisOne = CSLabel_ratingsIncludeRange(pCSLabel, pUserRange);
|
|
if (FVal_isZero(&thisOne))
|
|
return thisOne;
|
|
if (retInitialized) {
|
|
if (FVal_nearerZero(&thisOne, &ret))
|
|
ret = thisOne;
|
|
} else {
|
|
ret = thisOne;
|
|
retInitialized = YES;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|