|
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 |
|