/*
 * GS1 AI checker generated by "backend/tools/gen_gs1_lint.php" from
 * https://raw.githubusercontent.com/bwipp/postscriptbarcode/master/contrib/development/gs1-format-spec.txt
 */
/*
    libzint - the open source barcode library
    Copyright (C) 2021 Robin Stuart <rstuart114@gmail.com>

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
    3. Neither the name of the project nor the names of its contributors
       may be used to endorse or promote products derived from this software
       without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
 */

#ifndef GS1_LINT_H
#define GS1_LINT_H

/* N18,csum,key (Used by SSCC) */
static int n18_csum_key(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 18
            && csum(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && key(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 0)
            && key(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 0);
}

/* N14,csum,key (Used by GTIN, CONTENT) */
static int n14_csum_key(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 14
            && csum(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && key(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 0)
            && key(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..20 (Used by BATCH/LOT, SERIAL, CPV, PCN...) */
static int x1__20(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 20
            && cset82(data, data_len, 0, 1, 20, p_err_no, p_err_posn, err_msg);
}

/* N6,yymmd0 (Used by PROD DATE, DUE DATE, PACK DATE, BEST BEFORE or BEST BY...) */
static int n6_yymmd0(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 6
            && yymmd0(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
            && yymmd0(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0);
}

/* N2 (Used by VARIANT) */
static int n2(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 2
            && numeric(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg);
}

/* X1..28 (Used by TPX) */
static int x1__28(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 28
            && cset82(data, data_len, 0, 1, 28, p_err_no, p_err_posn, err_msg);
}

/* X1..30 (Used by ADDITIONAL ID, CUST. PART NO., SECONDARY SERIAL, REF. TO SOURCE...) */
static int x1__30(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 30
            && cset82(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg);
}

/* N1..6 (Used by MTO VARIANT) */
static int n1__6(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 6
            && numeric(data, data_len, 0, 1, 6, p_err_no, p_err_posn, err_msg);
}

/* N13,csum,key X0..17 (Used by GDTI) */
static int n13_csum_key_x0__17(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 13 && data_len <= 30
            && csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 0)
            && key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 0)
            && cset82(data, data_len, 13, 0, 17, p_err_no, p_err_posn, err_msg);
}

/* N13,csum,key N0..12 (Used by GCN) */
static int n13_csum_key_n0__12(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 13 && data_len <= 25
            && csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 0)
            && key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 13, 0, 12, p_err_no, p_err_posn, err_msg);
}

/* N1..8 (Used by VAR. COUNT, COUNT) */
static int n1__8(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 8
            && numeric(data, data_len, 0, 1, 8, p_err_no, p_err_posn, err_msg);
}

/* N6 (Used by NET WEIGHT (kg), LENGTH (m), WIDTH (m), HEIGHT (m)...) */
static int n6(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 6
            && numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg);
}

/* N1..15 (Used by AMOUNT, PRICE) */
static int n1__15(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 15
            && numeric(data, data_len, 0, 1, 15, p_err_no, p_err_posn, err_msg);
}

/* N3,iso4217 N1..15 (Used by AMOUNT, PRICE) */
static int n3_iso4217_n1__15(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 4 && data_len <= 18
            && iso4217(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
            && iso4217(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 3, 1, 15, p_err_no, p_err_posn, err_msg);
}

/* N4 (Used by PRCNT OFF, POINTS) */
static int n4(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 4
            && numeric(data, data_len, 0, 4, 4, p_err_no, p_err_posn, err_msg);
}

/* X1..30,key (Used by GINC, GIAI - ASSEMBLY, GIAI) */
static int x1__30_key(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 30
            && key(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset82(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg)
            && key(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg, 0);
}

/* N17,csum,key (Used by GSIN) */
static int n17_csum_key(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 17
            && csum(data, data_len, 0, 17, 17, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && key(data, data_len, 0, 17, 17, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 17, 17, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 0, 17, 17, p_err_no, p_err_posn, err_msg, 0)
            && key(data, data_len, 0, 17, 17, p_err_no, p_err_posn, err_msg, 0);
}

/* N13,csum,key (Used by SHIP TO LOC, BILL TO, PURCHASE FROM, SHIP FOR LOC...) */
static int n13_csum_key(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 13
            && csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 0)
            && key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 0);
}

/* N3,iso3166 X1..9 (Used by SHIP TO POST) */
static int n3_iso3166_x1__9(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 4 && data_len <= 12
            && iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
            && iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 0)
            && cset82(data, data_len, 3, 1, 9, p_err_no, p_err_posn, err_msg);
}

