/**
 * @file FLUCUP.h
 * @brief Specification for the FLUC subprogram interface
 * @author limes datentechnik gmbh
 * @date 18.02.2015\n
 * @copyright (c) 2014 limes datentechnik gmbh
 *
 * @mainpage FLUC Subprogram Interface
 *
 * This interface provides all FLCL commands (<code>CONV</code>,
 * <code>XCNV</code>, ...) as simple to use programming interface.
 * It is based on the Frankenstein Limes Universal Converter (FLUC).
 *
 * The programming interface can be used to integrate the source (file)
 * to target (file) data conversion capabilities provided by FLUC into
 * a custom program.
 *
 * Additionally, it provides interactive help, documentation, syntax
 * and other information to support the use of the commands.
 *
 * This interface is also provided as load module interface for COBOL,
 * PL1 and other languages. The corresponding load module interface is
 * called FLUCUPLB.
 *
 * @section ITFSTD Interface standards
 * For each command, there is a function that accepts a command line
 * and property file string that follows the FLCL syntax and produces
 * the same return/condition code as the FLCL. If the command string
 * starts with an <code>=</code> sign, then a parameter filename must
 * follow. The file is expected to contain the actual command string:
 *
 * <pre>
 * r=flucconv("=para.txt",NULL,":STDERR",NULL);
 * </pre>
 *
 * corresponds to:
 *
 * <pre>
 * FLCL CONV=para.txt
 * </pre>
 *
 * As second parameter you can provide a property file (NULL means no
 * properties). The third parameter controls the print outs. If you
 * define for a command, then no printouts are done. Normally ":STDERR"
 * is used for printouts, but you can also define ":STDOUT" or a file
 * name. The last parameter is optional and activates the trace output.
 *
 * For output files you can define ":STDERR" or ":STDOUT" to assign the
 * corresponding streams.
 *
 * @section PROPERTIES Properties
 * The property file string is parsed before the command line string.
 * The property string may contain command properties in the property
 * file syntax of FLCL. You can provide the contents of a property
 * file from an arbitrary source via the property string. To generate
 * a property file you can use:
 *
 * <pre>
 * FLCL GENPROP CONV=filename
 * (works for any command by replacing CONV with the right command)
 * </pre>
 *
 * You can also provide the filename of a property file by passing an
 * <code>=</code> sign followed by the filename. Properties are then
 * read from that file:
 *
 * <pre>
 * r=flucconv("=para.txt","=prop.txt",NULL,NULL);
 * </pre>
 *
 * To use FLCL property files, the program name must still be the
 * default "flcl". If you write a program which is not compatible to
 * FLCL, please set another program name (see next section). To manage
 * the contents of a property file, the function #flucpro() is provided.
 *
 * @subsection PGMOWN Program and owner names
 * The program and owner name can be managed by the corresponding functions.
 * The default program name is "flcl". The default owner name is "limes". The
 * default values are used, if a NULL pointer or an empty string is passed.
 * The owner id and program name are limited to 64 bytes, including the null
 * termination. Longer names are ignored.
 *
 * @section ENVVAR Environment variables
 * For all default character conversions, it is useful to set the environment
 * variable LANG. Other used environment variables of FLAM can be found
 * in the FLCL manual. With version 5.1.19 a new function (#flucenv()) to
 * load the FLAM environment was introduced. This function can be used
 * in front of the first API call to establish the same environment
 * used by FLAM utilities, subsystems and so on. This give the application
 * developer the possibility to adjust the environment before the first
 * real call is done. Till 5.1.18 each function has read the system
 * variables on z/OS. This is now part of the #flucenv() function to give
 * complete control about the environment to the user of the API.
 *
 * @section CONDCODE Condition codes
 * The return codes of the subprogram are called condition codes and are
 * returned on subprogram termination.
 *
 * * 0  - command line, command syntax, mapping, execution and finish of the command was successful
 * * 1  - command line, command syntax, mapping, execution and finish of the command was successful but a warning can be found in the log
 * * 2  - command line, command syntax, mapping, execution was successful but cleanup of the command failed (may not happened)
 * * 4  - command line, command syntax and mapping was successful but execution of the command returns with a warning
 * * 8  - command line, command syntax and mapping was successful but execution of the command returns with an error
 * * 12 - command line and command syntax was OK but mapping failed
 * * 16 - command line was OK but command syntax was wrong
 * * 20 - command line was wrong (user error)
 * * 24 - initialization of parameter structure of the command failed (may not happened)
 * * 28 - configuration is wrong (user error)
 * * 32 - table error (something within the predefined tables is wrong)
 * * 36 - system error (e.g. load of environment or open of file failed)
 * * 40 - access control or license error
 * * 44 - interface error (e.g. parameter pointer equals NULL)
 * * 48 - memory allocation failed (e.g. dynamic string handling)
 * * 64 - fatal error (basic things are damaged)
 * * >64 - for few special conditions codes (see FLCLBOOK)
 *
 * Special condition codes can be found in the FLCL manual (FLCLBOOK).
 *
 * @section RSNCODE Reason codes
 * The reason code (internal FLAM return code) can be determined by
 * calling the function #flucrsn(). A corresponding text message is
 * returned by the function #flucmsg().
 * All FLAM reason codes are listed in FLCL manual (FLCLBOOK).
 *
 * @section SAMPLE Sample programs
 * Sample programs in C with name SCFCUCNV/GZP/LST/REM can be found as part of the
 * installation package for mainframe systems in the library SRCLIBC(SCFCUxxx),
 * with the corresponding compile and link step in JOBLIB(SBUILD).
 * For other platforms (Windows, UNIX) the sample program source of SCFCUCNV/GZP/LST/REM
 * is located in the <code>sample</code> directory. The compile and
 * link procedures can be found in the Makefile of the same directory.
 *
 **********************************************************************/

