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