[Opensrf-commits] r1929 - in trunk: include/opensrf src/libopensrf (scottmk)

svn at svn.open-ils.org svn at svn.open-ils.org
Mon Feb 22 12:53:39 EST 2010


Author: scottmk
Date: 2010-02-22 12:53:35 -0500 (Mon, 22 Feb 2010)
New Revision: 1929

Modified:
   trunk/include/opensrf/osrfConfig.h
   trunk/src/libopensrf/osrfConfig.c
Log:
1. Added doxygen-style comments to document all functions.

2. For osrfConfigHasDefault() and osrfConfigCleanup(): added a formal void parameter
so that the header will contain prototypes rather than mere declarations.

3. In osrfConfigValueObject: added a sanity check for a non-loaded configuration.

4. In osrfConfigGetValueList(): replaced a call to jsonObjectToSimpleString() with
a call to jsonObjectGetString(), in order to eliminate a malloc() and free().

5. Tidied up the white space here and there.

M    include/opensrf/osrfConfig.h
M    src/libopensrf/osrfConfig.c


Modified: trunk/include/opensrf/osrfConfig.h
===================================================================
--- trunk/include/opensrf/osrfConfig.h	2010-02-21 02:31:58 UTC (rev 1928)
+++ trunk/include/opensrf/osrfConfig.h	2010-02-22 17:53:35 UTC (rev 1929)
@@ -16,6 +16,23 @@
 #ifndef OSRF_CONFIG_H
 #define OSRF_CONFIG_H
 
+/**
+	@file osrfConfig.h
+	@brief Routines for loading, storing, and searching configurations.
+
+	A configuration file, encoded as XML, is loaded and translated into a jsonObject.  This
+	object is stored in an osrfConfig, along with an optional context string which, if
+	present, restricts subsequent searches to a subset of the jsonObject.
+
+	In theory the context string could identify multiple subtrees of the total configuration.
+	In practice it is used to partition a configuration file into different pieces, each piece
+	to be used by a different application.
+
+	Normally an application loads a default configuration, accessible from every linked
+	module.  It is also possible, although seldom useful, to create and search a configuration
+	distinct from the default configuration.
+*/
+
 #include <opensrf/xml_utils.h>
 #include <opensrf/utils.h>
 #include <opensrf/string_array.h>
@@ -25,90 +42,30 @@
 extern "C" {
 #endif
 
+/**
+	@brief Represents a configuration; normally loaded from an XML configuration file.
+*/
 typedef struct {
-	jsonObject* config;
-	char* configContext;
+	jsonObject* config;   /**< Represents the contents of the XML configuration file. */
+	char* configContext;  /**< Context string (optional). */
 } osrfConfig;
 
-
-/**
-	Parses a new config file.  Caller is responsible for freeing the returned
-		config object when finished.  
-	@param configFile The XML config file to parse.
-	@param configContext Optional root of the subtree in the config file where 
-	we will look for values. If it's not provided,  searches will be 
-	performed from the root of the config file
-	@return The config object if the file parses successfully.  Otherwise
-		it returns NULL;
-*/
 osrfConfig* osrfConfigInit(const char* configFile, const char* configContext);
 
-/**
-	@return True if we have a default config defined
-*/
-int osrfConfigHasDefaultConfig();
+int osrfConfigHasDefaultConfig( void );
 
-/**
-	Replaces the config object's json object.  This is useful
-	if you have a json object already and not an XML config
-	file to parse.
-	@param cfg The config object to alter
-	@param obj The json object to use when searching values
-*/
 void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj);
 
-/** Deallocates a config object 
-	@param cfg The config object to free
-*/
 void osrfConfigFree(osrfConfig* cfg);
 
-
-/* Assigns the default config file.  This file will be used whenever
-	NULL is passed to config retrieval functions 
-	@param cfg The config object to use as the default config
-*/
 void osrfConfigSetDefaultConfig(osrfConfig* cfg);
 
-/* frees the default config if one exists */
-void osrfConfigCleanup();
+void osrfConfigCleanup( void );
 
