OpenTTD Source  20240919-master-gdf0233f4c2
getoptdata.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "../stdafx.h"
11 #include "getoptdata.h"
12 
13 #include "../safeguards.h"
14 
23 {
24  const char *s = this->cont;
25  if (s == nullptr) {
26  if (this->arguments.empty()) return -1; // No arguments left -> finished.
27 
28  s = this->arguments[0];
29  if (*s != '-') return -1; // No leading '-' -> not an option -> finished.
30 
31  this->arguments = this->arguments.subspan(1);
32 
33  /* Is it a long option? */
34  for (auto &option : this->options) {
35  if (option.longname != nullptr && !strcmp(option.longname, s)) { // Long options always use the entire argument.
36  this->cont = nullptr;
37  return this->GetOpt(option);
38  }
39  }
40 
41  s++; // Skip leading '-'.
42  }
43 
44  /* Is it a short option? */
45  for (auto &option : this->options) {
46  if (option.shortname != '\0' && *s == option.shortname) {
47  this->cont = (s[1] != '\0') ? s + 1 : nullptr;
48  return this->GetOpt(option);
49  }
50  }
51 
52  return -2; // No other ways to interpret the text -> error.
53 }
54 
55 int GetOptData::GetOpt(const OptionData &option)
56 {
57  this->opt = nullptr;
58  switch (option.type) {
59  case ODF_NO_VALUE:
60  return option.id;
61 
62  case ODF_HAS_VALUE:
63  case ODF_OPTIONAL_VALUE:
64  if (this->cont != nullptr) { // Remainder of the argument is the option value.
65  this->opt = this->cont;
66  this->cont = nullptr;
67  return option.id;
68  }
69  /* No more arguments, either return an error or a value-less option. */
70  if (this->arguments.empty()) return (option.type == ODF_HAS_VALUE) ? -2 : option.id;
71 
72  /* Next argument looks like another option, let's not return it as option value. */
73  if (option.type == ODF_OPTIONAL_VALUE && this->arguments[0][0] == '-') return option.id;
74 
75  this->opt = this->arguments[0]; // Next argument is the option value.
76  this->arguments = this->arguments.subspan(1);
77  return option.id;
78 
79  default: NOT_REACHED();
80  }
81 }
82 
GetOptData::opt
const char * opt
Option value, if available (else nullptr).
Definition: getoptdata.h:35
GetOptData::cont
const char * cont
Next call to GetOpt should start here (in the middle of an argument).
Definition: getoptdata.h:36
GetOptData::arguments
ArgumentSpan arguments
Remaining command line arguments.
Definition: getoptdata.h:33
ODF_OPTIONAL_VALUE
@ ODF_OPTIONAL_VALUE
An option with an optional value.
Definition: getoptdata.h:17
ODF_HAS_VALUE
@ ODF_HAS_VALUE
An option with a value.
Definition: getoptdata.h:16
ODF_NO_VALUE
@ ODF_NO_VALUE
A plain option (no value attached to it).
Definition: getoptdata.h:15
OptionData
Data of an option.
Definition: getoptdata.h:21
OptionData::type
OptionDataType type
The type of option.
Definition: getoptdata.h:22
OptionData::id
char id
Unique identification of this option data, often the same as shortname.
Definition: getoptdata.h:23
GetOptData::GetOpt
int GetOpt()
Find the next option.
Definition: getoptdata.cpp:22
getoptdata.h
GetOptData::options
const OptionSpan options
Command line option descriptions.
Definition: getoptdata.h:34