diff -rcN isn/isn.c newisn/isn.c
*** isn/isn.c	2006-09-08 23:07:52.000000000 -0500
--- newisn/isn.c	2006-09-10 14:23:04.203125000 -0500
***************
*** 31,37 ****
  
  enum isn_type { INVALID, ANY, EAN13, ISBN, ISMN, ISSN, UPC };
  
! static const char *isn_names[] = { "ISN", "ISN", "EAN13", "ISBN", "ISMN", "ISSN", "UPC" };
  
  static bool g_weak = false;
  static bool g_initialized = false;
--- 31,37 ----
  
  enum isn_type { INVALID, ANY, EAN13, ISBN, ISMN, ISSN, UPC };
  
! static const char *isn_names[] = { "EAN13/UPC/ISxN", "EAN13/UPC/ISxN", "EAN13", "ISBN", "ISMN", "ISSN", "UPC" };
  
  static bool g_weak = false;
  static bool g_initialized = false;
***************
*** 43,53 ****
  
  /***********************************************************************
   **
!  **		Routines for ISNs.
   **
   ** Note:
   **  In this code, a normalized string is one that is known to be a valid 
!  **  ISN number containing only digits and hyphens and with enough space 
   **  to hold the full 13 digits plus the maximum of four hyphens.
   ***********************************************************************/
  
--- 43,53 ----
  
  /***********************************************************************
   **
!  **		Routines for EAN13/UPC/ISxNs.
   **
   ** Note:
   **  In this code, a normalized string is one that is known to be a valid 
!  **  ISxN number containing only digits and hyphens and with enough space 
   **  to hold the full 13 digits plus the maximum of four hyphens.
   ***********************************************************************/
  
***************
*** 217,223 ****
  }
  
  /*
!  * weight_checkdig -- Receives a buffer with a normalized ISN string number, 
   *                     and the length to weight.
   *
   * Returns the weight of the number (the check digit value, 0-10)
--- 217,223 ----
  }
  
  /*
!  * weight_checkdig -- Receives a buffer with a normalized ISxN string number, 
   *                     and the length to weight.
   *
   * Returns the weight of the number (the check digit value, 0-10)
***************
*** 239,245 ****
  
  
  /*
!  * checkdig --- Receives a buffer with a normalized ISN string number, 
   *               and the length to check.
   *
   * Returns the check digit value (0-9)
--- 239,245 ----
  
  
  /*
!  * checkdig --- Receives a buffer with a normalized ISxN string number, 
   *               and the length to check.
   *
   * Returns the check digit value (0-9)
***************
*** 267,274 ****
  }
  
  /*
!  * ean2isn --- Convert in-place a normalized EAN13 string to the corresponding 
!  *            ISN string number. Assumes the input string is normalized.
   */
  static inline
  void ean2ISBN(char *isn)