-
-/** 
-	Returns the value in the config found at 'path'.
-	If the value found at 'path' is a long or a double,
-	the value is stringified and then returned.
-	The caller must free the returned char* 
-
-	if there is a configContext, then it will be appended to 
-	the front of the path like so: //<configContext>/<path>
-	if no configContext was provided to osfConfigSetFile, then 
-	the path is interpreted literally.
-	@param cfg The config file to search or NULL if the default
-		config should be used
-	@param path The search path
-*/
 char* osrfConfigGetValue(const osrfConfig* cfg, const char* path, ...);
 
+jsonObject* osrfConfigGetValueObject(osrfConfig* cfg, const char* path, ...);
 
-/**
- *  @see osrfConfigGetValue
- *  @return jsonObject found at path
- */
-jsonObject* osrfConfigGetValueObject(osrfConfig* cfg, char* path, ...);
-
-
-/** 
-	Puts the list of values found at 'path' into the pre-allocated 
-	string array.  
-	Note that the config node found at 'path' must be an array.
-	@param cfg The config file to search or NULL if the default
-		config should be used
-	@param arr An allocated string_array where the values will
-		be stored
-	@param path The search path
-	@return the number of values added to the string array;
-*/
-
 int osrfConfigGetValueList(const osrfConfig* cfg, osrfStringArray* arr,
 		const char* path, ...);
 

Modified: trunk/src/libopensrf/osrfConfig.c
===================================================================
--- trunk/src/libopensrf/osrfConfig.c	2010-02-21 02:31:58 UTC (rev 1928)
+++ trunk/src/libopensrf/osrfConfig.c	2010-02-22 17:53:35 UTC (rev 1929)
@@ -1,9 +1,23 @@
 /* defines the currently used bootstrap config file */
 #include <opensrf/osrfConfig.h>
 
+/**
+	@file osrfConfig.c
+	@brief Routines for managing osrfConfigs to represent configuration information.
+*/
+
+/**
+	@brief Points to the default configuration.
+*/
 static osrfConfig* osrfConfigDefault = NULL;
 
+/**
+	@brief Install a specified osrfConfig as the default configuration.
+	@param cfg Pointer to the configuration to be stored.
 
+	Store the passed pointer for future reference.  The calling code yields ownership of the
+	associated osrfConfig.
+*/
 void osrfConfigSetDefaultConfig(osrfConfig* cfg) {
 	if(cfg) {
 		if( osrfConfigDefault )
@@ -12,37 +26,69 @@
 	}
 }
 
+/**
+	@brief Free an osrfConfig.
+	@param cfg Pointer to the osrfConfig to be freed.
+*/
 void osrfConfigFree(osrfConfig* cfg) {
 	if(cfg) {
 		jsonObjectFree(cfg->config);
 		free(cfg->configContext);
 		free(cfg);
-	}	
+	}
 }
 
