17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
22*9585STim.Szeto@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #ifndef	_CMDPARSE_H
277836SJohn.Forte@Sun.COM #define	_CMDPARSE_H
287836SJohn.Forte@Sun.COM 
297836SJohn.Forte@Sun.COM #ifdef	__cplusplus
307836SJohn.Forte@Sun.COM extern "C" {
317836SJohn.Forte@Sun.COM #endif
327836SJohn.Forte@Sun.COM 
337836SJohn.Forte@Sun.COM #include <getopt.h>
347836SJohn.Forte@Sun.COM 
357836SJohn.Forte@Sun.COM #define	SUBCOMMAND_BASE  1
367836SJohn.Forte@Sun.COM 
377836SJohn.Forte@Sun.COM /* bit defines for operand macros */
387836SJohn.Forte@Sun.COM #define	OPERAND_SINGLE		0x2
397836SJohn.Forte@Sun.COM #define	OPERAND_MULTIPLE	0x4
407836SJohn.Forte@Sun.COM #define	OPERAND_MANDATORY	0x8
417836SJohn.Forte@Sun.COM #define	OPERAND_OPTIONAL	0x10
427836SJohn.Forte@Sun.COM 
437836SJohn.Forte@Sun.COM /* maximum length of an option argument */
447836SJohn.Forte@Sun.COM #define	MAXOPTARGLEN   256
457836SJohn.Forte@Sun.COM 
467836SJohn.Forte@Sun.COM 
477836SJohn.Forte@Sun.COM /* Following are used to express operand requirements */
487836SJohn.Forte@Sun.COM #define	OPERAND_NONE		    0x1
497836SJohn.Forte@Sun.COM #define	OPERAND_MANDATORY_SINGLE    (OPERAND_MANDATORY | OPERAND_SINGLE)
507836SJohn.Forte@Sun.COM #define	OPERAND_OPTIONAL_SINGLE	    (OPERAND_OPTIONAL | OPERAND_SINGLE)
517836SJohn.Forte@Sun.COM #define	OPERAND_MANDATORY_MULTIPLE  (OPERAND_MANDATORY | OPERAND_MULTIPLE)
527836SJohn.Forte@Sun.COM #define	OPERAND_OPTIONAL_MULTIPLE   (OPERAND_OPTIONAL | OPERAND_MULTIPLE)
537836SJohn.Forte@Sun.COM 
547836SJohn.Forte@Sun.COM /* subcommands must have a single bit on and must have exclusive values */
557836SJohn.Forte@Sun.COM #define	SUBCOMMAND(x)  (SUBCOMMAND_BASE << x)
567836SJohn.Forte@Sun.COM 
577836SJohn.Forte@Sun.COM /*
587836SJohn.Forte@Sun.COM  * This structure is passed into the caller's callback function and
597836SJohn.Forte@Sun.COM  * will contain a list of all options entered and their associated
607836SJohn.Forte@Sun.COM  * option arguments if applicable
617836SJohn.Forte@Sun.COM  */
627836SJohn.Forte@Sun.COM typedef struct _cmdOptions {
637836SJohn.Forte@Sun.COM 	int optval;
647836SJohn.Forte@Sun.COM 	char optarg[MAXOPTARGLEN + 1];
657836SJohn.Forte@Sun.COM } cmdOptions_t;
667836SJohn.Forte@Sun.COM 
677836SJohn.Forte@Sun.COM /*
687836SJohn.Forte@Sun.COM  * subcommand callback function
697836SJohn.Forte@Sun.COM  *
707836SJohn.Forte@Sun.COM  * argc - number of arguments in argv
717836SJohn.Forte@Sun.COM  * argv - operand arguments
727836SJohn.Forte@Sun.COM  * options - options entered on command line
737836SJohn.Forte@Sun.COM  * callData - pointer to caller data to be passed to subcommand function
747836SJohn.Forte@Sun.COM  */
757836SJohn.Forte@Sun.COM typedef int (*handler_t)(int argc, char *argv[], cmdOptions_t *options,
767836SJohn.Forte@Sun.COM     void *callData);
777836SJohn.Forte@Sun.COM 
787836SJohn.Forte@Sun.COM /*
797836SJohn.Forte@Sun.COM  * list of subcommands and associated properties
807836SJohn.Forte@Sun.COM  *
817836SJohn.Forte@Sun.COM  * name -> subcommand name
827836SJohn.Forte@Sun.COM  * handler -> function to call on successful syntax check
837836SJohn.Forte@Sun.COM  * optionString -> short options that are valid
847836SJohn.Forte@Sun.COM  * required -> Does it require at least one option?
857836SJohn.Forte@Sun.COM  * exclusive -> short options that are required to be exclusively entered
867836SJohn.Forte@Sun.COM  * operand -> Type of operand input. Can be:
877836SJohn.Forte@Sun.COM  *
887836SJohn.Forte@Sun.COM  *		NO_OPERAND
897836SJohn.Forte@Sun.COM  *		OPERAND_MANDATORY_SINGLE
907836SJohn.Forte@Sun.COM  *		OPERAND_OPTIONAL_SINGLE
917836SJohn.Forte@Sun.COM  *		OPERAND_MANDATORY_MULTIPLE
927836SJohn.Forte@Sun.COM  *		OPERAND_OPTIONAL_MULTIPLE
937836SJohn.Forte@Sun.COM  *
947836SJohn.Forte@Sun.COM  * operandDefinition -> char * definition of the operand
957836SJohn.Forte@Sun.COM  *
967836SJohn.Forte@Sun.COM  * The long options table specifies whether an option argument is required.
977836SJohn.Forte@Sun.COM  *
987836SJohn.Forte@Sun.COM  *
997836SJohn.Forte@Sun.COM  * EXAMPLE:
1007836SJohn.Forte@Sun.COM  *
1017836SJohn.Forte@Sun.COM  * Based on "list-target" entry below:
1027836SJohn.Forte@Sun.COM  *
1037836SJohn.Forte@Sun.COM  *  "list-target" is expected as the subcommand input
1047836SJohn.Forte@Sun.COM  *  listTarget is the function to be called on success
1057836SJohn.Forte@Sun.COM  *  "list-target" accepts -i, -s, -t and -l
1067836SJohn.Forte@Sun.COM  *  "list-target" requires the option 'i'.
1077836SJohn.Forte@Sun.COM  *  "list-target" has no exclusive options
1087836SJohn.Forte@Sun.COM  *  "list-target" may have one or more operands
1097836SJohn.Forte@Sun.COM  *  "list-target" operand description is "target-name"
1107836SJohn.Forte@Sun.COM  *
1117836SJohn.Forte@Sun.COM  *
1127836SJohn.Forte@Sun.COM  *	optionRules_t optionRules[] = {
1137836SJohn.Forte@Sun.COM  *	    {"list-target", listTarget, "istl", "i", NULL,
1147836SJohn.Forte@Sun.COM  *		OPERAND_OPTIONAL_MULTIPLE, "target-name"},
1157836SJohn.Forte@Sun.COM  *	    {"modify-target", modifyTarget, "t", "t", NULL,
1167836SJohn.Forte@Sun.COM  *		OPERAND_MANDATORY_MULTIPLE, "target-name"},
1177836SJohn.Forte@Sun.COM  *	    {"enable", enable, NULL, NULL, NULL, NO_OPERAND, NULL},
1187836SJohn.Forte@Sun.COM  *	    {NULL, 0, 0, NULL, 0, NULL}
1197836SJohn.Forte@Sun.COM  *	};
1207836SJohn.Forte@Sun.COM  */
1217836SJohn.Forte@Sun.COM typedef struct _subCommandProps {
1227836SJohn.Forte@Sun.COM 	char *name;
1237836SJohn.Forte@Sun.COM 	handler_t handler;
1247836SJohn.Forte@Sun.COM 	char *optionString;
1257836SJohn.Forte@Sun.COM 	char *required;
1267836SJohn.Forte@Sun.COM 	char *exclusive;
1277836SJohn.Forte@Sun.COM 	int operand;
1287836SJohn.Forte@Sun.COM 	char *operandDefinition;
129*9585STim.Szeto@Sun.COM 	char *helpText;
130*9585STim.Szeto@Sun.COM 	uint8_t reserved[60];
1317836SJohn.Forte@Sun.COM } subCommandProps_t;
1327836SJohn.Forte@Sun.COM 
1337836SJohn.Forte@Sun.COM 
1347836SJohn.Forte@Sun.COM 
1357836SJohn.Forte@Sun.COM #define	required_arg	required_argument
1367836SJohn.Forte@Sun.COM #define	no_arg		no_argument
1377836SJohn.Forte@Sun.COM 
1387836SJohn.Forte@Sun.COM /*
1397836SJohn.Forte@Sun.COM  * Add short options and long options here
1407836SJohn.Forte@Sun.COM  *
1417836SJohn.Forte@Sun.COM  *  name -> long option name
1427836SJohn.Forte@Sun.COM  *  has_arg -> required_arg, no_arg
1437836SJohn.Forte@Sun.COM  *  val -> short option character
1447836SJohn.Forte@Sun.COM  *  argDesc -> description of option argument
1457836SJohn.Forte@Sun.COM  *
1467836SJohn.Forte@Sun.COM  * Note: This structure may not be used if your CLI has no
1477836SJohn.Forte@Sun.COM  * options. However, -?, --help and -V, --version will still be supported
1487836SJohn.Forte@Sun.COM  * as they are standard for every CLI.
1497836SJohn.Forte@Sun.COM  *
1507836SJohn.Forte@Sun.COM  * EXAMPLE:
1517836SJohn.Forte@Sun.COM  *
1527836SJohn.Forte@Sun.COM  *	optionTbl_t options[] = {
1537836SJohn.Forte@Sun.COM  *	    {"filename", arg_required, 'f', "out-filename"},
1547836SJohn.Forte@Sun.COM  *	    {NULL, 0, 0}
1557836SJohn.Forte@Sun.COM  *	};
1567836SJohn.Forte@Sun.COM  *
1577836SJohn.Forte@Sun.COM  */
1587836SJohn.Forte@Sun.COM typedef struct _optionTbl {
1597836SJohn.Forte@Sun.COM 	char *name;
1607836SJohn.Forte@Sun.COM 	int has_arg;
1617836SJohn.Forte@Sun.COM 	int val;
1627836SJohn.Forte@Sun.COM 	char *argDesc;
1637836SJohn.Forte@Sun.COM } optionTbl_t;
1647836SJohn.Forte@Sun.COM 
1657836SJohn.Forte@Sun.COM /*
1667836SJohn.Forte@Sun.COM  * After tables are set, assign them to this structure
1677836SJohn.Forte@Sun.COM  * for passing into cmdparse()
1687836SJohn.Forte@Sun.COM  */
1697836SJohn.Forte@Sun.COM typedef struct _synTables {
1707836SJohn.Forte@Sun.COM 	char *versionString;
1717836SJohn.Forte@Sun.COM 	optionTbl_t *longOptionTbl;
1727836SJohn.Forte@Sun.COM 	subCommandProps_t *subCommandPropsTbl;
1737836SJohn.Forte@Sun.COM } synTables_t;
1747836SJohn.Forte@Sun.COM 
1757836SJohn.Forte@Sun.COM /*
1767836SJohn.Forte@Sun.COM  * cmdParse is a parser that checks syntax of the input command against
1777836SJohn.Forte@Sun.COM  * rules and property tables.
1787836SJohn.Forte@Sun.COM  *
1797836SJohn.Forte@Sun.COM  * When syntax is successfully validated, the function associated with the
1807836SJohn.Forte@Sun.COM  * subcommand is called using the subcommands table functions.
1817836SJohn.Forte@Sun.COM  *
1827836SJohn.Forte@Sun.COM  * Syntax for the command is as follows:
1837836SJohn.Forte@Sun.COM  *
1847836SJohn.Forte@Sun.COM  *	command [options] subcommand [<options>] [<operand ...>]
1857836SJohn.Forte@Sun.COM  *
1867836SJohn.Forte@Sun.COM  *
1877836SJohn.Forte@Sun.COM  * There are two standard short and long options assumed:
1887836SJohn.Forte@Sun.COM  *	-?, --help	Provides usage on a command or subcommand
1897836SJohn.Forte@Sun.COM  *			and stops further processing of the arguments
1907836SJohn.Forte@Sun.COM  *
1917836SJohn.Forte@Sun.COM  *	-V, --version	Provides version information on the command
1927836SJohn.Forte@Sun.COM  *			and stops further processing of the arguments
1937836SJohn.Forte@Sun.COM  *
1947836SJohn.Forte@Sun.COM  *	These options are loaded by this function.
1957836SJohn.Forte@Sun.COM  *
1967836SJohn.Forte@Sun.COM  * input:
1977836SJohn.Forte@Sun.COM  *  argc, argv from main
1987836SJohn.Forte@Sun.COM  *  syntax rules tables (synTables_t structure)
1997836SJohn.Forte@Sun.COM  *  callArgs - void * passed by caller to be passed to subcommand function
2007836SJohn.Forte@Sun.COM  *
2017836SJohn.Forte@Sun.COM  * output:
2027836SJohn.Forte@Sun.COM  *  funcRet - pointer to int that holds subcommand function return value
2037836SJohn.Forte@Sun.COM  *
2047836SJohn.Forte@Sun.COM  * Returns:
2057836SJohn.Forte@Sun.COM  *
2067836SJohn.Forte@Sun.COM  *     zero on successful syntax parse and function call
2077836SJohn.Forte@Sun.COM  *
2087836SJohn.Forte@Sun.COM  *     1 on unsuccessful syntax parse (no function has been called)
2097836SJohn.Forte@Sun.COM  *		This could be due to a version or help call or simply a
2107836SJohn.Forte@Sun.COM  *		general usage call.
2117836SJohn.Forte@Sun.COM  *
2127836SJohn.Forte@Sun.COM  *     -1 check errno, call failed
2137836SJohn.Forte@Sun.COM  *
2147836SJohn.Forte@Sun.COM  */
2157836SJohn.Forte@Sun.COM int cmdParse(int numOperands, char *operands[], synTables_t synTables,
2167836SJohn.Forte@Sun.COM     void *callerArgs, int *funcRet);
2177836SJohn.Forte@Sun.COM 
2187836SJohn.Forte@Sun.COM #ifdef	__cplusplus
2197836SJohn.Forte@Sun.COM }
2207836SJohn.Forte@Sun.COM #endif
2217836SJohn.Forte@Sun.COM 
2227836SJohn.Forte@Sun.COM #endif	/* _CMDPARSE_H */
223