PostgreSQL Source Code  git master
isn.c File Reference
#include "postgres.h"
#include "EAN13.h"
#include "ISBN.h"
#include "ISMN.h"
#include "ISSN.h"
#include "UPC.h"
#include "fmgr.h"
#include "isn.h"
#include "utils/builtins.h"
Include dependency graph for isn.c:

Go to the source code of this file.

Macros

#define ISN_DEBUG   0
 
#define MAXEAN13LEN   18
 

Enumerations

enum  isn_type {
  INVALID, ANY, EAN13, ISBN,
  ISMN, ISSN, UPC
}
 

Functions

 pg_attribute_unused ()
 
static unsigned dehyphenate (char *bufO, char *bufI)
 
static unsigned hyphenate (char *bufO, char *bufI, const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
 
static unsigned weight_checkdig (char *isn, unsigned size)
 
static unsigned checkdig (char *num, unsigned size)
 
static bool ean2isn (ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
 
static void ean2ISBN (char *isn)
 
static void ean2ISMN (char *isn)
 
static void ean2ISSN (char *isn)
 
static void ean2UPC (char *isn)
 
static ean13 str2ean (const char *num)
 
static bool ean2string (ean13 ean, bool errorOK, char *result, bool shortType)
 
static bool string2ean (const char *str, bool errorOK, ean13 *result, enum isn_type accept)
 
void _PG_init (void)
 
 PG_FUNCTION_INFO_V1 (isn_out)
 
Datum isn_out (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ean13_out)
 
Datum ean13_out (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ean13_in)
 
Datum ean13_in (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (isbn_in)
 
Datum isbn_in (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ismn_in)
 
Datum ismn_in (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (issn_in)
 
Datum issn_in (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (upc_in)
 
Datum upc_in (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (isbn_cast_from_ean13)
 
Datum isbn_cast_from_ean13 (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ismn_cast_from_ean13)
 
Datum ismn_cast_from_ean13 (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (issn_cast_from_ean13)
 
Datum issn_cast_from_ean13 (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (upc_cast_from_ean13)
 
Datum upc_cast_from_ean13 (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (is_valid)
 
Datum is_valid (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (make_valid)
 
Datum make_valid (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (accept_weak_input)
 
Datum accept_weak_input (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (weak_input_status)
 
Datum weak_input_status (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 
static const char *const isn_names [] = {"EAN13/UPC/ISxN", "EAN13/UPC/ISxN", "EAN13", "ISBN", "ISMN", "ISSN", "UPC"}
 
static bool g_weak = false
 

Macro Definition Documentation

◆ ISN_DEBUG

#define ISN_DEBUG   0

Definition at line 31 of file isn.c.

Referenced by _PG_init().

◆ MAXEAN13LEN

#define MAXEAN13LEN   18

Definition at line 34 of file isn.c.

Referenced by ean13_out(), ean2isn(), ean2string(), and isn_out().

Enumeration Type Documentation

◆ isn_type

enum isn_type
Enumerator
INVALID 
ANY 
EAN13 
ISBN 
ISMN 
ISSN 
UPC 

Definition at line 36 of file isn.c.

37 {
39 };
Definition: isn.c:38
Definition: isn.c:38
Definition: isn.c:38
Definition: isn.c:38
Definition: isn.c:38
Definition: isn.c:38
Definition: isn.c:38

Function Documentation

◆ _PG_init()

void _PG_init ( void  )

Definition at line 930 of file isn.c.

References EAN13_index, EAN13_range, elog, ERROR, ISBN_index, ISBN_range, ISMN_index, ISMN_range, ISN_DEBUG, isn_out(), ISSN_index, ISSN_range, PG_FUNCTION_INFO_V1(), UPC_index, and UPC_range.

Referenced by string2ean().

931 {
932  if (ISN_DEBUG)
933  {
934  if (!check_table(EAN13_range, EAN13_index))
935  elog(ERROR, "EAN13 failed check");
936  if (!check_table(ISBN_range, ISBN_index))
937  elog(ERROR, "ISBN failed check");
938  if (!check_table(ISMN_range, ISMN_index))
939  elog(ERROR, "ISMN failed check");
940  if (!check_table(ISSN_range, ISSN_index))
941  elog(ERROR, "ISSN failed check");
942  if (!check_table(UPC_range, UPC_index))
943  elog(ERROR, "UPC failed check");
944  }
945 }
#define ISN_DEBUG
Definition: isn.c:31
const unsigned UPC_index[10][2]
Definition: UPC.h:14
const unsigned ISSN_index[10][2]
Definition: ISSN.h:34
const unsigned EAN13_index[10][2]
Definition: EAN13.h:14
#define ERROR
Definition: elog.h:43
const unsigned ISMN_index[10][2]
Definition: ISMN.h:33
const char * EAN13_range[][2]
Definition: EAN13.h:26
const char * ISSN_range[][2]
Definition: ISSN.h:46
const unsigned ISBN_index[10][2]
Definition: ISBN.h:37
const char * ISMN_range[][2]
Definition: ISMN.h:45
const char * ISBN_range[][2]
Definition: ISBN.h:50
#define elog(elevel,...)
Definition: elog.h:214
const char * UPC_range[][2]
Definition: UPC.h:26

◆ accept_weak_input()

Datum accept_weak_input ( PG_FUNCTION_ARGS  )

Definition at line 1124 of file isn.c.

References g_weak, PG_FUNCTION_INFO_V1(), PG_GETARG_BOOL, PG_RETURN_BOOL, and weak_input_status().

Referenced by make_valid().

1125 {
1126 #ifdef ISN_WEAK_MODE
1127  g_weak = PG_GETARG_BOOL(0);
1128 #else
1129  /* function has no effect */
1130 #endif /* ISN_WEAK_MODE */
1132 }
static bool g_weak
Definition: isn.c:43
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358

◆ checkdig()

static unsigned checkdig ( char *  num,
unsigned  size 
)
static

Definition at line 304 of file isn.c.

Referenced by string2ean().

305 {
306  unsigned check = 0,
307  check3 = 0;
308  unsigned pos = 0;
309 
310  if (*num == 'M')
311  { /* ISMN start with 'M' */
312  check3 = 3;
313  pos = 1;
314  }
315  while (*num && size > 1)
316  {
317  if (isdigit((unsigned char) *num))
318  {
319  if (pos++ % 2)
320  check3 += *num - '0';
321  else
322  check += *num - '0';
323  size--;
324  }
325  num++;
326  }
327  check = (check + 3 * check3) % 10;
328  if (check != 0)
329  check = 10 - check;
330  return check;
331 }

◆ dehyphenate()

static unsigned dehyphenate ( char *  bufO,
char *  bufI 
)
static

Definition at line 143 of file isn.c.

Referenced by ean2UPC().

144 {
145  unsigned ret = 0;
146 
147  while (*bufI)
148  {
149  if (isdigit((unsigned char) *bufI))
150  {
151  *bufO++ = *bufI;
152  ret++;
153  }
154  bufI++;
155  }
156  *bufO = '\0';
157  return ret;
158 }

◆ ean13_in()

Datum ean13_in ( PG_FUNCTION_ARGS  )

Definition at line 983 of file isn.c.

References EAN13, isbn_in(), PG_FUNCTION_INFO_V1(), PG_GETARG_CSTRING, PG_RETURN_EAN13, generate_unaccent_rules::str, and string2ean().

Referenced by ean13_out().

984 {
985  const char *str = PG_GETARG_CSTRING(0);
986  ean13 result;
987 
988  (void) string2ean(str, false, &result, EAN13);
989  PG_RETURN_EAN13(result);
990 }
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
uint64 ean13
Definition: isn.h:26
static bool string2ean(const char *str, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:685
Definition: isn.c:38
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277

◆ ean13_out()

Datum ean13_out ( PG_FUNCTION_ARGS  )

Definition at line 967 of file isn.c.

References buf, ean13_in(), ean2string(), MAXEAN13LEN, PG_FUNCTION_INFO_V1(), PG_GETARG_EAN13, PG_RETURN_CSTRING, pstrdup(), and val.

Referenced by isn_out().

968 {
970  char *result;
971  char buf[MAXEAN13LEN + 1];
972 
973  (void) ean2string(val, false, buf, false);
974 
975  result = pstrdup(buf);
976  PG_RETURN_CSTRING(result);
977 }
static bool ean2string(ean13 ean, bool errorOK, char *result, bool shortType)
Definition: isn.c:533
char * pstrdup(const char *in)
Definition: mcxt.c:1186
uint64 ean13
Definition: isn.h:26
static char * buf
Definition: pg_test_fsync.c:67
#define MAXEAN13LEN
Definition: isn.c:34
#define PG_GETARG_EAN13(n)
Definition: isn.h:30
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:361
long val
Definition: informix.c:664

◆ ean2ISBN()

static void ean2ISBN ( char *  isn)
inlinestatic

Definition at line 443 of file isn.c.

References hyphenate(), and weight_checkdig().

Referenced by ean2string().

444 {
445  char *aux;
446  unsigned check;
447 
448  /*
449  * The number should come in this format: 978-0-000-00000-0 or may be an
450  * ISBN-13 number, 979-..., which does not have a short representation. Do
451  * the short output version if possible.
452  */
453  if (strncmp("978-", isn, 4) == 0)
454  {
455  /* Strip the first part and calculate the new check digit */
456  hyphenate(isn, isn + 4, NULL, NULL);
457  check = weight_checkdig(isn, 10);
458  aux = strchr(isn, '\0');
459  while (!isdigit((unsigned char) *--aux));
460  if (check == 10)
461  *aux = 'X';
462  else
463  *aux = check + '0';
464  }
465 }
static unsigned weight_checkdig(char *isn, unsigned size)
Definition: isn.c:278
static unsigned hyphenate(char *bufO, char *bufI, const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
Definition: isn.c:168

◆ ean2ISMN()

static void ean2ISMN ( char *  isn)
inlinestatic

Definition at line 468 of file isn.c.

References hyphenate().

Referenced by ean2string().

469 {
470  /* the number should come in this format: 979-0-000-00000-0 */
471  /* Just strip the first part and change the first digit ('0') to 'M' */
472  hyphenate(isn, isn + 4, NULL, NULL);
473  isn[0] = 'M';
474 }
static unsigned hyphenate(char *bufO, char *bufI, const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
Definition: isn.c:168

◆ ean2isn()

static bool ean2isn ( ean13  ean,
bool  errorOK,
ean13 result,
enum isn_type  accept 
)
static

Definition at line 341 of file isn.c.

References ANY, buf, EAN13, EAN13_FORMAT, ereport, errcode(), errmsg(), ERROR, INVALID, ISBN, ISMN, isn_names, ISSN, MAXEAN13LEN, snprintf, generate_unaccent_rules::type, and UPC.

Referenced by isbn_cast_from_ean13(), ismn_cast_from_ean13(), issn_cast_from_ean13(), and upc_cast_from_ean13().

342 {
343  enum isn_type type = INVALID;
344 
345  char buf[MAXEAN13LEN + 1];
346  char *aux;
347  unsigned digval;
348  unsigned search;
349  ean13 ret = ean;
350 
351  ean >>= 1;
352  /* verify it's in the EAN13 range */
353  if (ean > UINT64CONST(9999999999999))
354  goto eantoobig;
355 
356  /* convert the number */
357  search = 0;
358  aux = buf + 13;
359  *aux = '\0'; /* terminate string; aux points to last digit */
360  do
361  {
362  digval = (unsigned) (ean % 10); /* get the decimal value */
363  ean /= 10; /* get next digit */
364  *--aux = (char) (digval + '0'); /* convert to ascii and store */
365  } while (ean && search++ < 12);
366  while (search++ < 12)
367  *--aux = '0'; /* fill the remaining EAN13 with '0' */
368 
369  /* find out the data type: */
370  if (strncmp("978", buf, 3) == 0)
371  { /* ISBN */
372  type = ISBN;
373  }
374  else if (strncmp("977", buf, 3) == 0)
375  { /* ISSN */
376  type = ISSN;
377  }
378  else if (strncmp("9790", buf, 4) == 0)
379  { /* ISMN */
380  type = ISMN;
381  }
382  else if (strncmp("979", buf, 3) == 0)
383  { /* ISBN-13 */
384  type = ISBN;
385  }
386  else if (*buf == '0')
387  { /* UPC */
388  type = UPC;
389  }
390  else
391  {
392  type = EAN13;
393  }
394  if (accept != ANY && accept != EAN13 && accept != type)
395  goto eanwrongtype;
396 
397  *result = ret;
398  return true;
399 
400 eanwrongtype:
401  if (!errorOK)
402  {
403  if (type != EAN13)
404  {
405  ereport(ERROR,
406  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
407  errmsg("cannot cast EAN13(%s) to %s for number: \"%s\"",
408  isn_names[type], isn_names[accept], buf)));
409  }
410  else
411  {
412  ereport(ERROR,
413  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
414  errmsg("cannot cast %s to %s for number: \"%s\"",
415  isn_names[type], isn_names[accept], buf)));
416  }
417  }
418  return false;
419 
420 eantoobig:
421  if (!errorOK)
422  {
423  char eanbuf[64];
424 
425  /*
426  * Format the number separately to keep the machine-dependent format
427  * code out of the translatable message text
428  */
429  snprintf(eanbuf, sizeof(eanbuf), EAN13_FORMAT, ean);
430  ereport(ERROR,
431  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
432  errmsg("value \"%s\" is out of range for %s type",
433  eanbuf, isn_names[type])));
434  }
435  return false;
436 }
Definition: isn.c:38
#define accept(s, addr, addrlen)
Definition: win32_port.h:434
Definition: isn.c:38
int errcode(int sqlerrcode)
Definition: elog.c:610
Definition: isn.c:38
isn_type
Definition: isn.c:36
#define EAN13_FORMAT
Definition: isn.h:28
#define ERROR
Definition: elog.h:43
uint64 ean13
Definition: isn.h:26
static char * buf
Definition: pg_test_fsync.c:67
Definition: isn.c:38
#define MAXEAN13LEN
Definition: isn.c:34
static const char *const isn_names[]
Definition: isn.c:41
#define ereport(elevel,...)
Definition: elog.h:144
Definition: isn.c:38
Definition: isn.c:38
Definition: isn.c:38
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define snprintf
Definition: port.h:193

◆ ean2ISSN()

static void ean2ISSN ( char *  isn)
inlinestatic

Definition at line 477 of file isn.c.

References hyphenate(), and weight_checkdig().

Referenced by ean2string().

478 {
479  unsigned check;
480 
481  /* the number should come in this format: 977-0000-000-00-0 */
482  /* Strip the first part, crop, and calculate the new check digit */
483  hyphenate(isn, isn + 4, NULL, NULL);
484  check = weight_checkdig(isn, 8);
485  if (check == 10)
486  isn[8] = 'X';
487  else
488  isn[8] = check + '0';
489  isn[9] = '\0';
490 }
static unsigned weight_checkdig(char *isn, unsigned size)
Definition: isn.c:278
static unsigned hyphenate(char *bufO, char *bufI, const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
Definition: isn.c:168

◆ ean2string()

static bool ean2string ( ean13  ean,
bool  errorOK,
char *  result,
bool  shortType 
)
static

Definition at line 533 of file isn.c.

References EAN13, EAN13_FORMAT, EAN13_index, EAN13_range, ean2ISBN(), ean2ISMN(), ean2ISSN(), ean2UPC(), ereport, errcode(), errmsg(), ERROR, hyphenate(), INVALID, ISBN, ISBN_index, ISBN_index_new, ISBN_range, ISBN_range_new, ISMN, ISMN_index, ISMN_range, isn_names, ISSN, ISSN_index, ISSN_range, MAXEAN13LEN, snprintf, generate_unaccent_rules::type, UPC, UPC_index, and UPC_range.

Referenced by ean13_out(), and isn_out().

534 {
535  const char *(*TABLE)[2];
536  const unsigned (*TABLE_index)[2];
537  enum isn_type type = INVALID;
538 
539  char *aux;
540  unsigned digval;
541  unsigned search;
542  char valid = '\0'; /* was the number initially written with a
543  * valid check digit? */
544 
545  TABLE_index = ISBN_index;
546 
547  if ((ean & 1) != 0)
548  valid = '!';
549  ean >>= 1;
550  /* verify it's in the EAN13 range */
551  if (ean > UINT64CONST(9999999999999))
552  goto eantoobig;
553 
554  /* convert the number */
555  search = 0;
556  aux = result + MAXEAN13LEN;
557  *aux = '\0'; /* terminate string; aux points to last digit */
558  *--aux = valid; /* append '!' for numbers with invalid but
559  * corrected check digit */
560  do
561  {
562  digval = (unsigned) (ean % 10); /* get the decimal value */
563  ean /= 10; /* get next digit */
564  *--aux = (char) (digval + '0'); /* convert to ascii and store */
565  if (search == 0)
566  *--aux = '-'; /* the check digit is always there */
567  } while (ean && search++ < 13);
568  while (search++ < 13)
569  *--aux = '0'; /* fill the remaining EAN13 with '0' */
570 
571  /* The string should be in this form: ???DDDDDDDDDDDD-D" */
572  search = hyphenate(result, result + 3, EAN13_range, EAN13_index);
573 
574  /* verify it's a logically valid EAN13 */
575  if (search == 0)
576  {
577  search = hyphenate(result, result + 3, NULL, NULL);
578  goto okay;
579  }
580 
581  /* find out what type of hyphenation is needed: */
582  if (strncmp("978-", result, search) == 0)
583  { /* ISBN -13 978-range */
584  /* The string should be in this form: 978-??000000000-0" */
585  type = ISBN;
586  TABLE = ISBN_range;
587  TABLE_index = ISBN_index;
588  }
589  else if (strncmp("977-", result, search) == 0)
590  { /* ISSN */
591  /* The string should be in this form: 977-??000000000-0" */
592  type = ISSN;
593  TABLE = ISSN_range;
594  TABLE_index = ISSN_index;
595  }
596  else if (strncmp("979-0", result, search + 1) == 0)
597  { /* ISMN */
598  /* The string should be in this form: 979-0?000000000-0" */
599  type = ISMN;
600  TABLE = ISMN_range;
601  TABLE_index = ISMN_index;
602  }
603  else if (strncmp("979-", result, search) == 0)
604  { /* ISBN-13 979-range */
605  /* The string should be in this form: 979-??000000000-0" */
606  type = ISBN;
607  TABLE = ISBN_range_new;
608  TABLE_index = ISBN_index_new;
609  }
610  else if (*result == '0')
611  { /* UPC */
612  /* The string should be in this form: 000-00000000000-0" */
613  type = UPC;
614  TABLE = UPC_range;
615  TABLE_index = UPC_index;
616  }
617  else
618  {
619  type = EAN13;
620  TABLE = NULL;
621  TABLE_index = NULL;
622  }
623 
624  /* verify it's a logically valid EAN13/UPC/ISxN */
625  digval = search;
626  search = hyphenate(result + digval, result + digval + 2, TABLE, TABLE_index);
627 
628  /* verify it's a valid EAN13 */
629  if (search == 0)
630  {
631  search = hyphenate(result + digval, result + digval + 2, NULL, NULL);
632  goto okay;
633  }
634 
635 okay:
636  /* convert to the old short type: */
637  if (shortType)
638  switch (type)
639  {
640  case ISBN:
641  ean2ISBN(result);
642  break;
643  case ISMN:
644  ean2ISMN(result);
645  break;
646  case ISSN:
647  ean2ISSN(result);
648  break;
649  case UPC:
650  ean2UPC(result);
651  break;
652  default:
653  break;
654  }
655  return true;
656 
657 eantoobig:
658  if (!errorOK)
659  {
660  char eanbuf[64];
661 
662  /*
663  * Format the number separately to keep the machine-dependent format
664  * code out of the translatable message text
665  */
666  snprintf(eanbuf, sizeof(eanbuf), EAN13_FORMAT, ean);
667  ereport(ERROR,
668  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
669  errmsg("value \"%s\" is out of range for %s type",
670  eanbuf, isn_names[type])));
671  }
672  return false;
673 }
const char * ISBN_range_new[][2]
Definition: ISBN.h:983
Definition: isn.c:38
const unsigned UPC_index[10][2]
Definition: UPC.h:14
const unsigned ISSN_index[10][2]
Definition: ISSN.h:34
Definition: isn.c:38
static void ean2ISBN(char *isn)
Definition: isn.c:443
static void ean2UPC(char *isn)
Definition: isn.c:493
int errcode(int sqlerrcode)
Definition: elog.c:610
Definition: isn.c:38
isn_type
Definition: isn.c:36
const unsigned EAN13_index[10][2]
Definition: EAN13.h:14
#define EAN13_FORMAT
Definition: isn.h:28
#define ERROR
Definition: elog.h:43
const unsigned ISMN_index[10][2]
Definition: ISMN.h:33
const char * EAN13_range[][2]
Definition: EAN13.h:26
const unsigned ISBN_index_new[10][2]
Definition: ISBN.h:970
#define MAXEAN13LEN
Definition: isn.c:34
static const char *const isn_names[]
Definition: isn.c:41
const char * ISSN_range[][2]
Definition: ISSN.h:46
#define ereport(elevel,...)
Definition: elog.h:144
Definition: isn.c:38
Definition: isn.c:38
static unsigned hyphenate(char *bufO, char *bufI, const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
Definition: isn.c:168
static void ean2ISMN(char *isn)
Definition: isn.c:468
const unsigned ISBN_index[10][2]
Definition: ISBN.h:37
const char * ISMN_range[][2]
Definition: ISMN.h:45
Definition: isn.c:38
const char * ISBN_range[][2]
Definition: ISBN.h:50
int errmsg(const char *fmt,...)
Definition: elog.c:824
static void ean2ISSN(char *isn)
Definition: isn.c:477
#define snprintf
Definition: port.h:193
const char * UPC_range[][2]
Definition: UPC.h:26

◆ ean2UPC()

static void ean2UPC ( char *  isn)
inlinestatic

Definition at line 493 of file isn.c.

References dehyphenate().

Referenced by ean2string().

494 {
495  /* the number should come in this format: 000-000000000-0 */
496  /* Strip the first part, crop, and dehyphenate */
497  dehyphenate(isn, isn + 1);
498  isn[12] = '\0';
499 }
static unsigned dehyphenate(char *bufO, char *bufI)
Definition: isn.c:143

◆ hyphenate()

static unsigned hyphenate ( char *  bufO,
char *  bufI,
const char *(*)  TABLE[2],
const unsigned  TABLE_index[10][2] 
)
static

Definition at line 168 of file isn.c.

References lower(), and upper().

Referenced by ean2ISBN(), ean2ISMN(), ean2ISSN(), and ean2string().

169 {
170  unsigned ret = 0;
171  const char *ean_aux1,
172  *ean_aux2,
173  *ean_p;
174  char *firstdig,
175  *aux1,
176  *aux2;
177  unsigned search,
178  upper,
179  lower,
180  step;
181  bool ean_in1,
182  ean_in2;
183 
184  /* just compress the string if no further hyphenation is required */
185  if (TABLE == NULL || TABLE_index == NULL)
186  {
187  while (*bufI)
188  {
189  *bufO++ = *bufI++;
190  ret++;
191  }
192  *bufO = '\0';
193  return (ret + 1);
194  }
195 
196  /* add remaining hyphenations */
197 
198  search = *bufI - '0';
199  upper = lower = TABLE_index[search][0];
200  upper += TABLE_index[search][1];
201  lower--;
202 
203  step = (upper - lower) / 2;
204  if (step == 0)
205  return 0;
206  search = lower + step;
207 
208  firstdig = bufI;
209  ean_in1 = ean_in2 = false;
210  ean_aux1 = TABLE[search][0];
211  ean_aux2 = TABLE[search][1];
212  do
213  {
214  if ((ean_in1 || *firstdig >= *ean_aux1) && (ean_in2 || *firstdig <= *ean_aux2))
215  {
216  if (*firstdig > *ean_aux1)
217  ean_in1 = true;
218  if (*firstdig < *ean_aux2)
219  ean_in2 = true;
220  if (ean_in1 && ean_in2)
221  break;
222 
223  firstdig++, ean_aux1++, ean_aux2++;
224  if (!(*ean_aux1 && *ean_aux2 && *firstdig))
225  break;
226  if (!isdigit((unsigned char) *ean_aux1))
227  ean_aux1++, ean_aux2++;
228  }
229  else
230  {
231  /*
232  * check in what direction we should go and move the pointer
233  * accordingly
234  */
235  if (*firstdig < *ean_aux1 && !ean_in1)
236  upper = search;
237  else
238  lower = search;
239 
240  step = (upper - lower) / 2;
241  search = lower + step;
242 
243  /* Initialize stuff again: */
244  firstdig = bufI;
245  ean_in1 = ean_in2 = false;
246  ean_aux1 = TABLE[search][0];
247  ean_aux2 = TABLE[search][1];
248  }
249  } while (step);
250 
251  if (step)
252  {
253  aux1 = bufO;
254  aux2 = bufI;
255  ean_p = TABLE[search][0];
256  while (*ean_p && *aux2)
257  {
258  if (*ean_p++ != '-')
259  *aux1++ = *aux2++;
260  else
261  *aux1++ = '-';
262  ret++;
263  }
264  *aux1++ = '-';
265  *aux1 = *aux2; /* add a lookahead char */
266  return (ret + 1);
267  }
268  return ret;
269 }
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74

◆ is_valid()

Datum is_valid ( PG_FUNCTION_ARGS  )

Definition at line 1099 of file isn.c.

References make_valid(), PG_FUNCTION_INFO_V1(), PG_GETARG_EAN13, PG_RETURN_BOOL, and val.

Referenced by upc_cast_from_ean13().

1100 {
1101  ean13 val = PG_GETARG_EAN13(0);
1102 
1103  PG_RETURN_BOOL((val & 1) == 0);
1104 }
uint64 ean13
Definition: isn.h:26
#define PG_GETARG_EAN13(n)
Definition: isn.h:30
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
long val
Definition: informix.c:664

◆ isbn_cast_from_ean13()

Datum isbn_cast_from_ean13 ( PG_FUNCTION_ARGS  )

Definition at line 1048 of file isn.c.

References ean2isn(), ISBN, ismn_cast_from_ean13(), PG_FUNCTION_INFO_V1(), PG_GETARG_EAN13, PG_RETURN_EAN13, and val.

Referenced by upc_in().

1049 {
1050  ean13 val = PG_GETARG_EAN13(0);
1051  ean13 result;
1052 
1053  (void) ean2isn(val, false, &result, ISBN);
1054 
1055  PG_RETURN_EAN13(result);
1056 }
Definition: isn.c:38
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
uint64 ean13
Definition: isn.h:26
static bool ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:341
#define PG_GETARG_EAN13(n)
Definition: isn.h:30
long val
Definition: informix.c:664

◆ isbn_in()

Datum isbn_in ( PG_FUNCTION_ARGS  )

Definition at line 996 of file isn.c.

References ISBN, ismn_in(), PG_FUNCTION_INFO_V1(), PG_GETARG_CSTRING, PG_RETURN_EAN13, generate_unaccent_rules::str, and string2ean().

Referenced by ean13_in().

997 {
998  const char *str = PG_GETARG_CSTRING(0);
999  ean13 result;
1000 
1001  (void) string2ean(str, false, &result, ISBN);
1002  PG_RETURN_EAN13(result);
1003 }
Definition: isn.c:38
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
uint64 ean13
Definition: isn.h:26
static bool string2ean(const char *str, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:685
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277

◆ ismn_cast_from_ean13()

Datum ismn_cast_from_ean13 ( PG_FUNCTION_ARGS  )

Definition at line 1060 of file isn.c.

References ean2isn(), ISMN, issn_cast_from_ean13(), PG_FUNCTION_INFO_V1(), PG_GETARG_EAN13, PG_RETURN_EAN13, and val.

Referenced by isbn_cast_from_ean13().

1061 {
1062  ean13 val = PG_GETARG_EAN13(0);
1063  ean13 result;
1064 
1065  (void) ean2isn(val, false, &result, ISMN);
1066 
1067  PG_RETURN_EAN13(result);
1068 }
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
Definition: isn.c:38
uint64 ean13
Definition: isn.h:26
static bool ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:341
#define PG_GETARG_EAN13(n)
Definition: isn.h:30
long val
Definition: informix.c:664

◆ ismn_in()

Datum ismn_in ( PG_FUNCTION_ARGS  )

Definition at line 1009 of file isn.c.

References ISMN, issn_in(), PG_FUNCTION_INFO_V1(), PG_GETARG_CSTRING, PG_RETURN_EAN13, generate_unaccent_rules::str, and string2ean().

Referenced by isbn_in().

1010 {
1011  const char *str = PG_GETARG_CSTRING(0);
1012  ean13 result;
1013 
1014  (void) string2ean(str, false, &result, ISMN);
1015  PG_RETURN_EAN13(result);
1016 }
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
Definition: isn.c:38
uint64 ean13
Definition: isn.h:26
static bool string2ean(const char *str, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:685
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277

◆ isn_out()

Datum isn_out ( PG_FUNCTION_ARGS  )

Definition at line 951 of file isn.c.

References buf, ean13_out(), ean2string(), MAXEAN13LEN, PG_FUNCTION_INFO_V1(), PG_GETARG_EAN13, PG_RETURN_CSTRING, pstrdup(), and val.

Referenced by _PG_init().

952 {
954  char *result;
955  char buf[MAXEAN13LEN + 1];
956 
957  (void) ean2string(val, false, buf, true);
958 
959  result = pstrdup(buf);
960  PG_RETURN_CSTRING(result);
961 }
static bool ean2string(ean13 ean, bool errorOK, char *result, bool shortType)
Definition: isn.c:533
char * pstrdup(const char *in)
Definition: mcxt.c:1186
uint64 ean13
Definition: isn.h:26
static char * buf
Definition: pg_test_fsync.c:67
#define MAXEAN13LEN
Definition: isn.c:34
#define PG_GETARG_EAN13(n)
Definition: isn.h:30
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:361
long val
Definition: informix.c:664

◆ issn_cast_from_ean13()

Datum issn_cast_from_ean13 ( PG_FUNCTION_ARGS  )

Definition at line 1072 of file isn.c.

References ean2isn(), ISSN, PG_FUNCTION_INFO_V1(), PG_GETARG_EAN13, PG_RETURN_EAN13, upc_cast_from_ean13(), and val.

Referenced by ismn_cast_from_ean13().

1073 {
1074  ean13 val = PG_GETARG_EAN13(0);
1075  ean13 result;
1076 
1077  (void) ean2isn(val, false, &result, ISSN);
1078 
1079  PG_RETURN_EAN13(result);
1080 }
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
uint64 ean13
Definition: isn.h:26
static bool ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:341
#define PG_GETARG_EAN13(n)
Definition: isn.h:30
Definition: isn.c:38
long val
Definition: informix.c:664

◆ issn_in()

Datum issn_in ( PG_FUNCTION_ARGS  )

Definition at line 1022 of file isn.c.

References ISSN, PG_FUNCTION_INFO_V1(), PG_GETARG_CSTRING, PG_RETURN_EAN13, generate_unaccent_rules::str, string2ean(), and upc_in().

Referenced by ismn_in().

1023 {
1024  const char *str = PG_GETARG_CSTRING(0);
1025  ean13 result;
1026 
1027  (void) string2ean(str, false, &result, ISSN);
1028  PG_RETURN_EAN13(result);
1029 }
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
uint64 ean13
Definition: isn.h:26
Definition: isn.c:38
static bool string2ean(const char *str, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:685
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277

◆ make_valid()

Datum make_valid ( PG_FUNCTION_ARGS  )

Definition at line 1110 of file isn.c.

References accept_weak_input(), PG_FUNCTION_INFO_V1(), PG_GETARG_EAN13, PG_RETURN_EAN13, and val.

Referenced by is_valid().

1111 {
1112  ean13 val = PG_GETARG_EAN13(0);
1113 
1114  val &= ~((ean13) 1);
1115  PG_RETURN_EAN13(val);
1116 }
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
uint64 ean13
Definition: isn.h:26
#define PG_GETARG_EAN13(n)
Definition: isn.h:30
long val
Definition: informix.c:664

◆ pg_attribute_unused()

pg_attribute_unused ( )

Definition at line 63 of file isn.c.

References DEBUG1, elog, i, and init.

Referenced by get_collation_actual_version(), and pg_newlocale_from_collation().

66 {
67  const char *aux1,
68  *aux2;
69  int a,
70  b,
71  x = 0,
72  y = -1,
73  i = 0,
74  j,
75  init = 0;
76 
77  if (TABLE == NULL || TABLE_index == NULL)
78  return true;
79 
80  while (TABLE[i][0] && TABLE[i][1])
81  {
82  aux1 = TABLE[i][0];
83  aux2 = TABLE[i][1];
84 
85  /* must always start with a digit: */
86  if (!isdigit((unsigned char) *aux1) || !isdigit((unsigned char) *aux2))
87  goto invalidtable;
88  a = *aux1 - '0';
89  b = *aux2 - '0';
90 
91  /* must always have the same format and length: */
92  while (*aux1 && *aux2)
93  {
94  if (!(isdigit((unsigned char) *aux1) &&
95  isdigit((unsigned char) *aux2)) &&
96  (*aux1 != *aux2 || *aux1 != '-'))
97  goto invalidtable;
98  aux1++;
99  aux2++;
100  }
101  if (*aux1 != *aux2)
102  goto invalidtable;
103 
104  /* found a new range */
105  if (a > y)
106  {
107  /* check current range in the index: */
108  for (j = x; j <= y; j++)
109  {
110  if (TABLE_index[j][0] != init)
111  goto invalidindex;
112  if (TABLE_index[j][1] != i - init)
113  goto invalidindex;
114  }
115  init = i;
116  x = a;
117  }
118 
119  /* Always get the new limit */
120  y = b;
121  if (y < x)
122  goto invalidtable;
123  i++;
124  }
125 
126  return true;
127 
128 invalidtable:
129  elog(DEBUG1, "invalid table near {\"%s\", \"%s\"} (pos: %d)",
130  TABLE[i][0], TABLE[i][1], i);
131  return false;
132 
133 invalidindex:
134  elog(DEBUG1, "index %d is invalid", j);
135  return false;
136 }
#define DEBUG1
Definition: elog.h:25
#define init()
#define elog(elevel,...)
Definition: elog.h:214
int i

◆ PG_FUNCTION_INFO_V1() [1/15]

◆ PG_FUNCTION_INFO_V1() [2/15]

PG_FUNCTION_INFO_V1 ( ean13_out  )

◆ PG_FUNCTION_INFO_V1() [3/15]

PG_FUNCTION_INFO_V1 ( ean13_in  )

◆ PG_FUNCTION_INFO_V1() [4/15]

PG_FUNCTION_INFO_V1 ( isbn_in  )

◆ PG_FUNCTION_INFO_V1() [5/15]

PG_FUNCTION_INFO_V1 ( ismn_in  )

◆ PG_FUNCTION_INFO_V1() [6/15]

PG_FUNCTION_INFO_V1 ( issn_in  )

◆ PG_FUNCTION_INFO_V1() [7/15]

PG_FUNCTION_INFO_V1 ( upc_in  )

◆ PG_FUNCTION_INFO_V1() [8/15]

PG_FUNCTION_INFO_V1 ( isbn_cast_from_ean13  )

◆ PG_FUNCTION_INFO_V1() [9/15]

PG_FUNCTION_INFO_V1 ( ismn_cast_from_ean13  )

◆ PG_FUNCTION_INFO_V1() [10/15]

PG_FUNCTION_INFO_V1 ( issn_cast_from_ean13  )

◆ PG_FUNCTION_INFO_V1() [11/15]

PG_FUNCTION_INFO_V1 ( upc_cast_from_ean13  )

◆ PG_FUNCTION_INFO_V1() [12/15]

PG_FUNCTION_INFO_V1 ( is_valid  )

◆ PG_FUNCTION_INFO_V1() [13/15]

PG_FUNCTION_INFO_V1 ( make_valid  )

◆ PG_FUNCTION_INFO_V1() [14/15]

PG_FUNCTION_INFO_V1 ( accept_weak_input  )

◆ PG_FUNCTION_INFO_V1() [15/15]

PG_FUNCTION_INFO_V1 ( weak_input_status  )

◆ str2ean()

static ean13 str2ean ( const char *  num)
static

Definition at line 509 of file isn.c.

Referenced by string2ean().

510 {
511  ean13 ean = 0; /* current ean */
512 
513  while (*num)
514  {
515  if (isdigit((unsigned char) *num))
516  ean = 10 * ean + (*num - '0');
517  num++;
518  }
519  return (ean << 1); /* also give room to a flag */
520 }
uint64 ean13
Definition: isn.h:26

◆ string2ean()

static bool string2ean ( const char *  str,
bool  errorOK,
ean13 result,
enum isn_type  accept 
)
static

Definition at line 685 of file isn.c.

References _PG_init(), ANY, buf, checkdig(), EAN13, ereport, errcode(), errmsg(), ERROR, g_weak, INVALID, ISBN, ISMN, isn_names, ISSN, NODE::length, generate_unaccent_rules::str, str2ean(), generate_unaccent_rules::type, UPC, and weight_checkdig().

Referenced by ean13_in(), isbn_in(), ismn_in(), issn_in(), and upc_in().

687 {
688  bool digit,
689  last;
690  char buf[17] = " ";
691  char *aux1 = buf + 3; /* leave space for the first part, in case
692  * it's needed */
693  const char *aux2 = str;
694  enum isn_type type = INVALID;
695  unsigned check = 0,
696  rcheck = (unsigned) -1;
697  unsigned length = 0;
698  bool magic = false,
699  valid = true;
700 
701  /* recognize and validate the number: */
702  while (*aux2 && length <= 13)
703  {
704  last = (*(aux2 + 1) == '!' || *(aux2 + 1) == '\0'); /* is the last character */
705  digit = (isdigit((unsigned char) *aux2) != 0); /* is current character
706  * a digit? */
707  if (*aux2 == '?' && last) /* automagically calculate check digit if
708  * it's '?' */
709  magic = digit = true;
710  if (length == 0 && (*aux2 == 'M' || *aux2 == 'm'))
711  {
712  /* only ISMN can be here */
713  if (type != INVALID)
714  goto eaninvalid;
715  type = ISMN;
716  *aux1++ = 'M';
717  length++;
718  }
719  else if (length == 7 && (digit || *aux2 == 'X' || *aux2 == 'x') && last)
720  {
721  /* only ISSN can be here */
722  if (type != INVALID)
723  goto eaninvalid;
724  type = ISSN;
725  *aux1++ = toupper((unsigned char) *aux2);
726  length++;
727  }
728  else if (length == 9 && (digit || *aux2 == 'X' || *aux2 == 'x') && last)
729  {
730  /* only ISBN and ISMN can be here */
731  if (type != INVALID && type != ISMN)
732  goto eaninvalid;
733  if (type == INVALID)
734  type = ISBN; /* ISMN must start with 'M' */
735  *aux1++ = toupper((unsigned char) *aux2);
736  length++;
737  }
738  else if (length == 11 && digit && last)
739  {
740  /* only UPC can be here */
741  if (type != INVALID)
742  goto eaninvalid;
743  type = UPC;
744  *aux1++ = *aux2;
745  length++;
746  }
747  else if (*aux2 == '-' || *aux2 == ' ')
748  {
749  /* skip, we could validate but I think it's worthless */
750  }
751  else if (*aux2 == '!' && *(aux2 + 1) == '\0')
752  {
753  /* the invalid check digit suffix was found, set it */
754  if (!magic)
755  valid = false;
756  magic = true;
757  }
758  else if (!digit)
759  {
760  goto eaninvalid;
761  }
762  else
763  {
764  *aux1++ = *aux2;
765  if (++length > 13)
766  goto eantoobig;
767  }
768  aux2++;
769  }
770  *aux1 = '\0'; /* terminate the string */
771 
772  /* find the current check digit value */
773  if (length == 13)
774  {
775  /* only EAN13 can be here */
776  if (type != INVALID)
777  goto eaninvalid;
778  type = EAN13;
779  check = buf[15] - '0';
780  }
781  else if (length == 12)
782  {
783  /* only UPC can be here */
784  if (type != UPC)
785  goto eaninvalid;
786  check = buf[14] - '0';
787  }
788  else if (length == 10)
789  {
790  if (type != ISBN && type != ISMN)
791  goto eaninvalid;
792  if (buf[12] == 'X')
793  check = 10;
794  else
795  check = buf[12] - '0';
796  }
797  else if (length == 8)
798  {
799  if (type != INVALID && type != ISSN)
800  goto eaninvalid;
801  type = ISSN;
802  if (buf[10] == 'X')
803  check = 10;
804  else
805  check = buf[10] - '0';
806  }
807  else
808  goto eaninvalid;
809 
810  if (type == INVALID)
811  goto eaninvalid;
812 
813  /* obtain the real check digit value, validate, and convert to ean13: */
814  if (accept == EAN13 && type != accept)
815  goto eanwrongtype;
816  if (accept != ANY && type != EAN13 && type != accept)
817  goto eanwrongtype;
818  switch (type)
819  {
820  case EAN13:
821  valid = (valid && ((rcheck = checkdig(buf + 3, 13)) == check || magic));
822  /* now get the subtype of EAN13: */
823  if (buf[3] == '0')
824  type = UPC;
825  else if (strncmp("977", buf + 3, 3) == 0)
826  type = ISSN;
827  else if (strncmp("978", buf + 3, 3) == 0)
828  type = ISBN;
829  else if (strncmp("9790", buf + 3, 4) == 0)
830  type = ISMN;
831  else if (strncmp("979", buf + 3, 3) == 0)
832  type = ISBN;
833  if (accept != EAN13 && accept != ANY && type != accept)
834  goto eanwrongtype;
835  break;
836  case ISMN:
837  memcpy(buf, "9790", 4); /* this isn't for sure yet, for now ISMN
838  * it's only 9790 */
839  valid = (valid && ((rcheck = checkdig(buf, 13)) == check || magic));
840  break;
841  case ISBN:
842  memcpy(buf, "978", 3);
843  valid = (valid && ((rcheck = weight_checkdig(buf + 3, 10)) == check || magic));
844  break;
845  case ISSN:
846  memcpy(buf + 10, "00", 2); /* append 00 as the normal issue
847  * publication code */
848  memcpy(buf, "977", 3);
849  valid = (valid && ((rcheck = weight_checkdig(buf + 3, 8)) == check || magic));
850  break;
851  case UPC:
852  buf[2] = '0';
853  valid = (valid && ((rcheck = checkdig(buf + 2, 13)) == check || magic));
854  default:
855  break;
856  }
857 
858  /* fix the check digit: */
859  for (aux1 = buf; *aux1 && *aux1 <= ' '; aux1++);
860  aux1[12] = checkdig(aux1, 13) + '0';
861  aux1[13] = '\0';
862 
863  if (!valid && !magic)
864  goto eanbadcheck;
865 
866  *result = str2ean(aux1);
867  *result |= valid ? 0 : 1;
868  return true;
869 
870 eanbadcheck:
871  if (g_weak)
872  { /* weak input mode is activated: */
873  /* set the "invalid-check-digit-on-input" flag */
874  *result = str2ean(aux1);
875  *result |= 1;
876  return true;
877  }
878 
879  if (!errorOK)
880  {
881  if (rcheck == (unsigned) -1)
882  {
883  ereport(ERROR,
884  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
885  errmsg("invalid %s number: \"%s\"",
886  isn_names[accept], str)));
887  }
888  else
889  {
890  ereport(ERROR,
891  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
892  errmsg("invalid check digit for %s number: \"%s\", should be %c",
893  isn_names[accept], str, (rcheck == 10) ? ('X') : (rcheck + '0'))));
894  }
895  }
896  return false;
897 
898 eaninvalid:
899  if (!errorOK)
900  ereport(ERROR,
901  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
902  errmsg("invalid input syntax for %s number: \"%s\"",
903  isn_names[accept], str)));
904  return false;
905 
906 eanwrongtype:
907  if (!errorOK)
908  ereport(ERROR,
909  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
910  errmsg("cannot cast %s to %s for number: \"%s\"",
911  isn_names[type], isn_names[accept], str)));
912  return false;
913 
914 eantoobig:
915  if (!errorOK)
916  ereport(ERROR,
917  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
918  errmsg("value \"%s\" is out of range for %s type",
919  str, isn_names[accept])));
920  return false;
921 }
Definition: isn.c:38
#define accept(s, addr, addrlen)
Definition: win32_port.h:434
Definition: isn.c:38
static bool g_weak
Definition: isn.c:43
int errcode(int sqlerrcode)
Definition: elog.c:610
Definition: isn.c:38
isn_type
Definition: isn.c:36
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:67
static unsigned weight_checkdig(char *isn, unsigned size)
Definition: isn.c:278
Definition: isn.c:38
static const char *const isn_names[]
Definition: isn.c:41
static unsigned checkdig(char *num, unsigned size)
Definition: isn.c:304
#define ereport(elevel,...)
Definition: elog.h:144
static ean13 str2ean(const char *num)
Definition: isn.c:509
Definition: isn.c:38
Definition: isn.c:38
Definition: isn.c:38
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ upc_cast_from_ean13()

Datum upc_cast_from_ean13 ( PG_FUNCTION_ARGS  )

Definition at line 1084 of file isn.c.

References ean2isn(), is_valid(), PG_FUNCTION_INFO_V1(), PG_GETARG_EAN13, PG_RETURN_EAN13, UPC, and val.

Referenced by issn_cast_from_ean13().

1085 {
1086  ean13 val = PG_GETARG_EAN13(0);
1087  ean13 result;
1088 
1089  (void) ean2isn(val, false, &result, UPC);
1090 
1091  PG_RETURN_EAN13(result);
1092 }
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
uint64 ean13
Definition: isn.h:26
static bool ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:341
#define PG_GETARG_EAN13(n)
Definition: isn.h:30
Definition: isn.c:38
long val
Definition: informix.c:664

◆ upc_in()

Datum upc_in ( PG_FUNCTION_ARGS  )

Definition at line 1035 of file isn.c.

References isbn_cast_from_ean13(), PG_FUNCTION_INFO_V1(), PG_GETARG_CSTRING, PG_RETURN_EAN13, generate_unaccent_rules::str, string2ean(), and UPC.

Referenced by issn_in().

1036 {
1037  const char *str = PG_GETARG_CSTRING(0);
1038  ean13 result;
1039 
1040  (void) string2ean(str, false, &result, UPC);
1041  PG_RETURN_EAN13(result);
1042 }
#define PG_RETURN_EAN13(x)
Definition: isn.h:31
uint64 ean13
Definition: isn.h:26
Definition: isn.c:38
static bool string2ean(const char *str, bool errorOK, ean13 *result, enum isn_type accept)
Definition: isn.c:685
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277

◆ weak_input_status()

Datum weak_input_status ( PG_FUNCTION_ARGS  )

Definition at line 1136 of file isn.c.

References g_weak, and PG_RETURN_BOOL.

Referenced by accept_weak_input().

1137 {
1139 }
static bool g_weak
Definition: isn.c:43
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358

◆ weight_checkdig()

static unsigned weight_checkdig ( char *  isn,
unsigned  size 
)
static

Definition at line 278 of file isn.c.

Referenced by ean2ISBN(), ean2ISSN(), and string2ean().

279 {
280  unsigned weight = 0;
281 
282  while (*isn && size > 1)
283  {
284  if (isdigit((unsigned char) *isn))
285  {
286  weight += size-- * (*isn - '0');
287  }
288  isn++;
289  }
290  weight = weight % 11;
291  if (weight != 0)
292  weight = 11 - weight;
293  return weight;
294 }

Variable Documentation

◆ g_weak

bool g_weak = false
static

Definition at line 43 of file isn.c.

Referenced by accept_weak_input(), string2ean(), and weak_input_status().

◆ isn_names

const char* const isn_names[] = {"EAN13/UPC/ISxN", "EAN13/UPC/ISxN", "EAN13", "ISBN", "ISMN", "ISSN", "UPC"}
static

Definition at line 41 of file isn.c.

Referenced by ean2isn(), ean2string(), and string2ean().

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 26 of file isn.c.