jargv.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "jargv.hpp"
  14. #include "jlog.hpp"
  15. //=========================================================================================
  16. void expandCommaList(StringArray & target, const char * text)
  17. {
  18. const char * cur = text;
  19. for (;;)
  20. {
  21. const char * comma = strchr(cur, ',');
  22. if (!comma)
  23. break;
  24. if (comma != cur)
  25. {
  26. StringAttr temp(cur, comma-cur);
  27. target.append(temp);
  28. }
  29. cur = comma+1;
  30. }
  31. if (*cur)
  32. target.append(cur);
  33. }
  34. bool processArgvFilenamesFromFile(IFileArray & filenames, const char * filename)
  35. {
  36. char buffer[255];
  37. FILE * in = fopen(filename, "r");
  38. if (!in)
  39. {
  40. UERRLOG("Error: File '%s' does not exist", filename);
  41. return false;
  42. }
  43. while (!feof(in))
  44. {
  45. if (fgets(buffer, sizeof(buffer), in))
  46. {
  47. size_t len = strlen(buffer);
  48. while (len && !isprint(buffer[len-1]))
  49. len--;
  50. buffer[len] = 0;
  51. if (len)
  52. processArgvFilename(filenames, filename); //Potential for infinite recursion if user is daft
  53. }
  54. }
  55. fclose(in);
  56. return true;
  57. }
  58. bool processArgvFilename(IFileArray & filenames, const char * filename)
  59. {
  60. if (filename[0] == '@')
  61. return processArgvFilenamesFromFile(filenames, filename+1);
  62. if (containsFileWildcard(filename))
  63. {
  64. StringBuffer dirPath, dirWildcard;
  65. splitFilename(filename, &dirPath, &dirPath, &dirWildcard, &dirWildcard);
  66. Owned<IDirectoryIterator> iter = createDirectoryIterator(dirPath.str(), dirWildcard.str());
  67. ForEach(*iter)
  68. {
  69. IFile & cur = iter->query();
  70. if (cur.isFile() == foundYes)
  71. filenames.append(OLINK(cur));
  72. }
  73. }
  74. else
  75. {
  76. Owned<IFile> cur = createIFile(filename);
  77. if (cur->isFile() != foundYes)
  78. {
  79. UERRLOG("Error: File '%s' does not exist", filename);
  80. return false;
  81. }
  82. filenames.append(*cur.getClear());
  83. }
  84. return true;
  85. }
  86. //=========================================================================================
  87. bool ArgvIterator::matchOption(StringAttr & value, const char * name)
  88. {
  89. const char * arg = query();
  90. size_t len = strlen(name);
  91. if (memcmp(arg, name, len) != 0)
  92. return false;
  93. if (arg[len] == '=')
  94. {
  95. value.set(arg+len+1);
  96. return true;
  97. }
  98. //Not = => a different option
  99. if (arg[len] != 0)
  100. return false;
  101. if (hasMore(1))
  102. {
  103. next();
  104. value.set(query());
  105. return true;
  106. }
  107. UERRLOG("Error: Need to supply a value for %s", arg);
  108. return false;
  109. }
  110. bool ArgvIterator::matchOption(unsigned & value, const char * name)
  111. {
  112. StringAttr text;
  113. if (!matchOption(text, name))
  114. return false;
  115. value = atoi(text);
  116. return true;
  117. }
  118. // -Xvalue, -X option
  119. bool ArgvIterator::matchFlag(StringAttr & value, const char * name)
  120. {
  121. const char * arg = query();
  122. size_t len = strlen(name);
  123. if (memcmp(arg, name, len) != 0)
  124. return false;
  125. if (arg[len] != 0)
  126. {
  127. value.set(arg+len);
  128. return true;
  129. }
  130. if (hasMore(1))
  131. {
  132. next();
  133. value.set(query());
  134. return true;
  135. }
  136. UERRLOG("Error: %s needs to supply an associated value", arg);
  137. return false;
  138. }
  139. bool ArgvIterator::matchFlag(bool & value, const char * name)
  140. {
  141. const char * arg = query();
  142. size_t len = strlen(name);
  143. if (memcmp(arg, name, len) != 0)
  144. return false;
  145. char next = arg[len];
  146. if ((next == 0) || (next == '+'))
  147. {
  148. value = true;
  149. return true;
  150. }
  151. if (next == '-')
  152. {
  153. value = false;
  154. return true;
  155. }
  156. if (next == '=')
  157. {
  158. value = strToBool(arg+len+1);
  159. return true;
  160. }
  161. return false;
  162. }
  163. bool ArgvIterator::matchPathFlag(StringBuffer & option, const char * name)
  164. {
  165. const char * arg = query();
  166. size_t len = strlen(name);
  167. if (memcmp(arg, name, len) != 0)
  168. return false;
  169. if (arg[len])
  170. {
  171. //Allow -xZ -x=Z
  172. if (arg[len] == '=')
  173. len++;
  174. option.append(ENVSEPCHAR).append(arg+len);
  175. return true;
  176. }
  177. if (hasMore(1))
  178. {
  179. //-x Z
  180. next();
  181. option.append(ENVSEPCHAR).append(query());
  182. return true;
  183. }
  184. UERRLOG("Error: %s needs to specify a directory", arg);
  185. return false;
  186. }