Used to ensure that an AI component conforms to the North American Coupon Code (NACC) specification, as carried in AI (8110).
185{
186
188 size_t pos;
189 int vli;
190 const char *p, *q;
191 char expiry_date[7] = {0};
192 int expiry_set = 0;
193 char gcp[14] = {0};
194
195 assert(data);
196
197
198
199
200
201 for (pos = 0; data[pos] != '\0'; pos++) {
205 pos,
206 1
207 );
208 }
209
210 p = data;
211 q = data + pos;
212
213
214
215
216
217
218
219
220
224 0,
225 (size_t)(q - data)
226 );
230 (size_t)(p - data),
231 1
232 );
233 vli = *p - '0' + 6;
234
238 (p == q) ? 0 : (size_t)(p - data),
239 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
240 );
241
242
243
244
245
246 strncpy(gcp, p, (size_t)vli);
248
252
255 ret,
256 (size_t)(p - data),
257 (size_t)vli
258 );
259
260 p += vli;
261
262
263
264
265
266
270 (p == q) ? 0 : (size_t)(p - data),
271 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
272 );
273
274 p += 6;
275
276
277
278
279
280
281
282
283
287 0,
288 (size_t)(q - data)
289 );
293 (size_t)(p - data),
294 1
295 );
296 vli = *p - '0';
297
301 (p == q) ? 0 : (size_t)(p - data),
302 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
303 );
304
305 p += vli;
306
307
308
309
310
311
312
313
314
318 0,
319 (size_t)(q - data)
320 );
324 (size_t)(p - data),
325 1
326 );
327 vli = *p - '0';
328
332 (p == q) ? 0 : (size_t)(p - data),
333 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
334 );
335
336 p += vli;
337
338
339
340
341
342
343
344
345
349 0,
350 (size_t)(q - data)
351 );
352
356 (size_t)(p - data),
357 1
358 );
359
360
361
362
363
364
368 (p == q) ? 0 : (size_t)(p - data),
369 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
370 );
371
372 p += 3;
373
374
375
376
377
378
379
380
381
382 if (p < q && *p == '1') {
383
384
385
386
387
388
389
390
394 0,
395 (size_t)(q - data)
396 );
397
401 (size_t)(p - data),
402 1
403 );
404
405
406
407
408
409
410
411
412
413
417 0,
418 (size_t)(q - data)
419 );
423 (size_t)(p - data),
424 1
425 );
426 vli = *p - '0';
427
431 (p == q) ? 0 : (size_t)(p - data),
432 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
433 );
434
435 p += vli;
436
437
438
439
440
441
442
443
444
448 0,
449 (size_t)(q - data)
450 );
451
455 (size_t)(p - data),
456 1
457 );
458
459
460
461
462
463
464
468 (p == q) ? 0 : (size_t)(p - data),
469 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
470 );
471
472 p += 3;
473
474
475
476
477
478
479
480
481
482
486 0,
487 (size_t)(q - data)
488 );
492 (size_t)(p - data),
493 1
494 );
495 vli = (*p != '9') ? *p - '0' + 6 : 0;
496
500 (p == q) ? 0 : (size_t)(p - data),
501 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
502 );
503
504
505
506
507
508 strncpy(gcp, p, (size_t)vli);
510
514
517 ret,
518 (size_t)(p - data),
519 (size_t)vli
520 );
521
522 p += vli;
523
524 }
525
526
527
528
529
530
531
532
533
534 if (p < q && *p == '2') {
535
536
537
538
539
540
541
542
543
547 0,
548 (size_t)(q - data)
549 );
553 (size_t)(p - data),
554 1
555 );
556 vli = *p - '0';
557
561 (p == q) ? 0 : (size_t)(p - data),
562 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
563 );
564
565 p += vli;
566
567
568
569
570
571
572
573
574
578 0,
579 (size_t)(q - data)
580 );
581
585 (size_t)(p - data),
586 1
587 );
588
589
590
591
592
593
594
598 (p == q) ? 0 : (size_t)(p - data),
599 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
600 );
601
602 p += 3;
603
604
605
606
607
608
609
610
611
612
616 0,
617 (size_t)(q - data)
618 );
622 (size_t)(p - data),
623 1
624 );
625 vli = (*p != '9') ? *p - '0' + 6 : 0;
626
630 (p == q) ? 0 : (size_t)(p - data),
631 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
632 );
633
634
635
636
637
638 strncpy(gcp, p, (size_t)vli);
640
644
647 ret,
648 (size_t)(p - data),
649 (size_t)vli
650 );
651
652 p += vli;
653
654 }
655
656
657
658
659
660
661
662
663
664 if (p < q && *p == '3') {
665
666
667
668
669
673 (p == q) ? 0 : (size_t)(p - data),
674 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
675 );
676
677 memcpy(expiry_date, p, 6);
679
686
690 (size_t)(p - data),
691 6
692 );
693
694 p += 6;
695
696 expiry_set = 1;
697
698 }
699
700
701
702
703
704
705
706
707
708 if (p < q && *p == '4') {
709
710 char start_date[7] = {0};
711
712
713
714
715
719 (p == q) ? 0 : (size_t)(p - data),
720 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
721 );
722
723 memcpy(start_date, p, 6);
725
732
736 (size_t)(p - data),
737 6
738 );
739
740
741
742
743
744
748 (size_t)(p - data - 8),
749 14
750 );
751
752 p += 6;
753
754 }
755
756
757
758
759
760
761
762
763
764 if (p < q && *p == '5') {
765
766
767
768
769
770
774 0,
775 (size_t)(q - data)
776 );
777 vli = *p - '0' + 6;
778
782 (p == q) ? 0 : (size_t)(p - data),
783 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
784 );
785
786 p += vli;
787
788 }
789
790
791
792
793
794
795
796
797
798 if (p < q && *p == '6') {
799
800
801
802
803
804
805
806
810 0,
811 (size_t)(q - data)
812 );
816 (size_t)(p - data),
817 1
818 );
819 vli = *p - '0' + 6;
820
824 (p == q) ? 0 : (size_t)(p - data),
825 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
826 );
827
828
829
830
831
832 strncpy(gcp, p, (size_t)vli);
834
838
841 ret,
842 (size_t)(p - data),
843 (size_t)vli
844 );
845
846 p += vli;
847
848 }
849
850
851
852
853
854
855
856
857
858 if (p < q && *p == '9') {
859
860
861
862
863
864
865
866
870 0,
871 (size_t)(q - data)
872 );
876 (size_t)(p - data),
877 1
878 );
879
880
881
882
883
884
885
886
890 0,
891 (size_t)(q - data)
892 );
896 (size_t)(p - data),
897 1
898 );
899
900
901
902
903
904
905
909 0,
910 (size_t)(q - data)
911 );
912
913
914
915
916
917
918
919
923 0,
924 (size_t)(q - data)
925 );
929 (size_t)(p - data),
930 1
931 );
932
933 p++;
934
935 }
936
937
938
939
940
944 (size_t)(p - data),
945 (size_t)(q - p)
946 );
947
949
950}
#define GS1_LINTER_UNLIKELY(x)
Implemention may provide hint to the compiler that the expression is likely to be false.
Definition gs1syntaxdictionary-utils.h:76
#define GS1_LINTER_RETURN_ERROR(error, position, length)
Return from a linter indicating that a problem was detected with the given data.
Definition gs1syntaxdictionary-utils.h:103
#define GS1_LINTER_RETURN_OK
Return from a linter indicating that no problem was detected with the given data.
Definition gs1syntaxdictionary-utils.h:88
GS1_SYNTAX_DICTIONARY_API gs1_lint_err_t gs1_lint_yymmdd(const char *data, size_t *err_pos, size_t *err_len)
Definition lint_yymmdd.c:53
gs1_lint_err_t
Linter return codes other than GS1_LINTER_OK indicate an error condition.
Definition gs1syntaxdictionary.h:76
@ GS1_LINTER_ILLEGAL_DAY
The date contains an illegal day of the month.
Definition gs1syntaxdictionary.h:114
@ GS1_LINTER_COUPON_TRUNCATED_2ND_PURCHASE_FAMILY_CODE
The coupon's second purchase Family Code is shorter than the required three digits.
Definition gs1syntaxdictionary.h:150
@ GS1_LINTER_COUPON_TRUNCATED_RETAILER_GCP_OR_GLN
The coupon's Retailer GCP/GLN is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:170
@ GS1_LINTER_COUPON_INVALID_2ND_PURCHASE_REQUIREMENT_LENGTH
The coupon's second purchase Requirement VLI must be "1" to "5".
Definition gs1syntaxdictionary.h:146
@ GS1_LINTER_COUPON_MISSING_3RD_PURCHASE_REQUIREMENT_VLI
The coupon's third purchase Requirement VLI is missing.
Definition gs1syntaxdictionary.h:154
@ GS1_LINTER_COUPON_MISSING_RETAILER_GCP_OR_GLN_VLI
The coupon's Retailer GCP/GLN VLI is missing.
Definition gs1syntaxdictionary.h:168
@ GS1_LINTER_COUPON_INVALID_3RD_PURCHASE_REQUIREMENT_LENGTH
The coupon's third purchase Requirement VLI must be "1" to "5".
Definition gs1syntaxdictionary.h:155
@ GS1_LINTER_COUPON_MISSING_1ST_PURCHASE_REQUIREMENT_VLI
The coupon's primary purchase Requirement VLI is missing.
Definition gs1syntaxdictionary.h:137
@ GS1_LINTER_COUPON_INVALID_SAVE_VALUE_CODE
The coupon's Save Value Code must be "0", "1", "2", "5" or "6".
Definition gs1syntaxdictionary.h:172
@ GS1_LINTER_COUPON_INVALID_2ND_PURCHASE_GCP_LENGTH
The coupon's second purchase GS1 Company Prefix VLI must be "0" to "6" or "9".
Definition gs1syntaxdictionary.h:152
@ GS1_LINTER_COUPON_TRUNCATED_1ST_PURCHASE_FAMILY_CODE
The coupon's primary purchase Family Code is shorter than the required three digits.
Definition gs1syntaxdictionary.h:142
@ GS1_LINTER_COUPON_INVALID_SAVE_VALUE_APPLIES_TO_ITEM
The coupon's Save Value Applies to Item must be "0" to "2".
Definition gs1syntaxdictionary.h:174
@ GS1_LINTER_COUPON_MISSING_SAVE_VALUE_APPLIES_TO_ITEM
The coupon's Save Value Applies to Item is missing.
Definition gs1syntaxdictionary.h:173
@ GS1_LINTER_COUPON_TRUNCATED_GCP
The coupon's primary GS1 Company Prefix is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:133
@ GS1_LINTER_COUPON_MISSING_3RD_PURCHASE_REQUIREMENT_CODE
The coupon's third purchase Requirement Code is missing.
Definition gs1syntaxdictionary.h:157
@ GS1_LINTER_COUPON_TRUNCATED_3RD_PURCHASE_REQUIREMENT
The coupon's third purchase Requirement is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:156
@ GS1_LINTER_DATE_TOO_LONG
The date is too long for YYMMDD format.
Definition gs1syntaxdictionary.h:106
@ GS1_LINTER_COUPON_TRUNCATED_SAVE_VALUE
The coupon's Save Value is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:136
@ GS1_LINTER_COUPON_INVALID_2ND_PURCHASE_REQUIREMENT_CODE
The coupon's second purchase Requirement Code must be "0" to "4" or "9".
Definition gs1syntaxdictionary.h:149
@ GS1_LINTER_GCP_DATASOURCE_OFFLINE
The data source for GCP lookups is offline.
Definition gs1syntaxdictionary.h:87
@ GS1_LINTER_COUPON_MISSING_SERIAL_NUMBER_VLI
The coupon's Serial Number VLI is missing.
Definition gs1syntaxdictionary.h:129
@ GS1_LINTER_COUPON_TRUNCATED_1ST_PURCHASE_REQUIREMENT
The coupon's primary purchase Requirement is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:139
@ GS1_LINTER_COUPON_MISSING_1ST_PURCHASE_REQUIREMENT_CODE
The coupon's primary purchase Requirement Code is missing.
Definition gs1syntaxdictionary.h:140
@ GS1_LINTER_ILLEGAL_MONTH
The date contains an illegal month of the year.
Definition gs1syntaxdictionary.h:113
@ GS1_LINTER_COUPON_MISSING_GCP_VLI
The coupon's primary GS1 Company Prefix VLI is missing.
Definition gs1syntaxdictionary.h:131
@ GS1_LINTER_COUPON_MISSING_2ND_PURCHASE_REQUIREMENT_CODE
The coupon's second purchase Requirement Code is missing.
Definition gs1syntaxdictionary.h:148
@ GS1_LINTER_COUPON_MISSING_2ND_PURCHASE_REQUIREMENT_VLI
The coupon's second purchase Requirement VLI is missing.
Definition gs1syntaxdictionary.h:145
@ GS1_LINTER_COUPON_TRUNCATED_3RD_PURCHASE_FAMILY_CODE
The coupon's third purchase Family Code is shorter than the required three digits.
Definition gs1syntaxdictionary.h:159
@ GS1_LINTER_COUPON_TRUNCATED_SERIAL_NUMBER
The coupon's Serial Number is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:130
@ GS1_LINTER_COUPON_TOO_SHORT_FOR_START_DATE
The coupon's start date is too short to YYMMDD format.
Definition gs1syntaxdictionary.h:165
@ GS1_LINTER_COUPON_INVALID_START_DATE
The coupon's start date is invalid.
Definition gs1syntaxdictionary.h:166
@ GS1_LINTER_COUPON_INVALID_SAVE_VALUE_LENGTH
The coupon's Save Value VLI must be "1" to "5".
Definition gs1syntaxdictionary.h:135
@ GS1_LINTER_COUPON_TRUNCATED_OFFER_CODE
The coupon's Offer Code is shorter than the required six digits.
Definition gs1syntaxdictionary.h:128
@ GS1_LINTER_COUPON_MISSING_ADDITIONAL_PURCHASE_RULES_CODE
The coupon's Additional Purchase Rules Code is missing.
Definition gs1syntaxdictionary.h:143
@ GS1_LINTER_COUPON_INVALID_DONT_MULTIPLY_FLAG
The coupon's Don't Multiply Flag must be "0" or "1".
Definition gs1syntaxdictionary.h:177
@ GS1_LINTER_COUPON_TRUNCATED_2ND_PURCHASE_GCP
The coupon's second purchase GS1 Company Prefix is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:153
@ GS1_LINTER_COUPON_MISSING_STORE_COUPON_FLAG
The coupon's Store Coupon Flag is missing.
Definition gs1syntaxdictionary.h:175
@ GS1_LINTER_COUPON_EXCESS_DATA
The coupon contains excess data after the recognised optional fields.
Definition gs1syntaxdictionary.h:178
@ GS1_LINTER_COUPON_MISSING_3RD_PURCHASE_GCP_VLI
The coupon's third purchase GS1 Company Prefix VLI is missing.
Definition gs1syntaxdictionary.h:160
@ GS1_LINTER_COUPON_MISSING_2ND_PURCHASE_GCP_VLI
The coupon's second purchase GS1 Company Prefix VLI is missing.
Definition gs1syntaxdictionary.h:151
@ GS1_LINTER_COUPON_TOO_SHORT_FOR_EXPIRATION_DATE
The coupon's expiration date is too short for YYMMDD format.
Definition gs1syntaxdictionary.h:163
@ GS1_LINTER_COUPON_INVALID_GCP_LENGTH
The coupon's primary GS1 Company Prefix VLI must be "0" to "6".
Definition gs1syntaxdictionary.h:132
@ GS1_LINTER_DATE_TOO_SHORT
The date is too short for YYMMDD format.
Definition gs1syntaxdictionary.h:105
@ GS1_LINTER_COUPON_INVALID_EXIPIRATION_DATE
The coupon's expiration date is invalid.
Definition gs1syntaxdictionary.h:164
@ GS1_LINTER_COUPON_MISSING_SAVE_VALUE_VLI
The coupon's Save Value VLI is missing.
Definition gs1syntaxdictionary.h:134
@ GS1_LINTER_COUPON_INVALID_1ST_PURCHASE_REQUIREMENT_CODE
The coupon's primary purchase Requirement Code must be "0" to "4" or "9".
Definition gs1syntaxdictionary.h:141
@ GS1_LINTER_COUPON_TRUNCATED_2ND_PURCHASE_REQUIREMENT
The coupon's second purchase Requirement is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:147
@ GS1_LINTER_OK
No issues were detected by the linter.
Definition gs1syntaxdictionary.h:77
@ GS1_LINTER_COUPON_INVALID_3RD_PURCHASE_REQUIREMENT_CODE
The coupon's third purchase Requirement Code must be "0" to "4" or "9".
Definition gs1syntaxdictionary.h:158
@ GS1_LINTER_COUPON_EXPIRATION_BEFORE_START
The coupon's expiration date preceed the start date.
Definition gs1syntaxdictionary.h:167
@ GS1_LINTER_COUPON_INVALID_ADDITIONAL_PURCHASE_RULES_CODE
The coupon's Additional Purchase Rules Code must be "0" to "3".
Definition gs1syntaxdictionary.h:144
@ GS1_LINTER_COUPON_INVALID_1ST_PURCHASE_REQUIREMENT_LENGTH
The coupon's primary purchase Requirement VLI must be "1" to "5".
Definition gs1syntaxdictionary.h:138
@ GS1_LINTER_INVALID_GCP_PREFIX
The GS1 Company Prefix is invalid.
Definition gs1syntaxdictionary.h:89
@ GS1_LINTER_COUPON_TRUNCATED_3RD_PURCHASE_GCP
The coupon's third purchase GS1 Company Prefix is shorter than what is indicated by its VLI.
Definition gs1syntaxdictionary.h:162
@ GS1_LINTER_NON_DIGIT_CHARACTER
A non-digit character was found where a digit is expected.
Definition gs1syntaxdictionary.h:78
@ GS1_LINTER_COUPON_MISSING_DONT_MULTIPLY_FLAG
The coupon's Don't Multiply Flag is missing.
Definition gs1syntaxdictionary.h:176
@ GS1_LINTER_COUPON_MISSING_SAVE_VALUE_CODE
The coupon's Save Value Code is missing.
Definition gs1syntaxdictionary.h:171
@ GS1_LINTER_COUPON_INVALID_RETAILER_GCP_OR_GLN_LENGTH
The coupon's Retailer GCP/GLN VLI must be "1" to "7".
Definition gs1syntaxdictionary.h:169
@ GS1_LINTER_COUPON_INVALID_3RD_PURCHASE_GCP_LENGTH
The coupon's third purchase GS1 Company Prefix VLI must be "0" to "6" or "9".
Definition gs1syntaxdictionary.h:161
GS1_SYNTAX_DICTIONARY_API gs1_lint_err_t gs1_lint_gcppos1(const char *data, size_t *err_pos, size_t *err_len)
Definition lint_gcppos1.c:101