PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/gdeutil/arg_file.c

https://gitlab.com/segrived/theguide
C | 202 lines | 132 code | 34 blank | 36 comment | 8 complexity | 64535ff73d629fb3c1222cb4de8baddd MD5 | raw file
  1. /*********************************************************************
  2. This file is part of the argtable2 library.
  3. Copyright (C) 1998-2001,2003-2007 Stewart Heitmann
  4. sheitmann@users.sourceforge.net
  5. The argtable2 library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9. This software is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. USA.
  17. **********************************************************************/
  18. /* config.h must be included before anything else */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #ifdef HAVE_STRING_H
  23. #include <string.h>
  24. #endif
  25. #ifdef HAVE_STDLIB_H
  26. #include <stdlib.h>
  27. #endif
  28. #include "argtable2.h"
  29. #ifdef WIN32
  30. # define FILESEPARATOR '\\'
  31. #else
  32. # define FILESEPARATOR '/'
  33. #endif
  34. /* local error codes */
  35. enum {EMINCOUNT=1,EMAXCOUNT};
  36. static void resetfn(struct arg_file *parent)
  37. {
  38. /*printf("%s:resetfn(%p)\n",__FILE__,parent);*/
  39. parent->count=0;
  40. }
  41. /* Returns ptr to the base filename within *filename */
  42. static const char* arg_basename(const char *filename)
  43. {
  44. const char *result = (filename ? strrchr(filename,FILESEPARATOR) : NULL);
  45. if (result)
  46. result++;
  47. else
  48. result = filename;
  49. return result;
  50. }
  51. /* Returns ptr to the file extension within *filename */
  52. static const char* arg_extension(const char *filename)
  53. {
  54. const char *result = (filename ? strrchr(filename,'.') : NULL);
  55. if (filename && !result)
  56. result = filename+strlen(filename);
  57. return result;
  58. }
  59. static int scanfn(struct arg_file *parent, const char *argval)
  60. {
  61. int errorcode = 0;
  62. if (parent->count == parent->hdr.maxcount)
  63. {
  64. /* maximum number of arguments exceeded */
  65. errorcode = EMAXCOUNT;
  66. }
  67. else if (!argval)
  68. {
  69. /* a valid argument with no argument value was given. */
  70. /* This happens when an optional argument value was invoked. */
  71. /* leave parent arguiment value unaltered but still count the argument. */
  72. parent->count++;
  73. }
  74. else
  75. {
  76. parent->filename[parent->count] = argval;
  77. parent->basename[parent->count] = arg_basename(argval);
  78. parent->extension[parent->count] = arg_extension(argval);
  79. parent->count++;
  80. }
  81. /*printf("%s:scanfn(%p) returns %d\n",__FILE__,parent,errorcode);*/
  82. return errorcode;
  83. }
  84. static int checkfn(struct arg_file *parent)
  85. {
  86. int errorcode = (parent->count < parent->hdr.mincount) ? EMINCOUNT : 0;
  87. /*printf("%s:checkfn(%p) returns %d\n",__FILE__,parent,errorcode);*/
  88. return errorcode;
  89. }
  90. static void errorfn(struct arg_file *parent, FILE *fp, int errorcode, const char *argval, const char *progname)
  91. {
  92. const char *shortopts = parent->hdr.shortopts;
  93. const char *longopts = parent->hdr.longopts;
  94. const char *datatype = parent->hdr.datatype;
  95. /* make argval NULL safe */
  96. argval = argval ? argval : "";
  97. fprintf(fp,"%s: ",progname);
  98. switch(errorcode)
  99. {
  100. case EMINCOUNT:
  101. fputs("missing option ",fp);
  102. arg_print_option(fp,shortopts,longopts,datatype,"\n");
  103. break;
  104. case EMAXCOUNT:
  105. fputs("excess option ",fp);
  106. arg_print_option(fp,shortopts,longopts,argval,"\n");
  107. break;
  108. default:
  109. fprintf(fp,"unknown error at \"%s\"\n",argval);
  110. }
  111. }
  112. struct arg_file* arg_file0(const char* shortopts,
  113. const char* longopts,
  114. const char *datatype,
  115. const char *glossary)
  116. {
  117. return arg_filen(shortopts,longopts,datatype,0,1,glossary);
  118. }
  119. struct arg_file* arg_file1(const char* shortopts,
  120. const char* longopts,
  121. const char *datatype,
  122. const char *glossary)
  123. {
  124. return arg_filen(shortopts,longopts,datatype,1,1,glossary);
  125. }
  126. struct arg_file* arg_filen(const char* shortopts,
  127. const char* longopts,
  128. const char *datatype,
  129. int mincount,
  130. int maxcount,
  131. const char *glossary)
  132. {
  133. size_t nbytes;
  134. struct arg_file *result;
  135. /* foolproof things by ensuring maxcount is not less than mincount */
  136. maxcount = (maxcount<mincount) ? mincount : maxcount;
  137. nbytes = sizeof(struct arg_file) /* storage for struct arg_file */
  138. + sizeof(char*) * maxcount /* storage for filename[maxcount] array */
  139. + sizeof(char*) * maxcount /* storage for basename[maxcount] array */
  140. + sizeof(char*) * maxcount; /* storage for extension[maxcount] array */
  141. result = (struct arg_file*)malloc(nbytes);
  142. if (result)
  143. {
  144. /* init the arg_hdr struct */
  145. result->hdr.flag = ARG_HASVALUE;
  146. result->hdr.shortopts = shortopts;
  147. result->hdr.longopts = longopts;
  148. result->hdr.glossary = glossary;
  149. result->hdr.datatype = datatype ? datatype : "<file>";
  150. result->hdr.mincount = mincount;
  151. result->hdr.maxcount = maxcount;
  152. result->hdr.parent = result;
  153. result->hdr.resetfn = (arg_resetfn*)resetfn;
  154. result->hdr.scanfn = (arg_scanfn*)scanfn;
  155. result->hdr.checkfn = (arg_checkfn*)checkfn;
  156. result->hdr.errorfn = (arg_errorfn*)errorfn;
  157. /* store the filename,basename,extension arrays immediately after the arg_file struct */
  158. result->filename = (const char**)(result+1);
  159. result->basename = result->filename + maxcount;
  160. result->extension = result->basename + maxcount;
  161. result->count = 0;
  162. }
  163. /*printf("arg_filen() returns %p\n",result);*/
  164. return result;
  165. }