/*! @cond PRIVATE */
#ifdef __cplusplus
   extern "C" {
#endif

#ifndef INC_FLUCUP_H
#define INC_FLUCUP_H
/*! @endcond */

/**********************************************************************/
/**
 * @defgroup FCUFUC FLUC Function Codes
 *  Pass one of this to #fluchlp(), #flucsyn(), #flucdoc() or #flucpro() to get
 *  information about the corresponding command.
 *  @{
 */
#define FLUC_INFO                   1 /**< @brief INFO command */
#define FLUC_CONV                   2 /**< @brief CONV command */
#define FLUC_XCNV                   3 /**< @brief XCNV command */
#define FLUC_ICNV                   4 /**< @brief ICNV command */
#define FLUC_FLAM                   5 /**< @brief FLAM command */
#define FLUC_XCHK                   6 /**< @brief XCHK command */
#define FLUC_HASH                   7 /**< @brief HASH command */
#define FLUC_UTIL                   8 /**< @brief UTIL command */
#define FLUC_DIFF                   9 /**< @brief DIFF command */
#define FLUC_KEY                   10 /**< @brief KEY command  */
#define FLUC_GREP                  11 /**< @brief GREP command  */
/** @} */
/**********************************************************************/
/**
 * @defgroup FUNC Functions
* @{
*/

/**
 *  @brief Version
 *
 * This function returns a string with version information for each
 * used component. This should be used in a support case.
 *
 * @return a pointer to a static area containing the zero-terminated
 *         version string
 */
extern const char*   flucvsn(void);

/**
 *  @brief About
 *
 * This function returns a string with about information for this
 * library on multiple lines and license information for used external
 * libraries.
 *
 * @return a pointer to a static area containing the zero-terminated
 *         about string
 */
extern const char*   flucabo(void);

/**
 *  @brief Get license text
 *
 * This function can be used to get the current license text on multiple
 * lines. The license text defines the permissible use of this library.
 *
 * @return a pointer to a static area with a zero-terminated string
 *         containing the current license text.
 */
extern const char*   fluclic(void);

/**
 *  @brief Set/Get owner id
 *
 * This function can be used to get (pcOwn==NULL) or to set the current
 * owner id. The owner id is a logical qualifier to separate different
 * configurations for different clients in the same property file. If you
 * want use a configuration for another owner as "limes", then you must
 * define the owner id with this function first.
 *
 * @param [in] own   Define owner name (DEFAULT: "limes")
 * @return a pointer to a static area with a zero-terminated string
 *         containing the current owner id.
 */
extern const char* flucown(const char* own);

/**
 *  @brief Set/Get program name
 *
 * This function can be used to get (pcPgm==NULL) or to set ("mypg") the
 * current program name. If you implement an own property management or
 * a program which does not conform to the FLCL infrastructure components,
 * it might be useful to change the program name.
 *
 * @param [in] pgm   Define program name (DEFAULT: "flcl")
 * @return a pointer to a static area with a zero-terminated string
 *         containing the current program name.
 */
extern const char* flucpgm(const char* pgm);

/**
 * @brief Load the FLAM environment
 *
 * This function load the FLAM system variables (only on z/OS or in EDZ
 * environment), the STDENV definitions ('DD:STDENV' or '\<SYSUID>.STDENV'
 * on z/OS or '.stdenv' file in working or home directory on other system)
 * and a optional list if variables to the environment. You can adjust the
 * environment before the first call to a FLAM API function is done. This
 * function gives the possibility to work with the same environment used
 * by FLAM utilities, subsystems, etc.
 *
 * @param[in] sys True to load system variables,
 *                false no system variables active
 * @param[in] std True to load standard environment,
 *                false no standard environment variables active
 * @param[in] env Optional list (could be NULL or empty) of environment
 *                variables (KEYWORD=VALUE) separated by new line ('\\n') or semicolon (';')
 * @return negative (<0) error else (>=0) amount of environment variable load
 */
extern int flucenv(const int sys, const int std, const char* env);

/**
 *  @brief FLUC INFO - Provides various information
 *
 * This function calls the INFO command of FLUC
 *
 * Examples: e=flucinfo("get.file='test.gz'",NULL,NULL,NULL);
 *
 * @param [in] cmd   Command string with GET and LOG instructions (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with GET and LOG instructions (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then stderr is used)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucinfo(const char* cmd, const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC HASH - Simplified Hash calculation
 *
 * This function calls the HASH command of FLUC
 *
 * Examples: e=fluchash("file='test.gz' algo=md5",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with FILE and LOG instructions (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with FILE and LOG instructions (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int fluchash(const char* cmd, const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC CONV - Simplified data conversion
 *
 * This function calls the CONV command of FLUC
 *
 * Examples: e=flucconv("read.text(file='test.txt') write.record()",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with READ, WRITE and LOG instructions (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with READ, WRITE and LOG instructions (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucconv(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC XCNV - Extended data conversion
 *
 * This function calls the XCNV command of FLUC
 *
 * Examples: e=flucxcnv("inp(sav.fil(fio.blk(name='test.txt') cnv.chr(from='IBM-1141' to='UTF-8') fmt.txt())) out(sav.fil(fio.blk(name='test.out')))",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with INP, OUT and LOG instructions (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with INP, OUT and LOG instructions (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucxcnv(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC XCHK - Extended data evalation
 *
 * This function calls the XCHK command of FLUC
 *
 * Examples: e=flucxchk("inp(sav.fil(fio.blk(name='test.txt') cnv.hsh() ))",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with INP and LOG instructions (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with INP and LOG instructions (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucxchk(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC GREP - Matching pattern in files like GREP
 *
 * This function calls the GREP command of FLUC
 *
 * Examples: e=flucgrep("input='wrt*.txt' pattern='^Abfall'",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with GREP parameter (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with GREP parameter (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucgrep(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC ICNV - Character conversion like ICONV
 *
 * This function calls the ICNV command of FLUC
 *
 * Examples: e=flucicnv("in='test.txt' from='IBM-1141' to='UTF-8' ENL2LF out='test.out'",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with ICONV parameter (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with ICONV parameter (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucicnv(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC FLAM - Support of FLAM4 command in FLUC
 *
 * This function calls the FLAM command of FLUC
 *
 * Examples: e=flucflam("comp flamin='test.txt' flamfile='test.fla' inrecformat=undefined",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with FLAM parameter (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with FLAM parameter (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucflam(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC UTIL - Support of several utility function
 *
 * This function calls the UTIL command of FLUC
 *
 * Examples: e=flucutil("run.remove='~.test.**'",NULL,NULL,NULL);
 *
 * @param [in] cmd   Command string with UTIL parameter (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with UTIL parameter (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucutil(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 *  @brief FLUC DIFF - Compares two data sources
 *
 * This function calls the DIFF command of FLUC
 *
 * Examples: e=flucdiff("read.file'./test.txt.gz' compare.file='~.test.fba'",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with DIFF parameter (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with DIFF parameter (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int flucdiff(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 * @brief FLUC KEY - Key management functions
 *
 * This function calls the KEY command of FLUC
 *
 * Examples: e=fluckey("import.pgp(file='keyFile.gpg')",NULL,":STDERR",NULL);
 *
 * @param [in] cmd   Command string with KEY parameter (if starts with '=', a parameter file containing the command string must follow)
 * @param [in] pro   Property string with KEY parameter (can be empty or NULL)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 * @param [in] trc   Filename for tracing (if NULL or empty then no trace is written)
 * @return signed integer with condition code for the command\n
 */
extern int fluckey(const char* cmd,const char* pro,const char* out, const char* trc);

/**
 * @brief Get reason code
 *
 * This function return the reason code (internal FLAM error code) if a call to a FLUC command fails.
 *
 * @return signed integer with internal FLAM reason code
 */
extern int flucrsn(void);

/**
 * @brief Get a message for a reason code
 *
 * @param [in] rsn Signed integer containing the reason code
 * @return a pointer to a static area with a zero-terminated string
 *         containing the error message for that reason code.
 */
extern const char* flucmsg(const int rsn);

/**
 *  @brief Returns help information about the command string
 *
 * This function can be used to get all help messages or man pages for
 * each parameter in the command string. If depth 0 or greater then 9
 * aliases are provided. In all other cases aliases are suppressed.
 * Please use #flucsyn() to see possible aliases for the same argument.
 *
 * @param [in] what  Integer constant for the corresponding command string (FLUC_CONV or FLUC_XCNV or ...)
 * @param [in] depth Number of levels to display (0-Man page, 1-One Level, 2-Two Level, ..., <9-All)
 * @param [in] path  Path (e.g. conv.read.text.ccsid) to limit help to the (sub)tree of a certain object
 * @param [in] out   Filename for printouts (if NULL or empty then stderr is used)
 */
extern void fluchlp(const int what, const int depth, const char* path, const char* out);

/**
 *  @brief Return syntax information about the command string
 *
 * This function can be used to determine the complete syntax of the
 * command strings.
 *
 * @param [in] what  Integer constant for the corresponding command string (FLUC_CONV or FLUC_XCNV or ...)
 * @param [in] depth Number of levels to display (0-Man page, 1-One Level, 2-Two Level, ..., <9-All)
 * @param [in] path  Path (e.g. conv.read.text.ccsid) to limit syntax to the (sub)tree of a certain object
 * @param [in] out   Filename for printouts (if NULL or empty then stderr is used)
 */
extern void flucsyn(const int what, const int depth, const char* path, const char* out);

/**
 *  @brief Return documentation
 *
 * This function can be used to determine the complete documentation of the
 * corresponding command.
 *
 * @param [in] what  Integer constant for the corresponding command string (FLUC_CONV or FLUC_XCNV or ...)
 * @param [in] path  Path (e.g. conv.read.text.ccsid) to limit docu to the (sub)tree of a certain object
 * @param [in] out   Filename for printouts (if NULL or empty then stderr is used)
 */
extern void flucdoc(const int what, const char* path, const char* out);

/**
 *  @brief Manage properties
 *
 * This function can be used to manage a property file for one of the
 * supported commands. You can generate a property file if 'ipro' NULL
 * and 'opro' defined. You can printout the properties if 'ipro' defined
 * and 'opro' is NULL. You can validate and copy property files if 'ipro'
 * and 'opro' defined. You can adjust a property file if 'ipro' defined,
 * 'prop' are used and 'opro' set.
 *
 * @param [in] what  Integer constant for the corresponding command (FLUC_CONV or FLUC_XCNV or ...)
 * @param [in] ipro  Property file to read (if NULL or empty then then no property file is read)
 * @param [in] prop  Property string to manipulate the current properties (if NULL or empty then no update is done)
 * @param [in] opro  Property file to write (if NULL or empty then stdout is used)
 * @param [in] out   Filename for printouts (if NULL or empty then is no printout produced)
 */
extern void flucpro(const int what, const char* ipro, const char* prop, const char* opro, const char* out);

/** @} */
/******************************************************************************/
/*! @cond PRIVATE */
/*TODO: FLM5UP.h*/
extern int flamxcmp(const char* cmd,const char* pro,const char* out, const char* trc);
extern int flamxdco(const char* cmd,const char* pro,const char* out, const char* trc);
extern int flamxcmp2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flamxdco2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);

extern int flucinfo2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flucconv2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flucgrep2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flucxcnv2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flucicnv2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flucflam2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flucxchk2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int fluchash2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flucdiff2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int flucutil2(const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);
extern int fluckey2( const char* cmd,const char* pro,const char* out, const char* trc,const unsigned int per);

#endif /* INC_FLUCUP_H */

#ifdef __cplusplus
   }
#endif
/*! @endcond */
