xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/unittests/cli-utils-selftests.c (revision 7f2ac4106a41b75cd7b67d794305c00f598853fb)
1 /* Unit tests for the cli-utils.c file.
2 
3    Copyright (C) 2018-2019 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 "common/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 }
254