tidy-html5/src/config.h
Jim Derry aeb9a24fab Refactor Picklists and Option Parsers
This PR refactors how picklists and option parsers are implemented in LibTidy,
making is vastly easier to implement new picklists in the future, as well as
modify some of the existing picklists such that they have more logical names.

Picklist arrays are now arrays of structures that include the possible strings
capable of setting a particular option value, and a new parser has been written
to work with these structures.

In addition, several of the existing parsers were removed, as they are now
redundant, and a couple of the remaining parsers were refactored to take
advantage of the new parser.

In effect, this means that:

- New parsers don't have to be written in the majority of cases where new
  options are added that exceed yes/no/auto.
- Some of the existing options can have more meaningful names than yes/no/auto,
  in a backward compatible way. For example, vertical-spacing "auto" currently
  in no way reflects "auto" when used.
2017-05-11 14:40:21 -04:00

186 lines
6.8 KiB
C

#ifndef __CONFIG_H__
#define __CONFIG_H__
/**************************************************************************//**
* @file
* Read configuration files and manage configuration properties.
*
* Config files associate a property name with a value.
*
* // comments can start at the beginning of a line
* # comments can start at the beginning of a line
* name: short values fit onto one line
* name: a really long value that
* continues on the next line
*
* Property names are case insensitive and should be less than 60 characters
* in length, and must start at the begining of the line, as whitespace at
* the start of a line signifies a line continuation.
*
* @author HTACG, et al (consult git log)
*
* @copyright
* Copyright (c) 1998-2017 World Wide Web Consortium (Massachusetts
* Institute of Technology, European Research Consortium for Informatics
* and Mathematics, Keio University) and HTACG.
* @par
* All Rights Reserved.
* @par
* See `tidy.h` for the complete license.
*
* @date Additional updates: consult git log
*
******************************************************************************/
#include "forward.h"
#include "tidy.h"
#include "streamio.h"
/** PickLists may have up to 16 items. For some reason,
** this limit has always been hard-coded into Tidy.
*/
#define TIDY_PL_SIZE 16
/** Structs of this type contain information needed in order to present pick lists,
** relate pick list entries to public enum values, and parse strings that are
** accepted in order to assign the value.
*/
typedef struct PickListItem {
ctmbstr label; /**< PickList label for this item. */
const int value; /**< The option value represented by this label. */
ctmbstr inputs[10]; /**< String values that can select this value. */
} PickListItem;
/** An array of PickListItems, fixed in size for in-code declarations.
** Arrays must be populated in 0 to 10 order, as the option value is assigned
** based on this index and *not* on the structures' value field. It remains
** a best practice, however, to assign a public enum value with the proper
** index value.
*/
typedef const PickListItem PickListItems[TIDY_PL_SIZE];
struct _tidy_option;
typedef struct _tidy_option TidyOptionImpl;
typedef Bool (ParseProperty)( TidyDocImpl* doc, const TidyOptionImpl* opt );
struct _tidy_option
{
TidyOptionId id;
TidyConfigCategory category; /* put 'em in groups */
ctmbstr name; /* property name */
TidyOptionType type; /* string, int or bool */
ulong dflt; /* default for TidyInteger and TidyBoolean */
ParseProperty* parser; /* parsing method, read-only if NULL */
PickListItems* pickList; /* new style pick list */
ctmbstr pdflt; /* default for TidyString */
};
typedef union
{
ulong v; /* Value for TidyInteger and TidyBoolean */
char *p; /* Value for TidyString */
} TidyOptionValue;
typedef struct _tidy_config
{
TidyOptionValue value[ N_TIDY_OPTIONS + 1 ]; /* current config values */
TidyOptionValue snapshot[ N_TIDY_OPTIONS + 1 ]; /* Snapshot of values to be restored later */
/* track what tags user has defined to eliminate unnecessary searches */
uint defined_tags;
uint c; /* current char in input stream */
StreamIn* cfgIn; /* current input source */
} TidyConfigImpl;
/* Used to build a table of documentation cross-references. */
typedef struct {
TidyOptionId opt; /**< Identifier. */
TidyOptionId const *links; /**< Cross references. Last element must be 'TidyUnknownOption'. */
} TidyOptionDoc;
const TidyOptionImpl* TY_(lookupOption)( ctmbstr optnam );
const TidyOptionImpl* TY_(getOption)( TidyOptionId optId );
TidyIterator TY_(getOptionList)( TidyDocImpl* doc );
const TidyOptionImpl* TY_(getNextOption)( TidyDocImpl* doc, TidyIterator* iter );
TidyIterator TY_(getOptionPickList)( const TidyOptionImpl* option );
ctmbstr TY_(getNextOptionPick)( const TidyOptionImpl* option, TidyIterator* iter );
#if SUPPORT_CONSOLE_APP
const TidyOptionDoc* TY_(OptGetDocDesc)( TidyOptionId optId );
#endif /* SUPPORT_CONSOLE_APP */
void TY_(InitConfig)( TidyDocImpl* doc );
void TY_(FreeConfig)( TidyDocImpl* doc );
/* Bool SetOptionValue( TidyDocImpl* doc, TidyOptionId optId, ctmbstr val ); */
Bool TY_(SetOptionInt)( TidyDocImpl* doc, TidyOptionId optId, ulong val );
Bool TY_(SetOptionBool)( TidyDocImpl* doc, TidyOptionId optId, Bool val );
Bool TY_(ResetOptionToDefault)( TidyDocImpl* doc, TidyOptionId optId );
void TY_(ResetConfigToDefault)( TidyDocImpl* doc );
void TY_(TakeConfigSnapshot)( TidyDocImpl* doc );
void TY_(ResetConfigToSnapshot)( TidyDocImpl* doc );
void TY_(CopyConfig)( TidyDocImpl* docTo, TidyDocImpl* docFrom );
int TY_(ParseConfigFile)( TidyDocImpl* doc, ctmbstr cfgfil );
int TY_(ParseConfigFileEnc)( TidyDocImpl* doc,
ctmbstr cfgfil, ctmbstr charenc );
int TY_(SaveConfigFile)( TidyDocImpl* doc, ctmbstr cfgfil );
int TY_(SaveConfigSink)( TidyDocImpl* doc, TidyOutputSink* sink );
/* returns false if unknown option, missing parameter, or
option doesn't use parameter
*/
Bool TY_(ParseConfigOption)( TidyDocImpl* doc, ctmbstr optnam, ctmbstr optVal );
Bool TY_(ParseConfigValue)( TidyDocImpl* doc, TidyOptionId optId, ctmbstr optVal );
/* ensure that char encodings are self consistent */
Bool TY_(AdjustCharEncoding)( TidyDocImpl* doc, int encoding );
Bool TY_(ConfigDiffThanDefault)( TidyDocImpl* doc );
Bool TY_(ConfigDiffThanSnapshot)( TidyDocImpl* doc );
int TY_(CharEncodingId)( TidyDocImpl* doc, ctmbstr charenc );
ctmbstr TY_(CharEncodingName)( int encoding );
ctmbstr TY_(CharEncodingOptName)( int encoding );
/* Coordinates Config update and Tags data */
void TY_(DeclareUserTag)( TidyDocImpl* doc, TidyOptionId optId,
uint tagType, ctmbstr name );
#ifdef _DEBUG
/* Debug lookup functions will be type-safe and assert option type match */
ulong TY_(_cfgGet)( TidyDocImpl* doc, TidyOptionId optId );
Bool TY_(_cfgGetBool)( TidyDocImpl* doc, TidyOptionId optId );
TidyTriState TY_(_cfgGetAutoBool)( TidyDocImpl* doc, TidyOptionId optId );
ctmbstr TY_(_cfgGetString)( TidyDocImpl* doc, TidyOptionId optId );
#define cfg(doc, id) TY_(_cfgGet)( (doc), (id) )
#define cfgBool(doc, id) TY_(_cfgGetBool)( (doc), (id) )
#define cfgAutoBool(doc, id) TY_(_cfgGetAutoBool)( (doc), (id) )
#define cfgStr(doc, id) TY_(_cfgGetString)( (doc), (id) )
#else
/* Release build macros for speed */
#define cfg(doc, id) ((doc)->config.value[ (id) ].v)
#define cfgBool(doc, id) ((Bool) cfg(doc, id))
#define cfgAutoBool(doc, id) ((TidyTriState) cfg(doc, id))
#define cfgStr(doc, id) ((ctmbstr) (doc)->config.value[ (id) ].p)
#endif /* _DEBUG */
#endif /* __CONFIG_H__ */