1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte #ifndef _CMDPARSE_H 27*fcf3ce44SJohn Forte #define _CMDPARSE_H 28*fcf3ce44SJohn Forte 29*fcf3ce44SJohn Forte #ifdef __cplusplus 30*fcf3ce44SJohn Forte extern "C" { 31*fcf3ce44SJohn Forte #endif 32*fcf3ce44SJohn Forte 33*fcf3ce44SJohn Forte #include <getopt.h> 34*fcf3ce44SJohn Forte 35*fcf3ce44SJohn Forte #define SUBCOMMAND_BASE 1 36*fcf3ce44SJohn Forte 37*fcf3ce44SJohn Forte /* bit defines for operand macros */ 38*fcf3ce44SJohn Forte #define OPERAND_SINGLE 0x2 39*fcf3ce44SJohn Forte #define OPERAND_MULTIPLE 0x4 40*fcf3ce44SJohn Forte #define OPERAND_MANDATORY 0x8 41*fcf3ce44SJohn Forte #define OPERAND_OPTIONAL 0x10 42*fcf3ce44SJohn Forte 43*fcf3ce44SJohn Forte /* maximum length of an option argument */ 44*fcf3ce44SJohn Forte #define MAXOPTARGLEN 256 45*fcf3ce44SJohn Forte 46*fcf3ce44SJohn Forte 47*fcf3ce44SJohn Forte /* Following are used to express operand requirements */ 48*fcf3ce44SJohn Forte #define OPERAND_NONE 0x1 49*fcf3ce44SJohn Forte #define OPERAND_MANDATORY_SINGLE (OPERAND_MANDATORY | OPERAND_SINGLE) 50*fcf3ce44SJohn Forte #define OPERAND_OPTIONAL_SINGLE (OPERAND_OPTIONAL | OPERAND_SINGLE) 51*fcf3ce44SJohn Forte #define OPERAND_MANDATORY_MULTIPLE (OPERAND_MANDATORY | OPERAND_MULTIPLE) 52*fcf3ce44SJohn Forte #define OPERAND_OPTIONAL_MULTIPLE (OPERAND_OPTIONAL | OPERAND_MULTIPLE) 53*fcf3ce44SJohn Forte 54*fcf3ce44SJohn Forte /* subcommands must have a single bit on and must have exclusive values */ 55*fcf3ce44SJohn Forte #define SUBCOMMAND(x) (SUBCOMMAND_BASE << x) 56*fcf3ce44SJohn Forte 57*fcf3ce44SJohn Forte /* 58*fcf3ce44SJohn Forte * This structure is passed into the caller's callback function and 59*fcf3ce44SJohn Forte * will contain a list of all options entered and their associated 60*fcf3ce44SJohn Forte * option arguments if applicable 61*fcf3ce44SJohn Forte */ 62*fcf3ce44SJohn Forte typedef struct _cmdOptions { 63*fcf3ce44SJohn Forte int optval; 64*fcf3ce44SJohn Forte char optarg[MAXOPTARGLEN + 1]; 65*fcf3ce44SJohn Forte } cmdOptions_t; 66*fcf3ce44SJohn Forte 67*fcf3ce44SJohn Forte /* 68*fcf3ce44SJohn Forte * subcommand callback function 69*fcf3ce44SJohn Forte * 70*fcf3ce44SJohn Forte * argc - number of arguments in argv 71*fcf3ce44SJohn Forte * argv - operand arguments 72*fcf3ce44SJohn Forte * options - options entered on command line 73*fcf3ce44SJohn Forte * callData - pointer to caller data to be passed to subcommand function 74*fcf3ce44SJohn Forte */ 75*fcf3ce44SJohn Forte typedef int (*handler_t)(int argc, char *argv[], cmdOptions_t *options, 76*fcf3ce44SJohn Forte void *callData); 77*fcf3ce44SJohn Forte 78*fcf3ce44SJohn Forte /* 79*fcf3ce44SJohn Forte * list of subcommands and associated properties 80*fcf3ce44SJohn Forte * 81*fcf3ce44SJohn Forte * name -> subcommand name 82*fcf3ce44SJohn Forte * handler -> function to call on successful syntax check 83*fcf3ce44SJohn Forte * optionString -> short options that are valid 84*fcf3ce44SJohn Forte * required -> Does it require at least one option? 85*fcf3ce44SJohn Forte * exclusive -> short options that are required to be exclusively entered 86*fcf3ce44SJohn Forte * operand -> Type of operand input. Can be: 87*fcf3ce44SJohn Forte * 88*fcf3ce44SJohn Forte * NO_OPERAND 89*fcf3ce44SJohn Forte * OPERAND_MANDATORY_SINGLE 90*fcf3ce44SJohn Forte * OPERAND_OPTIONAL_SINGLE 91*fcf3ce44SJohn Forte * OPERAND_MANDATORY_MULTIPLE 92*fcf3ce44SJohn Forte * OPERAND_OPTIONAL_MULTIPLE 93*fcf3ce44SJohn Forte * 94*fcf3ce44SJohn Forte * operandDefinition -> char * definition of the operand 95*fcf3ce44SJohn Forte * 96*fcf3ce44SJohn Forte * The long options table specifies whether an option argument is required. 97*fcf3ce44SJohn Forte * 98*fcf3ce44SJohn Forte * 99*fcf3ce44SJohn Forte * EXAMPLE: 100*fcf3ce44SJohn Forte * 101*fcf3ce44SJohn Forte * Based on "list-target" entry below: 102*fcf3ce44SJohn Forte * 103*fcf3ce44SJohn Forte * "list-target" is expected as the subcommand input 104*fcf3ce44SJohn Forte * listTarget is the function to be called on success 105*fcf3ce44SJohn Forte * "list-target" accepts -i, -s, -t and -l 106*fcf3ce44SJohn Forte * "list-target" requires the option 'i'. 107*fcf3ce44SJohn Forte * "list-target" has no exclusive options 108*fcf3ce44SJohn Forte * "list-target" may have one or more operands 109*fcf3ce44SJohn Forte * "list-target" operand description is "target-name" 110*fcf3ce44SJohn Forte * 111*fcf3ce44SJohn Forte * 112*fcf3ce44SJohn Forte * optionRules_t optionRules[] = { 113*fcf3ce44SJohn Forte * {"list-target", listTarget, "istl", "i", NULL, 114*fcf3ce44SJohn Forte * OPERAND_OPTIONAL_MULTIPLE, "target-name"}, 115*fcf3ce44SJohn Forte * {"modify-target", modifyTarget, "t", "t", NULL, 116*fcf3ce44SJohn Forte * OPERAND_MANDATORY_MULTIPLE, "target-name"}, 117*fcf3ce44SJohn Forte * {"enable", enable, NULL, NULL, NULL, NO_OPERAND, NULL}, 118*fcf3ce44SJohn Forte * {NULL, 0, 0, NULL, 0, NULL} 119*fcf3ce44SJohn Forte * }; 120*fcf3ce44SJohn Forte */ 121*fcf3ce44SJohn Forte typedef struct _subCommandProps { 122*fcf3ce44SJohn Forte char *name; 123*fcf3ce44SJohn Forte handler_t handler; 124*fcf3ce44SJohn Forte char *optionString; 125*fcf3ce44SJohn Forte char *required; 126*fcf3ce44SJohn Forte char *exclusive; 127*fcf3ce44SJohn Forte int operand; 128*fcf3ce44SJohn Forte char *operandDefinition; 129*fcf3ce44SJohn Forte uint8_t reserved[64]; 130*fcf3ce44SJohn Forte } subCommandProps_t; 131*fcf3ce44SJohn Forte 132*fcf3ce44SJohn Forte 133*fcf3ce44SJohn Forte 134*fcf3ce44SJohn Forte #define required_arg required_argument 135*fcf3ce44SJohn Forte #define no_arg no_argument 136*fcf3ce44SJohn Forte 137*fcf3ce44SJohn Forte /* 138*fcf3ce44SJohn Forte * Add short options and long options here 139*fcf3ce44SJohn Forte * 140*fcf3ce44SJohn Forte * name -> long option name 141*fcf3ce44SJohn Forte * has_arg -> required_arg, no_arg 142*fcf3ce44SJohn Forte * val -> short option character 143*fcf3ce44SJohn Forte * argDesc -> description of option argument 144*fcf3ce44SJohn Forte * 145*fcf3ce44SJohn Forte * Note: This structure may not be used if your CLI has no 146*fcf3ce44SJohn Forte * options. However, -?, --help and -V, --version will still be supported 147*fcf3ce44SJohn Forte * as they are standard for every CLI. 148*fcf3ce44SJohn Forte * 149*fcf3ce44SJohn Forte * EXAMPLE: 150*fcf3ce44SJohn Forte * 151*fcf3ce44SJohn Forte * optionTbl_t options[] = { 152*fcf3ce44SJohn Forte * {"filename", arg_required, 'f', "out-filename"}, 153*fcf3ce44SJohn Forte * {NULL, 0, 0} 154*fcf3ce44SJohn Forte * }; 155*fcf3ce44SJohn Forte * 156*fcf3ce44SJohn Forte */ 157*fcf3ce44SJohn Forte typedef struct _optionTbl { 158*fcf3ce44SJohn Forte char *name; 159*fcf3ce44SJohn Forte int has_arg; 160*fcf3ce44SJohn Forte int val; 161*fcf3ce44SJohn Forte char *argDesc; 162*fcf3ce44SJohn Forte } optionTbl_t; 163*fcf3ce44SJohn Forte 164*fcf3ce44SJohn Forte /* 165*fcf3ce44SJohn Forte * After tables are set, assign them to this structure 166*fcf3ce44SJohn Forte * for passing into cmdparse() 167*fcf3ce44SJohn Forte */ 168*fcf3ce44SJohn Forte typedef struct _synTables { 169*fcf3ce44SJohn Forte char *versionString; 170*fcf3ce44SJohn Forte optionTbl_t *longOptionTbl; 171*fcf3ce44SJohn Forte subCommandProps_t *subCommandPropsTbl; 172*fcf3ce44SJohn Forte } synTables_t; 173*fcf3ce44SJohn Forte 174*fcf3ce44SJohn Forte /* 175*fcf3ce44SJohn Forte * cmdParse is a parser that checks syntax of the input command against 176*fcf3ce44SJohn Forte * rules and property tables. 177*fcf3ce44SJohn Forte * 178*fcf3ce44SJohn Forte * When syntax is successfully validated, the function associated with the 179*fcf3ce44SJohn Forte * subcommand is called using the subcommands table functions. 180*fcf3ce44SJohn Forte * 181*fcf3ce44SJohn Forte * Syntax for the command is as follows: 182*fcf3ce44SJohn Forte * 183*fcf3ce44SJohn Forte * command [options] subcommand [<options>] [<operand ...>] 184*fcf3ce44SJohn Forte * 185*fcf3ce44SJohn Forte * 186*fcf3ce44SJohn Forte * There are two standard short and long options assumed: 187*fcf3ce44SJohn Forte * -?, --help Provides usage on a command or subcommand 188*fcf3ce44SJohn Forte * and stops further processing of the arguments 189*fcf3ce44SJohn Forte * 190*fcf3ce44SJohn Forte * -V, --version Provides version information on the command 191*fcf3ce44SJohn Forte * and stops further processing of the arguments 192*fcf3ce44SJohn Forte * 193*fcf3ce44SJohn Forte * These options are loaded by this function. 194*fcf3ce44SJohn Forte * 195*fcf3ce44SJohn Forte * input: 196*fcf3ce44SJohn Forte * argc, argv from main 197*fcf3ce44SJohn Forte * syntax rules tables (synTables_t structure) 198*fcf3ce44SJohn Forte * callArgs - void * passed by caller to be passed to subcommand function 199*fcf3ce44SJohn Forte * 200*fcf3ce44SJohn Forte * output: 201*fcf3ce44SJohn Forte * funcRet - pointer to int that holds subcommand function return value 202*fcf3ce44SJohn Forte * 203*fcf3ce44SJohn Forte * Returns: 204*fcf3ce44SJohn Forte * 205*fcf3ce44SJohn Forte * zero on successful syntax parse and function call 206*fcf3ce44SJohn Forte * 207*fcf3ce44SJohn Forte * 1 on unsuccessful syntax parse (no function has been called) 208*fcf3ce44SJohn Forte * This could be due to a version or help call or simply a 209*fcf3ce44SJohn Forte * general usage call. 210*fcf3ce44SJohn Forte * 211*fcf3ce44SJohn Forte * -1 check errno, call failed 212*fcf3ce44SJohn Forte * 213*fcf3ce44SJohn Forte */ 214*fcf3ce44SJohn Forte int cmdParse(int numOperands, char *operands[], synTables_t synTables, 215*fcf3ce44SJohn Forte void *callerArgs, int *funcRet); 216*fcf3ce44SJohn Forte 217*fcf3ce44SJohn Forte #ifdef __cplusplus 218*fcf3ce44SJohn Forte } 219*fcf3ce44SJohn Forte #endif 220*fcf3ce44SJohn Forte 221*fcf3ce44SJohn Forte #endif /* _CMDPARSE_H */ 222