Blame IbaTools/opaxmlgenerate/opaxmlgenerate.c

Packit 857059
/* BEGIN_ICS_COPYRIGHT7 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015-2017, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
      documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT7   ****************************************/
Packit 857059
Packit 857059
/* [ICS VERSION STRING: unknown] */
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * File: opaxmlgenerate.c
Packit 857059
 *
Packit 857059
 * Description:
Packit 857059
 *	This file implements the opaxmlgenerate program.  opaxmlgenerate takes
Packit 857059
 *	CSV data as input and, with user-specified element names, generates
Packit 857059
 *	sequences of XML containing the element values within start and end tag
Packit 857059
 *	specifications.
Packit 857059
 *
Packit 857059
 *	opaxmlgenerate uses libXml to manage the XML generation state and for ouptut
Packit 857059
 *	functions.  It calls the following functions:
Packit 857059
 *	  IXmlInit()
Packit 857059
 *	  IXmlOutputStartAttrTag()
Packit 857059
 *	  IXmlOutputEndTag()
Packit 857059
 *	  IXmlOutputStrLen()
Packit 857059
 *
Packit 857059
 *	opaxmlgenerate uses 3 types of element names specified by the user.  The
Packit 857059
 *	types are distinguished by their command line option.  -g specifies an
Packit 857059
 *	an element name that, along with a value from the CSV input file, will
Packit 857059
 *	be used to generate XML of the form '<element_name>value</element_name>'.
Packit 857059
 *	-h specifies an element name that will be used to generate an "enclosing"
Packit 857059
 *	XML header start tag of the form '<element_name>'.  -e specifies an
Packit 857059
 *	element name that will be used to generate an enclosing XML header end
Packit 857059
 *	tag of the form '</element_name>'.  Enclosing elements do not contain
Packit 857059
 *	a value, but serve to separate and organize the elements that do contain
Packit 857059
 *	values.
Packit 857059
 *
Packit 857059
 *	The operation of opaxmlgenerate is further controlled by the following
Packit 857059
 *	command line options:
Packit 857059
 *	  -d delimiter - specifies the delimiter character that separates input
Packit 857059
 *	                 values in the CSV input file; default is semicolon
Packit 857059
 *	  -i indent - specifies the number of spaces to indent each level of
Packit 857059
 *	              XML output; default is zero
Packit 857059
 *	  -X input_file - input CSV data from input_file
Packit 857059
 *	  -P param_file - input command line options (parameters) from param_file
Packit 857059
 *	  -v - verbose output: output progress reports during generation
Packit 857059
 *
Packit 857059
 *	opaxmlgenerate generates sequences (fragments) of XML, as opposed to
Packit 857059
 *	complete XML specifications.  It is intended that opaxmlgenerate be
Packit 857059
 *	invoked from within a script (typically multiple times), using multiple
Packit 857059
 *	input files (with possibly different CSV formats) to create the desired
Packit 857059
 *	XML output.  The script would output any necessary XML header or trailer
Packit 857059
 *	information (XML version or report information) as well as "glue" XML
Packit 857059
 *	between fragments.
Packit 857059
 *
Packit 857059
 *	NOTES:
Packit 857059
 *	Output of start and end tags for enclosing elements is controlled by
Packit 857059
 *	the placement of command line options -h and -e respectively with
Packit 857059
 *	respect to -g options.  No check for matching tags or proper nesting
Packit 857059
 *	of tags is performed by opaxmlgenerate.
Packit 857059
 */
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * INCLUDES
Packit 857059
 */
Packit 857059
Packit 857059
#include <stddef.h>
Packit 857059
#include <stdio.h>
Packit 857059
#include <stdlib.h>
Packit 857059
#include <unistd.h>
Packit 857059
#include <string.h>
Packit 857059
#include <iba/ipublic.h>
Packit 857059
#include <iba/public/datatypes.h>
Packit 857059
#include <getopt.h>
Packit 857059
#include "ixml.h"
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * DEFINES
Packit 857059
 */
