GS1 Syntax Dictionary: Linter reference
A reference to the AI component linter routines referred to by the GS1 Syntax Dictionary. Copyright (c) 2022-2024 GS1 AISBL.
Macros
lint_yymmd0.c File Reference

Macros

#define CURRENT_YEAR   21
 20YY: For converting YY to 19YY, 20YY, 21YY, etc. for leap year validation
 

Purpose

The yymmd0 linter ensures that the data represents a meaningful date, in YYMMDD format, additionally permitting YYMM00 format indicating an unspecified day.

Functional Description

◆ gs1_lint_yymmd0()

GS1_SYNTAX_DICTIONARY_API gs1_lint_err_t gs1_lint_yymmd0 ( const char *const  data,
size_t *const  err_pos,
size_t *const  err_len 
)

Used to ensure that an AI component conforms to the YYMMDD or YYMM00 formats.

Parameters
[in]dataPointer to the null-terminated data to be linted. Must not be NULL.
[out]err_posTo facilitate error highlighting, the start position of the bad data is written to this pointer, if not NULL.
[out]err_lenThe length of the bad data is written to this pointer, if not NULL.
Returns
GS1_LINTER_OK if okay.
GS1_LINTER_DATE_TOO_SHORT if the data is too short for YYMMDD format.
GS1_LINTER_DATE_TOO_LONG if the data is too long for YYMMDD format.
GS1_LINTER_NON_DIGIT_CHARACTER if the data contains a non-digit character.
GS1_LINTER_ILLEGAL_MONTH if the data contains an invalid month.
GS1_LINTER_ILLEGAL_DAY if the data contains an invalid day of the month.
61{
62
63/// \cond
64#define YY ( (data[0] - '0') * 10 + (data[1] - '0') )
65/// \endcond
66
67 size_t len, pos;
68 char yyyymmdd[9] = {0};
70
71 assert(data);
72
73 len = strlen(data);
74
75 /*
76 * Data must be six characters.
77 *
78 */
79 if (len != 6) {
80 if (err_pos) *err_pos = 0;
81 if (err_len) *err_len = len;
83 }
84
85 /*
86 * Data must consist of all digits.
87 *
88 */
89 if ((pos = strspn(data, "0123456789")) != len) {
90 if (err_pos) *err_pos = pos;
91 if (err_len) *err_len = 1;
93 }
94
95 memcpy(yyyymmdd + 2, data, 6);
96
97 /*
98 * Convert YY to a year using a horizon based on CURRENT_YEAR.
99 *
100 */
101 if (YY - CURRENT_YEAR >= 51) {
102 yyyymmdd[0] = '1'; yyyymmdd[1] = '9';
103 } else if (YY - CURRENT_YEAR > -50) {
104 yyyymmdd[0] = '2'; yyyymmdd[1] = '0';
105 } else {
106 yyyymmdd[0] = '2'; yyyymmdd[1] = '1';
107 }
108
109 ret = gs1_lint_yyyymmd0(yyyymmdd, err_pos, err_len);
110
111 assert(ret == GS1_LINTER_OK ||
114
115 assert(!err_pos || ret == GS1_LINTER_OK || (*err_pos >= 2));
116 assert(!err_pos || !err_len || ret == GS1_LINTER_OK || (*err_pos + *err_len <= len + 2));
117
118 if (ret != GS1_LINTER_OK) {
119 if (err_pos) *err_pos -= 2;
120 return ret;
121 }
122
123 return GS1_LINTER_OK;
124
125}
GS1_SYNTAX_DICTIONARY_API gs1_lint_err_t gs1_lint_yyyymmd0(const char *data, size_t *err_pos, size_t *err_len)
Definition lint_yyyymmd0.c:54
gs1_lint_err_t
Linter return codes other than GS1_LINTER_OK indicate an error condition.
Definition gs1syntaxdictionary.h:65
@ GS1_LINTER_ILLEGAL_DAY
The date contains an illegal day of the month.
Definition gs1syntaxdictionary.h:102
@ GS1_LINTER_DATE_TOO_LONG
The date is too long for YYMMDD format.
Definition gs1syntaxdictionary.h:95
@ GS1_LINTER_ILLEGAL_MONTH
The date contains an illegal month of the year.
Definition gs1syntaxdictionary.h:101
@ GS1_LINTER_DATE_TOO_SHORT
The date is too short for YYMMDD format.
Definition gs1syntaxdictionary.h:94
@ GS1_LINTER_OK
No issues were detected by the linter.
Definition gs1syntaxdictionary.h:66
@ GS1_LINTER_NON_DIGIT_CHARACTER
A non-digit character was found where a digit is expected.
Definition gs1syntaxdictionary.h:67
#define CURRENT_YEAR
20YY: For converting YY to 19YY, 20YY, 21YY, etc. for leap year validation
Definition lint_yymmd0.c:37