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