Fix compile error with clang 3.8
[external/binutils.git] / gdb / unittests / cli-utils-selftests.c
1 /* Unit tests for the cli-utils.c file.
2
3    Copyright (C) 2018 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "cli/cli-utils.h"
22 #include "selftest.h"
23
24 namespace selftests {
25 namespace cli_utils {
26
27 static void
28 test_number_or_range_parser ()
29 {
30   /* Test parsing a simple integer.  */
31   {
32     number_or_range_parser one ("1");
33
34     SELF_CHECK (!one.finished ());
35     SELF_CHECK (one.get_number () == 1);
36     SELF_CHECK (one.finished ());
37     SELF_CHECK (strcmp (one.cur_tok (), "") == 0);
38   }
39
40   /* Test parsing an integer followed by a non integer.  */
41   {
42     number_or_range_parser one_after ("1 after");
43
44     SELF_CHECK (!one_after.finished ());
45     SELF_CHECK (one_after.get_number () == 1);
46     SELF_CHECK (one_after.finished ());
47     SELF_CHECK (strcmp (one_after.cur_tok (), "after") == 0);
48   }
49
50   /* Test parsing a range.  */
51   {
52     number_or_range_parser one_three ("1-3");
53
54     for (int i = 1; i < 4; i++)
55       {
56         SELF_CHECK (!one_three.finished ());
57         SELF_CHECK (one_three.get_number () == i);
58       }
59     SELF_CHECK (one_three.finished ());
60     SELF_CHECK (strcmp (one_three.cur_tok (), "") == 0);
61   }
62
63   /* Test parsing a range followed by a non-integer.  */
64   {
65     number_or_range_parser one_three_after ("1-3 after");
66
67     for (int i = 1; i < 4; i++)
68       {
69         SELF_CHECK (!one_three_after.finished ());
70         SELF_CHECK (one_three_after.get_number () == i);
71       }
72     SELF_CHECK (one_three_after.finished ());
73     SELF_CHECK (strcmp (one_three_after.cur_tok (), "after") == 0);
74   }
75
76   /* Test a negative integer gives an error.  */
77   {
78     number_or_range_parser minus_one ("-1");
79
80     SELF_CHECK (!minus_one.finished ());
81     TRY
82       {
83         minus_one.get_number ();
84         SELF_CHECK (false);
85       }
86     CATCH (ex, RETURN_MASK_ERROR)
87       {
88         SELF_CHECK (ex.reason == RETURN_ERROR);
89         SELF_CHECK (ex.error == GENERIC_ERROR);
90         SELF_CHECK (strcmp (ex.message, "negative value") == 0);
91         SELF_CHECK (strcmp (minus_one.cur_tok (), "-1") == 0);
92       }
93     END_CATCH;
94   }
95
96   /* Test that a - followed by not a number does not give an error.  */
97   {
98     number_or_range_parser nan ("-whatever");
99
100     SELF_CHECK (nan.finished ());
101     SELF_CHECK (strcmp (nan.cur_tok (), "-whatever") == 0);
102   }
103 }
104
105 static void
106 test_parse_flags ()
107 {
108   const char *flags = "abc";
109   const char *non_flags_args = "non flags args";
110
111   /* Extract twice the same flag, separated by one space.  */
112   {
113     const char *t1 = "-a -a non flags args";
114
115     SELF_CHECK (parse_flags (&t1, flags) == 1);
116     SELF_CHECK (parse_flags (&t1, flags) == 1);
117     SELF_CHECK (strcmp (t1, non_flags_args) == 0);
118   }
119
120   /* Extract some flags, separated by one or more spaces.  */
121   {
122     const char *t2 = "-c     -b -c  -b -c    non flags args";
123
124     SELF_CHECK (parse_flags (&t2, flags) == 3);
125     SELF_CHECK (parse_flags (&t2, flags) == 2);
126     SELF_CHECK (parse_flags (&t2, flags) == 3);
127     SELF_CHECK (parse_flags (&t2, flags) == 2);
128     SELF_CHECK (parse_flags (&t2, flags) == 3);
129     SELF_CHECK (strcmp (t2, non_flags_args) == 0);
130   }
131
132   /* Check behaviour where there is no flag to extract.  */
133   {
134     const char *t3 = non_flags_args;
135
136     SELF_CHECK (parse_flags (&t3, flags) == 0);
137     SELF_CHECK (strcmp (t3, non_flags_args) == 0);
138   }
139
140   /* Extract 2 known flags in front of unknown flags.  */
141   {
142     const char *t4 = "-c -b -x -y -z -c";
143
144     SELF_CHECK (parse_flags (&t4, flags) == 3);
145     SELF_CHECK (parse_flags (&t4, flags) == 2);
146     SELF_CHECK (strcmp (t4, "-x -y -z -c") == 0);
147     SELF_CHECK (parse_flags (&t4, flags) == 0);
148     SELF_CHECK (strcmp (t4, "-x -y -z -c") == 0);
149   }
150
151   /* Check combined flags are not recognised.  */
152   {
153     const char *t5 = "-c -cb -c";
154
155     SELF_CHECK (parse_flags (&t5, flags) == 3);
156     SELF_CHECK (parse_flags (&t5, flags) == 0);
157     SELF_CHECK (strcmp (t5, "-cb -c") == 0);
158   }
159 }
160
161 static void
162 test_parse_flags_qcs ()
163 {
164   const char *non_flags_args = "non flags args";
165
166   /* Test parsing of 2 flags out of the known 3.  */
167   {
168     const char *t1 = "-q -s    non flags args";
169     qcs_flags flags;
170
171     SELF_CHECK (parse_flags_qcs ("test_parse_flags_qcs.t1.q",
172                                  &t1,
173                                  &flags) == 1);
174     SELF_CHECK (flags.quiet && !flags.cont && !flags.silent);
175     SELF_CHECK (parse_flags_qcs ("test_parse_flags_qcs.t1.s",
176                                  &t1,
177                                  &flags) == 1);
178     SELF_CHECK (flags.quiet && !flags.cont && flags.silent);
179     SELF_CHECK (strcmp (t1, non_flags_args) == 0);
180   }
181
182   /* Test parsing when there is no flag.  */
183   {
184     const char *t2 = "non flags args";
185     qcs_flags flags;
186
187     SELF_CHECK (parse_flags_qcs ("test_parse_flags_qcs.t2",
188                                  &t2,
189                                  &flags) == 0);
190     SELF_CHECK (!flags.quiet && !flags.cont && !flags.silent);
191     SELF_CHECK (strcmp (t2, non_flags_args) == 0);
192   }
193
194   /* Test parsing stops at a negative integer.  */
195   {
196     const char *t3 = "-123 non flags args";
197     const char *orig_t3 = t3;
198     qcs_flags flags;
199
200     SELF_CHECK (parse_flags_qcs ("test_parse_flags_qcs.t3",
201                                  &t3,
202                                  &flags) == 0);
203     SELF_CHECK (!flags.quiet && !flags.cont && !flags.silent);
204     SELF_CHECK (strcmp (t3, orig_t3) == 0);
205   }
206
207   /* Test mutual exclusion between -c and -s.  */
208   {
209     const char *t4 = "-c -s non flags args";
210     qcs_flags flags;
211
212     TRY
213       {
214         SELF_CHECK (parse_flags_qcs ("test_parse_flags_qcs.t4.cs",
215                                      &t4,
216                                      &flags) == 1);
217
218         (void) parse_flags_qcs ("test_parse_flags_qcs.t4.cs",
219                                 &t4,
220                                 &flags);
221         SELF_CHECK (false);
222       }
223     CATCH (ex, RETURN_MASK_ERROR)
224       {
225         SELF_CHECK (ex.reason == RETURN_ERROR);
226         SELF_CHECK (ex.error == GENERIC_ERROR);
227         SELF_CHECK
228           (strcmp (ex.message,
229                    "test_parse_flags_qcs.t4.cs: "
230                    "-c and -s are mutually exclusive") == 0);
231       }
232     END_CATCH;
233   }
234
235 }
236
237 static void
238 test_cli_utils ()
239 {
240   selftests::cli_utils::test_number_or_range_parser ();
241   selftests::cli_utils::test_parse_flags ();
242   selftests::cli_utils::test_parse_flags_qcs ();
243 }
244
245 }
246 }
247
248 void
249 _initialize_cli_utils_selftests ()
250 {
251   selftests::register_test ("cli_utils",
252                             selftests::cli_utils::test_cli_utils);
253 }