Packit 857059
Packit 857059
#define OK  0
Packit 857059
#define ERROR (-1)
Packit 857059
Packit 857059
#define NAME_PROG  "opaxmlgenerate"		// Program name
Packit 857059
#define MAX_PARAMS_FILE  512			// Max number of param file parameters
Packit 857059
#define MAX_ELEMENTS  100				// Max number of elements parsable
Packit 857059
#define MAX_DELIMIT_CHARS  16			// Max size of delimiter string
Packit 857059
#define MAX_INPUT_BUF  8192				// Max size of input buffer
Packit 857059
#define MAX_PARAM_BUF  8192				// Max size of parameter file
Packit 857059
#define MAX_FILENAME_CHARS  256			// Max size of file name
Packit 857059
#define WHITE_SPACE  " \t\r\n"			// White space characters
Packit 857059
#define OPTION_LEN 2			// string length of an option(eg. -P)
Packit 857059
Packit 857059
// Element table entry
Packit 857059
typedef struct 
Packit 857059
{
Packit 857059
	int		lenName;					// Length of element name		
Packit 857059
	char	*pName;						// Element name
Packit 857059
	int		lenValue;					// Length of element value
Packit 857059
	char	*pValue;					// Element value
Packit 857059
	int		flags;						// Flags as:  xxxx xEHG
Packit 857059
										//   E = 1 - End header
Packit 857059
										//   H = 1 - Header
Packit 857059
										//   G = 1 - Generate value
Packit 857059
} ELEMENT_TABLE_ENTRY;
Packit 857059
Packit 857059
// Element table flags:
Packit 857059
#define ELEM_GENERATE  0x01
Packit 857059
#define ELEM_HEADER  0x02
Packit 857059
#define ELEM_END  0x04
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * GLOBAL VARIABLES
Packit 857059
 */
Packit 857059
Packit 857059
int		g_exitstatus  = 0;
Packit 857059
int		g_verbose  = 0;
Packit 857059
int		g_quiet  = 0;
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * LOCAL VARIABLES
Packit 857059
 */
Packit 857059
Packit 857059
int  numElementsTable  = 0;				// Number of elements in tbElements[]
Packit 857059
uint32  numIndentChars  = 0;		// Num of chars per indent level
Packit 857059
Packit 857059
FILE  * hFileInput  = NULL;				// Input file handle (default stdin)
Packit 857059
										// Input file name (default stdin)
Packit 857059
char  nameFileInput[MAX_FILENAME_CHARS + 1]  = "stdin";
Packit 857059
FILE  * hFileOutput  = NULL;			// Output file handle (default stdout)
Packit 857059
char  nameFileOutput[MAX_FILENAME_CHARS]  = "stdout";  // Output file name (default stdout)
Packit 857059
Packit 857059
uint32  fvDebugProg  = 0;			// Debug/Trace variable as:
Packit 857059
										//  0MMM MMMM NNNN NNNN  SSSS 21RC SIEB SNEB
Packit 857059
Packit 857059
// Command line option table, each has a short and long flag name
Packit 857059
struct option tbOptions[] =
Packit 857059
{
Packit 857059
	// Basic controls
Packit 857059
	{ "verbose", no_argument, NULL, 'v' },
Packit 857059
	{ "generate", required_argument, NULL, 'g' },
Packit 857059
	{ "header", required_argument, NULL, 'h' },
Packit 857059
	{ "end", required_argument, NULL, 'e' },
Packit 857059
	{ "infile", required_argument, NULL, 'X' },
Packit 857059
	{ "pfile", required_argument, NULL, 'P' },
Packit 857059
	{ "delimit", required_argument, NULL, 'd' },
Packit 857059
	{ "indent", required_argument, NULL, 'i' },
Packit 857059
	{ "debug", required_argument, NULL, 'Z' },
Packit 857059
	{ 0 }
Packit 857059
};
Packit 857059
Packit 857059
// Element table; contains information about each element of interest.
Packit 857059
//  Elements are contained in the table (0 - numElementsTable-1) in the
Packit 857059
//	order they appear on the command line.
Packit 857059
ELEMENT_TABLE_ENTRY  tbElements[MAX_ELEMENTS];
Packit 857059
Packit 857059
// IXml Output State
Packit 857059
IXmlOutputState_t state;
Packit 857059
Packit 857059
// Delimiter string buffer
Packit 857059
char  bfDelimit[MAX_DELIMIT_CHARS + 1] = ";";
Packit 857059
Packit 857059
// Input buffer
Packit 857059
char  bfInput[MAX_INPUT_BUF];
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * LOCAL FUNCTION PROTOTYPES
Packit 857059
 */
