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