--- 267,360 ----
  }
  
  /*
!  * ean2isn --- Try to convert an ean13 number to a UPC/ISxN number.
!  *             This doesn't verify for a valid check digit.
!  *
!  * If errorOK is false, ereport a useful error message if the ean13 is bad.
!  * If errorOK is true, just return "false" for bad input.
!  */
! static
! bool ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
! {
! 	enum isn_type type = INVALID;
! 
! 	char buf[MAXEAN13LEN + 1];
! 	char *firstdig, *aux;
! 	unsigned digval;
! 	unsigned search;
! 	ean13 ret = ean;
! 	
! 	ean >>= 1;
! 	/* verify it's in the EAN13 range */
! 	if(ean > UINT64CONST(9999999999999))
! 		goto eantoobig;
! 
! 	/* convert the number */
! 	search = 0;
! 	firstdig = aux = buf + 13;
! 	*aux = '\0';	    /* terminate string; aux points to last digit */
! 	do {
! 	    digval = (unsigned)(ean % 10);		/* get the decimal value */ 
! 	    ean /= 10;												/* get next digit */
! 		*--aux = (char)(digval + '0');			/* convert to ascii and store */
! 	} while(ean && search++<12);
! 	while(search++<12) *--aux = '0';			/* fill the remaining EAN13 with '0' */
! 	
! 	/* find out the data type: */
! 	if(!strncmp("978", buf, 3)) { /* ISBN */
! 		type = ISBN;
! 	} else if(!strncmp("977", buf, 3)) { /* ISSN */
! 		type = ISSN;
! 	} else if(!strncmp("9790", buf, 4)) { /* ISMN */
! 		type = ISMN;
! 	} else if(!strncmp("979", buf, 3)) { /* ISBN-13 */
! 		type = ISBN;
! 	} else if(*buf == '0') { /* UPC */
! 		type = UPC;
! 	} else {
! 		type = EAN13;
! 	}
! 	if(accept != ANY && accept != EAN13 && accept != type) goto eanwrongtype;
! 
! 	*result = ret;
! 	return true;
! 	
! eanwrongtype:
! 	if(!errorOK) {
! 		if(type!=EAN13) {
! 			ereport(ERROR,
! 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! 				 errmsg("cannot cast EAN13(%s) to %s for number: \"%s\"",
! 						isn_names[type], isn_names[accept], buf)));
! 		} else {
! 			ereport(ERROR,
! 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! 				 errmsg("cannot cast %s to %s for number: \"%s\"",
! 						isn_names[type], isn_names[accept], buf)));
! 		}
! 	}
! 	return false;
! 
! eantoobig:
! 	if(!errorOK) {
! 		char	eanbuf[64];
! 
! 		/*
! 		 * Format the number separately to keep the machine-dependent
! 		 * format code out of the translatable message text
! 		 */
! 		snprintf(eanbuf, sizeof(eanbuf), EAN13_FORMAT, ean);
! 		ereport(ERROR,
! 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("value \"%s\" is out of range for %s type",
! 						eanbuf, isn_names[type])));
! 	}
! 	return false;
! }
! 
! /*
!  * ean2UPC/ISxN --- Convert in-place a normalized EAN13 string to the corresponding 
!  *                  UPC/ISxN string number. Assumes the input string is normalized.
   */
  static inline
  void ean2ISBN(char *isn)
***************
*** 325,331 ****
  {
  	ean13 ean = 0;	/* current ean */
  	while(*num) {
! 		ean = 10 * ean + ((*num++) - '0');
  	}
      return (ean<<1); /* also give room to a flag */
  }
--- 411,418 ----
  {
  	ean13 ean = 0;	/* current ean */
  	while(*num) {
! 		if(isdigit(*num)) ean = 10 * ean + (*num - '0');
! 		num++;
  	}
      return (ean<<1); /* also give room to a flag */
  }
***************
*** 336,342 ****
   *                the string (maximum MAXEAN13LEN+1 bytes)
   *                This doesn't verify for a valid check digit.
   *
!  * If shortType is true, the returned string is in the old ISN short format.
   * If errorOK is false, ereport a useful error message if the string is bad.
   * If errorOK is true, just return "false" for bad input.
   */
--- 423,429 ----
   *                the string (maximum MAXEAN13LEN+1 bytes)
   *                This doesn't verify for a valid check digit.
   *
!  * If shortType is true, the returned string is in the old ISxN short format.
   * If errorOK is false, ereport a useful error message if the string is bad.
   * If errorOK is true, just return "false" for bad input.
   */
***************
*** 369,376 ****
  	    digval = (unsigned)(ean % 10);		/* get the decimal value */ 
  	    ean /= 10;												/* get next digit */
  		*--aux = (char)(digval + '0');			/* convert to ascii and store */
! 		if(++search == 1) *--aux = '-';			/* the check digit is always there */
! 	} while(ean);
  	while(search++<13) *--aux = '0';			/* fill the remaining EAN13 with '0' */
  
  	/* The string should be in this form: ???DDDDDDDDDDDD-D" */
--- 456,463 ----
  	    digval = (unsigned)(ean % 10);		/* get the decimal value */ 
  	    ean /= 10;												/* get next digit */
  		*--aux = (char)(digval + '0');			/* convert to ascii and store */
