parsecfg - a library for parsing a configuration file <author>Yuuki NINOMIYA <gm@debian.or.jp> <date>$Date: 2001/07/15 14:56:09 $ <abstract> This document is the user's manual for parsecfg library. It doesn't seem to be a good document, so you should also read source codes of a sample program and the library. :-p </abstract> <toc> <sect>Introduction <p> <sect1>Overview <p> Parsecfg is a library for parsing a configuration file. Values are stored in dynamically-allocated memory. <sect1>Features <p> <itemize> <item>Support for a simple syntax format (PARAMETER = VALUE) and Windoze INI-like (or SAMBA's) file using a section. <item>Support for numeric, boolean, string and linked-list stored strings as parameter type. <item>A function for fetching value from configuration file. <item>Writing configurations to a file. <item>The maximum number of parameters has no limitation. <item>Support for internationalization of messages by GNU gettext. Japanese, Polish and French translations are available now. </itemize> <sect1>Requirements <p> Parsecfg requires an ANSI C compiler. I tested this program with gcc version 2.95.4. I strongly recommend that your program uses GNU gettext though it is non-essential for parsecfg. It is very helpful for non-native English speakers to internationalize messages by gettext. See <url url="http://www.gnu.org/manual/gettext/html_node/gettext_toc.html"> for details of gettext. <sect>Usage <p> <sect1>Installation <p> Just include parsecfg.c and parsecfg.h as a part of your program. <sect1>Preparation <p> Create and initialize an array of cfgStruct to parse the configuration file. Set parameter name, type and address of the variable in each element in the array. (If type of the configuration file is INI, specify address of pointer to variable instead of address of the variable). cfgStruct is declared as the following in parsecfg.h. <code> typedef struct{ char *parameterName; cfgValueType type; void *value; } cfgStruct; </code> `parameterName' is the name of parameter (keyword), `type' is the type of parameter, `value` is the address of variable. (or the address of pointer) There is the following types as `type'. <descrip> <tag>CFG_BOOL</tag> Store 1 if the value is `True' or `Yes' or `T' or `Y' or `1'. Store 0 if the value is `False' or `No' or `F' or `N' or `0'. They are not case sensitive. <tag>CFG_INT</tag> Store as int. <tag>CFG_UINT</tag> Store as unsigned int. <tag>CFG_LONG</tag> Store as long. <tag>CFG_ULONG</tag> Store as unsigned long. <tag>CFG_FLOAT</tag> Store as float. <tag>CFG_DOUBLE</tag> Store as double. <tag>CFG_STRING</tag> Store as string. <tag>CFG_STRING_LIST</tag> Store as linked list for strings. <tag>CFG_END</tag> The last element in the array. </descrip> When INT/UINT/LONG/ULONG, the string includes a `0x' prefix, and the number will be read in base 16, a `0` prefix in base 8, otherwise base 10. See the sample program (sample.c) for more details. Type `make' to compile the sample program. <sect1>Function References <p> Include parsecfg.h before using the following functions. <descrip> <tag><tt>void cfgSetFatalFunc(void (*f)(int, const char *, int, const char *))</tt></tag> Set error handler by this function. Before calls this function, parsecfg uses default error handler written in parsecfg.c. <tag><tt>int cfgParse(const char *file, cfgStruct cfg[], cfgFileType type)</tt></tag> Call this function to parse the configuration file `file'. `type' is type of the configuration file. If it is CFG_SIMPLE, the file is parsed as simple format (PARAMETER = VALUE). If it is CFG_INI, this function parses it as Windoze INI-like format (using sections). Return value is the number of read sections (1,2,3,...). Return 0 usually if the type is CFG_SIMPLE. Return -1 on error. <tag><tt>int cfgDump(const char *file, cfgStruct cfg[], cfgFileType type, int max)</tt></tag> Call this function to output configurations to a file. Configurations are written to `file'. `type' is type of the configuration file. `max' is the number of sections. If `type' is CFG_SIMPLE, you can specify any number. (Normally, you want to specify 0.) Return 0 if successful, -1 on error. <tag><tt>int fetchVarFromCfgFile(const char *file, char *parameter_name, void *result_value, cfgValueType value_type, cfgFileType file_type, int section_num, const char *section_name)</tt></tag> Call this function to fetch value of `parameter_name' from `file'. Result is stored in `result_value'. The type of this variable is specified by `value_type'. `file_type' is type of the configuration file. `section_num' is section number you want to fetch from. If it is less than 1, fetch from the section specified in `section_name' instead of `section_num'. If `type' is `CFG_SIMPLE', you can specify any value. (Normally, you want to specify 0 and NULL.) Return 0 if successful, -1 on error. <tag><tt>int cfgSectionNameToNumber(const char *name)</tt></tag> Call this function to convert section name to section number. Return value is section number (0,1,2,...). Section name is not case sensitive. Return -1 if name doesn't match. <tag><tt>char *cfgSectionNumberToName(int num)</tt></tag> Call this function to convert section number to section name. Return NULL if there is no specified section. <tag><tt>int cfgAllocForNewSection(cfgStruct cfg[], const char *name)</tt></tag> Call this function to alloc memories for defining a new section. The new section is named string specified in `name'. Return the maximum number of section if successful, -1 on error. <tag><tt>int cfgStoreValue(cfgStruct cfg[], const char *parameter, const char *value, cfgFileType type, int section)</tt></tag> Call this function to store `value' according to `cfg'. `type' is type of the configuration file. `section' is section number (0,1,2,...) that you want to store value in. If `type' is CFG_SIMPLE, you can specify any number. (Normally, you want to specify 0.) Return 0 if successful, -1 on error. </descrip> <sect1>Format of Configuration File <p> White spaces and tabs are always skipped. If you want to use such a special character, quote strings with <tt>&dquot;</tt> or <tt>'</tt>. If you want to use <tt>&dquot;</tt>, use <tt>'</tt>. If you want to use <tt>'</tt>, use <tt>&dquot;</tt>. Lines that begin with the <tt>#</tt> character are ignored as comment. Parameter names are not case sensitive. Basic format is &dquot;PARAMETER = VALUE&dquot;. <code> # PARAMETER = VALUE ParameterINT = 65535 ParameterSTRING = GNU/Linux QuotedString = 'I pronounce "Linux" as "Leenooks".' TRUEorFALSE = FaLsE </code> If there are same parameters and parameter type is CFG_STRING_LIST , all values are stored. If other type, the last one is stored. <code> # multiple parameters # CFG_INT ParameterINT = 255 # ignored ParameterINT = 65535 # stored # CFG_STRING_LIST ListString = "Debian GNU/Linux" # stored ListString = "FreeBSD" # stored </code> If you want to specify multiple values to linked list, the following format is also available. <code> # for linked list ListString = { Internet "Exploder" } </code> If the configuration file type is CFG_INI, quote section name with <tt>[</tt> and <tt>]</tt>. <code> # Windoze INI-like file [Linux] STRING = rule! VALUE = 99999999 [Windoze] STRING = suck! VALUE = -99999999 </code> See sample.cfg and sample.ini for more details. <sect>License <p> Copyright (C) 1999-2001 Yuuki NINOMIYA <gm@debian.or.jp> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. <sect>Tested Operating Systems <p> <itemize> <item>Debian GNU/Linux 2.1/2.2/sid <item>SuSE Linux 6.1 <item>FreeBSD 3.4-RELEASE </itemize> <sect>Limitations <p> None. <sect>Known Bugs <p> <itemize> <item>There is no function to free allocated memories. <item>It may have some memory leaks. <item>CFG_SIMPLE is not tested enough. </itemize> <sect>Future Plans <p> None. <sect>FAQ <p> None. <sect>Request to Users <p> I have an incomplete mastery of the English language, so please help correct the text of the documents and messages in this program. Comments, suggestions, bug reports and patches are always welcome. Please mail them to the following address. <sect>Author <p> Yuuki NINOMIYA <gm@debian.or.jp><newline> <url url="http://www.enjoy.ne.jp/~gm/index.html"> <sect>The Latest Release <p> The latest official release of parsecfg is available from:<newline> <url url="http://www.enjoy.ne.jp/~gm/program/parsecfg/index.html"> <sect>The Latest Source Code <p> You can get the latest source code with Anonymous CVS. Specify `:pserver:anonymous@linuxlovers.yi.org:/var/cvs' as repository, `parsecfg' as project name, `anonymous' as password. <code> % cvs -d :pserver:anonymous@linuxlovers.yi.org:/var/cvs login (Logging in to anonymous@linuxlovers.yi.org) CVS password: anonymous % cvs -d :pserver:anonymous@linuxlovers.yi.org:/var/cvs checkout parsecfg </code> See <url url="http://www.cvshome.org/docs/manual/index.html"> for details about CVS. <sect>Related Links <p> <url url="http://members.tripod.com/toddsgreene/cfgstl.html" name="A Configuration File Parser Using C++ and STL"> <sect>Acknowledgement <p> <sect1>Borrowed Code / Library <p> <sect1>Contributions of Code or Document <p> <descrip> <tag>Kolb Norbert <nkolb@htl.de></tag> <itemize> <item>definition of constant macro PARSECFG_VERSION </itemize> <tag>And. Andruikhanov <andy@euinf.dp.ua></tag> <itemize> <item>bugfix for detecting end of file </itemize> <tag>Andreas Schuldei <schuldei@andrive.de></tag> <itemize> <item>support for float parameter type </itemize> <tag>Pascal Lengard <pascal.lengard@wanadoo.fr></tag> <itemize> <item>default error handler never call exit </itemize> <tag>Guillaume Hajduch <Guillaume.Hajduch@enst-bretagne.fr></tag> <itemize> <item>support for double parameter type </itemize> <tag>Richard Rowell <rrowell@shreve.net></tag> <itemize> <item>support for linking with C++ code. </itemize> </descrip> <sect1>Translations <p> <descrip> <tag>Krzysztof Krzyz.aniak <eloy@transilvania.eu.org></tag> <itemize> <item>Polish translations (pl.po) </itemize> <tag>Guillaume Hajduch <guillaume.hajduch@free.fr></tag> <itemize> <item>French translations (fr.po) </itemize> </descrip> <sect1>Other <p> Thanks to many people who send me comments, bug reports and suggestions. And thank you for using parsecfg! <sect>History <p> <descrip> <tag>June 27, 2001 Ver 3.6.7</tag> <itemize> <item>Support for 8 and 16 radix.<newline> Thanks to Carlos Nieves Onega <cnieves@tsc.uvigo.es> </itemize> <tag>February 22, 2001 Ver 3.6.6</tag> <itemize> <item>Support for linking with C++ code.<newline> Thanks to Richard Rowell <rrowell@shreve.net>. </itemize> <tag>February 15, 2001 Ver 3.6.5</tag> <itemize> <item>A memory leak is fixed. <item>Some messages are modified. </itemize> <tag>January 16, 2001 Ver 3.6.4</tag> <itemize> <item>The bug missing `static' declaration is fixed. <item>Indent of a part of source is modified. </itemize> <tag>December 19, 2000 Ver 3.6.3</tag> <itemize> <item>The bug is fixed that file stream closes twice on error. <item>The bug is fixed that reading file fails in rare cases. </itemize> <tag>December 18, 2000 Ver 3.6.2</tag> <itemize> <item>Add const qualifier to some arguments. </itemize> <tag>December 15, 2000 Ver 3.6.1</tag> <itemize> <item>The bug is fixed that wrong variable is referred for checking the range.<newline> Thanks to Elliott Church <echurch@gfs.com>. </itemize> <tag>December 06, 2000 Ver 3.6.0</tag> <itemize> <item>Functions for creating a new section and storing value in dynamic have been added. </itemize> <tag>November 23, 2000 Ver 3.5.0</tag> <itemize> <item>Support for double parameter type.<newline> Thanks to Guillaume Hajduch <Guillaume.Hajduch@enst-bretagne.fr>. <item>French translations (fr.po) has been added.<newline> Thanks to Guillaume Hajduch <guillaume.hajduch@free.fr>. </itemize> <tag>October 07, 2000 Ver 3.4.0</tag> <itemize> <item>* warning * This version doesn't have compatibility.<newline> Action of default error handler is changed. Any library functions never call exit though critical error happens. cfgParse returns -1 on error, so caller should process error handling. Or prepare your own error handler and set it by calling cfgSetFatalFunc.<newline> Thanks to Pascal Lengard <pascal.lengard@wanadoo.fr> <item>The bug is fixed that cfgDump outputs wrong data. <item>The bug is fixed that cfgDump causes SIGSEGV when string pointer is NULL. <item>Providing SGML documents. </itemize> <tag>July 20, 2000 Ver 3.3.0</tag> <itemize> <item>Polish translations (pl.po) has been added.<newline> Thanks to Krzysztof Krzyz.aniak <eloy@transilvania.eu.org>. <item>Support for float parameter type.<newline> Thanks to Andreas Schuldei <schuldei@andrive.de>. </itemize> <tag>February 24, 2000 Ver 3.2.1</tag> <itemize> <item>Bugfix for using freed memory block in parse_values_between_braces(). <item>Bugfix for outputing incorrect line when use braces and parameter is unrecognized. </itemize> <tag>February 13, 2000 Ver 3.2.0</tag> <itemize> <item>Move definition of PARSECFG_VERSION to parsecfg.h. <item>The bug is fixed that if last string in config file doesn't contain '\n' symbol, program doesn't detects last value or crashes.<newline> Thanks to And. Andruikhanov <andy@euinf.dp.ua>. <item>Bugfix for leaving the configuration file opened. <item>The bug is fixed that when program reads the end of file before brace is closed, it outputs incorrect error message. <item>Add function for fetching value from configuration file by input name. </itemize> <tag>December 24, 1999 Ver 3.1.2</tag> <itemize> <item>The bug is fixed that parsecfg crashes when there is a parameter before definition of a section. </itemize> <tag>December 23, 1999 Ver 3.1.1</tag> <itemize> <item>Definition of constant macro PARSECFG_VERSION.<newline> Thanks to Kolb Norbert <nkolb@htl.de>. </itemize> <tag>December 22, 1999 Ver 3.1.0</tag> <itemize> <item>Support for the function writing configurations to a file. </itemize> <tag>November 30, 1999 Ver 3.0.4a</tag> <itemize> <item>Documents are modified. </itemize> <tag>November 07, 1999 Ver 3.0.4</tag> <itemize> <item>Capitalize error messages. </itemize> <tag>October 19, 1999 Ver 3.0.3</tag> <itemize> <item>The buffer for fgets is allocated dynamically. </itemize> <tag>October 17, 1999 Ver 3.0.2</tag> <itemize> <item>Using typedef for enum. </itemize> <tag>October 11, 1999 Ver 3.0.1</tag> <itemize> <item>In INI type configuration file, if there is no parameter, the boolean value is initialized by FALSE (-1). <item>The bug is fixed that causes segmentation fault when calls cfgSectionNumberToName with minus value as argument. </itemize> <tag>October 10, 1999 Ver 3.0.0</tag> <itemize> <item>Rewrite most codes. Lose compatibility of functions and the format of the configuration file. <item>Supports the section Window INI-like file (or SAMBA's). <item>Parameters are not case sensitive. <item>Supports True/False, Yes/No, T/F, Y/N, 1/0 for boolean value. They are not case sensitive. <item>Supports quotations for using white spaces and tabs in value. <item>Abandon supporting tree structure. </itemize> <tag>September 27, 1999 Ver 2.0.3</tag> <itemize> <item>Modify a little messages. </itemize> <tag>August 12, 1999 Ver 2.0.2a</tag> <itemize> <item>Change the name. </itemize> <tag>August 08, 1999 Ver 2.0.2</tag> <itemize> <item>Modify around gettext. </itemize> <tag>July 01, 1999 Ver 2.0.1b</tag> <itemize> <item>Uses `int' instead of `void' as return type in main function in the sample program. </itemize> <tag>June 29, 1999 Ver 2.0.1a</tag> <itemize> <item>Divide documents. </itemize> <tag>June 09, 1999 Ver 2.0.1</tag> <itemize> <item>The overrun bug is fixed. </itemize> <tag>June 02, 1999 Ver 2.0.0</tag> <itemize> <item>Change the name. <item>Rewrite from scratch. <item>Comment begins '#' instead of ';'. </itemize> <tag>April 03, 1999 Ver 1.0.1</tag> <itemize> <item>The overrun bug is fixed. </itemize> <tag>April 02, 1999 Ver 1.0.0</tag> <itemize> <item>Initial release. </itemize> </descrip> </article>