Packit 857059
Packit 857059
void dispElementRecord(ELEMENT_TABLE_ENTRY * pElement, const char * pValue);
Packit 857059
void errUsage(void);
Packit 857059
int findElement(const char *pElement);
Packit 857059
void getRecu_opt( int argc, char ** argv, const char *pOptShort,
Packit 857059
	struct option tbOptLong[] );
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * dispElementRecord()
Packit 857059
 *
Packit 857059
 * Description:
Packit 857059
 *	Display (output) an element, either generate (with value) or header (Start
Packit 857059
 *	or End).
Packit 857059
 *
Packit 857059
 * Inputs:
Packit 857059
 *	pElement - Pointer to tbElement to output
Packit 857059
 *	  pValue - Pointer to value string to output (NULL means no value)
Packit 857059
 *
Packit 857059
 * Outputs:
Packit 857059
 *	none
Packit 857059
 */
Packit 857059
void dispElementRecord(ELEMENT_TABLE_ENTRY * pElement, const char * pValue)
Packit 857059
{
Packit 857059
	// Output header element name (as Start tag or End tag)
Packit 857059
	if (pElement->flags & ELEM_HEADER)
Packit 857059
		IXmlOutputStartAttrTag(&state, pElement->pName, NULL, NULL);
Packit 857059
Packit 857059
	else if (pElement->flags & ELEM_END)
Packit 857059
		IXmlOutputEndTag(&state, pElement->pName);
Packit 857059
Packit 857059
	// Output generate element name and value
Packit 857059
	else if ((pElement->flags & ELEM_GENERATE) && pValue)
Packit 857059
		IXmlOutputStrLen(&state, pElement->pName, pValue, strlen(pValue));
Packit 857059
Packit 857059
}	// End of dispElementRecord()
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * errUsage()
Packit 857059
 *
Packit 857059
 * Description:
Packit 857059
 *	Output information about program usage and parameters.
Packit 857059
 *
Packit 857059
 * Inputs:
Packit 857059
 *	none
Packit 857059
 *
Packit 857059
 * Outputs:
Packit 857059
 *	none
Packit 857059
 */
Packit 857059
void errUsage(void)
Packit 857059
{
Packit 857059
	fprintf(stderr, "Usage: " NAME_PROG " [-v][-d delimiter][-i number][-g element][-h element]\n");
Packit 857059
	fprintf(stderr, "                         [-e element][-X input_file][-P param_file]\n");
Packit 857059
	fprintf(stderr, "  At least 1 element must be specified\n");
Packit 857059
	fprintf(stderr, "  -g/--generate element     - name of XML element to generate\n");
Packit 857059
	fprintf(stderr, "                              can be used multiple times\n");
Packit 857059
	fprintf(stderr, "                              values assigned to elements in order xxx ... \n");
Packit 857059
	fprintf(stderr, "  -h/--header element       - name of XML element in which to enclose generated\n");
Packit 857059
	fprintf(stderr, "                              XML elements\n");
Packit 857059
	fprintf(stderr, "  -e/--end element          - name of header XML element to end (close)\n");
Packit 857059
	fprintf(stderr, "  -d/--delimit delimiter    - delimiter char input between element values\n");
Packit 857059
	fprintf(stderr, "                              default is semicolon\n");
Packit 857059
	fprintf(stderr, "  -i/--indent number        - number of spaces to indent each level of XML\n");
Packit 857059
	fprintf(stderr, "                              output; default is zero\n");
Packit 857059
	fprintf(stderr, "  -X/--infile input_file    - generate XML from CSV in input_file\n");
Packit 857059
	fprintf(stderr, "  -P/--pfile param_file     - read command parameters from param_file\n");
Packit 857059
	fprintf(stderr, "  -v/--verbose              - verbose output: progress reports during generation\n");
Packit 857059
Packit 857059
	if (hFileInput && (hFileInput != stdin))
Packit 857059
		fclose(hFileInput);
Packit 857059
Packit 857059
	exit(2);
Packit 857059
}	// End of errUsage()
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * findElement()
Packit 857059
 *