! 		if(search == 0) *--aux = '-';			/* the check digit is always there */
! 	} while(ean && search++<13);
  	while(search++<13) *--aux = '0';			/* fill the remaining EAN13 with '0' */
  
  	/* The string should be in this form: ???DDDDDDDDDDDD-D" */
***************
*** 409,415 ****
  		TABLE_index = NULL;
  	}
  
! 	/* verify it's a logically valid EAN13/ISN */
  	digval = search;
  	search = hyphenate(result+digval, result+digval+2, TABLE, TABLE_index);
  
--- 496,502 ----
  		TABLE_index = NULL;
  	}
  
! 	/* verify it's a logically valid EAN13/UPC/ISxN */
  	digval = search;
  	search = hyphenate(result+digval, result+digval+2, TABLE, TABLE_index);
  
***************
*** 452,459 ****
  		snprintf(eanbuf, sizeof(eanbuf), EAN13_FORMAT, ean);
  		ereport(ERROR,
  				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("value \"%s\" is out of range for ISN type",
! 						eanbuf)));
  	}
  	return false;
  }
--- 539,546 ----
  		snprintf(eanbuf, sizeof(eanbuf), EAN13_FORMAT, ean);
  		ereport(ERROR,
  				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
! 				 errmsg("value \"%s\" is out of range for %s type",
! 						eanbuf, isn_names[type])));
  	}
  	return false;
  }