-
-int osrfConfigHasDefaultConfig() {
+/**
+	@brief Report whether a default configuration has been installed.
+	@return Boolean: true if a default configuration is available, or false if not.
+*/
+int osrfConfigHasDefaultConfig( void ) {
 	return ( osrfConfigDefault != NULL );
 }
 
-
-void osrfConfigCleanup() { 
+/**
+	@brief Free the default configuration, if it exists.
+*/
+void osrfConfigCleanup( void ) {
 	osrfConfigFree(osrfConfigDefault);
 	osrfConfigDefault = NULL;
 }
 
+/**
+	@brief Replace the jsonObject of an osrfConfig.
+	@param cfg The osrfConfig to alter.
+	@param obj The jsonObject to install in the osrfConfig.
 
+	This is useful if you have a json object already, rather than an XML configuration file
+	to parse.
+*/
 void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj) {
 	if(!cfg || !obj) return;
 	jsonObjectFree(cfg->config);
-	cfg->config = jsonObjectClone(obj);	
+	cfg->config = jsonObjectClone(obj);
 }
 
+/**
+	@brief Load an XML configuration file into a jsonObject within an osrfConfig.
+	@param configFile Name of the XML configuration file.
+	@param configContext (Optional) Root of a subtree in the configuration file,
+	@return If successful, a pointer to the resulting osrfConfig; otherwise NULL.
+
+	If @a configContext is not NULL, save a copy of the string to which it points.  It is a
+	tag identifying one or more subtrees within the XML; subsequent searches will examine
+	only matching subtrees.  Otherwise they will search the tree from the root.
+
+	(In practice a configContext is always supplied, so that different programs can share
+	the same configuration file, partitioned by context tags.)
+
+	The calling code is responsible for freeing the returned config object by calling
+	osrfConfigFree().
+*/
 osrfConfig* osrfConfigInit(const char* configFile, const char* configContext) {
 	if(!configFile) return NULL;
 
 	// Load XML from the configuration file
-	
+
 	xmlDocPtr doc = xmlParseFile(configFile);
 	if(!doc) {
 		osrfLogWarning( OSRF_LOG_MARK, "Unable to parse XML config file %s", configFile);
@@ -50,34 +96,62 @@
 	}
 
 	// Translate it into a jsonObject
-	
 	jsonObject* json_config = xmlDocToJSON(doc);
 	xmlFreeDoc(doc);
 
 	if(!json_config ) {
 		osrfLogWarning( OSRF_LOG_MARK, "xmlDocToJSON failed for config %s", configFile);
 		return NULL;
-	}	
+	}
 
 	// Build an osrfConfig and return it by pointer
-	
 	osrfConfig* cfg = safe_malloc(sizeof(osrfConfig));
 
-	if(configContext) cfg->configContext = strdup(configContext);
-	else cfg->configContext = NULL;
+	if( configContext )
+		cfg->configContext = strdup(configContext);
+	else
+		cfg->configContext = NULL;
 
 	cfg->config = json_config;
-	
+
 	return cfg;
 }
 
+/**
+	@brief Search a configuration for a specified value.
+	@param cfg (Optional) The configuration to search, or NULL for the default configuration.
+	@param path A printf-style format string representing the search path.  Subsequent
+	parameters, if any, are inserted into the format string to form the search path.
+	@return A pointer to a newly allocated string containing the value, if found; otherwise
+	NULL.
 
+	Search for a value in the configuration, as specified by the search path.
+
+	If cfg is NULL, search the default configuration; otherwise search the configuration
+	specified.
+
+	If the configuration includes a configContext, then prepend it to the path, like so:
+	"//<configContext><path>".  Hence the path should begin with a slash to separate it from
+	the context.  Search for the resulting effective path at any level within the
+	configuration.
+
+	If the configuration does @em not include a configContext, then start the search at the
+	root of the configuration.  In this case the path should @em not begin with a slash.
+
+	If the configuration contains more than one entry at locations matching the effective
+	search path, return NULL.
+
+	Return numeric values as numeric strings.
+
+	The calling code is responsible for freeing the returned string by calling free().
+*/
 char* osrfConfigGetValue(const osrfConfig* cfg, const char* path, ...) {
 	if(!path) return NULL;
-	if(!cfg) cfg = osrfConfigDefault;
-	if(!cfg) { 
-		osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValue()"); 
-		return NULL; 
+	if(!cfg)
+		cfg = osrfConfigDefault;
+	if(!cfg) {
+		osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValue()");
+		return NULL;
 	}
 
 	VA_LIST_TO_STRING(path);
@@ -89,29 +163,88 @@
 		obj = jsonObjectExtractIndex( outer_obj, 0 );
 		jsonObjectFree( outer_obj );
 	} else
-		obj = jsonObjectFindPath( cfg->config, VA_BUF);
+		obj = jsonObjectFindPath( cfg->config, VA_BUF );
 
 	char* val = jsonObjectToSimpleString(obj);
 	jsonObjectFree(obj);
 	return val;
 }
 
