11/**
22 * GS1 Barcode Syntax Engine
33 *
4- * @author Copyright (c) 2021-2024 GS1 AISBL.
4+ * @author Copyright (c) 2021-2025 GS1 AISBL.
55 *
66 * Licensed under the Apache License, Version 2.0 (the "License");
77 * you may not use this file except in compliance with the License.
3131#include "debug.h"
3232#include "ai.h"
3333#include "dl.h"
34+ #include "tr.h"
3435
3536
3637/*
@@ -92,7 +93,7 @@ static bool populateAIlengthByPrefix(gs1_encoder* const ctx) {
9293 uint8_t prefix = (uint8_t )((e -> ai [0 ] - '0' ) * 10 + (e -> ai [1 ] - '0' ));
9394 uint8_t length = (uint8_t )strlen (e -> ai );
9495 if (ctx -> aiLengthByPrefix [prefix ] != 0 && ctx -> aiLengthByPrefix [prefix ] != length ) {
95- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "AI table is broken: AIs beginning '%c%c' have different lengths" , e -> ai [0 ], e -> ai [1 ]);
96+ SET_ERR_V ( AI_TABLE_BROKEN_PREFIXES_DIFFER_IN_LENGTH , e -> ai [0 ], e -> ai [1 ]);
9697 return false;
9798 }
9899 ctx -> aiLengthByPrefix [prefix ] = length ;
@@ -337,7 +338,7 @@ static size_t validate_ai_val(gs1_encoder* const ctx, const char* const ai, cons
337338 DEBUG_PRINT (" Considering AI (%.*s): %.*s\n" , (int )strlen (entry -> ai ), ai , (int )(r - p ), start );
338339
339340 if (p == r ) {
340- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "AI (%.*s) data is empty" , (int )strlen (entry -> ai ), ai );
341+ SET_ERR_V ( AI_DATA_IS_EMPTY , (int )strlen (entry -> ai ), ai );
341342 return 0 ;
342343 }
343344
@@ -359,7 +360,7 @@ static size_t validate_ai_val(gs1_encoder* const ctx, const char* const ai, cons
359360 continue ;
360361
361362 if (complen < part -> min ) {
362- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "AI (%.*s) data has incorrect length" , (int )strlen (entry -> ai ), ai );
363+ SET_ERR_V ( AI_DATA_HAS_INCORRECT_LENGTH , (int )strlen (entry -> ai ), ai );
363364 return 0 ;
364365 }
365366
@@ -384,7 +385,7 @@ static size_t validate_ai_val(gs1_encoder* const ctx, const char* const ai, cons
384385
385386 err = (* l )(compval , & errpos , & errlen );
386387 if (err ) {
387- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "AI (%.*s): %s" , (int )strlen (entry -> ai ), ai , gs1_lint_err_str [err ]);
388+ SET_ERR_V ( AI_LINTER_ERROR , (int )strlen (entry -> ai ), ai , gs1_lint_err_str [err ]);
388389 ctx -> linterErr = err ;
389390 errpos += (size_t )(p - start );
390391 snprintf (ctx -> linterErrMarkup , sizeof (ctx -> linterErrMarkup ), "(%.*s)%.*s|%.*s|%.*s" ,
@@ -438,18 +439,18 @@ bool gs1_aiValLengthContentCheck(gs1_encoder* const ctx, const char* const ai, c
438439 assert (aiVal );
439440
440441 if (vallen < aiEntryMinLength (entry )) {
441- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "AI (%.*s) value is too short" , (int )strlen (entry -> ai ), ai );
442+ SET_ERR_V ( AI_VALUE_IS_TOO_SHORT , (int )strlen (entry -> ai ), ai );
442443 return false;
443444 }
444445
445446 if (vallen > aiEntryMaxLength (entry )) {
446- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "AI (%.*s) value is too long" , (int )strlen (entry -> ai ), ai );
447+ SET_ERR_V ( AI_VALUE_IS_TOO_LONG , (int )strlen (entry -> ai ), ai );
447448 return false;
448449 }
449450
450451 // Also forbid data "^" characters at this stage so we don't conflate with FNC1
451452 if (memchr (aiVal , '^' , vallen ) != NULL ) {
452- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "AI (%.*s) contains illegal ^ character" , (int )strlen (entry -> ai ), ai );
453+ SET_ERR_V ( AI_CONTAINS_ILLEGAL_CARAT_CHARACTER , (int )strlen (entry -> ai ), ai );
453454 return false;
454455 }
455456
@@ -471,6 +472,7 @@ bool gs1_parseAIdata(gs1_encoder* const ctx, const char* const aiData, char* con
471472 assert (aiData );
472473
473474 * dataStr = '\0' ;
475+ ctx -> err = gs1_encoder_eNO_ERROR ;
474476 * ctx -> errMsg = '\0' ;
475477 ctx -> linterErr = GS1_LINTER_OK ;
476478 * ctx -> linterErrMarkup = '\0' ;
@@ -488,7 +490,7 @@ bool gs1_parseAIdata(gs1_encoder* const ctx, const char* const aiData, char* con
488490 ailen = (size_t )(r - p );
489491 entry = gs1_lookupAIentry (ctx , p , ailen );
490492 if (entry == NULL ) {
491- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "Unrecognised AI: %.*s" , (int )ailen , p );
493+ SET_ERR_V ( AI_UNRECOGNISED , (int )ailen , p );
492494 goto fail ;
493495 }
494496 ai = p ;
@@ -524,7 +526,7 @@ bool gs1_parseAIdata(gs1_encoder* const ctx, const char* const aiData, char* con
524526
525527 // Update the AI data
526528 if (ctx -> numAIs >= MAX_AIS ) {
527- strcpy ( ctx -> errMsg , "Too many AIs" );
529+ SET_ERR ( TOO_MANY_AIS );
528530 goto fail ;
529531 }
530532
@@ -548,7 +550,7 @@ bool gs1_parseAIdata(gs1_encoder* const ctx, const char* const aiData, char* con
548550fail :
549551
550552 if (* ctx -> errMsg == '\0' )
551- strcpy ( ctx -> errMsg , "Failed to parse AI data" );
553+ SET_ERR ( AI_PARSE_FAILED );
552554
553555 DEBUG_PRINT ("Parsing AI data failed: %s\n" , ctx -> errMsg );
554556
@@ -569,6 +571,7 @@ bool gs1_processAIdata(gs1_encoder* const ctx, const char* const dataStr, const
569571 assert (ctx );
570572 assert (dataStr );
571573
574+ ctx -> err = gs1_encoder_eNO_ERROR ;
572575 * ctx -> errMsg = '\0' ;
573576 ctx -> linterErr = GS1_LINTER_OK ;
574577 * ctx -> linterErrMarkup = '\0' ;
@@ -577,13 +580,13 @@ bool gs1_processAIdata(gs1_encoder* const ctx, const char* const dataStr, const
577580
578581 // Ensure FNC1 in first
579582 if (!* p || * p ++ != '^' ) {
580- strcpy ( ctx -> errMsg , "Missing FNC1 in first position" );
583+ SET_ERR ( MISSING_FNC1_IN_FIRST_POSITION );
581584 return false;
582585 }
583586
584587 // Must have some AI data
585588 if (!* p ) {
586- strcpy ( ctx -> errMsg , "The AI data is empty" );
589+ SET_ERR ( AI_DATA_EMPTY );
587590 return false;
588591 }
589592
@@ -603,7 +606,7 @@ bool gs1_processAIdata(gs1_encoder* const ctx, const char* const dataStr, const
603606 */
604607 if ((entry = gs1_lookupAIentry (ctx , p , 0 )) == NULL ||
605608 (extractAIs && entry == & unknownAI )) {
606- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "No known AI is a prefix of: %.4s..." , p );
609+ SET_ERR_V ( NO_AI_FOR_PREFIX , p );
607610 return false;
608611 }
609612
@@ -622,7 +625,7 @@ bool gs1_processAIdata(gs1_encoder* const ctx, const char* const dataStr, const
622625 // Add to the aiData
623626 if (extractAIs ) {
624627 if (ctx -> numAIs >= MAX_AIS ) {
625- strcpy ( ctx -> errMsg , "Too many AIs" );
628+ SET_ERR ( TOO_MANY_AIS );
626629 return false;
627630 }
628631 ctx -> aiData [ctx -> numAIs ++ ] = (struct aiValue ) {
@@ -639,7 +642,7 @@ bool gs1_processAIdata(gs1_encoder* const ctx, const char* const dataStr, const
639642 // After AIs requiring FNC1, we expect to find an FNC1 or be at the end
640643 p += vallen ;
641644 if (entry -> fnc1 && * p != '^' && * p != '\0' ) {
642- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "AI (%.*s) data is too long" , (int )strlen (entry -> ai ), ai );
645+ SET_ERR_V ( AI_DATA_IS_TOO_LONG , (int )strlen (entry -> ai ), ai );
643646 return false;
644647 }
645648
@@ -735,8 +738,7 @@ static bool validateAImutex(gs1_encoder* const ctx) {
735738 if (!aiExists (ctx , token , ai -> ai , & matchedAI ))
736739 continue ;
737740
738- snprintf (ctx -> errMsg , sizeof (ctx -> errMsg ), "It is invalid to pair AI (%.*s) with AI (%.*s)" ,
739- ai -> ailen , ai -> ai , matchedAI -> ailen , matchedAI -> ai );
741+ SET_ERR_V (INVALID_AI_PAIRS , ai -> ailen , ai -> ai , matchedAI -> ailen , matchedAI -> ai );
740742 return false;
741743
742744 }
@@ -804,7 +806,7 @@ static bool validateAIrequisites(gs1_encoder* const ctx) {
804806 }
805807
806808 if (!satisfied ) { /* Loop finished without satisfying one of the AI groups in "req" */
807- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "Required AIs for AI (%.*s) are not satisfied: %s" , ai -> ailen , ai -> ai , reqErr );
809+ SET_ERR_V ( REQUIRED_AIS_NOT_SATISFIED , ai -> ailen , ai -> ai , reqErr );
808810 return false;
809811 }
810812
@@ -847,7 +849,7 @@ static bool validateAIrepeats(gs1_encoder* const ctx) {
847849
848850 if (ai -> ailen == ai2 -> ailen && strncmp (ai -> ai , ai2 -> ai , ai -> ailen ) == 0 &&
849851 (ai -> vallen != ai2 -> vallen || strncmp (ai -> value , ai2 -> value , ai -> vallen ) != 0 )) {
850- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "Multiple instances of AI (%.*s) have different values" , ai -> ailen , ai -> ai );
852+ SET_ERR_V ( INSTANCES_OF_AI_HAVE_DIFFERENT_VALUES , ai -> ailen , ai -> ai );
851853 return false;
852854 }
853855
@@ -887,7 +889,7 @@ static bool validateDigSigRequiresSerialisedKey(gs1_encoder* const ctx) {
887889 continue ;
888890
889891 if (ai -> vallen == aiEntryMinLength (ai -> aiEntry )) {
890- snprintf ( ctx -> errMsg , sizeof ( ctx -> errMsg ), "Serial component must be present for AI (%.*s) when used with AI (8030)" , ai -> ailen , ai -> ai );
892+ SET_ERR_V ( SERIAL_NOT_PRESENT , ai -> ailen , ai -> ai );
891893 return false;
892894 }
893895
0 commit comments