Packit 857059
 * Description:
Packit 857059
 *	Find specified element in element table.
Packit 857059
 *
Packit 857059
 * Inputs:
Packit 857059
 *	pElement - Pointer to element name
Packit 857059
 *
Packit 857059
 * Outputs:
Packit 857059
 *	Index of element table containing element name, else
Packit 857059
 *	-1 - Element name not found
Packit 857059
 */
Packit 857059
int findElement(const char *pElement)
Packit 857059
{
Packit 857059
	int		ix;
Packit 857059
	int		length;
Packit 857059
Packit 857059
	length = strlen(pElement);
Packit 857059
	for (ix = 0; ix < numElementsTable; ix++)
Packit 857059
	{
Packit 857059
		if ((tbElements[ix].lenName - 1) == length)
Packit 857059
			if (!strcmp(pElement, tbElements[ix].pName))
Packit 857059
				return (ix);
Packit 857059
	}
Packit 857059
Packit 857059
	return (ERROR);
Packit 857059
Packit 857059
}	// End of findElement()
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * getRecu_opt()
Packit 857059
 *
Packit 857059
 * Description:
Packit 857059
 *	Get command line options (recursively).  Parses command line options
Packit 857059
 *	using short and long option (parameter) definitions.  Parameters (global
Packit 857059
 *	variables) are updated appropriately.  The parameter '-P param_file' which
Packit 857059
 *	takes command line options from a file is also handled.  The -P parameter
Packit 857059
 *	can be used within a parameter file; in such cases the function will call
Packit 857059
 *	itself recursively.
Packit 857059
 *
Packit 857059
 * Inputs:
Packit 857059
 *	     argc - Number of input parameters
Packit 857059
 *	     argv - Array of pointers to input parameters
Packit 857059
 *	pOptShort - Pointer to string of short option definitions
Packit 857059
 *	tbOptLong - Array of long option definitions
Packit 857059
 * 
Packit 857059
 * Outputs:
Packit 857059
 *	none
Packit 857059
 */
Packit 857059
void getRecu_opt( int argc, char ** argv, const char *pOptShort,
Packit 857059
	struct option tbOptLong[] )
