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 const char *expiry_date_p = NULL;
192 int expiry_set = 0;
193
194 assert(data);
195
196
197
198
199
200 for (pos = 0; pos < data_len; pos++) {
204 pos,
205 1
206 );
207 }
208
209 p = data;
210 q = data + data_len;
211
212
213
214
215
216
217
218
222 0,
223 (size_t)(q - data)
224 );
228 (size_t)(p - data),
229 1
230 );
231 vli = *p - '0' + 6;
232
236 (p == q) ? 0 : (size_t)(p - data),
237 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
238 );
239
240
241
242
243
245
249
252 ret,
253 (size_t)(p - data),
254 (size_t)vli
255 );
256
257 p += vli;
258
259
260
261
262
263
267 (p == q) ? 0 : (size_t)(p - data),
268 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
269 );
270
271 p += 6;
272
273
274
275
276
277
278
279
280
284 0,
285 (size_t)(q - data)
286 );
290 (size_t)(p - data),
291 1
292 );
293 vli = *p - '0';
294
298 (p == q) ? 0 : (size_t)(p - data),
299 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
300 );
301
302 p += vli;
303
304
305
306
307
308
309
310
311
315 0,
316 (size_t)(q - data)
317 );
321 (size_t)(p - data),
322 1
323 );
324 vli = *p - '0';
325
329 (p == q) ? 0 : (size_t)(p - data),
330 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
331 );
332
333 p += vli;
334
335
336
337
338
339
340
341
342
346 0,
347 (size_t)(q - data)
348 );
349
353 (size_t)(p - data),
354 1
355 );
356
357
358
359
360
361
365 (p == q) ? 0 : (size_t)(p - data),
366 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
367 );
368
369 p += 3;
370
371
372
373
374
375
376
377
378
379 if (p < q && *p == '1') {
380
381
382
383
384
385
386
387
391 0,
392 (size_t)(q - data)
393 );
394
398 (size_t)(p - data),
399 1
400 );
401
402
403
404
405
406
407
408
409
410
414 0,
415 (size_t)(q - data)
416 );
420 (size_t)(p - data),
421 1
422 );
423 vli = *p - '0';
424
428 (p == q) ? 0 : (size_t)(p - data),
429 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
430 );
431
432 p += vli;
433
434
435
436
437
438
439
440
441
445 0,
446 (size_t)(q - data)
447 );
448
452 (size_t)(p - data),
453 1
454 );
455
456
457
458
459
460
461
465 (p == q) ? 0 : (size_t)(p - data),
466 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
467 );
468
469 p += 3;
470
471
472
473
474
475
476
477
478
479
483 0,
484 (size_t)(q - data)
485 );
489 (size_t)(p - data),
490 1
491 );
492 vli = (*p != '9') ? *p - '0' + 6 : 0;
493
497 (p == q) ? 0 : (size_t)(p - data),
498 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
499 );
500
501
502
503
504
505 if (vli > 0) {
507
511
514 ret,
515 (size_t)(p - data),
516 (size_t)vli
517 );
518
519 p += vli;
520 }
521
522 }
523
524
525
526
527
528
529
530
531
532 if (p < q && *p == '2') {
533
534
535
536
537
538
539
540
541
545 0,
546 (size_t)(q - data)
547 );
551 (size_t)(p - data),
552 1
553 );
554 vli = *p - '0';
555
559 (p == q) ? 0 : (size_t)(p - data),
560 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
561 );
562
563 p += vli;
564
565
566
567
568
569
570
571
572
576 0,
577 (size_t)(q - data)
578 );
579
583 (size_t)(p - data),
584 1
585 );
586
587
588
589
590
591
592
596 (p == q) ? 0 : (size_t)(p - data),
597 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
598 );
599
600 p += 3;
601
602
603
604
605
606
607
608
609
610
614 0,
615 (size_t)(q - data)
616 );
620 (size_t)(p - data),
621 1
622 );
623 vli = (*p != '9') ? *p - '0' + 6 : 0;
624
628 (p == q) ? 0 : (size_t)(p - data),
629 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
630 );
631
632
633
634
635
636 if (vli > 0) {
638
642
645 ret,
646 (size_t)(p - data),
647 (size_t)vli
648 );
649
650 p += vli;
651 }
652
653 }
654
655
656
657
658
659
660
661
662
663 if (p < q && *p == '3') {
664
665
666
667
668
672 (p == q) ? 0 : (size_t)(p - data),
673 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
674 );
675
676 expiry_date_p = p;
678
685
689 (size_t)(p - data),
690 6
691 );
692
693 p += 6;
694
695 expiry_set = 1;
696
697 }
698
699
700
701
702
703
704
705
706
707 if (p < q && *p == '4') {
708
709 const char *start_date_p;
710
711
712
713
714
718 (p == q) ? 0 : (size_t)(p - data),
719 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
720 );
721
722 start_date_p = p;
724
731
735 (size_t)(p - data),
736 6
737 );
738
739
740
741
742
743
747 (size_t)(p - data - 8),
748 14
749 );
750
751 p += 6;
752
753 }
754
755
756
757
758
759
760
761
762
763 if (p < q && *p == '5') {
764
765
766
767
768
769
773 0,
774 (size_t)(q - data)
775 );
776 vli = *p - '0' + 6;
777
781 (p == q) ? 0 : (size_t)(p - data),
782 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
783 );
784
785 p += vli;
786
787 }
788
789
790
791
792
793
794
795
796
797 if (p < q && *p == '6') {
798
799
800
801
802
803
804
805
809 0,
810 (size_t)(q - data)
811 );
815 (size_t)(p - data),
816 1
817 );
818 vli = *p - '0' + 6;
819
823 (p == q) ? 0 : (size_t)(p - data),
824 (p == q) ? (size_t)(q - data) : (size_t)(q - p)
825 );
826
827
828
829
830
832
836
839 ret,
840 (size_t)(p - data),
841 (size_t)vli
842 );
843
844 p += vli;
845
846 }
847
848
849
850
851
852
853
854
855
856 if (p < q && *p == '9') {
857
858
859
860
861
862
863
864
868 0,
869 (size_t)(q - data)
870 );
874 (size_t)(p - data),
875 1
876 );
877
878
879
880
881
882
883
884
888 0,
889 (size_t)(q - data)
890 );
894 (size_t)(p - data),
895 1
896 );
897
898
899
900
901
902
903
907 0,
908 (size_t)(q - data)
909 );
910
911
912
913
914
915
916
917
921 0,
922 (size_t)(q - data)
923 );
927 (size_t)(p - data),
928 1
929 );
930
931 p++;
932
933 }
934
935
936
937
938
942 (size_t)(p - data),
943 (size_t)(q - p)
944 );
945
947
948}
#define GS1_LINTER_UNLIKELY(x)
Implementation 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_gcppos1(const char *data, size_t data_len, size_t *err_pos, size_t *err_len)
Definition lint_gcppos1.c:102
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 precede 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_yymmdd(const char *data, size_t data_len, size_t *err_pos, size_t *err_len)
Definition lint_yymmdd.c:53