28#ifdef USE_ASSERT_CHECKING
41static const char *
const isn_names[] = {
"EAN13/UPC/ISxN",
"EAN13/UPC/ISxN",
"EAN13",
"ISBN",
"ISMN",
"ISSN",
"UPC"};
66check_table(const
char *(*TABLE)[2], const
unsigned TABLE_index[10][2])
81 while (TABLE[
i][0] && TABLE[
i][1])
87 if (!isdigit((
unsigned char) *aux1) || !isdigit((
unsigned char) *aux2))
93 while (*aux1 && *aux2)
95 if (!(isdigit((
unsigned char) *aux1) &&
96 isdigit((
unsigned char) *aux2)) &&
97 (*aux1 != *aux2 || *aux1 !=
'-'))
109 for (
j =
x;
j <=
y;
j++)
130 elog(
DEBUG1,
"invalid table near {\"%s\", \"%s\"} (pos: %d)",
131 TABLE[
i][0], TABLE[
i][1],
i);
150 if (isdigit((
unsigned char) *bufI))
172 const char *ean_aux1,
199 search = *bufI -
'0';
207 search =
lower + step;
210 ean_in1 = ean_in2 =
false;
211 ean_aux1 = TABLE[search][0];
212 ean_aux2 = TABLE[search][1];
215 if ((ean_in1 || *firstdig >= *ean_aux1) && (ean_in2 || *firstdig <= *ean_aux2))
217 if (*firstdig > *ean_aux1)
219 if (*firstdig < *ean_aux2)
221 if (ean_in1 && ean_in2)
224 firstdig++, ean_aux1++, ean_aux2++;
225 if (!(*ean_aux1 && *ean_aux2 && *firstdig))
227 if (!isdigit((
unsigned char) *ean_aux1))
228 ean_aux1++, ean_aux2++;
236 if (*firstdig < *ean_aux1 && !ean_in1)
242 search =
lower + step;
246 ean_in1 = ean_in2 =
false;
247 ean_aux1 = TABLE[search][0];
248 ean_aux2 = TABLE[search][1];
256 ean_p = TABLE[search][0];
257 while (*ean_p && *aux2)
283 while (*isn && size > 1)
285 if (isdigit((
unsigned char) *isn))
287 weight += size-- * (*isn -
'0');
291 weight = weight % 11;
293 weight = 11 - weight;
316 while (*num && size > 1)
318 if (isdigit((
unsigned char) *num))
321 check3 += *num -
'0';
328 check = (check + 3 * check3) % 10;
363 digval = (unsigned) (ean % 10);
365 *--aux = (char) (digval +
'0');
366 }
while (ean && search++ < 12);
367 while (search++ < 12)
371 if (strncmp(
"978",
buf, 3) == 0)
375 else if (strncmp(
"977",
buf, 3) == 0)
379 else if (strncmp(
"9790",
buf, 4) == 0)
383 else if (strncmp(
"979",
buf, 3) == 0)
387 else if (*
buf ==
'0')
407 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
408 errmsg(
"cannot cast EAN13(%s) to %s for number: \"%s\"",
414 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
415 errmsg(
"cannot cast %s to %s for number: \"%s\"",
432 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
433 errmsg(
"value \"%s\" is out of range for %s type",
454 if (strncmp(
"978-", isn, 4) == 0)
459 aux = strchr(isn,
'\0');
460 while (!isdigit((
unsigned char) *--aux));
489 isn[8] = check +
'0';
516 if (isdigit((
unsigned char) *num))
517 ean = 10 * ean + (*num -
'0');
536 const char *(*TABLE)[2];
563 digval = (unsigned) (ean % 10);
565 *--aux = (char) (digval +
'0');
568 }
while (ean && search++ < 13);
569 while (search++ < 13)
578 search =
hyphenate(result, result + 3, NULL, NULL);
583 if (strncmp(
"978-", result, search) == 0)
590 else if (strncmp(
"977-", result, search) == 0)
597 else if (strncmp(
"979-0", result, search + 1) == 0)
604 else if (strncmp(
"979-", result, search) == 0)
611 else if (*result ==
'0')
632 search =
hyphenate(result + digval, result + digval + 2, NULL, NULL);
669 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
670 errmsg(
"value \"%s\" is out of range for %s type",
692 char *aux1 =
buf + 3;
694 const char *aux2 =
str;
697 rcheck = (unsigned) -1;
703 while (*aux2 && length <= 13)
705 last = (*(aux2 + 1) ==
'!' || *(aux2 + 1) ==
'\0');
706 digit = (isdigit((
unsigned char) *aux2) != 0);
708 if (*aux2 ==
'?' && last)
710 magic = digit =
true;
711 if (length == 0 && (*aux2 ==
'M' || *aux2 ==
'm'))
720 else if (length == 7 && (digit || *aux2 ==
'X' || *aux2 ==
'x') && last)
726 *aux1++ = toupper((
unsigned char) *aux2);
729 else if (length == 9 && (digit || *aux2 ==
'X' || *aux2 ==
'x') && last)
736 *aux1++ = toupper((
unsigned char) *aux2);
739 else if (length == 11 && digit && last)
748 else if (*aux2 ==
'-' || *aux2 ==
' ')
752 else if (*aux2 ==
'!' && *(aux2 + 1) ==
'\0')
780 check =
buf[15] -
'0';
782 else if (length == 12)
787 check =
buf[14] -
'0';
789 else if (length == 10)
796 check =
buf[12] -
'0';
798 else if (length == 8)
806 check =
buf[10] -
'0';
822 valid = (valid && ((rcheck =
checkdig(
buf + 3, 13)) == check || magic));
826 else if (strncmp(
"977",
buf + 3, 3) == 0)
828 else if (strncmp(
"978",
buf + 3, 3) == 0)
830 else if (strncmp(
"9790",
buf + 3, 4) == 0)
832 else if (strncmp(
"979",
buf + 3, 3) == 0)
838 memcpy(
buf,
"9790", 4);
840 valid = (valid && ((rcheck =
checkdig(
buf, 13)) == check || magic));
843 memcpy(
buf,
"978", 3);
847 memcpy(
buf + 10,
"00", 2);
849 memcpy(
buf,
"977", 3);
854 valid = (valid && ((rcheck =
checkdig(
buf + 2, 13)) == check || magic));
860 for (aux1 =
buf; *aux1 && *aux1 <=
' '; aux1++);
861 aux1[12] =
checkdig(aux1, 13) +
'0';
864 if (!valid && !magic)
868 *result |= valid ? 0 : 1;
880 if (rcheck == (
unsigned) -1)
883 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
884 errmsg(
"invalid %s number: \"%s\"",
890 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
891 errmsg(
"invalid check digit for %s number: \"%s\", should be %c",
897 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
898 errmsg(
"invalid input syntax for %s number: \"%s\"",
903 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
904 errmsg(
"cannot cast %s to %s for number: \"%s\"",
909 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
910 errmsg(
"value \"%s\" is out of range for %s type",
937 "Accept input with invalid ISN check digits.",
static const unsigned EAN13_index[10][2]
static const char * EAN13_range[][2]
static const char * ISBN_range[][2]
static const unsigned ISBN_index[10][2]
static const unsigned ISBN_index_new[10][2]
static const char * ISBN_range_new[][2]
static const char * ISMN_range[][2]
static const unsigned ISMN_index[10][2]
static const unsigned ISSN_index[10][2]
static const char * ISSN_range[][2]
static const unsigned UPC_index[10][2]
static const char * UPC_range[][2]
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereturn(context, dummy_value,...)
#define ereport(elevel,...)
#define PG_RETURN_CSTRING(x)
#define PG_GETARG_CSTRING(n)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_BOOL(x)
void DefineCustomBoolVariable(const char *name, const char *short_desc, const char *long_desc, bool *valueAddr, bool bootValue, GucContext context, int flags, GucBoolCheckHook check_hook, GucBoolAssignHook assign_hook, GucShowHook show_hook)
void MarkGUCPrefixReserved(const char *className)
int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
Datum upc_cast_from_ean13(PG_FUNCTION_ARGS)
Datum ean13_out(PG_FUNCTION_ARGS)
Datum issn_in(PG_FUNCTION_ARGS)
Datum isn_out(PG_FUNCTION_ARGS)
static bool string2ean(const char *str, struct Node *escontext, ean13 *result, enum isn_type accept)
Datum make_valid(PG_FUNCTION_ARGS)
static void ean2ISBN(char *isn)
Datum ismn_in(PG_FUNCTION_ARGS)
Datum accept_weak_input(PG_FUNCTION_ARGS)
static bool ean2string(ean13 ean, bool errorOK, char *result, bool shortType)
const unsigned TABLE_index[10][2]
Datum weak_input_status(PG_FUNCTION_ARGS)
Datum upc_in(PG_FUNCTION_ARGS)
static bool ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
static const char *const isn_names[]
Datum isbn_in(PG_FUNCTION_ARGS)
Datum issn_cast_from_ean13(PG_FUNCTION_ARGS)
static void ean2UPC(char *isn)
Datum ean13_in(PG_FUNCTION_ARGS)
Datum ismn_cast_from_ean13(PG_FUNCTION_ARGS)
Datum isbn_cast_from_ean13(PG_FUNCTION_ARGS)
static unsigned hyphenate(char *bufO, char *bufI, const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
static unsigned checkdig(char *num, unsigned size)
static void ean2ISMN(char *isn)
Datum is_valid(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(isn_out)
static unsigned dehyphenate(char *bufO, char *bufI)
static unsigned weight_checkdig(char *isn, unsigned size)
static ean13 str2ean(const char *num)
pg_attribute_unused() static bool check_table(const char *(*TABLE)[2]
static void ean2ISSN(char *isn)
#define PG_GETARG_EAN13(n)
#define PG_RETURN_EAN13(x)
char * pstrdup(const char *in)
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
#define accept(s, addr, addrlen)