/* N3,iso3166 (Used by ORIGIN, COUNTRY - PROCESS, COUNTRY - FULL PROCESS) */
static int n3_iso3166(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 3
            && iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
            && iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 0);
}

/* N3..15,iso3166list (Used by COUNTRY - INITIAL PROCESS, COUNTRY - DISASSEMBLY) */
static int n3__15_iso3166list(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 3 && data_len <= 15
            && iso3166list(data, data_len, 0, 3, 15, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 3, 15, p_err_no, p_err_posn, err_msg)
            && iso3166list(data, data_len, 0, 3, 15, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..3 (Used by ORIGIN SUBDIVISION, AQUATIC SPECIES) */
static int x1__3(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 3
            && cset82(data, data_len, 0, 1, 3, p_err_no, p_err_posn, err_msg);
}

/* X1..35,pcenc (Used by SHIP TO COMP, SHIP TO NAME, RTN TO COMP, RTN TO NAME...) */
static int x1__35_pcenc(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 35
            && pcenc(data, data_len, 0, 1, 35, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset82(data, data_len, 0, 1, 35, p_err_no, p_err_posn, err_msg)
            && pcenc(data, data_len, 0, 1, 35, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..70,pcenc (Used by SHIP TO ADD1, SHIP TO ADD2, SHIP TO SUB, SHIP TO LOC...) */
static int x1__70_pcenc(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 70
            && pcenc(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset82(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg)
            && pcenc(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 0);
}

/* X2,iso3166alpha2 (Used by SHIP TO COUNTRY, RTN TO COUNTRY) */
static int x2_iso3166alpha2(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 2
            && iso3166alpha2(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset82(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg)
            && iso3166alpha2(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg, 0);
}

/* N1,yesno (Used by DANGEROUS GOODS, AUTH LEAVE, SIG REQUIRED) */
static int n1_yesno(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 1
            && yesno(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg)
            && yesno(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 0);
}

/* N6,yymmd0 N4,hhmm (Used by NBEF DEL DT., NAFT DEL DT.) */
static int n6_yymmd0_n4_hhmm(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 10
            && yymmd0(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && hhmm(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
            && yymmd0(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg)
            && hhmm(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 0);
}

/* N6,yymmdd (Used by REL DATE, FIRST FREEZE DATE) */
static int n6_yymmdd(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 6
            && yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
            && yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0);
}

/* N13 (Used by NSN) */
static int n13(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 13
            && numeric(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg);
}

/* N6,yymmdd N4,hhmm (Used by EXPIRY TIME) */
static int n6_yymmdd_n4_hhmm(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 10
            && yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && hhmm(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
            && yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg)
            && hhmm(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 0);
}

/* N1..4 (Used by ACTIVE POTENCY) */
static int n1__4(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 4
            && numeric(data, data_len, 0, 1, 4, p_err_no, p_err_posn, err_msg);
}

/* X1..12 (Used by CATCH AREA) */
static int x1__12(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 12
            && cset82(data, data_len, 0, 1, 12, p_err_no, p_err_posn, err_msg);
}

/* N6,yymmdd N0..6,yymmdd (Used by HARVEST DATE) */
static int n6_yymmdd_n0__6_yymmdd(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 6 && data_len <= 12
            && yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && yymmdd(data, data_len, 6, 0, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
            && yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 6, 0, 6, p_err_no, p_err_posn, err_msg)
            && yymmdd(data, data_len, 6, 0, 6, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..10 (Used by FISHING GEAR TYPE) */
static int x1__10(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 10
            && cset82(data, data_len, 0, 1, 10, p_err_no, p_err_posn, err_msg);
}

/* X1..2 (Used by PROD METHOD) */
static int x1__2(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 2
            && cset82(data, data_len, 0, 1, 2, p_err_no, p_err_posn, err_msg);
}

/* N3,iso3166999 X1..27 (Used by PROCESSOR # s) */
static int n3_iso3166999_x1__27(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 4 && data_len <= 30
            && iso3166999(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
            && iso3166999(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 0)
            && cset82(data, data_len, 3, 1, 27, p_err_no, p_err_posn, err_msg);
}

/* N1 X1 X1 X1,importeridx (Used by UIC+EXT) */
static int n1_x1_x1_x1_importeridx(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 4
            && importeridx(data, data_len, 3, 1, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg)
            && cset82(data, data_len, 1, 1, 1, p_err_no, p_err_posn, err_msg)
            && cset82(data, data_len, 2, 1, 1, p_err_no, p_err_posn, err_msg)
            && cset82(data, data_len, 3, 1, 1, p_err_no, p_err_posn, err_msg)
            && importeridx(data, data_len, 3, 1, 1, p_err_no, p_err_posn, err_msg, 0);
}

/* X2 X1..28 (Used by CERT # s) */
static int x2_x1__28(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 3 && data_len <= 30
            && cset82(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg)
            && cset82(data, data_len, 2, 1, 28, p_err_no, p_err_posn, err_msg);
}

/* N4,nonzero N5,nonzero N3,nonzero N1,winding N1 (Used by DIMENSIONS) */
static int n4_nonzero_n5_nonzero_n3_nonzero_n1_winding_n1(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 14
            && nonzero(data, data_len, 0, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && nonzero(data, data_len, 4, 5, 5, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && nonzero(data, data_len, 9, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && winding(data, data_len, 12, 1, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 4, 4, p_err_no, p_err_posn, err_msg)
            && nonzero(data, data_len, 0, 4, 4, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 4, 5, 5, p_err_no, p_err_posn, err_msg)
            && nonzero(data, data_len, 4, 5, 5, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 9, 3, 3, p_err_no, p_err_posn, err_msg)
            && nonzero(data, data_len, 9, 3, 3, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 12, 1, 1, p_err_no, p_err_posn, err_msg)
            && winding(data, data_len, 12, 1, 1, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 13, 1, 1, p_err_no, p_err_posn, err_msg);
}

/* N1,zero N13,csum,key X0..16 (Used by GRAI) */
static int n1_zero_n13_csum_key_x0__16(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 14 && data_len <= 30
            && zero(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && csum(data, data_len, 1, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && key(data, data_len, 1, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg)
            && zero(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 1, 13, 13, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 1, 13, 13, p_err_no, p_err_posn, err_msg, 0)
            && key(data, data_len, 1, 13, 13, p_err_no, p_err_posn, err_msg, 0)
            && cset82(data, data_len, 14, 0, 16, p_err_no, p_err_posn, err_msg);
}

/* N14,csum N4,pieceoftotal (Used by ITIP, ITIP CONTENT) */
static int n14_csum_n4_pieceoftotal(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 18
            && csum(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && pieceoftotal(data, data_len, 14, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 14, 4, 4, p_err_no, p_err_posn, err_msg)
            && pieceoftotal(data, data_len, 14, 4, 4, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..34,iban (Used by IBAN) */
static int x1__34_iban(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 34
            && iban(data, data_len, 0, 1, 34, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset82(data, data_len, 0, 1, 34, p_err_no, p_err_posn, err_msg)
            && iban(data, data_len, 0, 1, 34, p_err_no, p_err_posn, err_msg, 0);
}

/* N8,yymmddhh N0..4,mmoptss (Used by PROD TIME) */
static int n8_yymmddhh_n0__4_mmoptss(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 8 && data_len <= 12
            && yymmddhh(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && mmoptss(data, data_len, 8, 0, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg)
            && yymmddhh(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg, 0)
            && numeric(data, data_len, 8, 0, 4, p_err_no, p_err_posn, err_msg)
            && mmoptss(data, data_len, 8, 0, 4, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..50 (Used by OPTSEN) */
static int x1__50(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 50
            && cset82(data, data_len, 0, 1, 50, p_err_no, p_err_posn, err_msg);
}

/* C1..30,key (Used by CPID) */
static int c1__30_key(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 30
            && key(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset39(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg)
            && key(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg, 0);
}

/* N1..12,nozeroprefix (Used by CPID SERIAL) */
static int n1__12_nozeroprefix(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 12
            && nozeroprefix(data, data_len, 0, 1, 12, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 1, 12, p_err_no, p_err_posn, err_msg)
            && nozeroprefix(data, data_len, 0, 1, 12, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..25,csumalpha,key (Used by GMN) */
static int x1__25_csumalpha_key(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 25
            && csumalpha(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && key(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset82(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg)
            && csumalpha(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 0)
            && key(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 0);
}

/* N18,csum (Used by GSRN - PROVIDER, GSRN - RECIPIENT) */
static int n18_csum(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len == 18
            && csum(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && numeric(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg)
            && csum(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 0);
}

/* N1..10 (Used by SRIN) */
static int n1__10(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 10
            && numeric(data, data_len, 0, 1, 10, p_err_no, p_err_posn, err_msg);
}

/* X1..25 (Used by REF NO.) */
static int x1__25(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 25
            && cset82(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg);
}

/* X1..70,couponcode */
static int x1__70_couponcode(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 70
            && couponcode(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset82(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg)
            && couponcode(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..70,couponposoffer */
static int x1__70_couponposoffer(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 70
            && couponposoffer(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
            && cset82(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg)
            && couponposoffer(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 0);
}

/* X1..70 (Used by PRODUCT URL) */
static int x1__70(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 70
            && cset82(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg);
}

/* X1..90 (Used by INTERNAL) */
static int x1__90(const unsigned char *data, const int data_len,
            int *p_err_no, int *p_err_posn, char err_msg[50]) {
    return data_len >= 1 && data_len <= 90
            && cset82(data, data_len, 0, 1, 90, p_err_no, p_err_posn, err_msg);
}

/* Entry point. Returns 1 on success, 0 on failure: `*p_err_no` set to 1 if unknown AI, 2 if bad data length */
static int gs1_lint(const int ai, const unsigned char *data, const int data_len, int *p_err_no, int *p_err_posn,
            char err_msg[50]) {

    /* Assume data length failure */
    *p_err_no = 2;

    if (ai < 100) {

        if (ai == 0) {
            return n18_csum_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 1 || ai == 2) {
            return n14_csum_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 10 || ai == 21 || ai == 22) {
            return x1__20(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if ((ai >= 11 && ai <= 13) || (ai >= 15 && ai <= 17)) {
            return n6_yymmd0(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 20) {
            return n2(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 30 || ai == 37) {
            return n1__8(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 90) {
            return x1__30(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai >= 91) {
            return x1__90(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 300) {

        if (ai == 235) {
            return x1__28(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 240 || ai == 241 || ai == 250 || ai == 251) {
            return x1__30(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 242) {
            return n1__6(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 243 || ai == 254) {
            return x1__20(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 253) {
            return n13_csum_key_x0__17(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 255) {
            return n13_csum_key_n0__12(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 500) {

        if (ai == 400 || ai == 403) {
            return x1__30(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 401) {
            return x1__30_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 402) {
            return n17_csum_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai >= 410 && ai <= 417) {
            return n13_csum_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 420) {
            return x1__20(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 421) {
            return n3_iso3166_x1__9(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 422 || ai == 424 || ai == 426) {
            return n3_iso3166(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 423 || ai == 425) {
            return n3__15_iso3166list(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 427) {
            return x1__3(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 800) {

        if (ai >= 710 && ai <= 714) {
            return x1__20(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 3200) {

        if ((ai >= 3100 && ai <= 3105) || (ai >= 3110 && ai <= 3115) || (ai >= 3120 && ai <= 3125)
                || (ai >= 3130 && ai <= 3135) || (ai >= 3140 && ai <= 3145) || (ai >= 3150 && ai <= 3155)
                || (ai >= 3160 && ai <= 3165)) {
            return n6(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 3300) {

        if (ai <= 3205 || (ai >= 3210 && ai <= 3215) || (ai >= 3220 && ai <= 3225) || (ai >= 3230 && ai <= 3235)
                || (ai >= 3240 && ai <= 3245) || (ai >= 3250 && ai <= 3255) || (ai >= 3260 && ai <= 3265)
                || (ai >= 3270 && ai <= 3275) || (ai >= 3280 && ai <= 3285) || (ai >= 3290 && ai <= 3295)) {
            return n6(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 3400) {

        if (ai <= 3305 || (ai >= 3310 && ai <= 3315) || (ai >= 3320 && ai <= 3325) || (ai >= 3330 && ai <= 3335)
                || (ai >= 3340 && ai <= 3345) || (ai >= 3350 && ai <= 3355) || (ai >= 3360 && ai <= 3365)
                || (ai >= 3370 && ai <= 3375)) {
            return n6(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 3500) {

        if (ai <= 3405 || (ai >= 3410 && ai <= 3415) || (ai >= 3420 && ai <= 3425) || (ai >= 3430 && ai <= 3435)
                || (ai >= 3440 && ai <= 3445) || (ai >= 3450 && ai <= 3455) || (ai >= 3460 && ai <= 3465)
                || (ai >= 3470 && ai <= 3475) || (ai >= 3480 && ai <= 3485) || (ai >= 3490 && ai <= 3495)) {
            return n6(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 3600) {

        if (ai <= 3505 || (ai >= 3510 && ai <= 3515) || (ai >= 3520 && ai <= 3525) || (ai >= 3530 && ai <= 3535)
                || (ai >= 3540 && ai <= 3545) || (ai >= 3550 && ai <= 3555) || (ai >= 3560 && ai <= 3565)
                || (ai >= 3570 && ai <= 3575)) {
            return n6(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 3700) {

        if (ai <= 3605 || (ai >= 3610 && ai <= 3615) || (ai >= 3620 && ai <= 3625) || (ai >= 3630 && ai <= 3635)
                || (ai >= 3640 && ai <= 3645) || (ai >= 3650 && ai <= 3655) || (ai >= 3660 && ai <= 3665)
                || (ai >= 3670 && ai <= 3675) || (ai >= 3680 && ai <= 3685) || (ai >= 3690 && ai <= 3695)) {
            return n6(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 4000) {

        if ((ai >= 3900 && ai <= 3909) || (ai >= 3920 && ai <= 3929)) {
            return n1__15(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if ((ai >= 3910 && ai <= 3919) || (ai >= 3930 && ai <= 3939)) {
            return n3_iso4217_n1__15(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai >= 3940 && ai <= 3943) {
            return n4(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai >= 3950 && ai <= 3955) {
            return n6(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 4400) {

        if (ai == 4300 || ai == 4301 || ai == 4310 || ai == 4311 || ai == 4320) {
            return x1__35_pcenc(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if ((ai >= 4302 && ai <= 4306) || (ai >= 4312 && ai <= 4316)) {
            return x1__70_pcenc(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 4307 || ai == 4317) {
            return x2_iso3166alpha2(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 4308 || ai == 4319) {
            return x1__30(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 4318) {
            return x1__20(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai >= 4321 && ai <= 4323) {
            return n1_yesno(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 4324 || ai == 4325) {
            return n6_yymmd0_n4_hhmm(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 4326) {
            return n6_yymmdd(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 7100) {

        if (ai == 7001) {
            return n13(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7002) {
            return x1__30(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7003) {
            return n6_yymmdd_n4_hhmm(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7004) {
            return n1__4(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7005) {
            return x1__12(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7006) {
            return n6_yymmdd(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7007) {
            return n6_yymmdd_n0__6_yymmdd(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7008) {
            return x1__3(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7009) {
            return x1__10(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7010) {
            return x1__2(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai >= 7020 && ai <= 7022) {
            return x1__20(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7023) {
            return x1__30_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai >= 7030 && ai <= 7039) {
            return n3_iso3166999_x1__27(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7040) {
            return n1_x1_x1_x1_importeridx(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 7300) {

        if (ai >= 7230 && ai <= 7239) {
            return x2_x1__28(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 7240) {
            return x1__20(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 8100) {

        if (ai == 8001) {
            return n4_nonzero_n5_nonzero_n3_nonzero_n1_winding_n1(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8002 || ai == 8012) {
            return x1__20(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8003) {
            return n1_zero_n13_csum_key_x0__16(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8004) {
            return x1__30_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8005) {
            return n6(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8006 || ai == 8026) {
            return n14_csum_n4_pieceoftotal(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8007) {
            return x1__34_iban(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8008) {
            return n8_yymmddhh_n0__4_mmoptss(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8009) {
            return x1__50(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8010) {
            return c1__30_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8011) {
            return n1__12_nozeroprefix(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8013) {
            return x1__25_csumalpha_key(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8017 || ai == 8018) {
            return n18_csum(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8019) {
            return n1__10(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8020) {
            return x1__25(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 8200) {

        if (ai == 8110) {
            return x1__70_couponcode(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8111) {
            return n4(data, data_len, p_err_no, p_err_posn, err_msg);
        }
        if (ai == 8112) {
            return x1__70_couponposoffer(data, data_len, p_err_no, p_err_posn, err_msg);
        }

    } else if (ai < 8300) {

        if (ai == 8200) {
            return x1__70(data, data_len, p_err_no, p_err_posn, err_msg);
        }
    }

    /* Unknown AI */
    *p_err_no = 1;
    return 0;
}

#endif /* GS1_LINT_H */
