1 //
2 // srecord - manipulate eprom load files
3 // Copyright (C) 1998-2014 Peter Miller
4 // Copyright (C) 2014 Scott Finneran
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or (at
9 // your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 
20 #ifndef SRECORD_ARGLEX_TOOL_H
21 #define SRECORD_ARGLEX_TOOL_H
22 
23 #include <srecord/arglex.h>
24 #include <srecord/defcon.h>
25 #include <srecord/endian.h>
26 #include <srecord/input.h>
27 #include <srecord/output.h>
28 
29 
30 namespace srecord
31 {
32 
33 class interval; // forward
34 
35 /**
36   * The srecord::arglex_tool is used to parse command line with srec-specific
37   * arguments.
38   */
39 class arglex_tool:
40     public arglex
41 {
42 public:
43     enum
44     {
45         token_a430 = arglex::token_MAX,
46         token_adler16_be,
47         token_adler16_le,
48         token_adler32_be,
49         token_adler32_le,
50         token_and,
51         token_aomf,
52         token_ascii_hex,
53         token_assembler,
54         token_atmel_generic_be,
55         token_atmel_generic_le,
56         token_basic_data,
57         token_big,
58         token_binary,
59         token_bitrev,
60         token_brecord,
61         token_byte_swap,
62         token_c_array,
63         token_c_compressed,
64         token_checksum_be_bitnot,
65         token_checksum_be_negative,
66         token_checksum_be_positive,
67         token_checksum_le_bitnot,
68         token_checksum_le_negative,
69         token_checksum_le_positive,
70         token_cl430,
71         token_constant,
72         token_constant_be,
73         token_constant_le,
74         token_constant_not,
75         token_contradictory_bytes,
76         token_cosmac,
77         token_crc16_augment,
78         token_crc16_augment_not,
79         token_crc16_be,
80         token_crc16_broken,
81         token_crc16_ccitt,
82         token_crc16_le,
83         token_crc16_least_to_most,
84         token_crc16_most_to_least,
85         token_crc16_xmodem,
86         token_crc32_be,
87         token_crc32_le,
88         token_crop,
89         token_dec_binary,
90         token_eeprom,
91         token_emon52,
92         token_exclude,
93         token_exclusive_length,
94         token_exclusive_length_be,
95         token_exclusive_length_le,
96         token_exclusive_maximum,
97         token_exclusive_maximum_be,
98         token_exclusive_maximum_le,
99         token_exclusive_minimum,
100         token_exclusive_minimum_be,
101         token_exclusive_minimum_le,
102         token_fairchild,
103         token_fast_load,
104         token_fill,
105         token_fletcher16_be,
106         token_fletcher16_le,
107         token_fletcher32_be,
108         token_fletcher32_le,
109         token_formatted_binary,
110         token_forth,
111         token_four_packed_code,
112         token_gcrypt,
113         token_generator,
114         token_guess,
115         token_haval,
116         token_hexdump,
117         token_idt,
118         token_ignore_checksums,
119         token_lattice_memory_initialization_format,
120         token_logisim,
121         token_include,
122         token_include_not,
123         token_intel,
124         token_intel16,
125         token_intersection,
126         token_length,
127         token_length_be,
128         token_length_le,
129         token_maximum_address,
130         token_maximum_be,
131         token_maximum_le,
132         token_md2,
133         token_md5,
134         token_memory_initialization_file,
135         token_minimum_address,
136         token_minimum_be,
137         token_minimum_le,
138         token_minus,
139         token_mips_flash_be,
140         token_mips_flash_le,
141         token_mos_tech,
142         token_motorola,
143         token_msbin,
144         token_multiple,
145         token_needham_hex,
146         token_not,
147         token_offset,
148         token_ohio_scientific,
149         token_or,
150         token_output,
151         token_output_word,
152         token_over,
153         token_paren_begin,
154         token_paren_end,
155         token_polynomial,
156         token_postfix,
157         token_ppb,
158         token_ppx,
159         token_prefix,
160         token_ram,
161         token_random,
162         token_random_fill,
163         token_range_padding,
164         token_redundant_bytes,
165         token_repeat_data,
166         token_repeat_string,
167         token_rmd160,
168         token_round_down,
169         token_round_nearest,
170         token_round_up,
171         token_sequence_warnings_disable,
172         token_sequence_warnings_enable,
173         token_sha1,
174         token_sha224,
175         token_sha256,
176         token_sha384,
177         token_sha512,
178         token_signetics,
179         token_spasm_be,
180         token_spasm_le,
181         token_spectrum,
182         token_split,
183         token_stewie,
184         token_stm32_crc_be,
185         token_stm32_crc_le,
186         token_style_dot,
187         token_style_hexadecimal,
188         token_style_hexadecimal_not,
189         token_style_section,
190         token_tektronix,
191         token_tektronix_extended,
192         token_tiger,
193         token_ti_tagged,
194         token_ti_tagged_16,
195         token_ti_txt,
196         token_trs80,
197         token_unfill,
198         token_union,
199         token_unsplit,
200         token_vhdl,
201         token_vmem,
202         token_whirlpool,
203         token_wilson,
204         token_within,
205         token_xilinx_coefficient_file,
206         token_xor,
207         token_MAX
208     };
209 
210     /**
211       * The destructor.
212       */
213     virtual ~arglex_tool();
214 
215     /**
216       * The constructor.  Pass the argc and argv as given to main;
217       * there is not need to change the values at all.
218       */
219     arglex_tool(int argc, char **argv);
220 
221     /**
222       * The get_input method is used to parse an input specification
223       * (filename, file format, filters, everything) from the
224       * command line.
225       *
226       * If the parse is unsuccessful (is not present on command
227       * line) a fatal error will be issued and the method call will
228       * not return.
229       */
230     input::pointer get_input(void);
231 
232     /**
233       * The get_output method is used to parse an output specification
234       * (filename and file format) from the command line.
235       *
236       * If the parse is unsuccessful (is not present on command
237       * line) a fatal error will be issued and the method call will
238       * not return.
239       */
240     output::pointer get_output(void);
241 
242     /**
243       * The get_number method is used to parse a numeric value from the
244       * command line.
245       */
246     unsigned long get_number(const char *caption);
247 
248     /**
249       * The get_number method is used to parse a numeric value
250       * from the command line, and check it agains a specified range.
251       *
252       * @param caption
253       *     for the error message, if necessary
254       * @param min
255       *     The minimum acceptable value (inclusive)
256       * @param max
257       *     The maximum acceptable value (inclusive)
258       */
259     unsigned long get_number(const char *caption, long min, long max);
260 
261     /**
262       * The can_get_number method is used to determine if it is possible
263       * to parse a number from the next token on the command line.
264       */
265     bool can_get_number(void) const;
266 
267     /**
268       * The get_interval method is used to parse an interval
269       * set form the command line.  It consists of as many
270       * get_interval_inner()s as possible.
271       *
272       * Used by the get_input method to parse the address intervals used
273       * by various filters.  It is the lowest precedence level, and
274       * handsles set union (the implicit operator) and set difference
275       * (the - operator).
276       *
277       * If the parse is unsuccessful (is not present on command
278       * line) a fatal error will be issued and the method call will
279       * not return.
280       */
281     interval get_interval(const char *err_msg_caption);
282 
283     /**
284       * The get_interval_small method may be used to parse an interval
285       * set form the command line.  It checks that the interval is
286       * <=1GB, and errors if it is not, with a --big override.  Commonly
287       * used to sanity check things like --fill.
288       */
289     interval get_interval_small(const char *err_msg_caption);
290 
291     /**
292       * The get_string method may be used to get a string from the
293       * command line, or issue a fatal error if one is not available.
294       *
295       * @param caption
296       *     The text for the error message.
297       */
298     std::string get_string(const char *caption);
299 
300     // See base class for documentation.
301     void default_command_line_processing(void);
302 
get_redundant_bytes(void)303     defcon_t get_redundant_bytes(void) const { return redundant_bytes; }
get_contradictory_bytes(void)304     defcon_t get_contradictory_bytes(void) const { return contradictory_bytes; }
305 
306 private:
307     /**
308       * The get_interval_factor method is used to parse a single
309       * interval from the command line (usually, a pair of number
310       * representing the [lower, upper) bounds, but it could be
311       * -over or -within, too).
312       *
313       * This method parses the highest precedence operators in the range
314       * parsing.
315       *
316       * This method should only every be called by the get_interval_term
317       * method.
318       *
319       * If the parse is unsuccessful (is not present on command
320       * line) a fatal error will be issued and the method call will
321       * not return.
322       */
323     interval get_interval_factor(const char *err_msg_caption);
324 
325     /**
326       * The get_interval_term method is used to parse set-intersection
327       * precedence intervals from the command line.  This method parses
328       * the middle precedence operators in the range parsing.
329       *
330       * This method should only every be called by the get_interval_term
331       * method.
332       *
333       * If the parse is unsuccessful (is not present on command
334       * line) a fatal error will be issued and the method call will
335       * not return.
336       */
337     interval get_interval_term(const char *err_msg_caption);
338 
339     /**
340       * The get_address method is used to parse an address from the
341       * command line.
342       *
343       * If the parse is unsuccessful (is not present on command
344       * line) a fatal error will be issued and the method call will
345       * not return.
346       */
347     void get_address(const char *err_msg_caption, unsigned long &addr);
348 
349     /**
350       * The get_address_and_nbytes method is used to parse an address
351       * and a byte count from the command line.
352       *
353       * If the parse is unsuccessful (is not present on command
354       * line) a fatal error will be issued and the method call will
355       * not return.
356       */
357     void get_address_and_nbytes(const char *err_msg_caption,
358             unsigned long &addr, int &nbytes);
359 
360     /**
361       * The get_address_nbytes_width method is used to parse an address
362       * a byte count and a width from the command line.
363       *
364       * If the parse is unsuccessful (is not present on command
365       * line) a fatal error will be issued and the method call will
366       * not return.
367       */
368     void get_address_nbytes_width(const char *err_msg_caption,
369         unsigned long &addr, int &nbytes, int &width);
370 
371     /**
372       * The stdin_used instance variable is used to remember whether
373       * or not the standard input has been used by a filter, yet.
374       * Only one use of the standard input may be made; the second
375       * use will result in a fatal error.
376       */
377     bool stdin_used;
378 
379     /**
380       * The stdout_used instance variable is used to remember whether
381       * or not the standard output has been used by a filter, yet.
382       * Only one use of the standard output may be made; the second
383       * use will result in a fatal error.
384       */
385     bool stdout_used;
386 
387     /**
388       * The issue_sequence_warnings instance variable is used to
389       * remember whether or not to issue data sequence warnings when
390       * data records are not in strictly ascending address order.
391       *
392       * Negative means not set from the command line, zero means diabled
393       * from the command line, positive means enabled on the command
394       * line.
395       */
396     int issue_sequence_warnings;
397 
398     /**
399       * The get_simple_input method is used to parse an input filename
400       * or generator from the command line.  It shall only be used by
401       * the #get_input method.
402       *
403       * If the parse is unsuccessful (is not present on command
404       * line) a fatal error will be issued and the method call will
405       * not return.
406       */
407     input::pointer get_simple_input();
408 
409     /**
410       * The get_endian_by_token method is sued to obtain the endian-ness
411       * of a given token.  This is for when there are big-endian and
412       * little-endian variants of filters and file formats.
413       *
414       * @param tok
415       *     the noken the endien-ness is required for.
416       */
417     endian_t get_endian_by_token(int tok) const;
418 
419     /**
420       * The get_endian_by_token method is sued to obtain the endian-ness
421       * of the current token.
422       */
423     endian_t
get_endian_by_token(void)424     get_endian_by_token(void)
425         const
426     {
427         return get_endian_by_token(token_cur());
428     }
429 
430     /**
431       * The get_inclusive_by_token method is used to determine whether
432       * or not a token is inclusive (e.g. token_length_be) or exclusive
433       * (e.g. token_exclusive_length_be).
434       *
435       * @param tok
436       *     The token to examine.
437       */
438     bool get_inclusive_by_token(int tok) const;
439 
440     /**
441       * The get_inclusive_by_token method is used to determine whether
442       * or not the current token is inclusive or exclusive.
443       */
444     bool
get_inclusive_by_token(void)445     get_inclusive_by_token(void)
446         const
447     {
448         return get_inclusive_by_token(token_cur());
449     }
450 
451     /**
452       * The redundant_bytes instance variable is used to remember what
453       * to do when faced with multiple identical byte values for a
454       * memory address.
455       */
456     defcon_t redundant_bytes;
457 
458     /**
459       * The vontradivtory_bytes instance variable is used to remember what
460       * to do when faced with multiple different byte values for a
461       * memory address.
462       */
463     defcon_t contradictory_bytes;
464 
465     /**
466       * The default constructor.  Do not use.
467       */
468     arglex_tool();
469 
470     /**
471       * The copy constructor.  Do not use.
472       */
473     arglex_tool(const arglex_tool &);
474 
475     /**
476       * The assignment operator.  Do not use.
477       */
478     arglex_tool &operator=(const arglex_tool &);
479 };
480 
481 };
482 
483 // vim: set ts=8 sw=4 et :
484 #endif // SRECORD_ARGLEX_TOOL_H
485