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