Option.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include "Option.h"
  6. #include "TextsCore.h"
  7. //---------------------------------------------------------------------------
  8. #pragma package(smart_init)
  9. //---------------------------------------------------------------------------
  10. __fastcall TOptions::TOptions()
  11. {
  12. FSwitchMarks = L"-/";
  13. FSwitchValueDelimiters = L":=";
  14. FNoMoreSwitches = false;
  15. FParamCount = 0;
  16. }
  17. //---------------------------------------------------------------------------
  18. void __fastcall TOptions::Add(UnicodeString Value)
  19. {
  20. if (!FNoMoreSwitches &&
  21. (Value.Length() == 2) &&
  22. (Value[1] == Value[2]) &&
  23. (FSwitchMarks.Pos(Value[1]) > 0))
  24. {
  25. FNoMoreSwitches = true;
  26. }
  27. else
  28. {
  29. bool Switch = false;
  30. int Index = 0; // shut up
  31. if (!FNoMoreSwitches &&
  32. (Value.Length() >= 2) &&
  33. (FSwitchMarks.Pos(Value[1]) > 0))
  34. {
  35. Index = 2;
  36. Switch = true;
  37. while (Switch && (Index <= Value.Length()))
  38. {
  39. if (Value.IsDelimiter(FSwitchValueDelimiters, Index))
  40. {
  41. break;
  42. }
  43. // this is to treat /home/martin as parameter, not as switch
  44. else if ((Value[Index] != L'?') && !IsLetter(Value[Index]))
  45. {
  46. Switch = false;
  47. break;
  48. }
  49. ++Index;
  50. }
  51. }
  52. if (Switch)
  53. {
  54. TOption Option;
  55. Option.Type = otSwitch;
  56. Option.Name = Value.SubString(2, Index - 2);
  57. Option.Value = Value.SubString(Index + 1, Value.Length());
  58. Option.Used = false;
  59. FOptions.push_back(Option);
  60. }
  61. else
  62. {
  63. TOption Option;
  64. Option.Type = otParam;
  65. Option.Value = Value;
  66. Option.Used = false;
  67. FOptions.push_back(Option);
  68. ++FParamCount;
  69. }
  70. }
  71. }
  72. //---------------------------------------------------------------------------
  73. UnicodeString __fastcall TOptions::GetParam(int Index)
  74. {
  75. assert((Index >= 1) && (Index <= FParamCount));
  76. UnicodeString Result;
  77. size_t I = 0;
  78. while ((I < FOptions.size()) && (Index > 0))
  79. {
  80. if (FOptions[I].Type == otParam)
  81. {
  82. --Index;
  83. if (Index == 0)
  84. {
  85. Result = FOptions[I].Value;
  86. FOptions[I].Used = true;
  87. }
  88. }
  89. ++I;
  90. }
  91. return Result;
  92. }
  93. //---------------------------------------------------------------------------
  94. bool __fastcall TOptions::GetEmpty()
  95. {
  96. return FOptions.empty();
  97. }
  98. //---------------------------------------------------------------------------
  99. bool __fastcall TOptions::FindSwitch(const UnicodeString Switch,
  100. UnicodeString & Value, int & ParamsStart, int & ParamsCount)
  101. {
  102. ParamsStart = 0;
  103. int Index = 0;
  104. bool Found = false;
  105. while ((Index < int(FOptions.size())) && !Found)
  106. {
  107. if (FOptions[Index].Type == otParam)
  108. {
  109. ParamsStart++;
  110. }
  111. else if (FOptions[Index].Type == otSwitch)
  112. {
  113. if (AnsiSameText(FOptions[Index].Name, Switch))
  114. {
  115. Found = true;
  116. Value = FOptions[Index].Value;
  117. FOptions[Index].Used = true;
  118. }
  119. }
  120. Index++;
  121. }
  122. ParamsCount = 0;
  123. if (Found)
  124. {
  125. ParamsStart++;
  126. while ((Index + ParamsCount < int(FOptions.size())) &&
  127. (FOptions[Index + ParamsCount].Type == otParam))
  128. {
  129. ParamsCount++;
  130. }
  131. }
  132. else
  133. {
  134. ParamsStart = 0;
  135. }
  136. return Found;
  137. }
  138. //---------------------------------------------------------------------------
  139. bool __fastcall TOptions::FindSwitch(const UnicodeString Switch, UnicodeString & Value)
  140. {
  141. int ParamsStart;
  142. int ParamsCount;
  143. return FindSwitch(Switch, Value, ParamsStart, ParamsCount);
  144. }
  145. //---------------------------------------------------------------------------
  146. bool __fastcall TOptions::FindSwitch(const UnicodeString Switch)
  147. {
  148. UnicodeString Value;
  149. int ParamsStart;
  150. int ParamsCount;
  151. return FindSwitch(Switch, Value, ParamsStart, ParamsCount);
  152. }
  153. //---------------------------------------------------------------------------
  154. bool __fastcall TOptions::FindSwitch(const UnicodeString Switch,
  155. TStrings * Params, int ParamsMax)
  156. {
  157. UnicodeString Value;
  158. int ParamsStart;
  159. int ParamsCount;
  160. bool Result = FindSwitch(Switch, Value, ParamsStart, ParamsCount);
  161. if (Result)
  162. {
  163. if ((ParamsMax >= 0) && (ParamsCount > ParamsMax))
  164. {
  165. ParamsCount = ParamsMax;
  166. }
  167. int Index = 0;
  168. while (Index < ParamsCount)
  169. {
  170. Params->Add(Param[ParamsStart + Index]);
  171. Index++;
  172. }
  173. ParamsProcessed(ParamsStart, ParamsCount);
  174. }
  175. return Result;
  176. }
  177. //---------------------------------------------------------------------------
  178. UnicodeString __fastcall TOptions::SwitchValue(const UnicodeString Switch,
  179. const UnicodeString Default)
  180. {
  181. UnicodeString Value;
  182. FindSwitch(Switch, Value);
  183. if (Value.IsEmpty())
  184. {
  185. Value = Default;
  186. }
  187. return Value;
  188. }
  189. //---------------------------------------------------------------------------
  190. bool __fastcall TOptions::SwitchValue(const UnicodeString Switch, bool Default, bool DefaultOnNonExistence)
  191. {
  192. bool Result;
  193. int IntValue;
  194. UnicodeString Value;
  195. if (!FindSwitch(Switch, Value))
  196. {
  197. Result = DefaultOnNonExistence;
  198. }
  199. else if (Value.IsEmpty())
  200. {
  201. Result = Default;
  202. }
  203. else if (SameText(Value, "on"))
  204. {
  205. Result = true;
  206. }
  207. else if (SameText(Value, "off"))
  208. {
  209. Result = false;
  210. }
  211. else if (TryStrToInt(Value, IntValue))
  212. {
  213. Result = (IntValue != 0);
  214. }
  215. else
  216. {
  217. throw Exception(FMTLOAD(URL_OPTION_BOOL_VALUE_ERROR, (Value)));
  218. }
  219. return Result;
  220. }
  221. //---------------------------------------------------------------------------
  222. bool __fastcall TOptions::SwitchValue(const UnicodeString Switch, bool Default)
  223. {
  224. return SwitchValue(Switch, Default, Default);
  225. }
  226. //---------------------------------------------------------------------------
  227. bool __fastcall TOptions::UnusedSwitch(UnicodeString & Switch)
  228. {
  229. bool Result = false;
  230. size_t Index = 0;
  231. while (!Result && (Index < FOptions.size()))
  232. {
  233. if ((FOptions[Index].Type == otSwitch) &&
  234. !FOptions[Index].Used)
  235. {
  236. Switch = FOptions[Index].Name;
  237. Result = true;
  238. }
  239. ++Index;
  240. }
  241. return Result;
  242. }
  243. //---------------------------------------------------------------------------
  244. void __fastcall TOptions::ParamsProcessed(int ParamsStart, int ParamsCount)
  245. {
  246. if (ParamsCount > 0)
  247. {
  248. assert((ParamsStart >= 0) && ((ParamsStart - ParamsCount + 1) <= FParamCount));
  249. size_t Index = 0;
  250. while ((Index < FOptions.size()) && (ParamsStart > 0))
  251. {
  252. if (FOptions[Index].Type == otParam)
  253. {
  254. --ParamsStart;
  255. if (ParamsStart == 0)
  256. {
  257. while (ParamsCount > 0)
  258. {
  259. assert(Index < FOptions.size());
  260. assert(FOptions[Index].Type == otParam);
  261. FOptions.erase(FOptions.begin() + Index);
  262. --FParamCount;
  263. --ParamsCount;
  264. }
  265. }
  266. }
  267. Index++;
  268. }
  269. }
  270. }