***************
*** 483,489 ****
  	/* recognize and validate the number: */
  	while(*aux2 && length <= 13) {
  		last = (*(aux2+1) == '!' || *(aux2+1) == '\0'); /* is the last character */
! 		digit = isdigit(*aux2); /* is current character a digit? */
  		if(*aux2=='?' && last) /* automagically calculate check digit if it's '?' */
  			magic = digit = true;
  		if(length == 0 &&  (*aux2=='M' || *aux2=='m')) {
--- 570,576 ----
  	/* recognize and validate the number: */
  	while(*aux2 && length <= 13) {
  		last = (*(aux2+1) == '!' || *(aux2+1) == '\0'); /* is the last character */
! 		digit = (isdigit(*aux2)!=0); /* is current character a digit? */
  		if(*aux2=='?' && last) /* automagically calculate check digit if it's '?' */
  			magic = digit = true;
  		if(length == 0 &&  (*aux2=='M' || *aux2=='m')) {
***************
*** 583,601 ****
  			break;
  	}
  
! 	if(!valid && !magic) goto eanbadcheck;
! 			
  	for(aux1 = buf; *aux1 && *aux1 <= ' '; aux1++);
  	aux1[12] = checkdig(aux1, 13) + '0';
  	aux1[13] = '\0';
  	
  	*result = str2ean(aux1);
  	*result |= valid?0:1;
- 
  	return true;
  
  eanbadcheck: 
! 	if(!g_weak) {
  		if(!errorOK) {
  			if(rcheck == (unsigned)-1) {
  				ereport(ERROR,
--- 670,694 ----
  			break;
  	}
  
!   /* fix the check digit: */
  	for(aux1 = buf; *aux1 && *aux1 <= ' '; aux1++);
  	aux1[12] = checkdig(aux1, 13) + '0';
  	aux1[13] = '\0';
  	
+ 	if(!valid && !magic) goto eanbadcheck;
+ 
  	*result = str2ean(aux1);
  	*result |= valid?0:1;
  	return true;
  
  eanbadcheck: 
! 	if(g_weak) { /* weak input mode is activated: */
! 	  /* set the "invalid-check-digit-on-input" flag */ 
! 		*result = str2ean(aux1);
! 		*result |= 1;
! 	return true;
! 	}
! 
  		if(!errorOK) {
  			if(rcheck == (unsigned)-1) {
  				ereport(ERROR,
***************
*** 610,639 ****
  			}
  		}
  		return false;
- 	}
- 
- 	if(accept != EAN13 && accept != ANY && type != accept) goto eanwrongtype;
- 
- 	/* fix the check digit: */
- 	for(aux1 = buf; *aux1 && *aux1 <= ' '; aux1++);
- 	aux1[12] = checkdig(aux1, 13) + '0';
- 	aux1[13] = '\0';
- 	*result = str2ean(aux1);
- 
- 	 /* set the "invalid-check-digit-on-input" flag */ 
- 	*result |= 1;
- 
- 	/* just warn about the error when there was a real check digit error: */
- 	if(check != rcheck) {
- 		if(rcheck == (unsigned)-1) {
- 			elog(WARNING, "invalid %s number: \"%s\"",
- 				isn_names[accept], str);
- 		} else {
- 			elog(WARNING, "invalid check digit for %s number: \"%s\", should be %c",
- 				isn_names[accept], str, (rcheck==10)?('X'):(rcheck+'0'));
- 		}
- 	}
- 	return true;
  
  eaninvalid:
  	if(!errorOK)
--- 703,708 ----
***************
*** 647,654 ****
  	if(!errorOK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! 				 errmsg("invalid %s type for number: \"%s\"",
! 						isn_names[accept], str)));
  	return false;
  
  eantoobig:
--- 716,723 ----
  	if(!errorOK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! 				 errmsg("cannot cast %s to %s for number: \"%s\"",
! 						isn_names[type], isn_names[accept], str)));
  	return false;
  
  eantoobig:
***************
*** 804,809 ****
--- 873,927 ----
      PG_RETURN_TEXT_P(GET_TEXT(buf));
  }
  
+ PG_FUNCTION_INFO_V1(isbn_cast_from_ean13);
+ Datum
+ isbn_cast_from_ean13(PG_FUNCTION_ARGS)
+ {
+ 	ean13		val = PG_GETARG_EAN13(0);
+ 	ean13		result;
+ 
+ 	(void) ean2isn(val, false, &result, ISBN);
+ 
+ 	PG_RETURN_EAN13(result);
+ }
+ 
+ PG_FUNCTION_INFO_V1(ismn_cast_from_ean13);
+ Datum
+ ismn_cast_from_ean13(PG_FUNCTION_ARGS)
+ {
+ 	ean13		val = PG_GETARG_EAN13(0);
+ 	ean13		result;
+ 
+ 	(void) ean2isn(val, false, &result, ISMN);
+ 
+ 	PG_RETURN_EAN13(result);
+ }
+ 
+ PG_FUNCTION_INFO_V1(issn_cast_from_ean13);
+ Datum
+ issn_cast_from_ean13(PG_FUNCTION_ARGS)
+ {
+ 	ean13		val = PG_GETARG_EAN13(0);
+ 	ean13		result;
+ 
+ 	(void) ean2isn(val, false, &result, ISSN);
+ 
+ 	PG_RETURN_EAN13(result);
+ }
+ 
+ PG_FUNCTION_INFO_V1(upc_cast_from_ean13);
+ Datum
+ upc_cast_from_ean13(PG_FUNCTION_ARGS)
+ {
+ 	ean13		val = PG_GETARG_EAN13(0);
+ 	ean13		result;
+ 
+ 	(void) ean2isn(val, false, &result, UPC);
+ 
+ 	PG_RETURN_EAN13(result);
+ }
+ 
+ 
  PG_FUNCTION_INFO_V1(ean13_cast_from_text);
  Datum
  ean13_cast_from_text(PG_FUNCTION_ARGS)
diff -rcN isn/isn.h newisn/isn.h
*** isn/isn.h	2006-09-08 23:07:52.000000000 -0500
--- newisn/isn.h	2006-09-10 14:10:12.421875000 -0500
***************
*** 27,34 ****
  
  #define EAN13_FORMAT UINT64_FORMAT
  
! #define PG_GETARG_EAN13(n) PG_GETARG_INT64(n)
! #define PG_RETURN_EAN13(x) PG_RETURN_INT64(x)
  
  extern Datum isn_out(PG_FUNCTION_ARGS);
  extern Datum ean13_out(PG_FUNCTION_ARGS);
--- 27,34 ----
  
  #define EAN13_FORMAT UINT64_FORMAT
  
! #define PG_GETARG_EAN13(n) PG_GETARG_INT64((int64)n)
! #define PG_RETURN_EAN13(x) PG_RETURN_INT64((int64)x)
  
  extern Datum isn_out(PG_FUNCTION_ARGS);
  extern Datum ean13_out(PG_FUNCTION_ARGS);
***************
*** 45,50 ****
--- 45,54 ----
  extern Datum ismn_cast_from_text(PG_FUNCTION_ARGS);
  extern Datum issn_cast_from_text(PG_FUNCTION_ARGS);
  extern Datum upc_cast_from_text(PG_FUNCTION_ARGS);
+ extern Datum isbn_cast_from_ean13(PG_FUNCTION_ARGS);
+ extern Datum ismn_cast_from_ean13(PG_FUNCTION_ARGS);
+ extern Datum issn_cast_from_ean13(PG_FUNCTION_ARGS);
+ extern Datum upc_cast_from_ean13(PG_FUNCTION_ARGS);
  
  extern Datum is_valid(PG_FUNCTION_ARGS);
  extern Datum make_valid(PG_FUNCTION_ARGS);
diff -rcN isn/isn.sql.in newisn/isn.sql.in
*** isn/isn.sql.in	2006-09-08 23:07:52.000000000 -0500
--- newisn/isn.sql.in	2006-09-10 14:10:12.421875000 -0500
***************
*** 2131,2216 ****
  -- Type casts:
  --
  ---------------------------------------------------
  CREATE FUNCTION ean13(text)
  RETURNS ean13
  AS 'MODULE_PATHNAME', 'ean13_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION isbn13(text)
  RETURNS isbn13
  AS 'MODULE_PATHNAME', 'isbn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION ismn13(text)
  RETURNS ismn13
  AS 'MODULE_PATHNAME', 'ismn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION issn13(text)
  RETURNS issn13
  AS 'MODULE_PATHNAME', 'issn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION isbn(text)
  RETURNS isbn
  AS 'MODULE_PATHNAME', 'isbn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION ismn(text)
  RETURNS ismn
  AS 'MODULE_PATHNAME', 'ismn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION issn(text)
  RETURNS issn
  AS 'MODULE_PATHNAME', 'issn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION upc(text)
  RETURNS upc
  AS 'MODULE_PATHNAME', 'upc_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  
  CREATE FUNCTION text(ean13)
  RETURNS text
  AS 'MODULE_PATHNAME', 'ean13_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION text(isbn13)
  RETURNS text
  AS 'MODULE_PATHNAME', 'ean13_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION text(ismn13)
  RETURNS text
  AS 'MODULE_PATHNAME', 'ean13_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION text(issn13)
  RETURNS text
  AS 'MODULE_PATHNAME', 'ean13_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION text(isbn)
  RETURNS text
  AS 'MODULE_PATHNAME', 'isn_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION text(ismn)
  RETURNS text
  AS 'MODULE_PATHNAME', 'isn_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION text(issn)
  RETURNS text
  AS 'MODULE_PATHNAME', 'isn_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
- 
  CREATE FUNCTION text(upc)
  RETURNS text
  AS 'MODULE_PATHNAME', 'isn_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  
  CREATE CAST (isbn13 AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
  CREATE CAST (isbn AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
  CREATE CAST (ismn13 AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
--- 2131,2241 ----
  -- Type casts:
  --
  ---------------------------------------------------
+ CREATE FUNCTION isbn13(ean13)
+ RETURNS isbn13
+ AS 'MODULE_PATHNAME', 'isbn_cast_from_ean13'
+ LANGUAGE 'C' IMMUTABLE STRICT;
+ CREATE FUNCTION ismn13(ean13)
+ RETURNS ismn13
+ AS 'MODULE_PATHNAME', 'ismn_cast_from_ean13'
+ LANGUAGE 'C' IMMUTABLE STRICT;
+ CREATE FUNCTION issn13(ean13)
+ RETURNS issn13
+ AS 'MODULE_PATHNAME', 'issn_cast_from_ean13'
+ LANGUAGE 'C' IMMUTABLE STRICT;
+ CREATE FUNCTION isbn(ean13)
+ RETURNS isbn
+ AS 'MODULE_PATHNAME', 'isbn_cast_from_ean13'
+ LANGUAGE 'C' IMMUTABLE STRICT;
+ CREATE FUNCTION ismn(ean13)
+ RETURNS ismn
+ AS 'MODULE_PATHNAME', 'ismn_cast_from_ean13'
+ LANGUAGE 'C' IMMUTABLE STRICT;
+ CREATE FUNCTION issn(ean13)
+ RETURNS issn
+ AS 'MODULE_PATHNAME', 'issn_cast_from_ean13'
+ LANGUAGE 'C' IMMUTABLE STRICT;
+ CREATE FUNCTION upc(ean13)
+ RETURNS upc
+ AS 'MODULE_PATHNAME', 'upc_cast_from_ean13'
+ LANGUAGE 'C' IMMUTABLE STRICT;
+ 
+ 
  CREATE FUNCTION ean13(text)
  RETURNS ean13
  AS 'MODULE_PATHNAME', 'ean13_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION isbn13(text)
  RETURNS isbn13
  AS 'MODULE_PATHNAME', 'isbn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION ismn13(text)
  RETURNS ismn13
  AS 'MODULE_PATHNAME', 'ismn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION issn13(text)
  RETURNS issn13
  AS 'MODULE_PATHNAME', 'issn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION isbn(text)
  RETURNS isbn
  AS 'MODULE_PATHNAME', 'isbn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION ismn(text)
  RETURNS ismn
  AS 'MODULE_PATHNAME', 'ismn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION issn(text)
  RETURNS issn
  AS 'MODULE_PATHNAME', 'issn_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION upc(text)
  RETURNS upc
  AS 'MODULE_PATHNAME', 'upc_cast_from_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  
+ 
  CREATE FUNCTION text(ean13)
  RETURNS text
  AS 'MODULE_PATHNAME', 'ean13_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION text(isbn13)
  RETURNS text
  AS 'MODULE_PATHNAME', 'ean13_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION text(ismn13)
  RETURNS text
  AS 'MODULE_PATHNAME', 'ean13_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION text(issn13)
  RETURNS text
  AS 'MODULE_PATHNAME', 'ean13_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION text(isbn)
  RETURNS text
  AS 'MODULE_PATHNAME', 'isn_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION text(ismn)
  RETURNS text
  AS 'MODULE_PATHNAME', 'isn_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION text(issn)
  RETURNS text
  AS 'MODULE_PATHNAME', 'isn_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  CREATE FUNCTION text(upc)
  RETURNS text
  AS 'MODULE_PATHNAME', 'isn_cast_to_text'
  LANGUAGE 'C' IMMUTABLE STRICT;
  
+ CREATE CAST (ean13 AS isbn13) WITH FUNCTION isbn13(ean13);
+ CREATE CAST (ean13 AS isbn) WITH FUNCTION isbn(ean13);
+ CREATE CAST (ean13 AS ismn13) WITH FUNCTION ismn13(ean13);
+ CREATE CAST (ean13 AS ismn) WITH FUNCTION ismn(ean13);
+ CREATE CAST (ean13 AS issn13) WITH FUNCTION issn13(ean13);
+ CREATE CAST (ean13 AS issn) WITH FUNCTION issn(ean13);
+ CREATE CAST (ean13 AS upc) WITH FUNCTION upc(ean13);
+ 
  CREATE CAST (isbn13 AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
  CREATE CAST (isbn AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
  CREATE CAST (ismn13 AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
***************
*** 2218,2223 ****
--- 2243,2249 ----
  CREATE CAST (issn13 AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
  CREATE CAST (issn AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
  CREATE CAST (upc AS ean13) WITHOUT FUNCTION AS ASSIGNMENT;
+ 
  CREATE CAST (isbn AS isbn13) WITHOUT FUNCTION AS ASSIGNMENT;
  CREATE CAST (isbn13 AS isbn) WITHOUT FUNCTION AS ASSIGNMENT;
  CREATE CAST (ismn AS ismn13) WITHOUT FUNCTION AS ASSIGNMENT;
diff -rcN isn/README.isn newisn/README.isn
*** isn/README.isn	2006-09-08 23:07:52.000000000 -0500
--- newisn/README.isn	2006-09-10 14:16:45.593750000 -0500
***************
*** 1,6 ****
  
! EAN13 - UPC - ISBN (books) - ISMN (music) - ISSN (serials)
! ----------------------------------------------------------
  
  Copyright Germán Méndez Bravo (Kronuz), 2004 - 2006
  This module is released under the same BSD license as the rest of PostgreSQL.
--- 1,6 ----
  
! -- EAN13 - UPC - ISBN (books) - ISMN (music) - ISSN (serials)
! -------------------------------------------------------------
  
  Copyright Germán Méndez Bravo (Kronuz), 2004 - 2006
  This module is released under the same BSD license as the rest of PostgreSQL.
***************
*** 24,30 ****
          OF ANY KIND, EXPRESS OR IMPLIED.
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  
! Content of the Module
  -------------------------------------------------
  
  This directory contains definitions for a few PostgreSQL
--- 24,30 ----
          OF ANY KIND, EXPRESS OR IMPLIED.
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  
! -- Content of the Module
  -------------------------------------------------
  
  This directory contains definitions for a few PostgreSQL
***************
*** 143,149 ****
  
  (on failure, the functions 'ereport' the error)
  
! Testing/Playing Functions
  -------------------------------------------------
  isn_weak(boolean) - Sets the weak input mode. 
  This function is intended for testing use only!
--- 143,149 ----
  
  (on failure, the functions 'ereport' the error)
  
! -- Testing/Playing Functions
  -------------------------------------------------
  isn_weak(boolean) - Sets the weak input mode. 
  This function is intended for testing use only!
***************
*** 173,179 ****
    + make_valid(), which validates an invalid number (deleting the invalid flag)
    + is_valid(), which checks for the invalid flag presence.
  
! Examples of Use
  -------------------------------------------------
  --Using the types directly:
  	select isbn('978-0-393-04002-9');
--- 173,179 ----
    + make_valid(), which validates an invalid number (deleting the invalid flag)
    + is_valid(), which checks for the invalid flag presence.
  
! -- Examples of Use
  -------------------------------------------------
  --Using the types directly:
  	select isbn('978-0-393-04002-9');
***************
*** 181,189 ****
  	select issn('1436-4522');
  
  --Casting types:
! -- note that you can't cast from ean13 to other type, thus the following
! -- will NOT work: select upc(ean13('0220356483481'));
! 	select ean13(upc('220356483481'));
  
  --Create a table with a single column to hold ISBN numbers:
  	create table test ( id isbn );
--- 181,192 ----
  	select issn('1436-4522');
  
  --Casting types:
! -- note that you can only cast from ean13 to other type when the casted 
! -- number would be valid in the realm of the casted type; 
! -- thus, the following will NOT work: select isbn(ean13('0220356483481')); 
! -- but these will: 
!     select upc(ean13('0220356483481')); 
!     select ean13(upc('220356483481')); 
  
  --Create a table with a single column to hold ISBN numbers:
  	create table test ( id isbn );
***************
*** 210,216 ****
  
    select isbn13(id) from test;
  
! Contact
  -------------------------------------------------
  Please suggestions or bug reports to kronuz at users.sourceforge.net
  
--- 213,219 ----
  
    select isbn13(id) from test;
  
! -- Contact
  -------------------------------------------------
  Please suggestions or bug reports to kronuz at users.sourceforge.net
  
