tidy-html5/src/config.h

434 lines
15 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 beginning 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"
/** @addtogroup internal_api */
/** @{ */
/***************************************************************************//**
** @defgroup configuration_options Configuration Options
**
** This module organizes all of Tidy's configuration options, including
** picklist management, option setting and retrieval, option file utilities,
** and so on.
**
** @{
******************************************************************************/
/** Determines the maximum number of items in an option's picklist. PickLists
** may have up to 16 items. For some reason, this limit has been hard-coded
** into Tidy for some time. Feel free to increase this as needed.
*/
#define TIDY_PL_SIZE 16
/** Structs of this type contain information needed in order to present
** picklists, relate picklist 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; /* forward */
/** The TidyOptionImpl type implements the `_tidy_option` structure.
*/
typedef struct _tidy_option TidyOptionImpl;
/** This typedef describes a function that is used for parsing the input
** given for a particular Tidy option.
*/
typedef Bool (ParseProperty)( TidyDocImpl* doc, const TidyOptionImpl* opt );
/** This structure defines the internal representation of a Tidy option.
*/
struct _tidy_option
{
TidyOptionId id; /**< The unique identifier for this option. */
TidyConfigCategory category; /**< The category of the option. */
ctmbstr name; /**< The name of the option. */
TidyOptionType type; /**< The date type for the option. */
ulong dflt; /**< Default value for TidyInteger and TidyBoolean */
ParseProperty* parser; /**< Function to parse input; read-only if NULL. */
PickListItems* pickList; /**< The picklist of possible values for this option. */
ctmbstr pdflt; /**< Default value for TidyString. */
};
/** Stored option values can be one of two internal types.
*/
typedef union
{
ulong v; /**< Value for TidyInteger and TidyBoolean */
char *p; /**< Value for TidyString */
} TidyOptionValue;
/** This type is used to define a structure for keeping track of the values
** for each option.
*/
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. */
uint defined_tags; /**< Tracks user-defined tags. */
uint c; /**< Current char in input stream for reading options. */
StreamIn* cfgIn; /**< Current input source for reading options.*/
} 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;
/** Given an option name, return an instance of an option.
** @param optnam The option name to retrieve.
** @returns The instance of the requested option.
*/
TY_PRIVATE const TidyOptionImpl* TY_(lookupOption)( ctmbstr optnam );
/** Given an option ID, return an instance of an option.
** @param optId The option ID to retrieve.
** @returns The instance of the requested option.
*/
TY_PRIVATE const TidyOptionImpl* TY_(getOption)( TidyOptionId optId );
/** Given an option ID, indicates whether or not the option is a list.
** @param optId The option ID to check.
** @returns Returns yes if the option value is a list.
*/
TY_PRIVATE const Bool TY_(getOptionIsList)( TidyOptionId optId );
/** Initiates an iterator to cycle through all of the available options.
** @param doc The Tidy document to get options.
** @returns An iterator token to be used with TY_(getNextOption)().
*/
TY_PRIVATE TidyIterator TY_(getOptionList)( TidyDocImpl* doc );
/** Gets the next option provided by the iterator.
** @param doc The Tidy document to get options.
** @param iter The iterator token initialized by TY_(getOptionList)().
** @returns The instance of the next option.
*/
TY_PRIVATE const TidyOptionImpl* TY_(getNextOption)( TidyDocImpl* doc, TidyIterator* iter );
/** Initiates an iterator to cycle through all of the available picklist
** possibilities.
** @param option An instance of an option for which to iterate a picklist.
** @returns An iterator token to be used with TY_(getNextOptionPick)().
*/
TY_PRIVATE TidyIterator TY_(getOptionPickList)( const TidyOptionImpl* option );
/** Gets the next picklist possibility provided by the iterator.
** @param option The instance of the option for which to iterate a picklist.
** @param iter The iterator token initialized by TY_(getOptionPickList)().
** @returns The next picklist entry.
*/
TY_PRIVATE ctmbstr TY_(getNextOptionPick)( const TidyOptionImpl* option, TidyIterator* iter );
#if SUPPORT_CONSOLE_APP
/** Returns the cross-reference information structure for optID, which is
** used for generating documentation.
** @param optId The option ID to get cross-reference information for.
** @returns Cross reference information.
*/
TY_PRIVATE const TidyOptionDoc* TY_(OptGetDocDesc)( TidyOptionId optId );
#endif /* SUPPORT_CONSOLE_APP */
/** Initialize the configuration for the given Tidy document.
** @param doc The Tidy document.
*/
TY_PRIVATE void TY_(InitConfig)( TidyDocImpl* doc );
/** Frees the configuration memory for the given Tidy document.
** @param doc The Tidy document.
*/
TY_PRIVATE void TY_(FreeConfig)( TidyDocImpl* doc );
/** Gets the picklist label for a given value.
** @param optId the option id having a picklist to check.
** @param pick the picklist item to retrieve.
** @returns The label for the pick.
*/
TY_PRIVATE ctmbstr TY_(GetPickListLabelForPick)( TidyOptionId optId, uint pick );
/** Sets the integer value for the given option Id.
** @param doc The Tidy document.
** @param optId The option ID to set.
** @param val The value to set.
** @returns Success or failure.
*/
TY_PRIVATE Bool TY_(SetOptionInt)( TidyDocImpl* doc, TidyOptionId optId, ulong val );
/** Sets the bool value for the given option Id.
** @param doc The Tidy document.
** @param optId The option ID to set.
** @param val The value to set.
** @returns Success or failure.
*/
TY_PRIVATE Bool TY_(SetOptionBool)( TidyDocImpl* doc, TidyOptionId optId, Bool val );
/** Resets the given option to its default value.
** @param doc The Tidy document.
** @param optId The option ID to set.
** @returns Success or failure.
*/
TY_PRIVATE Bool TY_(ResetOptionToDefault)( TidyDocImpl* doc, TidyOptionId optId );
/** Resets all options in the document to their default values.
** @param doc The Tidy document.
*/
TY_PRIVATE void TY_(ResetConfigToDefault)( TidyDocImpl* doc );
/** Stores a snapshot of all of the configuration values that can be
** restored later.
** @param doc The Tidy document.
*/
TY_PRIVATE void TY_(TakeConfigSnapshot)( TidyDocImpl* doc );
/** Restores all of the configuration values to their snapshotted values.
** @param doc The Tidy document.
*/
TY_PRIVATE void TY_(ResetConfigToSnapshot)( TidyDocImpl* doc );
/** Copies the configuration from one document to another.
** @param docTo The destination Tidy document.
** @param docFrom The source Tidy document.
*/
TY_PRIVATE void TY_(CopyConfig)( TidyDocImpl* docTo, TidyDocImpl* docFrom );
/** Attempts to parse the given config file into the document.
** @param doc The Tidy document.
** @param cfgfil The file to load.
** @returns a file system error code.
*/
TY_PRIVATE int TY_(ParseConfigFile)( TidyDocImpl* doc, ctmbstr cfgfil );
/** Attempts to parse the given config file into the document, using
** the provided encoding.
** @param doc The Tidy document.
** @param cfgfil The file to load.
** @param charenc The name of the encoding to use for reading the file.
** @returns a file system error code.
*/
TY_PRIVATE int TY_(ParseConfigFileEnc)( TidyDocImpl* doc,
ctmbstr cfgfil, ctmbstr charenc );
/** Saves the current configuration for options not having default values
** into the specified file.
** @param doc The Tidy document.
** @param cfgfil The file to save.
** @returns a file system error code.
*/
TY_PRIVATE int TY_(SaveConfigFile)( TidyDocImpl* doc, ctmbstr cfgfil );
/** Writes the current configuration for options not having default values
** into the specified sink.
** @param doc The Tidy document.
** @param sink The sink to save into.
** @returns a file system error code.
*/
TY_PRIVATE int TY_(SaveConfigSink)( TidyDocImpl* doc, TidyOutputSink* sink );
/** Attempts to parse the provided value for the given option name. Returns
** false if unknown option, missing parameter, or the option doesn't
** use the parameter.
** @param doc The Tidy document.
** @param optnam The name of the option to be set.
** @param optVal The string value to attempt to parse.
** @returns Success or failure.
*/
TY_PRIVATE Bool TY_(ParseConfigOption)( TidyDocImpl* doc, ctmbstr optnam, ctmbstr optVal );
/** Attempts to parse the provided value for the given option id. Returns
** false if unknown option, missing parameter, or the option doesn't
** use the parameter.
** @param doc The Tidy document.
** @param optId The ID of the option to be set.
** @param optVal The string value to attempt to parse.
** @returns Success or failure.
*/
TY_PRIVATE Bool TY_(ParseConfigValue)( TidyDocImpl* doc, TidyOptionId optId, ctmbstr optVal );
/** Ensure that char encodings are self consistent.
** @param doc The Tidy document to adjust.
** @param encoding The encoding being applied.
** @returns A bool indicating success or failure.
*/
TY_PRIVATE Bool TY_(AdjustCharEncoding)( TidyDocImpl* doc, int encoding );
/** Ensure that the configuration options are self consistent.
** THIS PROCESS IS DESTRUCTIVE TO THE USER STATE. It examines
** certain user-specified options and changes other options
** as a result. This means that documented API functions such
** as tidyOptGetValue() won't return the user-set values after
** this is used. As a result, *don't* just use this function
** at every opportunity, but only where needed, which is ONLY
** prior to parsing a stream, and again prior to saving a
** stream (because we reset after parsing.)
** @param doc The Tidy document to adjust.
*/
TY_PRIVATE void TY_(AdjustConfig)( TidyDocImpl* doc );
/** Indicates whether or not the current configuration is completely default.
** @param doc The Tidy document.
** @returns The result.
*/
TY_PRIVATE Bool TY_(ConfigDiffThanDefault)( TidyDocImpl* doc );
/** Indicates whether or not the current configuration is different from the
** stored snapshot.
** @param doc The Tidy document.
** @returns The result.
*/
TY_PRIVATE Bool TY_(ConfigDiffThanSnapshot)( TidyDocImpl* doc );
/** Returns the character encoding ID for the given character encoding
** string.
** @param doc The Tidy document.
** @param charenc The name of the character encoding.
** @returns The Id of the character encoding.
*/
TY_PRIVATE int TY_(CharEncodingId)( TidyDocImpl* doc, ctmbstr charenc );
/** Returns the full name of the encoding for the given ID.
** @param encoding The Id of the encoding.
** @returns The name of the character encoding.
*/
TY_PRIVATE ctmbstr TY_(CharEncodingName)( int encoding );
/** Returns the Tidy command line option name of the encoding for the given ID.
** @param encoding The Id of the encoding.
** @returns The Tidy command line option representing the encoding.
*/
TY_PRIVATE ctmbstr TY_(CharEncodingOptName)( int encoding );
/** Coordinates Config update and list data.
** @param doc The Tidy document.
** @param opt The option the list item is intended for.
** @param name The name of the new list item.
*/
TY_PRIVATE void TY_(DeclareListItem)( TidyDocImpl* doc, const TidyOptionImpl* opt, ctmbstr name );
#ifdef _DEBUG
/* Debug lookup functions will be type-safe and assert option type match */
TY_PRIVATE ulong TY_(_cfgGet)( TidyDocImpl* doc, TidyOptionId optId );
TY_PRIVATE Bool TY_(_cfgGetBool)( TidyDocImpl* doc, TidyOptionId optId );
TY_PRIVATE TidyTriState TY_(_cfgGetAutoBool)( TidyDocImpl* doc, TidyOptionId optId );
TY_PRIVATE 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 */
/** Access the raw, non-string uint value of the given option ID. */
#define cfg(doc, id) ((doc)->config.value[ (id) ].v)
/** Access the Bool value of the given option ID. */
#define cfgBool(doc, id) ((Bool) cfg(doc, id))
/** Access the TidyTriState value of the given option ID. */
#define cfgAutoBool(doc, id) ((TidyTriState) cfg(doc, id))
/** Access the string value of the given option ID. */
#define cfgStr(doc, id) ((ctmbstr) (doc)->config.value[ (id) ].p)
#endif /* _DEBUG */
/** @} configuration_options group */
/** @} internal_api addtogroup */
#endif /* __CONFIG_H__ */