multisyntax.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*******************************************************************************
  2. * Example source code for using the argtable3 library to implement
  3. * a multi-syntax command line argument program
  4. *
  5. * usage 1: multisyntax [-nvR] insert <file> [<file>]... [-o <output>]
  6. * usage 2: multisyntax [-nv] remove <file>
  7. * usage 3: multisyntax [-v] search <pattern> [-o <output>]
  8. * usage 4: multisyntax [--help] [--version]
  9. *
  10. * This file is part of the argtable3 library.
  11. *
  12. * Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
  13. * <sheitmann@users.sourceforge.net>
  14. * All rights reserved.
  15. *
  16. * Redistribution and use in source and binary forms, with or without
  17. * modification, are permitted provided that the following conditions are met:
  18. * * Redistributions of source code must retain the above copyright
  19. * notice, this list of conditions and the following disclaimer.
  20. * * Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in the
  22. * documentation and/or other materials provided with the distribution.
  23. * * Neither the name of STEWART HEITMANN nor the names of its contributors
  24. * may be used to endorse or promote products derived from this software
  25. * without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. * ARE DISCLAIMED. IN NO EVENT SHALL STEWART HEITMANN BE LIABLE FOR ANY DIRECT,
  31. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  32. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  33. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  34. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. ******************************************************************************/
  38. #include "argtable3.h"
  39. #define REG_EXTENDED 1
  40. #define REG_ICASE (REG_EXTENDED << 1)
  41. /* mymain1 implements the actions for syntax 1 */
  42. int mymain1(int n, int v, int R, const char *outfile,
  43. const char **infiles, int ninfiles)
  44. {
  45. int i;
  46. printf("syntax 1 matched OK:\n");
  47. printf("n=%d\n", n);
  48. printf("v=%d\n", v);
  49. printf("R=%d\n", R);
  50. printf("outfile=\"%s\"\n", outfile);
  51. for (i=0; i<ninfiles; i++)
  52. printf("infile[%d]=\"%s\"\n",i,infiles[i]);
  53. return 0;
  54. }
  55. /* mymain2 implements the actions for syntax 2 */
  56. int mymain2(int n, int v, const char *infile)
  57. {
  58. printf("syntax 2 matched OK:\n");
  59. printf("n=%d\n", n);
  60. printf("v=%d\n", v);
  61. printf("infile=\"%s\"\n", infile);
  62. return 0;
  63. }
  64. /* mymain3 implements the actions for syntax 3 */
  65. int mymain3(int v, const char *pattern, const char *outfile)
  66. {
  67. printf("syntax 3 matched OK:\n");
  68. printf("v=%d\n", v);
  69. printf("pattern=\"%s\"\n", pattern);
  70. printf("outfile=\"%s\"\n", outfile);
  71. return 0;
  72. }
  73. /* mymain4 implements the actions for syntax 4 */
  74. int mymain4(int help, int version, const char *progname,
  75. void *argtable1, void *argtable2, void *argtable3, void *argtable4)
  76. {
  77. /* --help option */
  78. if (help)
  79. {
  80. printf("Usage: %s", progname);
  81. arg_print_syntax(stdout,argtable1,"\n");
  82. printf(" %s", progname);
  83. arg_print_syntax(stdout,argtable2,"\n");
  84. printf(" %s", progname);
  85. arg_print_syntax(stdout,argtable3,"\n");
  86. printf(" %s", progname);
  87. arg_print_syntax(stdout,argtable4,"\n");
  88. printf("This program demonstrates the use of the argtable2 library\n");
  89. printf("for parsing multiple command line syntaxes.\n");
  90. arg_print_glossary(stdout,argtable1," %-20s %s\n");
  91. arg_print_glossary(stdout,argtable2," %-20s %s\n");
  92. arg_print_glossary(stdout,argtable3," %-20s %s\n");
  93. arg_print_glossary(stdout,argtable4," %-20s %s\n");
  94. return 0;
  95. }
  96. /* --version option */
  97. if (version)
  98. {
  99. printf("'%s' example program for the \"argtable\" command line argument parser.\n",progname);
  100. return 0;
  101. }
  102. /* no command line options at all */
  103. printf("Try '%s --help' for more information.\n", progname);
  104. return 0;
  105. }
  106. int main(int argc, char **argv)
  107. {
  108. /* SYNTAX 1: insert [-nvR] <file> [file]... -o <file> */
  109. struct arg_rex *cmd1 = arg_rex1(NULL, NULL, "insert", NULL, REG_ICASE, NULL);
  110. struct arg_lit *noact1 = arg_lit0("n", NULL, "take no action");
  111. struct arg_lit *verbose1 = arg_lit0("v", "verbose", "verbose messages");
  112. struct arg_lit *recurse1 = arg_lit0("R", NULL, "recurse through subdirectories");
  113. struct arg_file *infiles1 = arg_filen(NULL, NULL, NULL, 1,argc+2, "input file(s)");
  114. struct arg_file *outfile1 = arg_file0("o", NULL, "<output>", "output file (default is \"-\")");
  115. struct arg_end *end1 = arg_end(20);
  116. void* argtable1[] = {cmd1,noact1,verbose1,recurse1,infiles1,outfile1,end1};
  117. int nerrors1;
  118. /* SYNTAX 2: remove [-nv] <file> */
  119. struct arg_rex *cmd2 = arg_rex1(NULL, NULL, "remove", NULL, REG_ICASE, NULL);
  120. struct arg_lit *noact2 = arg_lit0("n", NULL, NULL);
  121. struct arg_lit *verbose2 = arg_lit0("v", "verbose", NULL);
  122. struct arg_file *infiles2 = arg_file1(NULL, NULL, NULL, NULL);
  123. struct arg_end *end2 = arg_end(20);
  124. void* argtable2[] = {cmd2,noact2,verbose2,infiles2,end2};
  125. int nerrors2;
  126. /* SYNTAX 3: search [-v] <pattern> [-o <file>] [--help] [--version] */
  127. struct arg_rex *cmd3 = arg_rex1(NULL, NULL, "search", NULL, REG_ICASE, NULL);
  128. struct arg_lit *verbose3 = arg_lit0("v", "verbose", NULL);
  129. struct arg_str *pattern3 = arg_str1(NULL, NULL, "<pattern>", "search string");
  130. struct arg_file *outfile3 = arg_file0("o", NULL, "<output>", NULL);
  131. struct arg_end *end3 = arg_end(20);
  132. void* argtable3[] = {cmd3,verbose3,pattern3,outfile3,end3};
  133. int nerrors3;
  134. /* SYNTAX 4: [-help] [-version] */
  135. struct arg_lit *help4 = arg_lit0(NULL,"help", "print this help and exit");
  136. struct arg_lit *version4 = arg_lit0(NULL,"version", "print version information and exit");
  137. struct arg_end *end4 = arg_end(20);
  138. void* argtable4[] = {help4,version4,end4};
  139. int nerrors4;
  140. const char* progname = "multisyntax";
  141. int exitcode=0;
  142. /* verify all argtable[] entries were allocated sucessfully */
  143. if (arg_nullcheck(argtable1)!=0 ||
  144. arg_nullcheck(argtable2)!=0 ||
  145. arg_nullcheck(argtable3)!=0 ||
  146. arg_nullcheck(argtable4)!=0 )
  147. {
  148. /* NULL entries were detected, some allocations must have failed */
  149. printf("%s: insufficient memory\n",progname);
  150. exitcode=1;
  151. goto exit;
  152. }
  153. /* set any command line default values prior to parsing */
  154. outfile1->filename[0]="-";
  155. outfile3->filename[0]="-";
  156. /* Above we defined a separate argtable for each possible command line syntax */
  157. /* and here we parse each one in turn to see if any of them are successful */
  158. nerrors1 = arg_parse(argc,argv,argtable1);
  159. nerrors2 = arg_parse(argc,argv,argtable2);
  160. nerrors3 = arg_parse(argc,argv,argtable3);
  161. nerrors4 = arg_parse(argc,argv,argtable4);
  162. /* Execute the appropriate main<n> routine for the matching command line syntax */
  163. /* In this example program our alternate command line syntaxes are mutually */
  164. /* exclusive, so we know in advance that only one of them can be successful. */
  165. if (nerrors1==0)
  166. exitcode = mymain1(noact1->count, verbose1->count, recurse1->count,
  167. outfile1->filename[0], infiles1->filename, infiles1->count);
  168. else if (nerrors2==0)
  169. exitcode = mymain2(noact2->count, verbose2->count, infiles2->filename[0]);
  170. else if (nerrors3==0)
  171. exitcode = mymain3(verbose3->count, pattern3->sval[0], outfile3->filename[0]);
  172. else if (nerrors4==0)
  173. exitcode = mymain4(help4->count, version4->count, progname,
  174. argtable1, argtable2, argtable3, argtable4);
  175. else
  176. {
  177. /* We get here if the command line matched none of the possible syntaxes */
  178. if (cmd1->count > 0)
  179. {
  180. /* here the cmd1 argument was correct, so presume syntax 1 was intended target */
  181. arg_print_errors(stdout,end1,progname);
  182. printf("usage: %s ", progname);
  183. arg_print_syntax(stdout,argtable1,"\n");
  184. }
  185. else if (cmd2->count > 0)
  186. {
  187. /* here the cmd2 argument was correct, so presume syntax 2 was intended target */
  188. arg_print_errors(stdout,end2,progname);
  189. printf("usage: %s ", progname);
  190. arg_print_syntax(stdout,argtable2,"\n");
  191. }
  192. else if (cmd3->count > 0)
  193. {
  194. /* here the cmd3 argument was correct, so presume syntax 3 was intended target */
  195. arg_print_errors(stdout,end3,progname);
  196. printf("usage: %s ", progname);
  197. arg_print_syntax(stdout,argtable3,"\n");
  198. }
  199. else
  200. {
  201. /* no correct cmd literals were given, so we cant presume which syntax was intended */
  202. printf("%s: missing <insert|remove|search> command.\n",progname);
  203. printf("usage 1: %s ", progname); arg_print_syntax(stdout,argtable1,"\n");
  204. printf("usage 2: %s ", progname); arg_print_syntax(stdout,argtable2,"\n");
  205. printf("usage 3: %s ", progname); arg_print_syntax(stdout,argtable3,"\n");
  206. printf("usage 4: %s", progname); arg_print_syntax(stdout,argtable4,"\n");
  207. }
  208. }
  209. exit:
  210. /* deallocate each non-null entry in each argtable */
  211. arg_freetable(argtable1,sizeof(argtable1)/sizeof(argtable1[0]));
  212. arg_freetable(argtable2,sizeof(argtable2)/sizeof(argtable2[0]));
  213. arg_freetable(argtable3,sizeof(argtable3)/sizeof(argtable3[0]));
  214. arg_freetable(argtable4,sizeof(argtable4)/sizeof(argtable4[0]));
  215. return exitcode;
  216. }