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 30*fcf3ce44SJohn Forte #ifdef __cplusplus 31*fcf3ce44SJohn Forte extern "C" { 32*fcf3ce44SJohn Forte #endif 33*fcf3ce44SJohn Forte 34*fcf3ce44SJohn Forte #include <getopt.h> 35*fcf3ce44SJohn Forte 36*fcf3ce44SJohn Forte /* subcommands must have a single bit on and must have exclusive values */ 37*fcf3ce44SJohn Forte #define SUBCOMMAND_BASE 1 38*fcf3ce44SJohn Forte #define SUBCOMMAND(x) (SUBCOMMAND_BASE << x) 39*fcf3ce44SJohn Forte 40*fcf3ce44SJohn Forte #define OBJECT_BASE 1 41*fcf3ce44SJohn Forte #define OBJECT(x) (OBJECT_BASE << x) 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 /* 48*fcf3ce44SJohn Forte * Add objects here 49*fcf3ce44SJohn Forte * 50*fcf3ce44SJohn Forte * EXAMPLE: 51*fcf3ce44SJohn Forte * object_t object[] = { 52*fcf3ce44SJohn Forte * {"target", TARGET}, 53*fcf3ce44SJohn Forte * {NULL, 0} 54*fcf3ce44SJohn Forte * }; 55*fcf3ce44SJohn Forte */ 56*fcf3ce44SJohn Forte typedef struct _object { 57*fcf3ce44SJohn Forte char *name; 58*fcf3ce44SJohn Forte uint_t value; 59*fcf3ce44SJohn Forte } object_t; 60*fcf3ce44SJohn Forte 61*fcf3ce44SJohn Forte /* 62*fcf3ce44SJohn Forte * This structure is passed into the caller's callback function and 63*fcf3ce44SJohn Forte * will contain a list of all options entered and their associated 64*fcf3ce44SJohn Forte * option arguments if applicable 65*fcf3ce44SJohn Forte */ 66*fcf3ce44SJohn Forte typedef struct _cmdOptions { 67*fcf3ce44SJohn Forte int optval; 68*fcf3ce44SJohn Forte char optarg[MAXOPTARGLEN + 1]; 69*fcf3ce44SJohn Forte } cmdOptions_t; 70*fcf3ce44SJohn Forte 71*fcf3ce44SJohn Forte 72*fcf3ce44SJohn Forte /* 73*fcf3ce44SJohn Forte * list of objects, subcommands, valid short options, required flag and 74*fcf3ce44SJohn Forte * exlusive option string 75*fcf3ce44SJohn Forte * 76*fcf3ce44SJohn Forte * objectValue -> object 77*fcf3ce44SJohn Forte * subcommandValue -> subcommand value 78*fcf3ce44SJohn Forte * optionProp.optionString -> short options that are valid 79*fcf3ce44SJohn Forte * optionProp.required -> flag indicating whether at least one option is 80*fcf3ce44SJohn Forte * required 81*fcf3ce44SJohn Forte * optionProp.exclusive -> short options that are required to be exclusively 82*fcf3ce44SJohn Forte * entered 83*fcf3ce44SJohn Forte * 84*fcf3ce44SJohn Forte * 85*fcf3ce44SJohn Forte * If it's not here, there are no options for that object. 86*fcf3ce44SJohn Forte * 87*fcf3ce44SJohn Forte * The long options table specifies whether an option argument is required. 88*fcf3ce44SJohn Forte * 89*fcf3ce44SJohn Forte * 90*fcf3ce44SJohn Forte * EXAMPLE: 91*fcf3ce44SJohn Forte * 92*fcf3ce44SJohn Forte * Based on DISCOVERY entry below: 93*fcf3ce44SJohn Forte * 94*fcf3ce44SJohn Forte * MODIFY DISCOVERY accepts -i, -s, -t and -l 95*fcf3ce44SJohn Forte * MODIFY DISCOVERY requires at least one option 96*fcf3ce44SJohn Forte * MODIFY DISCOVERY has no exclusive options 97*fcf3ce44SJohn Forte * 98*fcf3ce44SJohn Forte * 99*fcf3ce44SJohn Forte * optionRules_t optionRules[] = { 100*fcf3ce44SJohn Forte * {DISCOVERY, MODIFY, "istl", B_TRUE, NULL}, 101*fcf3ce44SJohn Forte * {0, 0, NULL, 0, NULL} 102*fcf3ce44SJohn Forte * }; 103*fcf3ce44SJohn Forte */ 104*fcf3ce44SJohn Forte typedef struct _optionProp { 105*fcf3ce44SJohn Forte char *optionString; 106*fcf3ce44SJohn Forte boolean_t required; 107*fcf3ce44SJohn Forte char *exclusive; 108*fcf3ce44SJohn Forte } optionProp_t; 109*fcf3ce44SJohn Forte 110*fcf3ce44SJohn Forte typedef struct _optionRules { 111*fcf3ce44SJohn Forte uint_t objectValue; 112*fcf3ce44SJohn Forte uint_t subcommandValue; 113*fcf3ce44SJohn Forte optionProp_t optionProp; 114*fcf3ce44SJohn Forte } optionRules_t; 115*fcf3ce44SJohn Forte 116*fcf3ce44SJohn Forte /* 117*fcf3ce44SJohn Forte * Rules for subcommands and object operands 118*fcf3ce44SJohn Forte * 119*fcf3ce44SJohn Forte * Every object requires an entry 120*fcf3ce44SJohn Forte * 121*fcf3ce44SJohn Forte * value, reqOpCmd, optOpCmd, noOpCmd, invCmd, multOpCmd 122*fcf3ce44SJohn Forte * 123*fcf3ce44SJohn Forte * value -> numeric value of object 124*fcf3ce44SJohn Forte * 125*fcf3ce44SJohn Forte * The following five fields are comprised of values that are 126*fcf3ce44SJohn Forte * a bitwise OR of the subcommands related to the object 127*fcf3ce44SJohn Forte * 128*fcf3ce44SJohn Forte * reqOpCmd -> subcommands that must have an operand 129*fcf3ce44SJohn Forte * optOpCmd -> subcommands that may have an operand 130*fcf3ce44SJohn Forte * noOpCmd -> subcommands that will have no operand 131*fcf3ce44SJohn Forte * invCmd -> subcommands that are invalid 132*fcf3ce44SJohn Forte * multOpCmd -> subcommands that can accept multiple operands 133*fcf3ce44SJohn Forte * operandDefinition -> Usage definition for the operand of this object 134*fcf3ce44SJohn Forte * 135*fcf3ce44SJohn Forte * 136*fcf3ce44SJohn Forte * EXAMPLE: 137*fcf3ce44SJohn Forte * 138*fcf3ce44SJohn Forte * based on TARGET entry below: 139*fcf3ce44SJohn Forte * MODIFY and DELETE subcomamnds require an operand 140*fcf3ce44SJohn Forte * LIST optionally requires an operand 141*fcf3ce44SJohn Forte * There are no subcommands that requires that no operand is specified 142*fcf3ce44SJohn Forte * ADD and REMOVE are invalid subcommands for this operand 143*fcf3ce44SJohn Forte * DELETE can accept multiple operands 144*fcf3ce44SJohn Forte * 145*fcf3ce44SJohn Forte * objectRules_t objectRules[] = { 146*fcf3ce44SJohn Forte * {TARGET, MODIFY|DELETE, LIST, 0, ADD|REMOVE, DELETE, 147*fcf3ce44SJohn Forte * "target-name"}, 148*fcf3ce44SJohn Forte * {0, 0, 0, 0, 0, NULL} 149*fcf3ce44SJohn Forte * }; 150*fcf3ce44SJohn Forte */ 151*fcf3ce44SJohn Forte typedef struct _opCmd { 152*fcf3ce44SJohn Forte uint_t reqOpCmd; 153*fcf3ce44SJohn Forte uint_t optOpCmd; 154*fcf3ce44SJohn Forte uint_t noOpCmd; 155*fcf3ce44SJohn Forte uint_t invOpCmd; 156*fcf3ce44SJohn Forte uint_t multOpCmd; 157*fcf3ce44SJohn Forte } opCmd_t; 158*fcf3ce44SJohn Forte 159*fcf3ce44SJohn Forte typedef struct _objectRules { 160*fcf3ce44SJohn Forte uint_t value; 161*fcf3ce44SJohn Forte opCmd_t opCmd; 162*fcf3ce44SJohn Forte char *operandDefinition; 163*fcf3ce44SJohn Forte } objectRules_t; 164*fcf3ce44SJohn Forte 165*fcf3ce44SJohn Forte 166*fcf3ce44SJohn Forte /* 167*fcf3ce44SJohn Forte * subcommand callback function 168*fcf3ce44SJohn Forte * 169*fcf3ce44SJohn Forte * argc - number of arguments in argv 170*fcf3ce44SJohn Forte * argv - operand arguments 171*fcf3ce44SJohn Forte * options - options entered on command line 172*fcf3ce44SJohn Forte * callData - pointer to caller data to be passed to subcommand function 173*fcf3ce44SJohn Forte */ 174*fcf3ce44SJohn Forte typedef int (*handler_t)(int argc, char *argv[], int, cmdOptions_t *options, 175*fcf3ce44SJohn Forte void *callData, int *funtRet); 176*fcf3ce44SJohn Forte 177*fcf3ce44SJohn Forte /* 178*fcf3ce44SJohn Forte * Add new subcommands here 179*fcf3ce44SJohn Forte * 180*fcf3ce44SJohn Forte * EXAMPLE: 181*fcf3ce44SJohn Forte * subcommand_t subcommands[] = { 182*fcf3ce44SJohn Forte * {"add", ADD, addFunc}, 183*fcf3ce44SJohn Forte * {NULL, 0, NULL} 184*fcf3ce44SJohn Forte * }; 185*fcf3ce44SJohn Forte */ 186*fcf3ce44SJohn Forte typedef struct _subcommand { 187*fcf3ce44SJohn Forte char *name; 188*fcf3ce44SJohn Forte uint_t value; 189*fcf3ce44SJohn Forte handler_t handler; 190*fcf3ce44SJohn Forte } subcommand_t; 191*fcf3ce44SJohn Forte 192*fcf3ce44SJohn Forte #define required_arg required_argument 193*fcf3ce44SJohn Forte #define no_arg no_argument 194*fcf3ce44SJohn Forte 195*fcf3ce44SJohn Forte /* 196*fcf3ce44SJohn Forte * Add short options and long options here 197*fcf3ce44SJohn Forte * 198*fcf3ce44SJohn Forte * name -> long option name 199*fcf3ce44SJohn Forte * has_arg -> required_arg, no_arg 200*fcf3ce44SJohn Forte * val -> short option character 201*fcf3ce44SJohn Forte * argDesc -> description of option argument 202*fcf3ce44SJohn Forte * 203*fcf3ce44SJohn Forte * Note: This structure may not be used if your CLI has no 204*fcf3ce44SJohn Forte * options. However, -?, --help and -V, --version will still be supported 205*fcf3ce44SJohn Forte * as they are standard for every CLI. 206*fcf3ce44SJohn Forte * 207*fcf3ce44SJohn Forte * EXAMPLE: 208*fcf3ce44SJohn Forte * 209*fcf3ce44SJohn Forte * optionTbl_t options[] = { 210*fcf3ce44SJohn Forte * {"filename", arg_required, 'f', "out-filename"}, 211*fcf3ce44SJohn Forte * {NULL, 0, 0} 212*fcf3ce44SJohn Forte * }; 213*fcf3ce44SJohn Forte * 214*fcf3ce44SJohn Forte */ 215*fcf3ce44SJohn Forte typedef struct _optionTbl { 216*fcf3ce44SJohn Forte char *name; 217*fcf3ce44SJohn Forte int has_arg; 218*fcf3ce44SJohn Forte int val; 219*fcf3ce44SJohn Forte char *argDesc; 220*fcf3ce44SJohn Forte } optionTbl_t; 221*fcf3ce44SJohn Forte 222*fcf3ce44SJohn Forte /* 223*fcf3ce44SJohn Forte * After tables are set, assign them to this structure 224*fcf3ce44SJohn Forte * for passing into cmdparse() 225*fcf3ce44SJohn Forte */ 226*fcf3ce44SJohn Forte typedef struct _synTables { 227*fcf3ce44SJohn Forte char *versionString; 228*fcf3ce44SJohn Forte optionTbl_t *longOptionTbl; 229*fcf3ce44SJohn Forte subcommand_t *subcommandTbl; 230*fcf3ce44SJohn Forte object_t *objectTbl; 231*fcf3ce44SJohn Forte objectRules_t *objectRulesTbl; 232*fcf3ce44SJohn Forte optionRules_t *optionRulesTbl; 233*fcf3ce44SJohn Forte } synTables_t; 234*fcf3ce44SJohn Forte 235*fcf3ce44SJohn Forte /* 236*fcf3ce44SJohn Forte * cmdParse is a parser that checks syntax of the input command against 237*fcf3ce44SJohn Forte * various rules tables. 238*fcf3ce44SJohn Forte * 239*fcf3ce44SJohn Forte * When syntax is successfully validated, the function associated with the 240*fcf3ce44SJohn Forte * subcommand is called using the subcommands table functions. 241*fcf3ce44SJohn Forte * 242*fcf3ce44SJohn Forte * Syntax for the command is as follows: 243*fcf3ce44SJohn Forte * 244*fcf3ce44SJohn Forte * command subcommand [<options>] object [<operand ...>] 245*fcf3ce44SJohn Forte * 246*fcf3ce44SJohn Forte * 247*fcf3ce44SJohn Forte * There are two standard short and long options assumed: 248*fcf3ce44SJohn Forte * -?, --help Provides usage on a command or subcommand 249*fcf3ce44SJohn Forte * and stops further processing of the arguments 250*fcf3ce44SJohn Forte * 251*fcf3ce44SJohn Forte * -V, --version Provides version information on the command 252*fcf3ce44SJohn Forte * and stops further processing of the arguments 253*fcf3ce44SJohn Forte * 254*fcf3ce44SJohn Forte * These options are loaded by this function. 255*fcf3ce44SJohn Forte * 256*fcf3ce44SJohn Forte * input: 257*fcf3ce44SJohn Forte * argc, argv from main 258*fcf3ce44SJohn Forte * syntax rules tables (synTables_t structure) 259*fcf3ce44SJohn Forte * callArgs - void * passed by caller to be passed to subcommand function 260*fcf3ce44SJohn Forte * 261*fcf3ce44SJohn Forte * output: 262*fcf3ce44SJohn Forte * funcRet - pointer to int that holds subcommand function return value 263*fcf3ce44SJohn Forte * 264*fcf3ce44SJohn Forte * Returns: 265*fcf3ce44SJohn Forte * 266*fcf3ce44SJohn Forte * zero on successful syntax parse and function call 267*fcf3ce44SJohn Forte * 268*fcf3ce44SJohn Forte * 1 on unsuccessful syntax parse (no function has been called) 269*fcf3ce44SJohn Forte * This could be due to a version or help call or simply a 270*fcf3ce44SJohn Forte * general usage call. 271*fcf3ce44SJohn Forte * 272*fcf3ce44SJohn Forte * -1 check errno, call failed 273*fcf3ce44SJohn Forte * 274*fcf3ce44SJohn Forte */ 275*fcf3ce44SJohn Forte int cmdParse(int numOperands, char *operands[], synTables_t synTables, 276*fcf3ce44SJohn Forte void *callerArgs, int *funcRet); 277*fcf3ce44SJohn Forte 278*fcf3ce44SJohn Forte #ifdef __cplusplus 279*fcf3ce44SJohn Forte } 280*fcf3ce44SJohn Forte #endif 281*fcf3ce44SJohn Forte 282*fcf3ce44SJohn Forte #endif /* _CMDPARSE_H */ 283