@@ -189,7 +189,7 @@ export namespace gerber {
189
189
Zeros (Enum value) :
190
190
value (value) {}
191
191
192
- static Enum from_string (const std::string_view& str) {
192
+ static Enum fromString (const std::string_view& str) {
193
193
if (str == " L" ) {
194
194
return Enum::SKIP_LEADING;
195
195
} else if (str == " T" ) {
@@ -223,7 +223,7 @@ export namespace gerber {
223
223
CoordinateNotation (Enum value) :
224
224
value (value) {}
225
225
226
- static CoordinateNotation from_string (const std::string_view& str) {
226
+ static CoordinateNotation fromString (const std::string_view& str) {
227
227
if (str == " A" ) {
228
228
return Enum::ABSOLUTE;
229
229
} else if (str == " I" ) {
@@ -259,8 +259,8 @@ export namespace gerber {
259
259
int x_decimal,
260
260
int y_integral,
261
261
int y_decimal) :
262
- zeros (Zeros::from_string (zeros)),
263
- coordinate_mode (CoordinateNotation::from_string (coordinate_mode)),
262
+ zeros (Zeros::fromString (zeros)),
263
+ coordinate_mode (CoordinateNotation::fromString (coordinate_mode)),
264
264
x_integral (x_integral),
265
265
x_decimal (x_decimal),
266
266
y_integral (y_integral),
@@ -271,6 +271,57 @@ export namespace gerber {
271
271
}
272
272
};
273
273
274
+ class UnitMode {
275
+ public:
276
+ enum Enum : uint8_t {
277
+ INCHES,
278
+ MILLIMETERS
279
+ };
280
+
281
+ Enum value;
282
+
283
+ private:
284
+ UnitMode () = delete ;
285
+
286
+ public:
287
+ UnitMode (Enum value) :
288
+ value (value) {}
289
+
290
+ static UnitMode fromString (const std::string_view& str) {
291
+ if (str == " IN" ) {
292
+ return Enum::INCHES;
293
+ } else if (str == " MM" ) {
294
+ return Enum::MILLIMETERS;
295
+ }
296
+ throw std::invalid_argument (" Invalid unit mode" );
297
+ }
298
+
299
+ std::string toString () const {
300
+ return value == Enum::INCHES ? " IN" : " MM" ;
301
+ }
302
+
303
+ bool operator ==(const UnitMode& other) const {
304
+ return value == other.value ;
305
+ }
306
+
307
+ bool operator ==(const Enum& other) const {
308
+ return value == other;
309
+ }
310
+ };
311
+
312
+ class MO : public ExtendedCommand {
313
+ public:
314
+ UnitMode unit_mode;
315
+
316
+ public:
317
+ MO (const std::string_view& unit_mode) :
318
+ unit_mode (UnitMode::fromString(unit_mode)) {}
319
+
320
+ std::string getNodeName () const override {
321
+ return " MO" ;
322
+ }
323
+ };
324
+
274
325
class SyntaxError : public std ::runtime_error {
275
326
public:
276
327
explicit SyntaxError (const std::string& message) :
@@ -284,18 +335,16 @@ export namespace gerber {
284
335
location_t global_index;
285
336
// Regular expressions cache
286
337
// G-codes
287
- std::regex g_code_regex;
288
- std::regex g04_regex;
338
+ std::regex g_code_regex{ " ^[Gg]0*([1-9][0-9]*) \\ * " } ;
339
+ std::regex g04_regex{ " ^[Gg]0*4([^%*]+) \\ * " } ;
289
340
// Properties
290
- std::regex fs_regex;
341
+ std::regex fs_regex{" ^%FS([TL])([IA])X([0-9])([0-9])Y([0-9])([0-9])\\ *%" };
342
+ std::regex mo_regex{" ^%MO(IN|MM)\\ *%" };
291
343
292
344
Parser () :
293
345
commands (0 ),
294
346
full_source (" " ),
295
- global_index (0 ),
296
- g_code_regex (" ^[Gg]0*([1-9][0-9]*)\\ *" ),
297
- g04_regex (" ^[Gg]0*4([^%*]+)\\ *" ),
298
- fs_regex (" ^%FS([TL])([IA])X([0-9])([0-9])Y([0-9])([0-9])\\ *%" ) {}
347
+ global_index (0 ) {}
299
348
300
349
~Parser () {}
301
350
@@ -449,6 +498,10 @@ export namespace gerber {
449
498
return parse_fs_command (source, index);
450
499
break ;
451
500
501
+ case ' M' :
502
+ return parse_mo_command (source, index);
503
+ break ;
504
+
452
505
default :
453
506
break ;
454
507
}
@@ -482,5 +535,25 @@ export namespace gerber {
482
535
}
483
536
throw_syntax_error ();
484
537
}
538
+
539
+ offset_t parse_mo_command (const std::string_view& source, const location_t & index) {
540
+ if (source.length () < 6 ) {
541
+ throw_syntax_error ();
542
+ }
543
+ std::cmatch match;
544
+
545
+ const auto result = std::regex_search (
546
+ source.data (),
547
+ source.data () + source.size (),
548
+ match,
549
+ mo_regex,
550
+ std::regex_constants::match_continuous
551
+ );
552
+ if (result && match.size () == 2 ) {
553
+ commands.push_back (std::make_shared<MO>(match[1 ].str ()));
554
+ return match.length ();
555
+ }
556
+ throw_syntax_error ();
557
+ }
485
558
};
486
559
} // namespace gerber
0 commit comments