Packit 857059
{
Packit 857059
	int		ix;
Packit 857059
    int		cOpt;						// Option parsing char                         
Packit 857059
	int		ixOpt;						// Option parsing index
Packit 857059
	int		lenStr;						// String length
Packit 857059
	int		argc_recu;					// Recursive argc
Packit 857059
	char	*argv_recu[MAX_PARAMS_FILE];  // Recursive argv
Packit 857059
	int		optind_recu;				// Recursive optind
Packit 857059
	char	*optarg_recu;				// Recursive optarg
Packit 857059
Packit 857059
	int		ctCharParam;				// Parameter file char count
Packit 857059
	FILE	*hFileParam = NULL;			// Parameter file handle
Packit 857059
	char	nameFileParam[MAX_FILENAME_CHARS +1];  // Parameter file name
Packit 857059
	char	bfParam[MAX_PARAM_BUF + 1];
Packit 857059
Packit 857059
	// Input command line arguments
Packit 857059
	while ((cOpt = getopt_long(argc, argv, pOptShort, tbOptLong, &ixOpt)) != -1)
Packit 857059
    {
Packit 857059
		lenStr = 0;
Packit 857059
        switch (cOpt)
Packit 857059
        {
Packit 857059
		// Verbose
Packit 857059
		case 'v':
Packit 857059
			g_verbose = 1;
Packit 857059
			break;
Packit 857059
Packit 857059
		// Generate element name specification
Packit 857059
		case 'g':
Packit 857059
		// Header element name specification
Packit 857059
		case 'h':
Packit 857059
		// End (header) element name specification
Packit 857059
		case 'e':
Packit 857059
			if (numElementsTable == MAX_ELEMENTS)
Packit 857059
			{
Packit 857059
				fprintf(stderr, NAME_PROG ": Too many Element Names\n");
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			else if (!optarg || ((lenStr = strlen(optarg) + 1) == 1))
Packit 857059
			{
Packit 857059
				fprintf(stderr, NAME_PROG ": Invalid Element Name: %s\n", optarg ? optarg:"");
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			else
Packit 857059
			{
Packit 857059
				if ( (tbElements[numElementsTable].pName = malloc(lenStr)) )
Packit 857059
				{
Packit 857059
					strcpy(tbElements[numElementsTable].pName, optarg);
Packit 857059
					tbElements[numElementsTable].lenName = lenStr;
Packit 857059
				}
Packit 857059
Packit 857059
				else
Packit 857059
				{
Packit 857059
					fprintf(stderr, NAME_PROG ": Unable to Allocate Name Memory\n");
Packit 857059
					errUsage();
Packit 857059
				}
Packit 857059
Packit 857059
				if (cOpt == 'g')
Packit 857059
					tbElements[numElementsTable++].flags |= ELEM_GENERATE;
Packit 857059
Packit 857059
				else if (cOpt == 'h')
Packit 857059
					tbElements[numElementsTable++].flags |= ELEM_HEADER;
Packit 857059
Packit 857059
				else if (cOpt == 'e')
Packit 857059
					tbElements[numElementsTable++].flags |= ELEM_END;
Packit 857059
			}
Packit 857059
Packit 857059
			break;
Packit 857059
Packit 857059
		// Delimiter string specification
Packit 857059
		case 'd':
Packit 857059
			if ( !optarg || ((lenStr = strlen(optarg)) == 0) ||
Packit 857059
					(lenStr > MAX_DELIMIT_CHARS) )
Packit 857059
			{
Packit 857059
				fprintf(stderr, NAME_PROG ": Invalid delimiter size: %d\n", lenStr);
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			strncpy(bfDelimit, optarg, MAX_DELIMIT_CHARS);
Packit 857059
			bfDelimit[MAX_DELIMIT_CHARS]=0; // Ensure null terminated
Packit 857059
			break;
Packit 857059
Packit 857059
		// Indent chars specification
Packit 857059
		case 'i':
Packit 857059
			if (FSUCCESS != StringToUint32(&numIndentChars, optarg, NULL, 0, TRUE)) {
Packit 857059
				fprintf(stderr, NAME_PROG ": Invalid indent parameter size: %d\n", lenStr);
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
			break;
Packit 857059
Packit 857059
		// Input file specification
Packit 857059
		case 'X':
Packit 857059
			if ( !optarg || ((lenStr = strlen(optarg)) == 0) ||
Packit 857059
					(lenStr > MAX_FILENAME_CHARS) )
Packit 857059
			{
Packit 857059
				fprintf(stderr, NAME_PROG ": Invalid Input File Name: %s\n", optarg ? optarg:"");
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			else if (hFileInput != stdin)
Packit 857059
			{
Packit 857059
				fprintf( stderr, NAME_PROG ": Multiple Input Files: %s and %s\n",
Packit 857059
					nameFileInput, optarg );
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			if (strcmp(optarg, "-"))
Packit 857059
			{
Packit 857059
				strncpy(nameFileInput, optarg, MAX_FILENAME_CHARS);
Packit 857059
				nameFileInput[MAX_FILENAME_CHARS]=0; // Ensure null terminated
Packit 857059
				hFileInput = fopen(nameFileInput, "r");
Packit 857059
	
Packit 857059
				if (!hFileInput)
Packit 857059
				{
Packit 857059
					fprintf( stderr, NAME_PROG ": Unable to Open Input File: %s\n",
Packit 857059
						nameFileInput );
Packit 857059
					perror("");
Packit 857059
					errUsage();
Packit 857059
				}
Packit 857059
			}
Packit 857059
Packit 857059
			break;
Packit 857059
Packit 857059
		// Parameter file specification
Packit 857059
		case 'P':
Packit 857059
			if (!optarg || ((lenStr = strlen(optarg)) == 0) ||
Packit 857059
					(lenStr > MAX_FILENAME_CHARS) )
Packit 857059
			{
Packit 857059
				fprintf(stderr, NAME_PROG ": Invalid Parameter File Name: %s\n", optarg ? optarg:"");
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			// Open parameter file
Packit 857059
			strncpy(nameFileParam, optarg,MAX_FILENAME_CHARS);
Packit 857059
			nameFileParam[MAX_FILENAME_CHARS]=0; // Ensure null terminated.
Packit 857059
			hFileParam = fopen(nameFileParam, "r");
Packit 857059
Packit 857059
			if (!hFileParam)
Packit 857059
			{
Packit 857059
				fprintf( stderr, NAME_PROG ": Unable to Open Parameter File: %s\n",
Packit 857059
					nameFileParam );
Packit 857059
				perror("");
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			// Read parameter file
Packit 857059
			if (g_verbose)
Packit 857059
				fprintf(stderr, NAME_PROG ": Reading Param File: %s\n", nameFileParam);
Packit 857059
Packit 857059
			ctCharParam = (int)fread(bfParam, 1, MAX_PARAM_BUF, hFileParam);
Packit 857059
			bfParam[MAX_PARAM_BUF-1]=0;
Packit 857059
Packit 857059
			if (ferror(hFileParam))
Packit 857059
			{
Packit 857059
				fclose(hFileParam);
Packit 857059
				fprintf(stderr, NAME_PROG ": Read Error: %s\n", nameFileParam);
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			if ((ctCharParam == MAX_PARAM_BUF) && !feof(hFileParam))
Packit 857059
			{
Packit 857059
				fclose(hFileParam);
Packit 857059
				fprintf( stderr, NAME_PROG ": Parameter file (%s) too large (> %d bytes)\n",
Packit 857059
					nameFileParam, MAX_PARAM_BUF );
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
Packit 857059
			fclose(hFileParam);
Packit 857059
Packit 857059
			if (ctCharParam > 0)
Packit 857059
			{
Packit 857059
				// Parse parameter file into tokens
Packit 857059
				argc_recu = 2;
Packit 857059
				argv_recu[0] = nameFileParam;
Packit 857059
			
Packit 857059
				for (ix = 1; ; ix++, argc_recu++)
Packit 857059
				{
Packit 857059
					if (ix == MAX_PARAMS_FILE)
Packit 857059
					{
Packit 857059
						fprintf( stderr, NAME_PROG ": Parameter file (%s) has too many parameters (> %d)\n",
Packit 857059
										nameFileParam, MAX_PARAMS_FILE );
Packit 857059
						errUsage();
Packit 857059
					}
Packit 857059
					if ( (argv_recu[ix] = strtok((ix == 1) ? bfParam : NULL, WHITE_SPACE))
Packit 857059
							== NULL )
Packit 857059
					{
Packit 857059
						argc_recu--;
Packit 857059
						break;
Packit 857059
					}
Packit 857059
Packit 857059
					if (!strncmp(argv_recu[ix], "-P", OPTION_LEN))
Packit 857059
					{
Packit 857059
						fprintf( stderr, NAME_PROG ": Parameter file (%s) cannot contain -P option\n", nameFileParam);
Packit 857059
						errUsage();
Packit 857059
					}
Packit 857059
Packit 857059
					if ( (argv_recu[ix] - bfParam + strlen(argv_recu[ix]) + 1) ==
Packit 857059
							ctCharParam )
Packit 857059
						break;
Packit 857059
Packit 857059
				}
Packit 857059
Packit 857059
				// Process parameter file parameters
Packit 857059
				if (argc_recu > 1)
Packit 857059
				{
Packit 857059
					optind_recu = optind;	// Save optind & optarg
Packit 857059
					optarg_recu = optarg;
Packit 857059
					optind = 1;   			// Init optind & optarg
Packit 857059
					optarg = NULL;
Packit 857059
					getRecu_opt(argc_recu, argv_recu, pOptShort, tbOptLong);
Packit 857059
					optind = optind_recu;	// Restore optind & optarg
Packit 857059
					optarg = optarg_recu;
Packit 857059
				}
Packit 857059
Packit 857059
			}	// End of if (ctCharParam > 0)
Packit 857059
Packit 857059
			break;
Packit 857059
Packit 857059
		// Debug trace specification
Packit 857059
		case 'Z':
Packit 857059
			if (FSUCCESS != StringToUint32(&fvDebugProg, optarg, NULL, 0, TRUE)) {
Packit 857059
				fprintf(stderr, NAME_PROG ": Invalid Debug Setting: %s\n", optarg);
Packit 857059
				errUsage();
Packit 857059
			}
Packit 857059
			break;
Packit 857059
Packit 857059
		default:
Packit 857059
			fprintf(stderr, NAME_PROG ": Invalid Option -<%c>\n", cOpt);
Packit 857059
			errUsage();
Packit 857059
			break;
Packit 857059
Packit 857059
        }	// End of switch (cOpt)
Packit 857059
Packit 857059
    }	// End of while ((cOpt = getopt_long(argc, argv,
Packit 857059
Packit 857059
	// Validate command line arguments
Packit 857059
	if (optind < argc)
Packit 857059
	{
Packit 857059
		fprintf(stderr, "%s: invalid argument %s\n", NAME_PROG, argv[optind]);
Packit 857059
		errUsage();
Packit 857059
	}
Packit 857059
Packit 857059
}	// End of getRecu_opt()
Packit 857059
Packit 857059
Packit 857059
/*******************************************************************************
Packit 857059
 *
Packit 857059
 * main()
Packit 857059
 *
Packit 857059
 * Description:
Packit 857059
 *	main function for program.
Packit 857059
 *
Packit 857059
 * Inputs:
Packit 857059
 *	argc - Number of input parameters
Packit 857059
 *	argv - Array of pointers to input parameters
Packit 857059
 *
Packit 857059
 * Outputs:
Packit 857059
 *	Exit status 0 - no errors
Packit 857059
 *	Exit status 2 - error (input parameter, resources, file I/O, XML parsing)
Packit 857059
 */
Packit 857059
int main(int argc, char ** argv)
Packit 857059
{
Packit 857059
	int		ix;							// Loop index
Packit 857059
	int		ctCharInput = 0;			// Input file char count
Packit 857059
	char	*pValue = NULL;				// Pointer to current input value
Packit 857059
	char	*pValueNext = bfInput + MAX_INPUT_BUF;  // Ptr to next input value
Packit 857059
Packit 857059
	// Initialize for generation
Packit 857059
	hFileInput = stdin;
Packit 857059
	hFileOutput = stdout;
Packit 857059
Packit 857059
	for (ix = 0; ix < MAX_ELEMENTS; ix++)
Packit 857059
	{
Packit 857059
		tbElements[ix].lenName = 0;
Packit 857059
		tbElements[ix].pName = NULL;
Packit 857059
		tbElements[ix].lenValue = 0;
Packit 857059
		tbElements[ix].pValue = NULL;
Packit 857059
		tbElements[ix].flags = 0;
Packit 857059
	}
Packit 857059
Packit 857059
	// Get and validate command line arguments
Packit 857059
	getRecu_opt(argc, argv, "vg:h:e:X:P:d:i:Z:", tbOptions);
Packit 857059
	if (numElementsTable <= 0)
Packit 857059
	{
Packit 857059
		fprintf(stderr, NAME_PROG ": No Elements Specified\n");
Packit 857059
		errUsage();
Packit 857059
	}
Packit 857059
Packit 857059
	IXmlInit(&state, hFileOutput, numIndentChars, IXML_OUTPUT_FLAG_NONE, NULL);
Packit 857059
Packit 857059
	// Output Report
Packit 857059
	strcat(bfDelimit, "\n");			// Append New Line to bfDelimit
Packit 857059
Packit 857059
	for (ix = 0; ; )
Packit 857059
	{
Packit 857059
		// Generate element
Packit 857059
		if (tbElements[ix].flags & ELEM_GENERATE)
Packit 857059
		{
Packit 857059
			// Check for end of bfInput
Packit 857059
			if ( ((pValueNext - bfInput) > (MAX_INPUT_BUF >> 1)) &&
Packit 857059
					!feof(hFileInput) )
Packit 857059
			{
Packit 857059
				// Shift bfInput[] and read input file
Packit 857059
				memmove(bfInput, pValueNext, MAX_INPUT_BUF + bfInput - pValueNext);
Packit 857059
Packit 857059
				if (g_verbose)
Packit 857059
					fprintf( stderr, NAME_PROG ": Reading Input File: %s\n",
Packit 857059
						nameFileInput );
Packit 857059
Packit 857059
				ctCharInput = MAX_INPUT_BUF + bfInput - pValueNext +
Packit 857059
                    (int)fread( bfInput + MAX_INPUT_BUF - pValueNext + bfInput,
Packit 857059
                    1, pValueNext - bfInput, hFileInput );
Packit 857059
				pValueNext = bfInput;
Packit 857059
Packit 857059
				if (ferror(hFileInput))
Packit 857059
				{
Packit 857059
					fprintf(stderr, NAME_PROG ": Read Error: %s\n", nameFileInput);
Packit 857059
					errUsage();
Packit 857059
				}
Packit 857059
			}
Packit 857059
Packit 857059
			// Check for end of input file
Packit 857059
			if ((pValueNext - bfInput) >= ctCharInput)
Packit 857059
			{
Packit 857059
				fprintf( stderr,
Packit 857059
			NAME_PROG ": WARNING End of Input file (%s) before End of Element List (%d items)\n",
Packit 857059
						nameFileInput, numElementsTable );
Packit 857059
				g_exitstatus = 2;
Packit 857059
				break;
Packit 857059
			}
Packit 857059
Packit 857059
			/* strtok() skips over multiple consecutive delimiters as a group;
Packit 857059
			   the following causes a NULL element value to be processed if 2
Packit 857059
			   consecutive delimiters are encountered.
Packit 857059
			*/
Packit 857059
			if (!strchr(bfDelimit, *pValueNext))
Packit 857059
			{
Packit 857059
				pValue = strtok(pValueNext, bfDelimit);
Packit 857059
				if (!pValue) 
Packit 857059
				{
Packit 857059
					fprintf( stderr,
Packit 857059
						NAME_PROG ": WARNING Malformed Input file (%s) strtok() error.\n",
Packit 857059
						nameFileInput);
Packit 857059
					break;
Packit 857059
				}
Packit 857059
				dispElementRecord(&tbElements[ix++], pValue);
Packit 857059
				pValueNext = pValue + strlen(pValue) + 1;
Packit 857059
			}
Packit 857059
Packit 857059
			else
Packit 857059
			{
Packit 857059
				dispElementRecord(&tbElements[ix++], NULL);
Packit 857059
				pValueNext += 1;
Packit 857059
			}
Packit 857059
		}
Packit 857059
Packit 857059
		// Header or Header End element
Packit 857059
		else
Packit 857059
			dispElementRecord(&tbElements[ix++], NULL);
Packit 857059
Packit 857059
		// Check for end of tbElements[]
Packit 857059
		if (ix >= numElementsTable)
Packit 857059
		{
Packit 857059
			if ((pValueNext - bfInput) < ctCharInput)
Packit 857059
				ix = 0;					// Wrap to beg of tbElements[]
Packit 857059
Packit 857059
			else						// End of report
Packit 857059
				break;
Packit 857059
		}
Packit 857059
Packit 857059
	}	// End of for (ix = 0; ; )
Packit 857059
Packit 857059
	if (hFileInput && (hFileInput != stdin))
Packit 857059
		fclose(hFileInput);
Packit 857059
Packit 857059
	return (g_exitstatus);
Packit 857059
Packit 857059
}	// End of main()
Packit 857059
Packit 857059
Packit 857059
// End of file
Packit 857059