#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__ */