-jsonObject* osrfConfigGetValueObject(osrfConfig* cfg, char* path, ...) {
+/**
+	@brief Search for one or more subtrees of a configuration.
+	@param cfg (Optional) The configuration to search, or NULL for the default configuration.
+	@param path A printf-style format string representing the search path.  Subsequent
+	parameters, if any, are inserted into the format string to form the search path.
+	@return A pointer to a jsonObject representing a subset of the specified configuration,
+	if found; otherwise NULL.
+
+	Search for subtrees of the configuration, as specified by the search path.
+
+	If the configuration includes a configContext, then prepend it to the path, like so:
+	"//<configContext><path>".  Hence the path should begin with a slash to separate it from
+	the context.  Search for the resulting effective path at any level within the
+	configuration.
+
+	If the configuration does @em not include a configContext, then start the search at the
+	root of the configuration.  In this case the path should @em not begin with a slash.
+
+	If any entries match the effective path, return copies of them all as elements of a
+	jsonObject of type JSON_ARRAY.
+
+	If no entries match the effective path, return a jsonObject of type JSON_NULL.
+
+	The calling code is responsible for freeing the returned jsonObject by calling
+	jsonObjectFree().
+*/
+jsonObject* osrfConfigGetValueObject(osrfConfig* cfg, const char* path, ...) {
 	if(!path) return NULL;
-	if(!cfg) cfg = osrfConfigDefault;
+	if(!cfg)
+		cfg = osrfConfigDefault;
+	if(!cfg) {
+		osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValueObject()");
+		return NULL;
+	}
+
 	VA_LIST_TO_STRING(path);
-	if(cfg->configContext) 
-        return jsonObjectFindPath(cfg->config, "//%s%s", cfg->configContext, VA_BUF);
+	if(cfg->configContext)
+		return jsonObjectFindPath(cfg->config, "//%s%s", cfg->configContext, VA_BUF);
 	else
 		return jsonObjectFindPath(cfg->config, VA_BUF);
 }
 
+/**
+	@brief Search for one or more values in a configuration, specified by a path.
+	@param cfg (Optional) The configuration to search, or NULL for the default configuration.
+	@param arr Pointer to an osrfStringArray to be populated with values.
+	@param path A printf-style format string representing the search path.  Subsequent
+	parameters, if any, are inserted into the format string to form the search path.
+	@return The number of values loaded into the osrfStringArray.
+
+	Search the configuration for values specified by the search path.  Load any values
+	found (either strings or numbers) into an existing osrfStringArray supplied by the
+	calling code.
+
+	Make no effort to delete any strings that may already be in the osrfStringArray.
+	Ordinarily the calling code should ensure that the osrfStringArray is empty when passed.
+
+	If the configuration includes a configContext, then prepend it to the path, like so:
+	"//<configContext><path>".  Hence the path should begin with a slash to separate it from
+	the context.  Search for the resulting effective path at any level within the
+	configuration.
+
+	If the configuration does @em not include a configContext, then start the search at the
+	root of the configuration.  In this case the path should @em not begin with a slash.
+*/
 int osrfConfigGetValueList(const osrfConfig* cfg, osrfStringArray* arr,
 		const char* path, ...) {
 
 	if(!arr || !path) return 0;
-	if(!cfg) cfg = osrfConfigDefault;
-	if(!cfg) { osrfLogWarning( OSRF_LOG_MARK, "No Config object!"); return -1;}
+	if(!cfg)
+		cfg = osrfConfigDefault;
+	if(!cfg) {
+		osrfLogWarning( OSRF_LOG_MARK, "No Config object!");
+		return -1;
+	}
 
 	VA_LIST_TO_STRING(path);
 
@@ -129,11 +262,10 @@
 		int i;
 		for( i = 0; i < obj->size; i++ ) {
 
-			char* val = jsonObjectToSimpleString(jsonObjectGetIndex(obj, i));
+			const char* val = jsonObjectGetString( jsonObjectGetIndex(obj, i) );
 			if(val) {
 				count++;
 				osrfStringArrayAdd(arr, val);
-				free(val);
 			}
 		}
 	}
@@ -141,4 +273,3 @@
 	jsonObjectFree(obj);
 	return count;
 }
-



More information about the opensrf-commits mailing list