packages feed

hs-bibutils 5.0 → 5.5

raw patch · 60 files changed

+16039/−5129 lines, 60 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

bibutils/adsout.c view
@@ -1,8 +1,8 @@ /*  * adsout.c  *- * Copyright (c) Richard Mathar 2007-2013- * Copyright (c) Chris Putnam 2007-2013+ * Copyright (c) Richard Mathar 2007-2014+ * Copyright (c) Chris Putnam 2007-2014  *  * Program and source code released under the GPL version 2  *@@ -29,7 +29,7 @@ 	p->latexout         = 0; 	p->utf8out          = BIBL_CHARSET_UTF8_DEFAULT; 	p->utf8bom          = BIBL_CHARSET_BOM_DEFAULT;-	p->xmlout           = 0;+	p->xmlout           = BIBL_XMLOUT_FALSE; 	p->nosplittitle     = 0; 	p->verbose          = 0; 	p->addcount         = 0;
bibutils/bibcore.c view
@@ -1,7 +1,7 @@ /*  * bibcore.c  *- * Copyright (c) Chris Putnam 2005-2013+ * Copyright (c) Chris Putnam 2005-2014  *  * Source code released under the GPL version 2  *@@ -88,16 +88,26 @@ 	fflush( fp ); } -static void+/* bibl_duplicateparams()+ *+ * Returns status of BIBL_OK or BIBL_ERR_MEMERR+ */+static int bibl_duplicateparams( param *np, param *op ) {+	int ok; 	list_init( &(np->asis) ); 	list_init( &(np->corps) );-	list_copy( &(np->asis), &(op->asis ) );-	list_copy( &(np->corps), &(op->corps ) );+	ok = list_copy( &(np->asis), &(op->asis ) );+	if ( !ok ) return BIBL_ERR_MEMERR;+	ok = list_copy( &(np->corps), &(op->corps ) );+	if ( !ok ) return BIBL_ERR_MEMERR; 	 	if ( !op->progname ) np->progname = NULL;-	else np->progname = strdup( op->progname );+	else {+		np->progname = strdup( op->progname );+		if ( !np->progname ) return BIBL_ERR_MEMERR;+	}  	np->readformat = op->readformat; 	np->writeformat = op->writeformat;@@ -133,78 +143,121 @@ 	np->all = op->all; 	np->nall = op->nall; +	return BIBL_OK; } -static void+/* bibl_setreadparams()+ *+ * Returns status of BIBL_OK or BIBL_ERR_MEMERR+ */+static int bibl_setreadparams( param *np, param *op ) {-	bibl_duplicateparams( np, op );-	np->utf8out = 1;-	np->charsetout = BIBL_CHARSET_UNICODE;-	np->charsetout_src = BIBL_SRC_DEFAULT;-	np->xmlout = 0;-	np->latexout = 0;-	np->writeformat = BIBL_INTERNALOUT;+	int status;+	status = bibl_duplicateparams( np, op );+	if ( status == BIBL_OK ) {+		np->utf8out        = 1;+		np->charsetout     = BIBL_CHARSET_UNICODE;+		np->charsetout_src = BIBL_SRC_DEFAULT;+		np->xmlout         = BIBL_XMLOUT_FALSE;+		np->latexout       = 0;+		np->writeformat    = BIBL_INTERNALOUT;+	}+	return status; } -static void+/* bibl_setwriteparams()+ *+ * Returns status of BIBL_OK or BIBL_ERR_MEMERR+ */+static int bibl_setwriteparams( param *np, param *op ) {-	bibl_duplicateparams( np, op );-	np->xmlin = 0;-	np->latexin = 0;-	np->utf8in = 1;-	np->charsetin = BIBL_CHARSET_UNICODE;-	np->charsetin_src = BIBL_SRC_DEFAULT;-	np->readformat = BIBL_INTERNALIN;+	int status;+	status = bibl_duplicateparams( np, op );+	if ( status == BIBL_OK ) {+		np->xmlin         = 0;+		np->latexin       = 0;+		np->utf8in        = 1;+		np->charsetin     = BIBL_CHARSET_UNICODE;+		np->charsetin_src = BIBL_SRC_DEFAULT;+		np->readformat    = BIBL_INTERNALIN;+	}+	return status; }  void bibl_freeparams( param *p ) {-	list_free( &(p->asis) );-	list_free( &(p->corps) );-	if ( p->progname ) free( p->progname );-}--static void-bibl_readlist( list *pl, char *progname, char *filename )-{-	if ( !list_fill( pl, filename ) ) {-		fprintf( stderr, "%s: warning problems reading '%s' "-			"obtained %d elements\n", progname, filename,-			pl->n );+	if ( p ) {+		list_free( &(p->asis) );+		list_free( &(p->corps) );+		if ( p->progname ) free( p->progname ); 	} } -void-bibl_readasis( param *p, char *filename )+int+bibl_readasis( param *p, char *f ) {-	bibl_readlist( &(p->asis), p->progname, filename );-}+	int status; -void-bibl_readcorps( param *p, char *filename )-{-	bibl_readlist( &(p->corps), p->progname, filename );+	if ( !p ) return BIBL_ERR_BADINPUT;+	if ( !f ) return BIBL_ERR_BADINPUT;++	status = list_fill( &(p->asis), f, 1 );++	if ( status == LIST_ERR_CANNOTOPEN ) return BIBL_ERR_CANTOPEN;+	else if ( status == 0 ) return BIBL_ERR_MEMERR;+	return BIBL_OK; } -static void-bibl_addtolist( list *pl, char *entry )+int+bibl_readcorps( param *p, char *f ) {-	list_add( pl, entry );+	int status;++	if ( !p ) return BIBL_ERR_BADINPUT;+	if ( !f ) return BIBL_ERR_BADINPUT;++	status = list_fill( &(p->corps), f, 1 );++	if ( status == LIST_ERR_CANNOTOPEN ) return BIBL_ERR_CANTOPEN;+	else if ( status == 0 ) return BIBL_ERR_MEMERR;+	return BIBL_OK; } -void-bibl_addtoasis( param *p, char *entry )+/* bibl_addtoasis()+ *+ * Returns BIBL_OK or BIBL_ERR_MEMERR+ */+int+bibl_addtoasis( param *p, char *d ) {-	bibl_addtolist( &(p->asis), entry );+	newstr *s;++	if ( !p ) return BIBL_ERR_BADINPUT;+	if ( !d ) return BIBL_ERR_BADINPUT;++	s = list_addc( &(p->asis), d );++	return ( s==NULL )? BIBL_ERR_MEMERR : BIBL_OK; } -void-bibl_addtocorps( param *p, char *entry )+/* bibl_addtocorps()+ *+ * Returns BIBL_OK or BIBL_ERR_MEMERR+ */+int+bibl_addtocorps( param *p, char *d ) {-	bibl_addtolist( &(p->corps), entry );+	newstr *s;++	if ( !p ) return BIBL_ERR_BADINPUT;+	if ( !d ) return BIBL_ERR_BADINPUT;++	s = list_addc( &(p->corps), d );++	return ( s==NULL )? BIBL_ERR_MEMERR : BIBL_OK; }  void@@ -240,7 +293,7 @@ 	else return 0; } -void+static void bibl_verbose2( fields *f, char *filename, long nrefs ) { 	int i, n;@@ -256,7 +309,8 @@ 	fflush( stderr ); } -void+#if 0+static void bibl_verbose1( fields *f, fields *orig, char *filename, long nrefs ) { 	int i, n;@@ -270,8 +324,9 @@ 	} 	if ( f ) bibl_verbose2( f, filename, nrefs ); }+#endif -void+static void bibl_verbose0( bibl *bin ) { 	int i;@@ -287,7 +342,7 @@  * tag = "NGENRE"  * value = "Masters thesis"  */-static void+static int extract_tag_value( newstr *tag, newstr *value, char *p ) { 	newstr_empty( tag );@@ -295,12 +350,18 @@ 		newstr_addchar( tag, *p ); 		p++; 	}+	if ( newstr_memerr( tag ) ) return BIBL_ERR_MEMERR;+ 	if ( p && *p=='|' ) p++;+ 	newstr_empty( value ); 	while ( p && *p ) { 		newstr_addchar( value, *p ); 		p++; 	}+	if ( newstr_memerr( tag ) ) return BIBL_ERR_MEMERR;++	return BIBL_OK; }  /* process_defaultadd()@@ -312,29 +373,40 @@ static int process_defaultadd( fields *f, int reftype, param *r ) {-	int i, n, process, level, ok = 1;+	int i, n, process, level, status, ret = BIBL_OK; 	newstr tag, value; 	char *p;  	newstrs_init( &tag, &value, NULL );  	for ( i=0; i<r->all[reftype].ntags; ++i ) {+ 		process = ((r->all[reftype]).tags[i]).processingtype; 		if ( process!=DEFAULT ) continue;+ 		level   = ((r->all[reftype]).tags[i]).level; 		p       = ((r->all[reftype]).tags[i]).newstr;-		extract_tag_value( &tag, &value, p );++		status = extract_tag_value( &tag, &value, p );+		if ( status!=BIBL_OK ) {+			ret = status;+			goto out;+		}+ 		n = fields_find( f, tag.data, level ); 		if ( n==-1 ) {-			ok = fields_add( f, tag.data, value.data, level );-			if ( !ok ) goto out;+			status = fields_add( f, tag.data, value.data, level );+			if ( status!=FIELDS_OK ) {+				ret = BIBL_ERR_MEMERR;+				goto out;+			} 		}+ 	} out: 	newstrs_free( &tag, &value, NULL ); -	if ( ok ) return BIBL_OK;-	else return BIBL_ERR_MEMERR;+	return ret; }  /* process_alwaysadd()@@ -346,27 +418,37 @@ static int process_alwaysadd( fields *f, int reftype, param *r ) {-	int i, process, level, ok = 1;+	int i, process, level, status, ret = BIBL_OK; 	newstr tag, value; 	char *p;  	newstrs_init( &tag, &value, NULL );  	for ( i=0; i<r->all[reftype].ntags; ++i ) {+ 		process = ((r->all[reftype]).tags[i]).processingtype; 		if ( process!=ALWAYS ) continue;+ 		level   = ((r->all[reftype]).tags[i]).level;-		p = ((r->all[reftype]).tags[i]).newstr;-		extract_tag_value( &tag, &value, p );-		ok = fields_add( f, tag.data, value.data, level );-		if ( !ok ) goto out;+		p       = ((r->all[reftype]).tags[i]).newstr;++		status = extract_tag_value( &tag, &value, p );+		if ( status!=BIBL_OK ) {+			ret = status;+			goto out;+		}++		status = fields_add( f, tag.data, value.data, level );+		if ( status!=FIELDS_OK ) {+			ret = BIBL_ERR_MEMERR;+			goto out;+		} 	}  out: 	newstrs_free( &tag, &value, NULL ); -	if ( ok ) return BIBL_OK;-	else return BIBL_ERR_MEMERR;+	return ret; }  static int@@ -384,7 +466,7 @@ 		if ( !ref ) { 			ret = BIBL_ERR_MEMERR; 			bibl_free( bin );-			goto out0;+			goto out; 		} 		if ( p->processf( ref, reference.data, filename, nrefs+1 )){ 			ok = bibl_addref( bin, ref );@@ -393,7 +475,7 @@ 				bibl_free( bin ); 				fields_free( ref ); 				free( ref );-				goto out0;+				goto out; 			} 		} else { 			fields_free( ref );@@ -411,7 +493,7 @@ 		} 	} 	if ( p->charsetin==CHARSET_UNICODE ) p->utf8in = 1;-out0:+out: 	newstr_free( &line ); 	newstr_free( &reference ); 	return ret;@@ -421,15 +503,19 @@ static int bibl_notexify( char *tag ) {-	char *protected[] = { "DOI", "URL", "REFNUM" };+	char *protected[] = { "DOI", "URL", "REFNUM", "FILEATTACH" }; 	int i, nprotected = sizeof( protected ) / sizeof( protected[0] ); 	for ( i=0; i<nprotected; ++i ) 		if ( !strcasecmp( tag, protected[i] ) ) return 1; 	return 0; } +/* bibl_fixcharsetdata()+ *+ * returns BIBL_OK or BIBL_ERR_MEMERR+ */ static int-bibl_fixcharsetfields( fields *ref, param *p )+bibl_fixcharsetdata( fields *ref, param *p ) { 	newstr *data; 	char *tag;@@ -453,30 +539,35 @@ 				p->charsetout, p->latexout, p->utf8out, p->xmlout ); 		} -		if ( !ok ) return 0;+		if ( !ok ) return BIBL_ERR_MEMERR; 	} -	return 1;+	return BIBL_OK; } +/* bibl_fixcharsets()+ *+ * returns BIBL_OK or BIBL_ERR_MEMERR+ */ static int bibl_fixcharsets( bibl *b, param *p ) {+	int status = BIBL_OK; 	long i;-	int ok;-	for ( i=0; i<b->nrefs; ++i ) {-		ok = bibl_fixcharsetfields( b->ref[i], p );-		if ( !ok ) return 0;-	}-	return 1;+	for ( i=0; i<b->nrefs && status==BIBL_OK; ++i )+		status = bibl_fixcharsetdata( b->ref[i], p );+	return status; }  static int-build_refnum( fields *f, long nrefs )+build_refnum( fields *f, long nrefs, int *n ) { 	char *year, *author, *p, num[512];+	int status, ret = BIBL_OK; 	newstr refnum; +	*n = -1;+ 	newstr_init( &refnum );  	year = fields_findv( f, LEVEL_MAIN, FIELDS_CHRP_NOUSE, "YEAR" );@@ -500,38 +591,56 @@ 		sprintf( num, "%ld", nrefs ); 		newstr_mergestrs( &refnum, "ref", num, NULL ); 	}+	if ( newstr_memerr( &refnum ) ) {+		ret = BIBL_ERR_MEMERR;+		goto out;+	} -	fields_add( f, "REFNUM", refnum.data, 0 );+	status = fields_add( f, "REFNUM", refnum.data, 0 );+	if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;+	else *n = fields_find( f, "REFNUM", 0 );++out: 	newstr_free( &refnum ); -	return fields_find( f, "REFNUM", 0 );+	return ret; } -static void+static int bibl_checkrefid( bibl *b, param *p ) {+	char buf[512];+	int n, status; 	fields *ref; 	long i;-	char buf[512];-	int n;+ 	for ( i=0; i<b->nrefs; ++i ) { 		ref = b->ref[i]; 		n = fields_find( ref, "REFNUM", 0 );-		if ( n==-1 ) n = build_refnum( ref, i+1 );+		if ( n==-1 ) {+			status = build_refnum( ref, i+1, &n );+			if ( status!=BIBL_OK ) return status;+		} 		if ( p->addcount ) { 			sprintf( buf, "_%ld", i+1 ); 			newstr_strcat( &(ref->data[n]), buf );+			if ( newstr_memerr( &(ref->data[n]) ) )+				return BIBL_ERR_MEMERR; 		} 	}++	return BIBL_OK; }  static int generate_citekey( fields *f, int nref ) {-	newstr citekey;-	int n1, n2;+	int n1, n2, status, ret; 	char *p, buf[100];+	newstr citekey;+ 	newstr_init( &citekey );+ 	n1 = fields_find( f, "AUTHOR", 0 ); 	if ( n1==-1 ) n1 = fields_find( f, "AUTHOR", -1 ); 	n2 = fields_find( f, "YEAR", 0 );@@ -549,21 +658,31 @@ 			if ( !is_ws( *p ) ) newstr_addchar( &citekey, *p ); 			p++; 		}-		fields_add( f, "REFNUM", citekey.data, 0 );+		if ( newstr_memerr( &citekey ) ) {+			ret = -1;+			goto out;+		}+		status = fields_add( f, "REFNUM", citekey.data, 0 );+		if ( status!=FIELDS_OK ) {+			ret = -1;+			goto out;+		} 	} else { 		sprintf( buf, "ref%d\n", nref ); 		newstr_strcpy( &citekey, buf ); 	}+	ret = fields_find( f, "REFNUM", -1 );+out: 	newstr_free( &citekey );-	return fields_find( f, "REFNUM", -1 );+	return ret; } -static void+static int resolve_citekeys( bibl *b, list *citekeys, int *dup ) {-	char abc[]="abcdefghijklmnopqrstuvwxyz";+	const char abc[]="abcdefghijklmnopqrstuvwxyz";+	int nsame, ntmp, n, i, j, status = BIBL_OK; 	newstr tmp;-	int nsame, ntmp, n, i, j;  	newstr_init( &tmp ); @@ -573,6 +692,10 @@ 		for ( j=i; j<citekeys->n; ++j ) { 			if ( dup[j]!=i ) continue; 			newstr_newstrcpy( &tmp, &(citekeys->str[j]) );+			if ( newstr_memerr( &tmp ) ) {+				status = BIBL_ERR_MEMERR;+				goto out;+			} 			ntmp = nsame; 			while ( ntmp >= 26 ) { 				newstr_addchar( &tmp, 'a' );@@ -580,38 +703,56 @@ 			} 			if ( ntmp<26 && ntmp>=0 ) 			newstr_addchar( &tmp, abc[ntmp] );+			if ( newstr_memerr( &tmp ) ) {+				status = BIBL_ERR_MEMERR;+				goto out;+			} 			nsame++; 			dup[j] = -1; 			n = fields_find( b->ref[j], "REFNUM", -1 );-			if ( n!=-1 )+			if ( n!=-1 ) { 				newstr_newstrcpy(&((b->ref[j])->data[n]),&tmp);+				if ( newstr_memerr( &((b->ref[j])->data[n]) ) ) {+					status = BIBL_ERR_MEMERR;+					goto out;+				}+			} 		} 	}+out: 	newstr_free( &tmp );+	return status; } -static void+static int get_citekeys( bibl *b, list *citekeys ) {+	newstr *s; 	fields *f; 	int i, n; 	for ( i=0; i<b->nrefs; ++i ) { 		f = b->ref[i]; 		n = fields_find( f, "REFNUM", -1 ); 		if ( n==-1 ) n = generate_citekey( f, i );-		if ( n!=-1 && f->data[n].data )-			list_add( citekeys, f->data[n].data );-		else-			list_add( citekeys, "" );+		if ( n!=-1 && f->data[n].data ) {+			s = list_add( citekeys, &(f->data[n]) );+			if ( !s ) return BIBL_ERR_MEMERR;+		} else {+			s = list_addc( citekeys, "" );+			if ( !s ) return BIBL_ERR_MEMERR;+		} 	}+	return BIBL_OK; }  static int  dup_citekeys( bibl *b, list *citekeys ) {-	int i, j, *dup, ndup=0;+	int i, j, status = BIBL_OK, *dup, ndup=0;+ 	dup = ( int * ) malloc( sizeof( int ) * citekeys->n );-	if ( !dup ) return 0;+	if ( !dup ) return BIBL_ERR_MEMERR;+ 	for ( i=0; i<citekeys->n; ++i ) dup[i] = -1; 	for ( i=0; i<citekeys->n-1; ++i ) { 		if ( dup[i]!=-1 ) continue;@@ -624,32 +765,37 @@ 			} 		} 	}-	if ( ndup ) resolve_citekeys( b, citekeys, dup );+	if ( ndup ) status = resolve_citekeys( b, citekeys, dup ); 	free( dup );-	return ndup;+	return status; } -static void+static int uniqueify_citekeys( bibl *b ) { 	list citekeys;+	int status; 	list_init( &citekeys );-	get_citekeys( b, &citekeys );-	dup_citekeys( b, &citekeys );+	status = get_citekeys( b, &citekeys );+	if ( status!=BIBL_OK ) goto out;+	status = dup_citekeys( b, &citekeys );+out: 	list_free( &citekeys );+	return status; } -static void+static int clean_ref( bibl *bin, param *p ) {-	if ( p->cleanf ) p->cleanf( bin, p );+	if ( p->cleanf ) return p->cleanf( bin, p );+	else return BIBL_OK; }  static int  convert_ref( bibl *bin, char *fname, bibl *bout, param *p ) { 	fields *rin, *rout;-	int reftype = 0, ok;+	int reftype = 0, ok, status; 	long i;  	for ( i=0; i<bin->nrefs; ++i ) {@@ -658,37 +804,41 @@ 		if ( !rout ) return BIBL_ERR_MEMERR; 		if ( p->typef )  			reftype = p->typef( rin, fname, i+1, p, p->all, p->nall );-		ok = p->convertf( rin, rout, reftype, p, p->all, p->nall );-		if ( ok!=BIBL_OK ) return ok;+		status = p->convertf( rin, rout, reftype, p, p->all, p->nall );+		if ( status!=BIBL_OK ) return status; 		if ( p->all ) {-			ok = process_alwaysadd( rout, reftype, p );-			if ( ok!=BIBL_OK ) return ok;-			ok = process_defaultadd( rout, reftype, p );-			if ( ok!=BIBL_OK ) return ok;+			status = process_alwaysadd( rout, reftype, p );+			if ( status!=BIBL_OK ) return status;+			status = process_defaultadd( rout, reftype, p );+			if ( status!=BIBL_OK ) return status; 		}-		bibl_addref( bout, rout );+		ok = bibl_addref( bout, rout );+		if ( !ok ) return BIBL_ERR_MEMERR; 	}-	uniqueify_citekeys( bout );-	return BIBL_OK;+	status = uniqueify_citekeys( bout );+	return status; }  int bibl_read( bibl *b, FILE *fp, char *filename, param *p ) {-	int ret, ok;+	int ok, status; 	param lp; 	bibl bin; -	if ( !b ) return BIBL_ERR_BADINPUT;+	if ( !b )  return BIBL_ERR_BADINPUT; 	if ( !fp ) return BIBL_ERR_BADINPUT;-	if ( !p ) return BIBL_ERR_BADINPUT;+	if ( !p )  return BIBL_ERR_BADINPUT;+ 	if ( bibl_illegalinmode( p->readformat ) ) return BIBL_ERR_BADINPUT; -	bibl_setreadparams( &lp, p );+	status = bibl_setreadparams( &lp, p );+	if ( status!=BIBL_OK ) return status;+ 	bibl_init( &bin ); -	ret = read_ref( fp, &bin, filename, &lp );-	if ( ret!=BIBL_OK ) return ret;+	status = read_ref( fp, &bin, filename, &lp );+	if ( status!=BIBL_OK ) return status;  	if ( debug_set( p ) ) { 		fflush( stdout );@@ -700,8 +850,8 @@ 	}  	if ( !lp.output_raw || ( lp.output_raw & BIBL_RAW_WITHCHARCONVERT ) ) {-		ok = bibl_fixcharsets( &bin, &lp );-		if ( !ok ) return BIBL_ERR_MEMERR;+		status = bibl_fixcharsets( &bin, &lp );+		if ( status!=BIBL_OK ) return status; 		if ( debug_set( p ) ) { 			fprintf( stderr, "-------------------post_fixcharsets start for bibl_read\n"); 			bibl_verbose0( &bin );@@ -710,7 +860,8 @@ 		} 	} 	if ( !lp.output_raw ) {-		clean_ref( &bin, &lp );+		status = clean_ref( &bin, &lp );+		if ( status!=BIBL_OK ) return status; 		if ( debug_set( p ) ) { 			fprintf( stderr, "-------------------post_clean_ref start for bibl_read\n"); 			bibl_verbose0( &bin );@@ -779,48 +930,53 @@ }  static int-output_bibl( FILE *fp, bibl *b, param *p )+bibl_writeeachfp( FILE *fp, bibl *b, param *p ) { 	long i;-	if ( !p->singlerefperfile && p->headerf ) p->headerf( fp, p ); 	for ( i=0; i<b->nrefs; ++i ) {-		if ( p->singlerefperfile ) { -			fp = singlerefname( b->ref[i], i, p->writeformat );-			if ( fp ) {-				if ( p->headerf ) p->headerf( fp, p );-			} else return BIBL_ERR_CANTOPEN;-		}+		fp = singlerefname( b->ref[i], i, p->writeformat );+		if ( !fp ) return BIBL_ERR_CANTOPEN;+		if ( p->headerf ) p->headerf( fp, p ); 		p->writef( b->ref[i], fp, p, i );-		if ( p->singlerefperfile ) {-			if ( p->footerf ) p->footerf( fp );-			fclose( fp );-		}+		if ( p->footerf ) p->footerf( fp );+		fclose( fp ); 	}-	if ( !p->singlerefperfile && p->footerf ) p->footerf( fp );-	return 1;+	return BIBL_OK; } +static int+bibl_writefp( FILE *fp, bibl *b, param *p )+{+	long i;+	if ( p->headerf ) p->headerf( fp, p );+	for ( i=0; i<b->nrefs; ++i )+		p->writef( b->ref[i], fp, p, i );+	if ( p->footerf ) p->footerf( fp );+	return BIBL_OK;+}+ int bibl_write( bibl *b, FILE *fp, param *p ) {+	int status; 	param lp;-	int ok;  	if ( !b ) return BIBL_ERR_BADINPUT; 	if ( !p ) return BIBL_ERR_BADINPUT; 	if ( bibl_illegaloutmode( p->writeformat ) ) return BIBL_ERR_BADINPUT; 	if ( !fp && ( !p || !p->singlerefperfile ) ) return BIBL_ERR_BADINPUT; -	bibl_setwriteparams( &lp, p );+	status = bibl_setwriteparams( &lp, p );+	if ( status!=BIBL_OK ) return status; -	ok = bibl_fixcharsets( b, &lp );-	if ( !ok ) return BIBL_ERR_MEMERR;+	status = bibl_fixcharsets( b, &lp );+	if ( status!=BIBL_OK ) return status;  	if ( debug_set( p ) ) report_params( stderr, "bibl_write", &lp ); -	ok = output_bibl( fp, b, &lp );-	if ( !ok ) return BIBL_ERR_MEMERR;+	if ( p->singlerefperfile ) status = bibl_writeeachfp( fp, b, &lp );+	else status = bibl_writefp( fp, b, &lp ); -	return BIBL_OK;+	return status; } 
bibutils/bibl.c view
@@ -1,7 +1,7 @@ /*  * bibl.c  *- * Copyright (c) Chris Putnam 2005-2013+ * Copyright (c) Chris Putnam 2005-2014  *  * Source code released under the GPL version 2  *@@ -80,19 +80,20 @@ bibl_copy( bibl *bout, bibl *bin ) { 	fields *refin, *refout;-	int i, j, n, ok, level;+	int i, j, n, status, ok, level; 	char *tag, *value; 	for ( i=0; i<bin->nrefs; ++i ) { 		refin = bin->ref[i]; 		refout = fields_new();+		if ( !refout ) return 0; 		n = fields_num( refin ); 		for ( j=0; j<n; ++j ) { 			tag   = fields_tag( refin, j, FIELDS_CHRP ); 			value = fields_value( refin, j, FIELDS_CHRP ); 			level = fields_level( refin, j ); 			if ( tag && value ) {-				ok = fields_add( refout, tag, value, level );-				if ( !ok ) return 0;+				status = fields_add( refout, tag, value, level );+				if ( status!=FIELDS_OK ) return 0; 			} 		} 		ok = bibl_addref( bout, refout );
bibutils/bibl.h view
@@ -1,7 +1,7 @@ /*  * bibl.h  *- * Copyright (c) Chris Putnam 2005-2013+ * Copyright (c) Chris Putnam 2005-2014  *  * Source code released under the GPL version 2  *
bibutils/biblatexin.c view
@@ -1,1114 +1,1413 @@ /*  * biblatexin.c  *- * Copyright (c) Chris Putnam 2008-2013- * Copyright (c) Johannes Wilm 2010-2013- *- * Program and source code released under the GPL version 2- *- */-#include <stdio.h>-#include <stdlib.h>-#include <string.h>-#include <ctype.h>-#include "is_ws.h"-#include "strsearch.h"-#include "newstr.h"-#include "newstr_conv.h"-#include "fields.h"-#include "list.h"-#include "name.h"-#include "reftypes.h"-#include "biblatexin.h"--static list find    = { 0, 0, 0, NULL };-static list replace = { 0, 0, 0, NULL };--void-biblatexin_initparams( param *p, const char *progname )-{-	p->readformat       = BIBL_BIBLATEXIN;-	p->charsetin        = BIBL_CHARSET_DEFAULT;-	p->charsetin_src    = BIBL_SRC_DEFAULT;-	p->latexin          = 1;-	p->xmlin            = 0;-	p->utf8in           = 0;-	p->nosplittitle     = 0;-	p->verbose          = 0;-	p->addcount         = 0;-	p->output_raw       = 0;--	p->readf    = biblatexin_readf;-	p->processf = biblatexin_processf;-	p->cleanf   = biblatexin_cleanf;-	p->typef    = biblatexin_typef;-	p->convertf = biblatexin_convertf;-	p->all      = biblatex_all;-	p->nall     = biblatex_nall;--	list_init( &(p->asis) );-	list_init( &(p->corps) );--	if ( !progname ) p->progname = NULL;-	else p->progname = strdup( progname );-}--/*- * readf can "read too far", so we store this information in line, thus- * the next new text is in line, either from having read too far or- * from the next chunk obtained via newstr_fget()- *- * return 1 on success, 0 on error/end-of-file- *- */-static int-readmore( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line )-{-	if ( line->len ) return 1;-	else return newstr_fget( fp, buf, bufsize, bufpos, line );-}--/*- * readf()- *- * returns zero if cannot get reference and hit end of-file- * returns 1 if last reference in file, 2 if reference within file- */-int-biblatexin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line, newstr *reference, int *fcharset )-{-	int haveref = 0;-	char *p;-	while ( haveref!=2 && readmore( fp, buf, bufsize, bufpos, line ) ) {-		if ( line->len == 0 ) continue; /* blank line */-		p = &(line->data[0]);-		p = skip_ws( p );-		if ( *p == '%' ) { /* commented out line */-			newstr_empty( line );-			continue;-		}-		if ( *p == '@' ) haveref++;-		if ( haveref && haveref<2 ) {-			newstr_strcat( reference, p );-			newstr_addchar( reference, '\n' );-			newstr_empty( line );-		} else if ( !haveref ) newstr_empty( line );-	-	}-	*fcharset = CHARSET_UNKNOWN;-	return haveref;-}--static char *-biblatex_item( char *p, newstr *s )-{-	int surrounding_quotes = 0;-	int nbrackets = 0;-	int nquotes = 0;-	while ( *p ) {-		if ( !nquotes && !nbrackets ) {-			if ( *p==',' || *p=='=' || *p=='}' || *p==')' )-				goto out;-		}-		if ( *p=='\"' && *(p-1)!='\\' && nbrackets==0 ) {-			if ( s->len == 0 ) surrounding_quotes = 1;-			else {-				if ( !surrounding_quotes ) newstr_addchar( s, *p );-				if ( nquotes ) surrounding_quotes = 0;-			}-			nquotes = ( nquotes==0 );-		} else if ( *p=='{' ) {-			if ( nbrackets>0 || nquotes ) newstr_addchar( s, *p );-			nbrackets++;-		} else if ( *p=='}' ) {-			nbrackets--;-			if ( nbrackets>0 || nquotes ) newstr_addchar( s, *p );-		} else {-			if ( !is_ws( *p ) ) newstr_addchar( s, *p );-			else {-				if ( s->len!=0 && *p!='\n' && *p!='\r' )-					newstr_addchar( s, *p );-				else if ( s->len!=0 && (*p=='\n' || *p=='\r')) {-					newstr_addchar( s, ' ' );-					while ( is_ws( *(p+1) ) ) p++;-				}-			}-		}-		p++;-	}-out:-	newstr_trimendingws( s );-	return p;-}--static char *-process_biblatexline( char *p, newstr *tag, newstr *data )-{-	p = skip_ws( p );-	p = biblatex_item( p, tag );-	p = skip_ws( p );-	if ( *p=='=' ) {-		p++;-		p = skip_ws( p );-		p = biblatex_item( p, data );-		p = skip_ws( p );-	}-	if ( *p==',' || *p=='}' || *p==')' ) p++;-	p = skip_ws( p );-	return p;-}--static void-biblatex_cleantoken( newstr *s )-{-	/* 'textcomp' annotations */-	newstr_findreplace( s, "\\textit", "" );-	newstr_findreplace( s, "\\textbf", "" );-	newstr_findreplace( s, "\\textsl", "" );-	newstr_findreplace( s, "\\textsc", "" );-	newstr_findreplace( s, "\\textsf", "" );-	newstr_findreplace( s, "\\texttt", "" );-	newstr_findreplace( s, "\\textsubscript", "" );-	newstr_findreplace( s, "\\textsuperscript", "" );-	newstr_findreplace( s, "\\emph", "" );-	newstr_findreplace( s, "\\url", "" );--	/* Other text annotations */-	newstr_findreplace( s, "\\it ", "" );-	newstr_findreplace( s, "\\em ", "" );--	newstr_findreplace( s, "\\%", "%" );-	newstr_findreplace( s, "\\$", "$" );-	newstr_findreplace( s, "{", "" );-	newstr_findreplace( s, "}", "" );-	while ( newstr_findreplace( s, "  ", " " ) ) {}--	/* 'textcomp' annotations that we don't want to substitute on output*/-	newstr_findreplace( s, "\\textdollar", "$" );-	newstr_findreplace( s, "\\textunderscore", "_" );-}--static void-biblatex_split( list *tokens, newstr *s )-{-	int i, n = s->len, nbrackets = 0;-	newstr currtok;--	newstr_init( &currtok );--	for ( i=0; i<n; ++i ) {-		if ( s->data[i]=='{' ) {-			nbrackets++;-			newstr_addchar( &currtok, '{' );-		} else if ( s->data[i]=='}' ) {-			nbrackets--;-			newstr_addchar( &currtok, '}' );-		} else if ( s->data[i]=='#' && !nbrackets ) {-			if ( currtok.len ) list_add( tokens, currtok.data );-			newstr_empty( &currtok );-		} else if ( !is_ws( s->data[i] ) || nbrackets ) {-			newstr_addchar( &currtok, s->data[i] );-		} else if ( is_ws( s->data[i] ) ) {-			if ( currtok.len ) list_add( tokens, currtok.data );-			newstr_empty( &currtok );-		}-	}-	if ( currtok.len ) list_add( tokens, currtok.data );-	for ( i=0; i<tokens->n; ++i ) {-		newstr_trimstartingws( list_get( tokens, i ) );-		newstr_trimendingws( list_get( tokens, i ) );-	}-	newstr_free( &currtok );-}--/* get reference type */-static char*-process_biblatextype( char *p, newstr *data )-{-	newstr tmp;-	newstr_init( &tmp );--	newstr_empty( data );--	if ( *p=='@' ) p++; /* skip '@' character */-	while ( *p && *p!='{' && *p!='(' ) newstr_addchar( &tmp, *p++ );-	if ( *p=='{' || *p=='(' ) p++;-	p = skip_ws( p );--	if ( tmp.len ) {-		/* add '{' and '}' to protect from string expansion */-		newstr_addchar( data, '{' );-		newstr_strcat( data, tmp.data );-		newstr_addchar( data, '}' );-	}-	newstr_free( &tmp );-	return p;-}-/* get reference name */-static char*-process_biblatexid( char *p, newstr *data )-{-	newstr tmp;-	char *start_p = p;-	newstr_init( &tmp );-	newstr_empty( data );--	while ( *p && *p!=',' ) newstr_addchar( &tmp, *p++ );-	if ( *p==',' ) p++;-	p = skip_ws( p ); /* skip ending newline/carriage return */--	if ( tmp.len ) {-		if ( strchr( tmp.data, '=' ) ) {-			/* Endnote writes biblatex files w/o fields, try to-			 * distinguish via presence of an equal sign.... if-			 * it's there, assume that it's a tag/data pair instead-			 * and roll back.-			 */-			p = start_p;-		} else {-			/* add '{' and '}' to protect from string expansion */-			newstr_addchar( data, '{' );-			newstr_strcat( data, tmp.data );-			newstr_addchar( data, '}' );-		}-	}--	newstr_free( &tmp );-	return p;-}--static void-process_cite( fields *bibin, char *p, char *filename, long nref )-{-	newstr tag, data;-	newstrs_init( &tag, &data, NULL );-	p = process_biblatextype( p, &data );-	if ( data.len ) fields_add( bibin, "INTERNAL_TYPE", data.data, 0 );-	if ( *p ) p = process_biblatexid ( p, &data );-	if ( data.len ) fields_add( bibin, "REFNUM", data.data, 0 );-	newstr_empty( &data );-	while ( *p ) {-		p = process_biblatexline( p, &tag, &data );-		/* no anonymous or empty fields allowed */-		if ( tag.len && data.len )-			fields_add( bibin, tag.data, data.data, 0 );-		newstrs_empty( &tag, &data, NULL );-	}-	newstrs_free( &tag, &data, NULL );-}--static void-biblatex_addstring( char *p )-{-	newstr s1, s2;-	newstrs_init( &s1, &s2, NULL );-	p = skip_ws( p );-	if ( *p=='(' || *p=='{' ) p++;-	p = process_biblatexline( p, &s1, &s2 );-	newstr_findreplace( &s2, "\\ ", " " );-	biblatex_cleantoken( &s2 );-	if ( s1.data ) {-		list_add( &find, s1.data );-		if ( s2.data ) list_add( &replace, s2.data );-		else list_add( &replace, "" );-	}-	newstrs_free( &s1, &s2, NULL );-}--static int-biblatex_usestrings( newstr *s )-{-	int i;-	for ( i=0; i<find.n; ++i ) {-		if ( !strcasecmp( s->data, (find.str[i]).data ) ) {-			newstr_findreplace( s, (find.str[i]).data, -					(replace.str[i]).data );-			return 1;-		}-	}-	return 0;-}--static void-process_string( char *p )-{-	while ( *p && *p!='{' && *p!='(' ) p++;-	biblatex_addstring( p );-}--int-biblatexin_processf( fields *bibin, char *data, char *filename, long nref )-{-	if ( !strncasecmp( data, "@STRING", 7 ) ) {-		process_string( data );-		return 0;-        } else {-		process_cite( bibin, data, filename, nref );-		return 1;-	}-}--static void-biblatex_addtitleurl( fields *info, newstr *in )-{-	newstr s;-	char *p,*q;-	newstr_init( &s );-	q = p = in->data + 6; /*skip past \href{ */-	while ( *q && *q!='}' ) q++;-	newstr_segcpy( &s, p, q );-	fields_add( info, "URL", s.data, 0 );-	newstr_empty( &s );-	if ( *q=='}' ) q++;-	p = q;-	while ( *q ) q++;-	newstr_segcpy( &s, p, q );-	newstr_swapstrings( &s, in );-	newstr_free( &s );-}--static int-is_name_tag( newstr *tag )-{-	if ( tag->len ) {-		if ( !strcasecmp( tag->data, "author" ) ) return 1;-		if ( !strcasecmp( tag->data, "editor" ) ) return 1;-		if ( !strcasecmp( tag->data, "editorb" ) ) return 1;-		if ( !strcasecmp( tag->data, "editorc" ) ) return 1;-		if ( !strcasecmp( tag->data, "director" ) ) return 1;-		if ( !strcasecmp( tag->data, "producer" ) ) return 1;-		if ( !strcasecmp( tag->data, "execproducer" ) ) return 1;-		if ( !strcasecmp( tag->data, "writer" ) ) return 1;-		if ( !strcasecmp( tag->data, "redactor" ) ) return 1;-		if ( !strcasecmp( tag->data, "annotator" ) ) return 1;-		if ( !strcasecmp( tag->data, "commentator" ) ) return 1;-		if ( !strcasecmp( tag->data, "translator" ) ) return 1;-		if ( !strcasecmp( tag->data, "foreword" ) ) return 1;-		if ( !strcasecmp( tag->data, "afterword" ) ) return 1;-		if ( !strcasecmp( tag->data, "introduction" ) ) return 1;-	}-	return 0;-}--static void-biblatex_cleandata( newstr *tag, newstr *s, fields *info, param *p )-{-	list tokens;-	newstr *tok;-	int i;-	if ( !s->len ) return;-	list_init( &tokens );-	biblatex_split( &tokens, s );-	for ( i=0; i<tokens.n; ++i ) {-		biblatex_usestrings( &(tokens.str[i]) );-		if (!strncasecmp(tokens.str[i].data,"\\href{", 6)) {-			biblatex_addtitleurl( info, &(tokens.str[i]) );-		}-		if ( p && p->latexin && !is_name_tag( tag ) ) biblatex_cleantoken( &(tokens.str[i]) );-	}-	newstr_empty( s );-	for ( i=0; i<tokens.n; ++i ) {-		tok = list_get( &tokens, i );-		if ( i>0 ) newstr_addchar( s, ' ' );-		newstr_newstrcat( s, tok );-	}-	list_free( &tokens );-}--static long-biblatexin_findref( bibl *bin, char *citekey )-{-	int n;-	long i;-	for ( i=0; i<bin->nrefs; ++i ) {-		n = fields_find( bin->ref[i], "refnum", -1 );-		if ( n==-1 ) continue;-		if ( !strcmp( bin->ref[i]->data[n].data, citekey ) ) return i;-	}-	return -1;-}--static void-biblatexin_nocrossref( bibl *bin, long i, int n, param *p )-{-	int n1 = fields_find( bin->ref[i], "REFNUM", -1 );-	if ( p->progname ) fprintf( stderr, "%s: ", p->progname );-	fprintf( stderr, "Cannot find cross-reference '%s'", -			bin->ref[i]->data[n].data);-	if ( n1!=-1 )-		fprintf( stderr, " for reference '%s'\n", -				bin->ref[i]->data[n1].data );-	fprintf( stderr, "\n" );-}--static void-biblatexin_crossref( bibl *bin, param *p )-{-	char booktitle[] = "booktitle";-	long i, j, ncross;-	char *nt, *nd, *type;-	int n, ntype, nl;-        for ( i=0; i<bin->nrefs; ++i ) {-		n = fields_find( bin->ref[i], "CROSSREF", -1 );-		if ( n==-1 ) continue;-		ncross = biblatexin_findref( bin, bin->ref[i]->data[n].data );-		if ( ncross==-1 ) {-			biblatexin_nocrossref( bin, i, n, p );-#if 0-			int n1 = fields_find( bin->ref[i], "REFNUM", -1 );-			fprintf( stderr, "%s: Cannot find cross-reference '%s'",-				progname, bin->ref[i]->data[n].data);-			if ( n1!=-1 )-				fprintf( stderr, " for reference '%s'\n",-					bin->ref[i]->data[n1].data );-			fprintf( stderr, "\n" );-#endif			-			continue;-		}-		ntype = fields_find( bin->ref[i], "INTERNAL_TYPE", -1 );-		type = bin->ref[i]->data[ntype].data;-		fields_setused( bin->ref[i], n );-/*		bin->ref[i]->used[n] = 1; */-		for ( j=0; j<bin->ref[ncross]->n; ++j ) {-			nt = bin->ref[ncross]->tag[j].data;-			if ( !strcasecmp( nt, "INTERNAL_TYPE" ) ) continue;-			if ( !strcasecmp( nt, "REFNUM" ) ) continue;-			if ( !strcasecmp( nt, "TITLE" ) ) {-				if ( !strcasecmp( type, "Inproceedings" ) ||-				     !strcasecmp( type, "Incollection" ) )-					nt = booktitle;-			}-			nd = bin->ref[ncross]->data[j].data;-			nl = bin->ref[ncross]->level[j] + 1;-			fields_add( bin->ref[i], nt, nd, nl );--		}-	}-}--static void-biblatexin_cleanref( fields *bibin, param *p )-{-	newstr *t, *d;-	int i, n;-	n = fields_num( bibin );-	for ( i=0; i<n; ++i ) {-		t = fields_tag( bibin, i, FIELDS_STRP_NOUSE );-		d = fields_value( bibin, i, FIELDS_STRP_NOUSE );-		biblatex_cleandata( t, d, bibin, p );-		if ( !strsearch( t->data, "AUTHORS" ) ) {-			newstr_findreplace( d, "\n", " " );-			newstr_findreplace( d, "\r", " " );-		}-		else if ( !strsearch( t->data, "ABSTRACT" ) ||-		     !strsearch( t->data, "SUMMARY" ) || -		     !strsearch( t->data, "NOTE" ) ) {-			newstr_findreplace( d, "\n", "" );-			newstr_findreplace( d, "\r", "" );-		}-	}-}--void-biblatexin_cleanf( bibl *bin, param *p )-{-	long i;-        for ( i=0; i<bin->nrefs; ++i )-		biblatexin_cleanref( bin->ref[i], p );-	biblatexin_crossref( bin, p );-}--/* is_utf8_emdash()- *- * Internally pages="A---B" will convert --- to a UTF8- * emdash = 0xE2 (-30) 0x80 (-128) 0x94 (-108)- */-static int-is_utf8_emdash( char *p )-{-	static char emdash[3] = { -30, -128, -108 };-	if ( strncmp( p, emdash, 3 ) ) return 0;-	return 1;-}-/* is_utf8_endash()- *- * Internally pages="A--B" will convert -- to a UTF8- * endash = 0xE2 (-30) 0x80 (-128) 0x93 (-109)- */-static int-is_utf8_endash( char *p )-{-	static char endash[3] = { -30, -128, -109 };-	if ( strncmp( p, endash, 3 ) ) return 0;-	return 1;-}--static int-process_pages( fields *info, newstr *s, int level )-{-	newstr page;-	char *p;-	int ok;--	newstr_findreplace( s, " ", "" );-	if ( s->len==0 ) return 1;--	newstr_init( &page );-	p = skip_ws( s->data );-	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' && *p!=-30 )-		newstr_addchar( &page, *p++ );-	if ( page.len>0 ) {-		ok = fields_add( info, "PAGESTART", page.data, level );-		if ( !ok ) return 0;-	}--	while ( *p && (is_ws(*p) || *p=='-' ) ) p++;-	if ( *p && is_utf8_emdash( p ) ) p+=3;-	if ( *p && is_utf8_endash( p ) ) p+=3;--	newstr_empty( &page );-	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' )-		newstr_addchar( &page, *p++ );-	if ( page.len>0 ) {-		ok = fields_add( info, "PAGEEND", page.data, level );-		if ( !ok ) return 0;-	}--	newstr_free( &page );-	return 1;-}--static int-process_urlcore( fields *info, char *p, int level, char *default_tag )-{-	if ( !strncasecmp( p, "\\urllink", 8 ) )-		return fields_add( info, "URL", p+8, level );-	else if ( !strncasecmp( p, "\\url", 4 ) )-		return fields_add( info, "URL", p+4, level );-	else if ( !strncasecmp( p, "arXiv:", 6 ) )-		return fields_add( info, "ARXIV", p+6, level ); -	else if ( !strncasecmp( p, "http://arxiv.org/abs/", 21 ) )-		return fields_add( info, "ARXIV", p+21, level );-	else if ( !strncasecmp( p, "http:", 5 ) )-		return fields_add( info, "URL", p, level );-	else return fields_add( info, default_tag, p, level );-}--static int-process_url( fields *info, char *p, int level )-{-	return process_urlcore( info, p, level, "URL" );-}--/* process_howpublished()- *- *    howpublished={},- *- * Normally indicates the manner in which something was- * published in lieu of a formal publisher, so typically- * 'howpublished' and 'publisher' will never be in the- * same reference.- *- * Occasionally, people put Diploma thesis information- * into this field, so check for that first.- */-static int-process_howpublished( fields *info, char *p, int level )-{-        if ( !strncasecmp( p, "Diplom", 6 ) )-                return fields_replace_or_add( info, "NGENRE", "Diploma thesis", level );-        else if ( !strncasecmp( p, "Habilitation", 13 ) )-                return fields_replace_or_add( info, "NGENRE", "Habilitation thesis", level );-        else-		return fields_add( info, "PUBLISHER", p, level );-}--static int-process_thesistype( fields *info, char *p, int level )-{-	/* type in the @thesis is used to distinguish Ph.D. and Master's thesis */-	if ( !strncasecmp( p, "phdthesis", 9 ) ) {-		return fields_replace_or_add( info, "NGENRE", "Ph.D. thesis", level );-	} else if ( !strncasecmp( p, "mastersthesis", 13 ) || !strncasecmp( p, "masterthesis", 12 ) ) {-		return fields_replace_or_add( info, "NGENRE", "Masters thesis", level );-	} else if ( !strncasecmp( p, "mathesis", 8 ) ) {-		return fields_replace_or_add( info, "NGENRE", "Masters thesis", level );-	} else if ( !strncasecmp( p, "diploma", 7 ) ) {-		return fields_replace_or_add( info, "NGENRE", "Diploma thesis", level );-	} else if ( !strncasecmp( p, "habilitation", 12 ) ) {-		return fields_replace_or_add( info, "NGENRE", "Habilitation thesis", level );-	}-	return 1;-}--/* biblatex drops school field if institution is present */-static int-process_school( fields *bibin, fields *info, char *tag, char *value, int level )-{-	if ( fields_find( bibin, "institution", LEVEL_ANY ) != -1 )-		return 1;-	else-		return fields_add( info, tag, value, level );-}--/* biblatex drops school field if institution is present */-static int-process_subtype( fields *bibin, fields *info, char *tag, char *value, int level )-{-	int ok = 1;-	if ( !strcasecmp( value, "magazine" ) ) {-		ok = fields_add( info, "NGENRE", "magazine article", LEVEL_MAIN );-		if ( !ok ) return 0;-		ok = fields_add( info, "NGENRE", "magazine", LEVEL_HOST );-	} else if ( !strcasecmp( value, "newspaper" ) ) {-		ok = fields_add( info, "NGENRE", "newspaper article", LEVEL_MAIN );-		if ( !ok ) return 0;-		ok = fields_add( info, "GENRE", "newspaper", LEVEL_HOST );-	}-	return ok;-}--static int-process_eprint( fields *bibin, fields *info, int level )-{-	int neprint, netype, ok;-	char *eprint = NULL, *etype = NULL;-	neprint = fields_find( bibin, "eprint", -1 );-	netype  = fields_find( bibin, "eprinttype", -1 );-	if ( neprint!=-1 ) eprint = bibin->data[neprint].data;-	if ( netype!=-1 ) etype = bibin->data[netype].data;-	if ( eprint && etype ) {-		if ( !strncasecmp( etype, "arxiv", 5 ) ) {-			ok = fields_add( info, "ARXIV", eprint, level );-			if ( !ok ) return 0;-		} else if ( !strncasecmp( etype, "jstor", 5 ) ) {-			ok = fields_add( info, "JSTOR", eprint, level );-			if ( !ok ) return 0;-		} else if ( !strncasecmp( etype, "pubmed", 6 ) ) {-			ok = fields_add( info, "PMID", eprint, level );-			if ( !ok ) return 0;-		} else if ( !strncasecmp( etype, "medline", 7 ) ) {-			ok = fields_add( info, "MEDLINE", eprint, level );-			if ( !ok ) return 0;-		} else {-			ok = fields_add( info, "EPRINT", eprint, level );-			if ( !ok ) return 0;-			ok = fields_add( info, "EPRINTTYPE", etype, level );-			if ( !ok ) return 0;-		}-		fields_setused( bibin, neprint );-		fields_setused( bibin, netype );-	} else if ( eprint ) {-		ok = fields_add( info, "EPRINT", eprint, level );-		if ( !ok ) return 0;-		fields_setused( bibin, neprint );-	} else if ( etype ) {-		ok = fields_add( info, "EPRINTTYPE", etype, level );-		if ( !ok ) return 0;-		fields_setused( bibin, netype );-	}-	return 1;-}--int-biblatexin_typef( fields *bibin, char *filename, int nrefs, param *p,-		variants *all, int nall )-{-	char *refnum = "";-	int reftype, n, nrefnum;-	n = fields_find( bibin, "INTERNAL_TYPE", 0 );-	nrefnum = fields_find( bibin, "REFNUM", 0 );-	if ( nrefnum!=-1 ) refnum = (bibin->data[nrefnum]).data;-	if ( n!=-1 )-		/* figure out type */-		reftype = get_reftype( (bibin->data[n]).data, nrefs,-			p->progname, all, nall, refnum );-	else-		/* no type info, go for default */-		reftype = get_reftype( "", nrefs, p->progname, all, nall, refnum );-	return reftype;-}--static void-report( fields *f )-{-	int i, n;-	n = fields_num( f );-	for ( i=0; i<n; ++i )-		fprintf(stderr, "%d '%s' = '%s'\n",-			fields_level( f, i ),-			(char*)fields_tag( f, i, FIELDS_CHRP_NOUSE ),-			(char*)fields_value( f, i, FIELDS_CHRP_NOUSE ) );-}--static void-biblatexin_notag( param *p, char *tag )-{-	if ( p->verbose && strcmp( tag, "INTERNAL_TYPE" ) ) {-		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );-		fprintf( stderr, " Cannot find tag '%s'\n", tag );-	}-}--/* get_title_elements()- *- * find all of the biblatex title elements for the current level- *    internal "TITLE"      -> "title", "booktitle", "maintitle"- *    internal "SUBTITLE"   -> "subtitle", "booksubtitle", "mainsubtitle"- *    internal "TITLEADDON" -> "titleaddon", "booktitleaddon", "maintitleaddon"- *- * place in ttl, subttl, and ttladdon strings- *- * return 1 if an element is found, 0 if not- */-static int-get_title_elements( fields *bibin, int currlevel, int reftype, variants *all, int nall,-	newstr *ttl, newstr *subttl, newstr *ttladdon )-{-	int nfields, process, level, i, n;-	newstr *t, *d;-	char *newtag;--	newstrs_empty( ttl, subttl, ttladdon, NULL );--	nfields = fields_num( bibin );--	for ( i=0; i<nfields; ++i ) {--		/* ...skip already used titles */-		if ( fields_used( bibin, i ) ) continue;--		/* ...skip empty elements */-		t = fields_tag  ( bibin, i, FIELDS_STRP_NOUSE );-		d = fields_value( bibin, i, FIELDS_STRP_NOUSE );-		if ( d->len == 0 ) continue;--		n = translate_oldtag( t->data, reftype, all, nall, &process, &level, &newtag );-		if ( n==-1 ) continue;-		if ( process != TITLE ) continue;-		if ( level != currlevel ) continue;--		fields_setused( bibin, i );--		if ( !strcasecmp( newtag, "TITLE" ) ) {-			if ( ttl->len ) newstr_addchar( ttl, ' ' );-			newstr_newstrcat( ttl, d );-		} else if ( !strcasecmp( newtag, "SUBTITLE" ) ) {-			if ( subttl->len ) newstr_addchar( subttl, ' ' );-			newstr_newstrcat( subttl, d );-		} else if ( !strcasecmp( newtag, "TITLEADDON" ) ) {-			if ( ttladdon->len ) newstr_addchar( ttladdon, ' ' );-			newstr_newstrcat( ttladdon, d );-		}-	}--	return ( ttl->len>0 || subttl->len > 0 || ttladdon->len > 0 );-}--/* attach_addon()- *- * Add titleaddon to the title.- */-static void-attach_addon( newstr *title, newstr *addon )-{-	if ( title->len ) {-		if ( title->data[title->len-1]!='.' )-			newstr_addchar( title, '.' );-		newstr_addchar( title, ' ' );-	}-	newstr_newstrcat( title, addon );-}--static int-process_combined_title( fields *info, newstr *ttl, newstr *subttl, newstr *ttladdon, int currlevel )-{-	newstr combined;-	int ok, ret = 1;-	newstr_init( &combined );-	newstr_newstrcpy( &combined, ttl );-	if ( subttl->len ) {-		if ( combined.len && combined.data[combined.len-1]!=':' && combined.data[combined.len-1]!='?' )-			newstr_addchar( &combined, ':' );-		newstr_addchar( &combined, ' ' );-		newstr_newstrcat( &combined, subttl );-	}-	if ( ttladdon->len ) attach_addon( &combined, ttladdon );-	ok = fields_add( info, "TITLE", combined.data, currlevel );-	if ( !ok ) ret = 0;-	newstr_free( &combined );-	return ret;-}--static int-process_separated_title( fields *info, newstr *ttl, newstr *subttl, newstr *ttladdon, int currlevel )-{-	int ok;-	if ( ttladdon->len ) {-		if ( subttl->len ) attach_addon( subttl, ttladdon );-		else attach_addon( ttl, ttladdon );-	}-	if ( ttl->len ) {-		ok = fields_add( info, "TITLE", ttl->data, currlevel );-		if ( !ok ) return 0;-	}-	if ( subttl->len ) {-		ok = fields_add( info, "SUBTITLE", subttl->data, currlevel );-		if ( !ok ) return 0;-	}-	return 1;-}--static int-process_title_all( fields *bibin, fields *info, int reftype, param *p,-	variants *all, int nall )-{-	int currlevel, ok, found, ret=1;-	newstr ttl, subttl, ttladdon;-	newstrs_init( &ttl, &subttl, &ttladdon, NULL );-	for ( currlevel = 0; currlevel<LEVEL_SERIES+2; currlevel++ ) {-		found = get_title_elements( bibin, currlevel, reftype, all, nall,-				&ttl, &subttl, &ttladdon );-		if ( !found ) continue;-		if ( p->nosplittitle )-			ok = process_combined_title( info, &ttl, &subttl, &ttladdon, currlevel );-		else-			ok = process_separated_title( info, &ttl, &subttl, &ttladdon, currlevel );-		if ( !ok ) { ret = 0; goto out; }-	}-out:-	newstrs_free( &ttl, &subttl, &ttladdon, NULL );-	return ret;-}--static int-biblatex_matches_asis_corps( fields *info, char *tag, newstr *data, int level,-	list *asis, list *corps )-{-	newstr newtag;-	int i;-	for ( i=0; i<asis->n; ++i ) {-		if ( !strcmp( data->data, list_getc( asis, i ) ) ) {-			newstr_initstr( &newtag, tag );-			newstr_strcat( &newtag, ":ASIS" );-			fields_add( info, newtag.data, data->data, level );-			newstr_free( &newtag );-			return 1;-		}-	}-	for ( i=0; i<corps->n; ++i ) {-		if ( !strcmp( data->data, list_getc( corps, i ) ) ) {-			newstr_initstr( &newtag, tag );-			newstr_strcat( &newtag, ":CORP" );-			fields_add( info, newtag.data, data->data, level );-			newstr_free( &newtag );-			return 1;-		}-	}-	return 0;-}--static int-biblatex_names( fields *info, char *tag, newstr *data, int level, list *asis, list *corps )-{-	int begin, end, ok, n, etal, i, ret = 1;-	list tokens;--	/* If we match the asis or corps list add and bail. */-	if ( biblatex_matches_asis_corps( info, tag, data, level, asis, corps ) )-		return 1;--	list_init( &tokens );--	biblatex_split( &tokens, data );-	for ( i=0; i<tokens.n; ++i )-		biblatex_cleantoken( list_get( &tokens, i ) );--	etal = name_findetal( &tokens );--	begin = 0;-	n = tokens.n - etal;-	while ( begin < n ) {--		end = begin + 1;--		while ( end < n && strcasecmp( list_getc( &tokens, end ), "and" ) )-			end++;--		if ( end - begin == 1 ) {-			ok = name_addsingleelement( info, tag, list_getc( &tokens, begin ), level, 0 );-			if ( !ok ) { ret = 0; goto out; }-		} else {-			ok = name_addmultielement( info, tag, &tokens, begin, end, level );-			if ( !ok ) { ret = 0; goto out; }-		}--		begin = end + 1;--		/* Handle repeated 'and' errors */-		while ( begin < n && !strcasecmp( list_getc( &tokens, begin ), "and" ) )-			begin++;--	}--	if ( etal ) {-		ret = name_addsingleelement( info, tag, "et al.", level, 0 );-	}--out:-	list_free( &tokens );-	return ret;-}--/*- * biblatex has multiple editor fields "editor", "editora", "editorb", "editorc",- * each of which can be modified from a type of "EDITOR" via "editortype",- * "editoratype", "editorbtype", "editorctype".- *- * Defined types:- *     "editor"- *     "collaborator"- *     "compiler"- *     "redactor"- *- *     "reviser" ?- *     "founder" ?- *     "continuator" ?- *- *  bibtex-chicago- *- *     "director"- *     "producer"- *     "conductor"- *     "none" (for performer)- */-static int-process_editor( fields *bibin, fields *info, newstr *tag, newstr *value, int level, list *asis, list *corps )-{-	char *editor_fields[] = { "editor", "editora", "editorb", "editorc" };-	char *editor_types[]  = { "editortype", "editoratype", "editorbtype", "editorctype" };-	int i, n = 0, ntype, neditors = sizeof( editor_fields ) / sizeof( editor_fields[0] );-	char *type, *outtag = "EDITOR";-	for ( i=1; i<neditors; ++i )-		if ( !strcasecmp( tag->data, editor_fields[i] ) ) n = i;-	ntype = fields_find( bibin, editor_types[n], LEVEL_ANY );-	if ( ntype!=-1 ) {-		type = fields_value( bibin, ntype, FIELDS_CHRP_NOUSE );-		if ( !strcasecmp( type, "collaborator" ) )  outtag = "COLLABORATOR";-		else if ( !strcasecmp( type, "compiler" ) ) outtag = "COMPILER";-		else if ( !strcasecmp( type, "redactor" ) ) outtag = "REDACTOR";-		else if ( !strcasecmp( type, "director" ) ) outtag = "DIRECTOR";-		else if ( !strcasecmp( type, "producer" ) ) outtag = "PRODUCER";-		else if ( !strcasecmp( type, "none" ) )     outtag = "PERFORMER";-	}-	return biblatex_names( info, outtag, value, level, asis, corps );-}--int-biblatexin_convertf( fields *bibin, fields *info, int reftype, param *p,-		variants *all, int nall )-{-	int process, level, i, n, nfields, ok;-	newstr *t, *d;-	char *newtag;--	nfields = fields_num( bibin );-	for ( i=0; i<nfields; ++i ) {--               /* skip ones already "used" such as successful crossref */-                if ( fields_used( bibin, i ) ) continue;--		/* skip ones with no data or no tags (e.g. don't match ALWAYS/DEFAULT entries) */-		t = fields_tag  ( bibin, i, FIELDS_STRP_NOUSE );-		d = fields_value( bibin, i, FIELDS_STRP_NOUSE );-		if ( t->len == 0 || d->len == 0 ) continue;--		n = translate_oldtag( t->data, reftype, all, nall, &process, &level, &newtag );-		if ( n==-1 ) {-			biblatexin_notag( p, t->data );-			continue;-		}--		switch ( process ) {--		case SIMPLE:-			ok = fields_add( info, newtag, d->data, level );-			fields_setused( bibin, i );-			break;--		case PERSON:-			ok = biblatex_names( info, newtag, d, level, &(p->asis), &(p->corps) );-			fields_setused( bibin, i );-			break;--		case BLT_EDITOR:-			ok = process_editor( bibin, info, t, d, level, &(p->asis), &(p->corps) );-			fields_setused( bibin, i );-			break;--		case PAGES:-			ok = process_pages( info, d, level);-			fields_setused( bibin, i );-			break;--		case HOWPUBLISHED:-			ok = process_howpublished( info, d->data, level );-			fields_setused( bibin, i );-			break;--		case BT_URL:-			ok = process_url( info, d->data, level );-			fields_setused( bibin, i );-			break;--		case BT_GENRE:-			ok = fields_add( info, "NGENRE", d->data, level );-			fields_setused( bibin, i );-			break;--		case BT_EPRINT:-			ok = process_eprint( bibin, info, level );-			fields_setused( bibin, i );-			break;--		case BLT_THESIS_TYPE:-			ok = process_thesistype( info, d->data, level );-			fields_setused( bibin, i );-			break;--		case BLT_SCHOOL:-			ok = process_school( bibin, info, newtag, d->data, level );-			fields_setused( bibin, i );-			break;--		case BLT_SUBTYPE:-			ok = process_subtype( bibin, info, newtag, d->data, level );-			fields_setused( bibin, i );-			break;--		case BLT_SKIP:-			ok = 1;-			fields_setused( bibin, i );-			break;--		case TITLE:-			ok = 1; /* delay title processing until later */-			break;--		default:-			ok = 1;-			break;--		}-		if ( !ok ) return BIBL_ERR_MEMERR;--	}--	ok = process_title_all( bibin, info, reftype, p, all, nall );-	if ( !ok ) return BIBL_ERR_MEMERR;--	if ( p->verbose ) report( info );--	return BIBL_OK;+ * Copyright (c) Chris Putnam 2008-2014+ * Copyright (c) Johannes Wilm 2010-2014+ *+ * Program and source code released under the GPL version 2+ *+ */+#include <stdio.h>+#include <stdlib.h>+#include <string.h>+#include <ctype.h>+#include "is_ws.h"+#include "strsearch.h"+#include "newstr.h"+#include "newstr_conv.h"+#include "fields.h"+#include "list.h"+#include "name.h"+#include "reftypes.h"+#include "biblatexin.h"++extern const char progname[];++static list find    = { 0, 0, NULL, 0 };+static list replace = { 0, 0, NULL, 0 };++/*****************************************************+ PUBLIC: void biblatexin_initparams()+*****************************************************/++void+biblatexin_initparams( param *p, const char *progname )+{+	p->readformat       = BIBL_BIBLATEXIN;+	p->charsetin        = BIBL_CHARSET_DEFAULT;+	p->charsetin_src    = BIBL_SRC_DEFAULT;+	p->latexin          = 1;+	p->xmlin            = 0;+	p->utf8in           = 0;+	p->nosplittitle     = 0;+	p->verbose          = 0;+	p->addcount         = 0;+	p->output_raw       = 0;++	p->readf    = biblatexin_readf;+	p->processf = biblatexin_processf;+	p->cleanf   = biblatexin_cleanf;+	p->typef    = biblatexin_typef;+	p->convertf = biblatexin_convertf;+	p->all      = biblatex_all;+	p->nall     = biblatex_nall;++	list_init( &(p->asis) );+	list_init( &(p->corps) );++	if ( !progname ) p->progname = NULL;+	else p->progname = strdup( progname );+}++/*****************************************************+ PUBLIC: int biblatexin_readf()+*****************************************************/++/*+ * readf can "read too far", so we store this information in line, thus+ * the next new text is in line, either from having read too far or+ * from the next chunk obtained via newstr_fget()+ *+ * return 1 on success, 0 on error/end-of-file+ *+ */+static int+readmore( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line )+{+	if ( line->len ) return 1;+	else return newstr_fget( fp, buf, bufsize, bufpos, line );+}++/*+ * readf()+ *+ * returns zero if cannot get reference and hit end of-file+ * returns 1 if last reference in file, 2 if reference within file+ */+int+biblatexin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line, newstr *reference, int *fcharset )+{+	int haveref = 0;+	char *p;+	while ( haveref!=2 && readmore( fp, buf, bufsize, bufpos, line ) ) {+		if ( line->len == 0 ) continue; /* blank line */+		p = &(line->data[0]);+		p = skip_ws( p );+		if ( *p == '%' ) { /* commented out line */+			newstr_empty( line );+			continue;+		}+		if ( *p == '@' ) haveref++;+		if ( haveref && haveref<2 ) {+			newstr_strcat( reference, p );+			newstr_addchar( reference, '\n' );+			newstr_empty( line );+		} else if ( !haveref ) newstr_empty( line );+	+	}+	*fcharset = CHARSET_UNKNOWN;+	return haveref;+}++/*****************************************************+ PUBLIC: int biblatexin_processf()+*****************************************************/++static char *+process_biblatextype( char *p, newstr *type )+{+	newstr tmp;+	newstr_init( &tmp );++	if ( *p=='@' ) p++;+	p = newstr_cpytodelim( &tmp, p, "{( \t\r\n", 0 );+	p = skip_ws( p );+	if ( *p=='{' || *p=='(' ) p++;+	p = skip_ws( p );++	if ( tmp.len ) newstr_strcpy( type, tmp.data );+	else newstr_empty( type );++	newstr_free( &tmp );+	return p;+}++static char *+process_biblatexid( char *p, newstr *id )+{+	char *start_p = p;+	newstr tmp;++	newstr_init( &tmp );+	p = newstr_cpytodelim( &tmp, p, ",", 1 );++	if ( tmp.len ) {+		if ( strchr( tmp.data, '=' ) ) {+			/* Endnote writes biblatex files w/o fields, try to+			 * distinguish via presence of an equal sign.... if+			 * it's there, assume that it's a tag/data pair instead+			 * and roll back.+			 */+			p = start_p;+			newstr_empty( id );+		} else {+			newstr_strcpy( id, tmp.data );+		}+	} else {+		newstr_empty( id );+	}++	newstr_free( &tmp );+	return skip_ws( p );+}++static char *+biblatex_tag( char *p, newstr *tag )+{+	p = newstr_cpytodelim( tag, skip_ws( p ), "= \t\r\n", 0 );+	return skip_ws( p );+}++static char *+biblatex_data( char *p, fields *bibin, list *tokens )+{+	unsigned int nbracket = 0, nquotes = 0;+	char *startp = p;+	newstr tok, *s;++	newstr_init( &tok );+	while ( p && *p ) {+		if ( !nquotes && !nbracket ) {+			if ( *p==',' || *p=='=' || *p=='}' || *p==')' )+				goto out;+		}+		if ( *p=='\"' && nbracket==0 && ( p==startp || *(p-1)!='\\' ) ) {+			nquotes = !nquotes;+			newstr_addchar( &tok, *p );+			if ( !nquotes ) {+				s = list_add( tokens, &tok );+				if ( !s ) { p = NULL; goto outerr; }+				newstr_empty( &tok );+			}+		} else if ( *p=='#' && !nquotes && !nbracket ) {+			if ( tok.len ) {+				s = list_add( tokens, &tok );+				if ( !s ) { p = NULL; goto outerr; }+			}+			newstr_strcpy( &tok, "#" );+			s = list_add( tokens, &tok );+			if ( !s ) { p = NULL; goto outerr; }+			newstr_empty( &tok );+		} else if ( *p=='{' && !nquotes && ( p==startp || *(p-1)!='\\' ) ) {+			nbracket++;+			newstr_addchar( &tok, *p );+		} else if ( *p=='}' && !nquotes && ( p==startp || *(p-1)!='\\' ) ) {+			nbracket--;+			newstr_addchar( &tok, *p );+			if ( nbracket==0 ) {+				s = list_add( tokens, &tok );+				if ( !s ) { p = NULL; goto outerr; }+				newstr_empty( &tok );+			}+		} else if ( !is_ws( *p ) || nquotes || nbracket ) {+			if ( !is_ws( *p ) ) newstr_addchar( &tok, *p );+			else {+				if ( tok.len!=0 && *p!='\n' && *p!='\r' )+					newstr_addchar( &tok, *p );+				else if ( tok.len!=0 && (*p=='\n' || *p=='\r')) {+					newstr_addchar( &tok, ' ' );+					while ( is_ws( *(p+1) ) ) p++;+				}+			}+		} else if ( is_ws( *p ) ) {+			if ( tok.len ) {+				s = list_add( tokens, &tok );+				if ( !s ) { p = NULL; goto outerr; }+				newstr_empty( &tok );+			}+		}+		p++;+	}+out:+	if ( nbracket!=0 ) {+		fprintf( stderr, "%s: Mismatch in number of brackets in reference.\n", progname );+	}+	if ( nquotes!=0 ) {+		fprintf( stderr, "%s: Mismatch in number of quotes in reference.\n", progname );+	}+	if ( tok.len ) {+		s = list_add( tokens, &tok );+		if ( !s ) p = NULL;+	}+outerr:+	newstr_free( &tok );+	return p;+}++/* replace_strings()+ *+ * do string replacement -- only if unprotected by quotation marks or curly brackets+ */+static void+replace_strings( list *tokens, fields *bibin )+{+	int i, n, ok;+	newstr *s;+	char *q;+	i = 0;+	while ( i < tokens->n ) {+		s = list_get( tokens, i );+		if ( !strcmp( s->data, "#" ) ) {+		} else if ( s->data[0]!='\"' && s->data[0]!='{' ) {+			n = list_find( &find, s->data );+			if ( n!=-1 ) {+				newstr_newstrcpy( s, list_get( &replace, n ) );+			} else {+				q = s->data;+				ok = 1;+				while ( *q && ok ) {+					if ( !isdigit( *q ) ) ok = 0;+					q++;+				}+				if ( !ok ) {+					fprintf( stderr, "%s: Warning: Non-numeric "+					   "BibTeX elements should be in quotations or "+					   "curly brackets in reference.\n", progname );+				}+			}+		}+		i++;+	}+}++static int+string_concatenate( list *tokens, fields *bibin )+{+	int i, status;+	newstr *s, *t;+	i = 0;+	while ( i < tokens->n ) {+		s = list_get( tokens, i );+		if ( !strcmp( s->data, "#" ) ) {+			if ( i==0 || i==tokens->n-1 ) {+				fprintf( stderr, "%s: Warning: Stray string concatenation "+					"('#' character) in reference\n", progname );+				status = list_remove( tokens, i );+				if ( status!=LIST_OK ) return BIBL_ERR_MEMERR;+				continue;+			}+			s = list_get( tokens, i-1 );+			if ( s->data[0]!='\"' && s->data[s->len-1]!='\"' )+				fprintf( stderr, "%s: Warning: String concentation should "+					"be used in context of quotations marks.\n", progname );+			t = list_get( tokens, i+1 );+			if ( t->data[0]!='\"' && t->data[s->len-1]!='\"' )+				fprintf( stderr, "%s: Warning: String concentation should "+					"be used in context of quotations marks.\n", progname );+			if ( ( s->data[s->len-1]=='\"' && t->data[0]=='\"') || (s->data[s->len-1]=='}' && t->data[0]=='{') ) {+				newstr_trimend( s, 1 );+				newstr_trimbegin( t, 1 );+				newstr_newstrcat( s, t );+			} else {+				newstr_newstrcat( s, t );+			}+			status = list_remove( tokens, i );+			if ( status!=LIST_OK ) return BIBL_ERR_MEMERR;+			status = list_remove( tokens, i );+			if ( status!=LIST_OK ) return BIBL_ERR_MEMERR;+		} else i++;+	}+	return BIBL_OK;+}++static char *+process_biblatexline( char *p, newstr *tag, newstr *data, uchar stripquotes )+{+	int i, status;+	list tokens;+	newstr *s;++	newstr_empty( data );++	p = biblatex_tag( p, tag );+	if ( tag->len==0 ) return p;++	list_init( &tokens );++	if ( *p=='=' ) p = biblatex_data( p+1, NULL, &tokens );++	replace_strings( &tokens, NULL );++	status = string_concatenate( &tokens, NULL );+	if ( status!=BIBL_OK ) {+		p = NULL;+		goto out;+	}++	for ( i=0; i<tokens.n; i++ ) {+		s = list_get( &tokens, i );+		if ( ( stripquotes && s->data[0]=='\"' && s->data[s->len-1]=='\"' ) ||+		     ( s->data[0]=='{' && s->data[s->len-1]=='}' ) ) {+			newstr_trimbegin( s, 1 );+			newstr_trimend( s, 1 );+		}+		newstr_newstrcat( data, list_get( &tokens, i ) );+	}+out:+	list_free( &tokens );+	return p;+}++static int+process_cite( fields *bibin, char *p, char *filename, long nref )+{+	int fstatus, status = BIBL_OK;+	newstr tag, data;+	newstrs_init( &tag, &data, NULL );+	p = process_biblatextype( p, &data );+	if ( data.len ) {+		fstatus = fields_add( bibin, "INTERNAL_TYPE", data.data, 0 );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+	}+	p = process_biblatexid ( p, &data );+	if ( data.len ) {+		fstatus = fields_add( bibin, "REFNUM", data.data, 0 );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+	}+	while ( *p ) {+		p = process_biblatexline( p, &tag, &data, 1 );+		if ( !p ) { status = BIBL_ERR_MEMERR; goto out; }+		/* no anonymous or empty fields allowed */+		if ( tag.len && data.len ) {+			fstatus = fields_add( bibin, tag.data, data.data, 0 );+			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+		}+		newstrs_empty( &tag, &data, NULL );+	}+out:+	newstrs_free( &tag, &data, NULL );+	return status;+}++/* process_string()+ *+ * Handle lines like:+ *+ * '@STRING{TL = {Tetrahedron Lett.}}'+ *+ * p should point to just after '@STRING'+ *+ * In BibTeX, if a string is defined several times, the last one is kept.+ *+ */+static int+process_string( char *p )+{+	int n, status = BIBL_OK;+	newstr s1, s2, *s;+	newstrs_init( &s1, &s2, NULL );+	while ( *p && *p!='{' && *p!='(' ) p++;+	if ( *p=='{' || *p=='(' ) p++;+	p = process_biblatexline( skip_ws( p ), &s1, &s2, 0 );+	if ( s2.data ) {+		newstr_findreplace( &s2, "\\ ", " " );+		if ( newstr_memerr( &s2 ) ) { status = BIBL_ERR_MEMERR; goto out; }+	}+	if ( s1.data ) {+		n = list_find( &find, s1.data );+		if ( n==-1 ) {+			s = list_add( &find, &s1 );+			if ( s==NULL ) { status = BIBL_ERR_MEMERR; goto out; }+			if ( s2.data ) s = list_add( &replace, &s2 );+			else s = list_addc( &replace, "" );+			if ( s==NULL ) { status = BIBL_ERR_MEMERR; goto out; }+		} else {+			if ( s2.data ) s = list_set( &replace, n, &s2 );+			else s = list_setc( &replace, n, "" );+			if ( s==NULL ) { status = BIBL_ERR_MEMERR; goto out; }+		}+	}+out:+	newstrs_free( &s1, &s2, NULL );+	return status;+}++int+biblatexin_processf( fields *bibin, char *data, char *filename, long nref )+{+	if ( !strncasecmp( data, "@STRING", 7 ) ) {+		process_string( data+7 );+		return 0;+        } else {+		process_cite( bibin, data, filename, nref );+		return 1;+	}+}++/*****************************************************+ PUBLIC: void biblatexin_cleanf()+*****************************************************/++static void+biblatex_process_tilde( newstr *s )+{+	char *p, *q;+	int n = 0;++	p = q = s->data;+	if ( !p ) return;+	while ( *p ) {+		if ( *p=='~' ) {+			*q = ' ';+		} else if ( *p=='\\' && *(p+1)=='~' ) {+			n++;+			p++;+			*q = '~';+		} else {+			*q = *p;+		}+		p++;+		q++;+	}+	*q = '\0';+	s->len -= n;+}++static void+biblatex_process_bracket( newstr *s )+{+	char *p, *q;+	int n = 0;++	p = q = s->data;+	if ( !p ) return;+	while ( *p ) {+		if ( *p=='\\' && ( *(p+1)=='{' || *(p+1)=='}' ) ) {+			n++;+			p++;+			*q = *p;+			q++;+		} else if ( *p=='{' || *p=='}' ) {+			n++;+		} else {+			*q = *p;+			q++;+		}+		p++;+	}+	*q = '\0';+	s->len -= n;+}++static int+biblatex_cleantoken( newstr *s )+{+	/* 'textcomp' annotations */+	newstr_findreplace( s, "\\textit", "" );+	newstr_findreplace( s, "\\textbf", "" );+	newstr_findreplace( s, "\\textsl", "" );+	newstr_findreplace( s, "\\textsc", "" );+	newstr_findreplace( s, "\\textsf", "" );+	newstr_findreplace( s, "\\texttt", "" );+	newstr_findreplace( s, "\\textsubscript", "" );+	newstr_findreplace( s, "\\textsuperscript", "" );+	newstr_findreplace( s, "\\emph", "" );+	newstr_findreplace( s, "\\url", "" );++	/* Other text annotations */+	newstr_findreplace( s, "\\it ", "" );+	newstr_findreplace( s, "\\em ", "" );++	newstr_findreplace( s, "\\%", "%" );+	newstr_findreplace( s, "\\$", "$" );+	while ( newstr_findreplace( s, "  ", " " ) ) {}++	/* 'textcomp' annotations that we don't want to substitute on output*/+	newstr_findreplace( s, "\\textdollar", "$" );+	newstr_findreplace( s, "\\textunderscore", "_" );++	biblatex_process_bracket( s );+	biblatex_process_tilde( s );++	if ( !newstr_memerr( s ) ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}++static int+biblatex_split( list *tokens, newstr *s )+{+	int i, n = s->len, nbrackets = 0, status = BIBL_OK;+	newstr tok, *t;++	newstr_init( &tok );++	for ( i=0; i<n; ++i ) {+		if ( s->data[i]=='{' && ( i==0 || s->data[i-1]!='\\' ) ) {+			nbrackets++;+			newstr_addchar( &tok, '{' );+		} else if ( s->data[i]=='}' && ( i==0 || s->data[i-1]!='\\' ) ) {+			nbrackets--;+			newstr_addchar( &tok, '}' );+		} else if ( !is_ws( s->data[i] ) || nbrackets ) {+			newstr_addchar( &tok, s->data[i] );+		} else if ( is_ws( s->data[i] ) ) {+			if ( newstr_memerr( &tok ) ) { status = BIBL_ERR_MEMERR; goto out; }+			if ( tok.len ) {+				t = list_add( tokens, &tok );+				if ( !t ) { status = BIBL_ERR_MEMERR; goto out; }+			}+			newstr_empty( &tok );+		}+	}+	if ( tok.len ) {+		if ( newstr_memerr( &tok ) ) { status = BIBL_ERR_MEMERR; goto out; }+		t = list_add( tokens, &tok );+		if ( !t ) { status = BIBL_ERR_MEMERR; goto out; }+	}++	for ( i=0; i<tokens->n; ++i ) {+		t = list_get( tokens, i );+		newstr_trimstartingws( t );+		newstr_trimendingws( t );+		if ( newstr_memerr( t ) ) { status = BIBL_ERR_MEMERR; goto out; }+	}+out:+	newstr_free( &tok );+	return status;+}++static int+biblatexin_addtitleurl( fields *info, newstr *in )+{+	int fstatus, status = BIBL_OK;+	newstr s;+	char *p;++	newstr_init( &s );+	/* skip past "\href{" */+	p = newstr_cpytodelim( &s, in->data + 6, "}", 1 );+	if ( newstr_memerr( &s ) ) {+		status = BIBL_ERR_MEMERR;+		goto out;+	}+	fstatus = fields_add( info, "URL", s.data, 0 );+	if ( fstatus!=FIELDS_OK ) {+		status = BIBL_ERR_MEMERR;+		goto out;+	}++	p = newstr_cpytodelim( &s, p, "", 0 );+	if ( newstr_memerr( &s ) ) {+		status = BIBL_ERR_MEMERR;+		goto out;+	}+	newstr_swapstrings( &s, in );+out:+	newstr_free( &s );+	return status;+}++static int+is_name_tag( newstr *tag )+{+	if ( tag->len ) {+		if ( !strcasecmp( tag->data, "author" ) ) return 1;+		if ( !strcasecmp( tag->data, "editor" ) ) return 1;+		if ( !strcasecmp( tag->data, "editorb" ) ) return 1;+		if ( !strcasecmp( tag->data, "editorc" ) ) return 1;+		if ( !strcasecmp( tag->data, "director" ) ) return 1;+		if ( !strcasecmp( tag->data, "producer" ) ) return 1;+		if ( !strcasecmp( tag->data, "execproducer" ) ) return 1;+		if ( !strcasecmp( tag->data, "writer" ) ) return 1;+		if ( !strcasecmp( tag->data, "redactor" ) ) return 1;+		if ( !strcasecmp( tag->data, "annotator" ) ) return 1;+		if ( !strcasecmp( tag->data, "commentator" ) ) return 1;+		if ( !strcasecmp( tag->data, "translator" ) ) return 1;+		if ( !strcasecmp( tag->data, "foreword" ) ) return 1;+		if ( !strcasecmp( tag->data, "afterword" ) ) return 1;+		if ( !strcasecmp( tag->data, "introduction" ) ) return 1;+	}+	return 0;+}++static int+is_url_tag( newstr *tag )+{+	if ( tag->len ) {+		if ( !strcasecmp( tag->data, "url" ) ) return 1;+	}+	return 0;+}++static int+biblatexin_cleandata( newstr *tag, newstr *s, fields *info, param *p )+{+	list tokens;+	newstr *tok;+	int i, status = BIBL_OK;+	if ( !s->len ) return status;+	/* protect url from undergoing any parsing */+	if ( is_url_tag( tag ) ) return status;+	list_init( &tokens );+	biblatex_split( &tokens, s );+	for ( i=0; i<tokens.n; ++i ) {+		if (!strncasecmp(tokens.str[i].data,"\\href{", 6)) {+			status = biblatexin_addtitleurl( info, &(tokens.str[i]) );+			if ( status!=BIBL_OK ) goto out;+		}+		if ( p && p->latexin && !is_name_tag( tag ) ) {+			status = biblatex_cleantoken( &(tokens.str[i]) );+			if ( status!=BIBL_OK ) goto out;+		}+	}+	newstr_empty( s );+	for ( i=0; i<tokens.n; ++i ) {+		tok = list_get( &tokens, i );+		if ( i>0 ) newstr_addchar( s, ' ' );+		newstr_newstrcat( s, tok );+	}+out:+	list_free( &tokens );+	return status;+}++static long+biblatexin_findref( bibl *bin, char *citekey )+{+	int n;+	long i;+	for ( i=0; i<bin->nrefs; ++i ) {+		n = fields_find( bin->ref[i], "refnum", -1 );+		if ( n==-1 ) continue;+		if ( !strcmp( bin->ref[i]->data[n].data, citekey ) ) return i;+	}+	return -1;+}++static void+biblatexin_nocrossref( bibl *bin, long i, int n, param *p )+{+	int n1 = fields_find( bin->ref[i], "REFNUM", -1 );+	if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+	fprintf( stderr, "Cannot find cross-reference '%s'", +			bin->ref[i]->data[n].data);+	if ( n1!=-1 )+		fprintf( stderr, " for reference '%s'\n", +				bin->ref[i]->data[n1].data );+	fprintf( stderr, "\n" );+}++static int+biblatexin_crossref_oneref( fields *ref, fields *cross )+{+	int j, nl, ntype, fstatus;+	char *type, *nt, *nd;+	ntype = fields_find( ref, "INTERNAL_TYPE", -1 );+	type = ( char * ) fields_value( ref, ntype, FIELDS_CHRP_NOUSE );+	for ( j=0; j<cross->n; ++j ) {+		nt = ( char * ) fields_tag( cross, j, FIELDS_CHRP_NOUSE );+		if ( !strcasecmp( nt, "INTERNAL_TYPE" ) ) continue;+		if ( !strcasecmp( nt, "REFNUM" ) ) continue;+		if ( !strcasecmp( nt, "TITLE" ) ) {+			if ( !strcasecmp( type, "Inproceedings" ) ||+			     !strcasecmp( type, "Incollection" ) )+				nt = "booktitle";+		}+		nd = ( char * ) fields_value( cross, j, FIELDS_CHRP_NOUSE );+		nl = fields_level( cross, j ) + 1;+		fstatus = fields_add( ref, nt, nd, nl );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	return BIBL_OK;+}++static int+biblatexin_crossref( bibl *bin, param *p )+{+	int n, ncross, status = BIBL_OK;+	fields *ref, *cross;+	long i;+        for ( i=0; i<bin->nrefs; ++i ) {+		ref = bin->ref[i];+		n = fields_find( ref, "CROSSREF", -1 );+		if ( n==-1 ) continue;+		fields_setused( ref, n );+		ncross = biblatexin_findref(bin, (char*)fields_value(ref,n, FIELDS_CHRP_NOUSE));+		if ( ncross==-1 ) {+			biblatexin_nocrossref( bin, i, n, p );+			continue;+		}+		cross = bin->ref[ncross];+		status = biblatexin_crossref_oneref( ref, cross );+		if ( status!=BIBL_OK ) return status;+	}+	return status;+}++static int+biblatexin_cleanref( fields *bibin, param *p )+{+	int i, n, status;+	newstr *t, *d;+	n = fields_num( bibin );+	for ( i=0; i<n; ++i ) {+		t = fields_tag( bibin, i, FIELDS_STRP_NOUSE );+		d = fields_value( bibin, i, FIELDS_STRP_NOUSE );+		status = biblatexin_cleandata( t, d, bibin, p );+		if ( status!=BIBL_OK ) return status;+		if ( !strsearch( t->data, "AUTHORS" ) ) {+			newstr_findreplace( d, "\n", " " );+			newstr_findreplace( d, "\r", " " );+		}+		else if ( !strsearch( t->data, "ABSTRACT" ) ||+		     !strsearch( t->data, "SUMMARY" ) || +		     !strsearch( t->data, "NOTE" ) ) {+			newstr_findreplace( d, "\n", "" );+			newstr_findreplace( d, "\r", "" );+		}+	}+	return BIBL_OK;+}++int+biblatexin_cleanf( bibl *bin, param *p )+{+	int status;+	long i;+        for ( i=0; i<bin->nrefs; ++i ) {+		status = biblatexin_cleanref( bin->ref[i], p );+		if ( status!=BIBL_OK ) return status;+	}+	status = biblatexin_crossref( bin, p );+	return status;+}++/*****************************************************+ PUBLIC: void biblatexin_typef()+*****************************************************/++int+biblatexin_typef( fields *bibin, char *filename, int nrefs, param *p,+                variants *all, int nall )+{+        char *refnum = "";+        int reftype, n, nrefnum;+        n = fields_find( bibin, "INTERNAL_TYPE", 0 );+        nrefnum = fields_find( bibin, "REFNUM", 0 );+        if ( nrefnum!=-1 ) refnum = (bibin->data[nrefnum]).data;+        if ( n!=-1 )+                /* figure out type */+                reftype = get_reftype( (bibin->data[n]).data, nrefs,+                        p->progname, all, nall, refnum );+        else+                /* no type info, go for default */+                reftype = get_reftype( "", nrefs, p->progname, all, nall, refnum );+        return reftype;+}++/*****************************************************+ PUBLIC: int biblatexin_convertf(), returns BIBL_OK or BIBL_ERR_MEMERR+*****************************************************/++/* is_utf8_emdash()+ *+ * Internally pages="A---B" will convert --- to a UTF8+ * emdash = 0xE2 (-30) 0x80 (-128) 0x94 (-108)+ */+static int+is_utf8_emdash( char *p )+{+	static char emdash[3] = { -30, -128, -108 };+	if ( strncmp( p, emdash, 3 ) ) return 0;+	return 1;+}+/* is_utf8_endash()+ *+ * Internally pages="A--B" will convert -- to a UTF8+ * endash = 0xE2 (-30) 0x80 (-128) 0x93 (-109)+ */+static int+is_utf8_endash( char *p )+{+	static char endash[3] = { -30, -128, -109 };+	if ( strncmp( p, endash, 3 ) ) return 0;+	return 1;+}++static int+process_pages( fields *info, newstr *s, int level )+{+	int fstatus, status = BIBL_OK;+	newstr page;+	char *p;++	newstr_findreplace( s, " ", "" );+	if ( s->len==0 ) return status;++	newstr_init( &page );+	p = skip_ws( s->data );+	while ( *p && !is_ws(*p) && *p!='-' && *p!=-30 )+		newstr_addchar( &page, *p++ );+	if ( page.len>0 ) {+		fstatus = fields_add( info, "PAGESTART", page.data, level );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+	}++	while ( *p && (is_ws(*p) || *p=='-' ) ) p++;+	if ( *p && is_utf8_emdash( p ) ) p+=3;+	if ( *p && is_utf8_endash( p ) ) p+=3;++	newstr_empty( &page );+	while ( *p && !is_ws(*p) && *p!='-' && *p!=-30 )+		newstr_addchar( &page, *p++ );+	if ( page.len>0 ) {+		fstatus = fields_add( info, "PAGEEND", page.data, level );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+	}+out:+	newstr_free( &page );+	return status;+}++static int+process_url( fields *info, char *p, int level )+{+	int fstatus;+	if ( !strncasecmp( p, "\\urllink", 8 ) )+		fstatus = fields_add( info, "URL", p+8, level );+	else if ( !strncasecmp( p, "\\url", 4 ) )+		fstatus = fields_add( info, "URL", p+4, level );+	else if ( !strncasecmp( p, "arXiv:", 6 ) )+		fstatus = fields_add( info, "ARXIV", p+6, level ); +	else if ( !strncasecmp( p, "http://arxiv.org/abs/", 21 ) )+		fstatus = fields_add( info, "ARXIV", p+21, level );+	else if ( !strncasecmp( p, "http:", 5 ) )+		fstatus = fields_add( info, "URL", p, level );+	else +		fstatus = fields_add( info, "URL", p, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}+++/* process_howpublished()+ *+ *    howpublished={},+ *+ * Normally indicates the manner in which something was+ * published in lieu of a formal publisher, so typically+ * 'howpublished' and 'publisher' will never be in the+ * same reference.+ *+ * Occasionally, people put Diploma thesis information+ * into this field, so check for that first.+ */+static int+process_howpublished( fields *info, char *p, int level )+{+	int fstatus;+        if ( !strncasecmp( p, "Diplom", 6 ) )+                fstatus = fields_replace_or_add( info, "NGENRE", "Diploma thesis", level );+        else if ( !strncasecmp( p, "Habilitation", 13 ) )+                fstatus = fields_replace_or_add( info, "NGENRE", "Habilitation thesis", level );+        else+		fstatus = fields_add( info, "PUBLISHER", p, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}++static int+process_thesistype( fields *info, char *p, int level )+{+	int fstatus;+	/* type in the @thesis is used to distinguish Ph.D. and Master's thesis */+	if ( !strncasecmp( p, "phdthesis", 9 ) ) {+		fstatus = fields_replace_or_add( info, "NGENRE", "Ph.D. thesis", level );+	} else if ( !strncasecmp( p, "mastersthesis", 13 ) || !strncasecmp( p, "masterthesis", 12 ) ) {+		fstatus = fields_replace_or_add( info, "NGENRE", "Masters thesis", level );+	} else if ( !strncasecmp( p, "mathesis", 8 ) ) {+		fstatus = fields_replace_or_add( info, "NGENRE", "Masters thesis", level );+	} else if ( !strncasecmp( p, "diploma", 7 ) ) {+		fstatus = fields_replace_or_add( info, "NGENRE", "Diploma thesis", level );+	} else if ( !strncasecmp( p, "habilitation", 12 ) ) {+		fstatus = fields_replace_or_add( info, "NGENRE", "Habilitation thesis", level );+	}+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}++/* biblatex drops school field if institution is present */+static int+process_school( fields *bibin, fields *info, char *tag, char *value, int level )+{+	int fstatus;+	if ( fields_find( bibin, "institution", LEVEL_ANY ) != -1 )+		return BIBL_OK;+	else {+		fstatus = fields_add( info, tag, value, level );+		if ( fstatus==FIELDS_OK ) return BIBL_OK;+		else return BIBL_ERR_MEMERR;+	}+}++/* biblatex drops school field if institution is present */+static int+process_subtype( fields *bibin, fields *info, char *tag, char *value, int level )+{+	int fstatus;+	if ( !strcasecmp( value, "magazine" ) ) {+		fstatus = fields_add( info, "NGENRE", "magazine article", LEVEL_MAIN );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		fstatus = fields_add( info, "NGENRE", "magazine", LEVEL_HOST );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	} else if ( !strcasecmp( value, "newspaper" ) ) {+		fstatus = fields_add( info, "NGENRE", "newspaper article", LEVEL_MAIN );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		fstatus = fields_add( info, "GENRE", "newspaper", LEVEL_HOST );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	return BIBL_OK;+}++static int+process_eprint( fields *bibin, fields *info, int level )+{+	int neprint, netype, fstatus;+	char *eprint = NULL, *etype = NULL;+	neprint = fields_find( bibin, "eprint", -1 );+	netype  = fields_find( bibin, "eprinttype", -1 );+	if ( neprint!=-1 ) eprint = bibin->data[neprint].data;+	if ( netype!=-1 ) etype = bibin->data[netype].data;+	if ( eprint && etype ) {+		if ( !strncasecmp( etype, "arxiv", 5 ) ) {+			fstatus = fields_add( info, "ARXIV", eprint, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		} else if ( !strncasecmp( etype, "jstor", 5 ) ) {+			fstatus = fields_add( info, "JSTOR", eprint, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		} else if ( !strncasecmp( etype, "pubmed", 6 ) ) {+			fstatus = fields_add( info, "PMID", eprint, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		} else if ( !strncasecmp( etype, "medline", 7 ) ) {+			fstatus = fields_add( info, "MEDLINE", eprint, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		} else {+			fstatus = fields_add( info, "EPRINT", eprint, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+			fstatus = fields_add( info, "EPRINTTYPE", etype, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		}+		fields_setused( bibin, neprint );+		fields_setused( bibin, netype );+	} else if ( eprint ) {+		fstatus = fields_add( info, "EPRINT", eprint, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		fields_setused( bibin, neprint );+	} else if ( etype ) {+		fstatus = fields_add( info, "EPRINTTYPE", etype, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		fields_setused( bibin, netype );+	}+	return BIBL_OK;+}++static void+report( fields *f )+{+	int i, n;+	n = fields_num( f );+	for ( i=0; i<n; ++i )+		fprintf(stderr, "%d '%s' = '%s'\n",+			fields_level( f, i ),+			(char*)fields_tag( f, i, FIELDS_CHRP_NOUSE ),+			(char*)fields_value( f, i, FIELDS_CHRP_NOUSE ) );+}++static void+biblatexin_notag( param *p, char *tag )+{+	if ( p->verbose && strcmp( tag, "INTERNAL_TYPE" ) ) {+		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+		fprintf( stderr, " Cannot find tag '%s'\n", tag );+	}+}++/* get_title_elements()+ *+ * find all of the biblatex title elements for the current level+ *    internal "TITLE"      -> "title", "booktitle", "maintitle"+ *    internal "SUBTITLE"   -> "subtitle", "booksubtitle", "mainsubtitle"+ *    internal "TITLEADDON" -> "titleaddon", "booktitleaddon", "maintitleaddon"+ *+ * place in ttl, subttl, and ttladdon strings+ *+ * return 1 if an element is found, 0 if not+ */+static int+get_title_elements( fields *bibin, int currlevel, int reftype, variants *all, int nall,+	newstr *ttl, newstr *subttl, newstr *ttladdon )+{+	int nfields, process, level, i, n;+	newstr *t, *d;+	char *newtag;++	newstrs_empty( ttl, subttl, ttladdon, NULL );++	nfields = fields_num( bibin );++	for ( i=0; i<nfields; ++i ) {++		/* ...skip already used titles */+		if ( fields_used( bibin, i ) ) continue;++		/* ...skip empty elements */+		t = fields_tag  ( bibin, i, FIELDS_STRP_NOUSE );+		d = fields_value( bibin, i, FIELDS_STRP_NOUSE );+		if ( d->len == 0 ) continue;++		n = translate_oldtag( t->data, reftype, all, nall, &process, &level, &newtag );+		if ( n==-1 ) continue;+		if ( process != TITLE ) continue;+		if ( level != currlevel ) continue;++		fields_setused( bibin, i );++		if ( !strcasecmp( newtag, "TITLE" ) ) {+			if ( ttl->len ) newstr_addchar( ttl, ' ' );+			newstr_newstrcat( ttl, d );+		} else if ( !strcasecmp( newtag, "SUBTITLE" ) ) {+			if ( subttl->len ) newstr_addchar( subttl, ' ' );+			newstr_newstrcat( subttl, d );+		} else if ( !strcasecmp( newtag, "TITLEADDON" ) ) {+			if ( ttladdon->len ) newstr_addchar( ttladdon, ' ' );+			newstr_newstrcat( ttladdon, d );+		}+	}++	return ( ttl->len>0 || subttl->len > 0 || ttladdon->len > 0 );+}++/* attach_addon()+ *+ * Add titleaddon to the title.+ */+static void+attach_addon( newstr *title, newstr *addon )+{+	if ( title->len ) {+		if ( title->data[title->len-1]!='.' )+			newstr_addchar( title, '.' );+		newstr_addchar( title, ' ' );+	}+	newstr_newstrcat( title, addon );+}++static int+process_combined_title( fields *info, newstr *ttl, newstr *subttl, newstr *ttladdon, int currlevel )+{+	int fstatus, status = BIBL_OK;+	newstr combined;++	newstr_init( &combined );+	newstr_newstrcpy( &combined, ttl );+	if ( subttl->len ) {+		if ( combined.len && combined.data[combined.len-1]!=':' && combined.data[combined.len-1]!='?' )+			newstr_addchar( &combined, ':' );+		newstr_addchar( &combined, ' ' );+		newstr_newstrcat( &combined, subttl );+	}+	if ( ttladdon->len ) attach_addon( &combined, ttladdon );+	if ( newstr_memerr( &combined ) ) { status = BIBL_ERR_MEMERR; goto out; }+	fstatus = fields_add( info, "TITLE", combined.data, currlevel );+	if ( fstatus==FIELDS_OK ) status = BIBL_ERR_MEMERR;+out:+	newstr_free( &combined );+	return status;+}++static int+process_separated_title( fields *info, newstr *ttl, newstr *subttl, newstr *ttladdon, int currlevel )+{+	int fstatus;+	if ( ttladdon->len ) {+		if ( subttl->len ) attach_addon( subttl, ttladdon );+		else attach_addon( ttl, ttladdon );+	}+	if ( ttl->len ) {+		fstatus = fields_add( info, "TITLE", ttl->data, currlevel );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	if ( subttl->len ) {+		fstatus = fields_add( info, "SUBTITLE", subttl->data, currlevel );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	return BIBL_OK;+}++static int+process_title_all( fields *bibin, fields *info, int reftype, param *p,+	variants *all, int nall )+{+	int currlevel, found, status = BIBL_OK;+	newstr ttl, subttl, ttladdon;+	newstrs_init( &ttl, &subttl, &ttladdon, NULL );+	for ( currlevel = 0; currlevel<LEVEL_SERIES+2; currlevel++ ) {+		found = get_title_elements( bibin, currlevel, reftype, all, nall,+				&ttl, &subttl, &ttladdon );+		if ( !found ) continue;+		if ( p->nosplittitle )+			status = process_combined_title( info, &ttl, &subttl, &ttladdon, currlevel );+		else+			status = process_separated_title( info, &ttl, &subttl, &ttladdon, currlevel );+		if ( status!=BIBL_OK ) goto out;+	}+out:+	newstrs_free( &ttl, &subttl, &ttladdon, NULL );+	return status;+}+++static int+biblatex_matches_list( fields *info, char *tag, char *suffix, newstr *data, int level,+                list *names, int *match )+{+	int i, fstatus, status = BIBL_OK;+	newstr newtag;++	*match = 0;+	if ( names->n==0 ) return status;++	newstr_init( &newtag );++	for ( i=0; i<names->n; ++i ) {+		if ( strcmp( data->data, list_getc( names, i ) ) ) continue;+		newstr_initstr( &newtag, tag );+		newstr_strcat( &newtag, suffix );+		fstatus = fields_add( info, newtag.data, data->data, level );+		if ( fstatus!=FIELDS_OK ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		}+		*match = 1;+		goto out;+	}++out:+	newstr_free( &newtag );+	return status;+}++static int+biblatex_names( fields *info, char *tag, newstr *data, int level, list *asis, list *corps )+{+	int begin, end, ok, n, etal, i, match, status = BIBL_OK;+	list tokens;++	/* If we match the asis or corps list add and bail. */+	status = biblatex_matches_list( info, tag, ":ASIS", data, level, asis, &match );+	if ( match==1 || status!=BIBL_OK ) return status;+	status = biblatex_matches_list( info, tag, ":CORP", data, level, corps, &match );+	if ( match==1 || status!=BIBL_OK ) return status;++	list_init( &tokens );++	biblatex_split( &tokens, data );+	for ( i=0; i<tokens.n; ++i )+		biblatex_cleantoken( list_get( &tokens, i ) );++	etal = name_findetal( &tokens );++	begin = 0;+	n = tokens.n - etal;+	while ( begin < n ) {++		end = begin + 1;++		while ( end < n && strcasecmp( list_getc( &tokens, end ), "and" ) )+			end++;++		if ( end - begin == 1 ) {+			ok = name_addsingleelement( info, tag, list_getc( &tokens, begin ), level, 0 );+			if ( !ok ) { status = BIBL_ERR_MEMERR; goto out; }+		} else {+			ok = name_addmultielement( info, tag, &tokens, begin, end, level );+			if ( !ok ) { status = BIBL_ERR_MEMERR; goto out; }+		}++		begin = end + 1;++		/* Handle repeated 'and' errors */+		while ( begin < n && !strcasecmp( list_getc( &tokens, begin ), "and" ) )+			begin++;++	}++	if ( etal ) {+		ok = name_addsingleelement( info, tag, "et al.", level, 0 );+		if ( !ok ) status = BIBL_ERR_MEMERR;+	}++out:+	list_free( &tokens );+	return status;+}++/*+ * biblatex has multiple editor fields "editor", "editora", "editorb", "editorc",+ * each of which can be modified from a type of "EDITOR" via "editortype",+ * "editoratype", "editorbtype", "editorctype".+ *+ * Defined types:+ *     "editor"+ *     "collaborator"+ *     "compiler"+ *     "redactor"+ *+ *     "reviser" ?+ *     "founder" ?+ *     "continuator" ?+ *+ *  bibtex-chicago+ *+ *     "director"+ *     "producer"+ *     "conductor"+ *     "none" (for performer)+ */+static int+process_editor( fields *bibin, fields *info, newstr *tag, newstr *value, int level, list *asis, list *corps )+{+	char *editor_fields[] = { "editor", "editora", "editorb", "editorc" };+	char *editor_types[]  = { "editortype", "editoratype", "editorbtype", "editorctype" };+	int i, n = 0, ntype, neditors = sizeof( editor_fields ) / sizeof( editor_fields[0] );+	char *type, *outtag = "EDITOR";+	for ( i=1; i<neditors; ++i )+		if ( !strcasecmp( tag->data, editor_fields[i] ) ) n = i;+	ntype = fields_find( bibin, editor_types[n], LEVEL_ANY );+	if ( ntype!=-1 ) {+		type = fields_value( bibin, ntype, FIELDS_CHRP_NOUSE );+		if ( !strcasecmp( type, "collaborator" ) )  outtag = "COLLABORATOR";+		else if ( !strcasecmp( type, "compiler" ) ) outtag = "COMPILER";+		else if ( !strcasecmp( type, "redactor" ) ) outtag = "REDACTOR";+		else if ( !strcasecmp( type, "director" ) ) outtag = "DIRECTOR";+		else if ( !strcasecmp( type, "producer" ) ) outtag = "PRODUCER";+		else if ( !strcasecmp( type, "none" ) )     outtag = "PERFORMER";+	}+	return biblatex_names( info, outtag, value, level, asis, corps );+}++static int+biblatexin_simple( fields *f, char *tag, char *value, int level )+{+	int fstatus = fields_add( f, tag, value, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}++int+biblatexin_convertf( fields *bibin, fields *info, int reftype, param *p,+		variants *all, int nall )+{+	int process, level, i, n, nfields, status = BIBL_OK;+	newstr *t, *d;+	char *newtag;++	nfields = fields_num( bibin );+	for ( i=0; i<nfields; ++i ) {++               /* skip ones already "used" such as successful crossref */+                if ( fields_used( bibin, i ) ) continue;++		/* skip ones with no data or no tags (e.g. don't match ALWAYS/DEFAULT entries) */+		t = fields_tag  ( bibin, i, FIELDS_STRP_NOUSE );+		d = fields_value( bibin, i, FIELDS_STRP_NOUSE );+		if ( t->len == 0 || d->len == 0 ) continue;++		n = translate_oldtag( t->data, reftype, all, nall, &process, &level, &newtag );+		if ( n==-1 ) {+			biblatexin_notag( p, t->data );+			continue;+		}++		switch ( process ) {++		case SIMPLE:+			status = biblatexin_simple( info, newtag, d->data, level );+			fields_setused( bibin, i );+			break;++		case PERSON:+			status = biblatex_names( info, newtag, d, level, &(p->asis), &(p->corps) );+			fields_setused( bibin, i );+			break;++		case BLT_EDITOR:+			status = process_editor( bibin, info, t, d, level, &(p->asis), &(p->corps) );+			fields_setused( bibin, i );+			break;++		case PAGES:+			status = process_pages( info, d, level);+			fields_setused( bibin, i );+			break;++		case HOWPUBLISHED:+			status = process_howpublished( info, d->data, level );+			fields_setused( bibin, i );+			break;++		case BT_URL:+			status = process_url( info, d->data, level );+			fields_setused( bibin, i );+			break;++		case BT_GENRE:+			status = biblatexin_simple( info, "NGENRE", d->data, level );+			fields_setused( bibin, i );+			break;++		case BT_EPRINT:+			status = process_eprint( bibin, info, level );+			fields_setused( bibin, i );+			break;++		case BLT_THESIS_TYPE:+			status = process_thesistype( info, d->data, level );+			fields_setused( bibin, i );+			break;++		case BLT_SCHOOL:+			status = process_school( bibin, info, newtag, d->data, level );+			fields_setused( bibin, i );+			break;++		case BLT_SUBTYPE:+			status = process_subtype( bibin, info, newtag, d->data, level );+			fields_setused( bibin, i );+			break;++		case BLT_SKIP:+			status = BIBL_OK;+			fields_setused( bibin, i );+			break;++		case TITLE:+			status = BIBL_OK; /* delay title processing until later */+			break;++		default:+			status = BIBL_OK;+			break;++		}+		if ( status!=BIBL_OK ) return status;++	}++	status = process_title_all( bibin, info, reftype, p, all, nall );++	if ( status==BIBL_OK && p->verbose ) report( info );++	return status; } 
bibutils/biblatexin.h view
@@ -1,7 +1,7 @@ /*  * biblatexin.h  *- * Copyright (c) Chris Putnam 2008-2013+ * Copyright (c) Chris Putnam 2008-2014  *  * Source code released under the GPL version 2  *@@ -18,7 +18,7 @@  extern int  biblatexin_convertf( fields *bibin, fields *info, int reftype, param *p, variants *all, int nall ); extern int  biblatexin_processf( fields *bibin, char *data, char *filename, long nref );-extern void biblatexin_cleanf( bibl *bin, param *p );+extern int  biblatexin_cleanf( bibl *bin, param *p ); extern int  biblatexin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line, newstr *reference, int *fcharset ); extern int  biblatexin_typef( fields *bibin, char *filename, int nrefs,         param *p, variants *all, int nall );
bibutils/bibtexin.c view
@@ -1,1055 +1,1375 @@ /*  * bibtexin.c  *- * Copyright (c) Chris Putnam 2003-2013- *- * Program and source code released under the GPL version 2- *- */-#include <stdio.h>-#include <stdlib.h>-#include <string.h>-#include <ctype.h>-#include "is_ws.h"-#include "strsearch.h"-#include "newstr.h"-#include "newstr_conv.h"-#include "fields.h"-#include "list.h"-#include "name.h"-#include "title.h"-#include "reftypes.h"-#include "bibtexin.h"--static list find    = { 0, 0, 0, NULL };-static list replace = { 0, 0, 0, NULL };--void-bibtexin_initparams( param *p, const char *progname )-{-	p->readformat       = BIBL_BIBTEXIN;-	p->charsetin        = BIBL_CHARSET_DEFAULT;-	p->charsetin_src    = BIBL_SRC_DEFAULT;-	p->latexin          = 1;-	p->xmlin            = 0;-	p->utf8in           = 0;-	p->nosplittitle     = 0;-	p->verbose          = 0;-	p->addcount         = 0;-	p->output_raw       = 0;--	p->readf    = bibtexin_readf;-	p->processf = bibtexin_processf;-	p->cleanf   = bibtexin_cleanf;-	p->typef    = bibtexin_typef;-	p->convertf = bibtexin_convertf;-	p->all      = bibtex_all;-	p->nall     = bibtex_nall;--	list_init( &(p->asis) );-	list_init( &(p->corps) );--	if ( !progname ) p->progname = NULL;-	else p->progname = strdup( progname );-}--/*- * readf can "read too far", so we store this information in line, thus- * the next new text is in line, either from having read too far or- * from the next chunk obtained via newstr_fget()- *- * return 1 on success, 0 on error/end-of-file- *- */-static int-readmore( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line )-{-	if ( line->len ) return 1;-	else return newstr_fget( fp, buf, bufsize, bufpos, line );-}--/*- * readf()- *- * returns zero if cannot get reference and hit end of-file- * returns 1 if last reference in file, 2 if reference within file- */-int-bibtexin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line, newstr *reference, int *fcharset )-{-	int haveref = 0;-	char *p;-	*fcharset = CHARSET_UNKNOWN;-	while ( haveref!=2 && readmore( fp, buf, bufsize, bufpos, line ) ) {-		if ( line->len == 0 ) continue; /* blank line */-		p = &(line->data[0]);-		/* Recognize UTF8 BOM */-		if ( line->len > 2 && -				(unsigned char)(p[0])==0xEF &&-				(unsigned char)(p[1])==0xBB &&-				(unsigned char)(p[2])==0xBF ) {-			*fcharset = CHARSET_UNICODE;-			p += 3;-		}-		p = skip_ws( p );-		if ( *p == '%' ) { /* commented out line */-			newstr_empty( line );-			continue;-		}-		if ( *p == '@' ) haveref++;-		if ( haveref && haveref<2 ) {-			newstr_strcat( reference, p );-			newstr_addchar( reference, '\n' );-			newstr_empty( line );-		} else if ( !haveref ) newstr_empty( line );-	-	}-	return haveref;-}--static char *-bibtex_item( char *p, newstr *s )-{-	int surrounding_quotes = 0;-	int nbrackets = 0;-	int nquotes = 0;-	while ( *p ) {-		if ( !nquotes && !nbrackets ) {-			if ( *p==',' || *p=='=' || *p=='}' || *p==')' )-				goto out;-		}-		if ( *p=='\"' && *(p-1)!='\\' && nbrackets==0 ) {-			if ( s->len == 0 ) surrounding_quotes = 1;-			else {-				if ( !surrounding_quotes ) newstr_addchar( s, *p );-				if ( nquotes ) surrounding_quotes = 0;-			}-			nquotes = ( nquotes==0 );-		} else if ( *p=='{' ) {-			if ( nbrackets>0 || nquotes ) newstr_addchar( s, *p );-			nbrackets++;-		} else if ( *p=='}' ) {-			nbrackets--;-			if ( nbrackets>0 || nquotes ) newstr_addchar( s, *p );-		} else {-			if ( !is_ws( *p ) ) newstr_addchar( s, *p );-			else {-				if ( s->len!=0 && *p!='\n' && *p!='\r' )-					newstr_addchar( s, *p );-				else if ( s->len!=0 && (*p=='\n' || *p=='\r')) {-					newstr_addchar( s, ' ' );-					while ( is_ws( *(p+1) ) ) p++;-				}-			}-		}-		p++;-	}-out:-	newstr_trimendingws( s );-	return p;-}--static char *-process_bibtexline( char *p, newstr *tag, newstr *data )-{-	p = skip_ws( p );-	p = bibtex_item( p, tag );-	p = skip_ws( p );-	if ( *p=='=' ) {-		p++;-		p = skip_ws( p );-		p = bibtex_item( p, data );-		p = skip_ws( p );-	}-	if ( *p==',' || *p=='}' || *p==')' ) p++;-	p = skip_ws( p );-	return p;-}--static void-bibtex_process_tilde( newstr *s )-{-	char *p, *q;-	int n = 0;--	p = q = s->data;-	while ( *p ) {-		if ( *p=='~' ) {-			*q = ' ';-		} else if ( *p=='\\' && *(p+1)=='~' ) {-			n++;-			p++;-			*q = '~';-		} else {-			*q = *p;-		}-		p++;-		q++;-	}-	*q = '\0';-	s->len -= n;-}--static void-bibtex_cleantoken( newstr *s )-{-	/* 'textcomp' annotations */-	newstr_findreplace( s, "\\textit", "" );-	newstr_findreplace( s, "\\textbf", "" );-	newstr_findreplace( s, "\\textsl", "" );-	newstr_findreplace( s, "\\textsc", "" );-	newstr_findreplace( s, "\\textsf", "" );-	newstr_findreplace( s, "\\texttt", "" );-	newstr_findreplace( s, "\\textsubscript", "" );-	newstr_findreplace( s, "\\textsuperscript", "" );-	newstr_findreplace( s, "\\emph", "" );-	newstr_findreplace( s, "\\url", "" );-	newstr_findreplace( s, "\\mbox", "" );--	/* Other text annotations */-	newstr_findreplace( s, "\\it ", "" );-	newstr_findreplace( s, "\\em ", "" );--	newstr_findreplace( s, "\\%", "%" );-	newstr_findreplace( s, "\\$", "$" );-	newstr_findreplace( s, "{", "" );-	newstr_findreplace( s, "}", "" );-	while ( newstr_findreplace( s, "  ", " " ) ) {}--	/* 'textcomp' annotations that we don't want to substitute on output*/-	newstr_findreplace( s, "\\textdollar", "$" );-	newstr_findreplace( s, "\\textunderscore", "_" );--	bibtex_process_tilde( s );--}--static void-bibtex_addstring( char *p )-{-	newstr s1, s2;-	newstrs_init( &s1, &s2, NULL );-	p = skip_ws( p );-	if ( *p=='(' || *p=='{' ) p++;-	p = process_bibtexline( p, &s1, &s2 );-	newstr_findreplace( &s2, "\\ ", " " );-	bibtex_cleantoken( &s2 );-	if ( s1.data ) {-		list_add( &find, s1.data );-		if ( s2.data ) list_add( &replace, s2.data );-		else list_add( &replace, "" );-	}-	newstrs_free( &s1, &s2, NULL );-}--static int-bibtex_protected( newstr *data )-{-	if ( data->data[0]=='{' && data->data[data->len-1]=='}' ) return 1;-	if ( data->data[0]=='\"' && data->data[data->len-1]=='\"' ) return 1;-	return 0;-}--static void-bibtex_split( list *tokens, newstr *s )-{-	int i, n = s->len, nbrackets = 0;-	newstr currtok;--	newstr_init( &currtok );--	for ( i=0; i<n; ++i ) {-		if ( s->data[i]=='{' ) {-			nbrackets++;-			newstr_addchar( &currtok, '{' );-		} else if ( s->data[i]=='}' ) {-			nbrackets--;-			newstr_addchar( &currtok, '}' );-		} else if ( s->data[i]=='#' && !nbrackets ) {-			if ( currtok.len ) list_add( tokens, currtok.data );-			newstr_empty( &currtok );-		} else if ( !is_ws( s->data[i] ) || nbrackets ) {-			newstr_addchar( &currtok, s->data[i] );-		} else if ( is_ws( s->data[i] ) ) {-			if ( currtok.len ) list_add( tokens, currtok.data );-			newstr_empty( &currtok );-		}-	}-	if ( currtok.len ) list_add( tokens, currtok.data );-	for ( i=0; i<tokens->n; ++i ) {-		newstr_trimstartingws( list_get( tokens, i ) );-		newstr_trimendingws( list_get( tokens, i ) );-	}-	newstr_free( &currtok );-}--static int-bibtex_usestrings( newstr *s )-{-	char *p;-	int i;-	for ( i=0; i<find.n; ++i ) {-		p = list_getc( &find, i );-		if ( !strcasecmp( s->data, p ) ) {-			newstr_findreplace( s, p, list_getc( &replace, i ) );-			return 1;-		}-	}-	return 0;-}--/* get reference type */-static char*-process_bibtextype( char *p, newstr *data )-{-	newstr tmp;-	newstr_init( &tmp );--	newstr_empty( data );--	if ( *p=='@' ) p++; /* skip '@' character */-	while ( *p && *p!='{' && *p!='(' && !is_ws( *p ) ) newstr_addchar( &tmp, *p++ );-	p = skip_ws( p );-	if ( *p=='{' || *p=='(' ) p++;-	p = skip_ws( p );--	if ( tmp.len ) {-		/* add '{' and '}' to protect from string expansion */-		newstr_addchar( data, '{' );-		newstr_strcat( data, tmp.data );-		newstr_addchar( data, '}' );-	}-	newstr_free( &tmp );-	return p;-}-/* get reference name */-static char*-process_bibtexid( char *p, newstr *data )-{-	newstr tmp;-	char *start_p = p;-	newstr_init( &tmp );-	newstr_empty( data );--	while ( *p && *p!=',' ) newstr_addchar( &tmp, *p++ );-	if ( *p==',' ) p++;-	p = skip_ws( p ); /* skip ending newline/carriage return */--	if ( tmp.len ) {-		if ( strchr( tmp.data, '=' ) ) {-			/* Endnote writes bibtex files w/o fields, try to-			 * distinguish via presence of an equal sign.... if-			 * it's there, assume that it's a tag/data pair instead-			 * and roll back.-			 */-			p = start_p;-		} else {-			/* add '{' and '}' to protect from string expansion */-			newstr_addchar( data, '{' );-			newstr_strcat( data, tmp.data );-			newstr_addchar( data, '}' );-		}-	}--	newstr_free( &tmp );-	return p;-}--static void-process_cite( fields *bibin, char *p, char *filename, long nref )-{-	newstr tag, data;-	newstrs_init( &tag, &data, NULL );-	p = process_bibtextype( p, &data );-	if ( data.len ) fields_add( bibin, "INTERNAL_TYPE", data.data, 0 );-	if ( *p ) p = process_bibtexid ( p, &data );-	if ( data.len ) fields_add( bibin, "REFNUM", data.data, 0 );-	newstr_empty( &data );-	while ( *p ) {-		p = process_bibtexline( p, &tag, &data );-		/* no anonymous or empty fields allowed */-		if ( tag.len && data.len )-			fields_add( bibin, tag.data, data.data, 0 );-		newstrs_empty( &tag, &data, NULL );-	}-	newstrs_free( &tag, &data, NULL );-}--static void-process_string( char *p )-{-	while ( *p && *p!='{' && *p!='(' ) p++;-	bibtex_addstring( p );-}--int-bibtexin_processf( fields *bibin, char *data, char *filename, long nref )-{-	if ( !strncasecmp( data, "@STRING", 7 ) ) {-		process_string( data );-		return 0;-	} else if ( !strncasecmp( data, "@COMMENT", 8 ) ) {-		/* Not sure if these are real Bibtex, but not references */-		return 0;-	} else {-		process_cite( bibin, data, filename, nref );-		return 1;-	}-}--static void-bibtex_addtitleurl( fields *info, newstr *in )-{-	newstr s;-	char *p,*q;-	newstr_init( &s );-	q = p = in->data + 6; /*skip past \href{ */-	while ( *q && *q!='}' ) q++;-	newstr_segcpy( &s, p, q );-	fields_add( info, "URL", s.data, 0 );-	newstr_empty( &s );-	if ( *q=='}' ) q++;-	p = q;-	while ( *q ) q++;-	newstr_segcpy( &s, p, q );-	newstr_swapstrings( &s, in );-	newstr_free( &s );-}--static int-is_url_tag( newstr *tag )-{-	if ( tag->len ) {-		if ( !strcasecmp( tag->data, "url" ) ) return 1;-	}-	return 0;-}--static int-is_name_tag( newstr *tag )-{-	if ( tag->len ) {-		if ( !strcasecmp( tag->data, "author" ) ) return 1;-		if ( !strcasecmp( tag->data, "editor" ) ) return 1;-	}-	return 0;-}--static void-bibtex_cleandata( newstr *tag, newstr *s, fields *info, param *p )-{-	list tokens;-	newstr *tok;-	int i;-	if ( !s->len ) return;-	list_init( &tokens );-	bibtex_split( &tokens, s );-	for ( i=0; i<tokens.n; ++i ) {-		tok = list_get( &tokens, i );-		if ( !bibtex_protected( tok ) ) {-			bibtex_usestrings( tok );-		} else {-			if (!strncasecmp(tok->data,"\\href{", 6)) {-				bibtex_addtitleurl( info, tok );-			}-		}-		if ( p->latexin && !is_name_tag( tag ) && !is_url_tag( tag ) ) bibtex_cleantoken( tok );-	}-	newstr_empty( s );-	for ( i=0; i<tokens.n; ++i ) {-		tok = list_get( &tokens, i );-		if ( i>0 ) newstr_addchar( s, ' ' );-		newstr_newstrcat( s, tok );-	}-	list_free( &tokens );-}--static long-bibtexin_findref( bibl *bin, char *citekey )-{-	int n;-	long i;-	for ( i=0; i<bin->nrefs; ++i ) {-		n = fields_find( bin->ref[i], "refnum", -1 );-		if ( n==-1 ) continue;-		if ( !strcmp( bin->ref[i]->data[n].data, citekey ) ) return i;-	}-	return -1;-}--static void-bibtexin_nocrossref( bibl *bin, long i, int n, param *p )-{-	int n1 = fields_find( bin->ref[i], "REFNUM", -1 );-	if ( p->progname ) fprintf( stderr, "%s: ", p->progname );-	fprintf( stderr, "Cannot find cross-reference '%s'",-			bin->ref[i]->data[n].data );-	if ( n1!=-1 ) fprintf( stderr, " for reference '%s'\n",-			bin->ref[i]->data[n1].data );-	fprintf( stderr, "\n" );-}--static void-bibtexin_crossref( bibl *bin, param *p )-{-	char booktitle[] = "booktitle";-	long i, j, ncross;-	char *nt, *nd, *type;-	int n, ntype, nl;-        for ( i=0; i<bin->nrefs; ++i ) {-		n = fields_find( bin->ref[i], "CROSSREF", -1 );-		if ( n==-1 ) continue;-		ncross = bibtexin_findref( bin, bin->ref[i]->data[n].data );-		if ( ncross==-1 ) {-			bibtexin_nocrossref( bin, i, n, p );-			continue;-		}-		ntype = fields_find( bin->ref[i], "INTERNAL_TYPE", -1 );-		type = bin->ref[i]->data[ntype].data;-		fields_setused( bin->ref[i], n );-		for ( j=0; j<bin->ref[ncross]->n; ++j ) {-			nt = bin->ref[ncross]->tag[j].data;-			if ( !strcasecmp( nt, "INTERNAL_TYPE" ) ) continue;-			if ( !strcasecmp( nt, "REFNUM" ) ) continue;-			if ( !strcasecmp( nt, "TITLE" ) ) {-				if ( !strcasecmp( type, "Inproceedings" ) ||-				     !strcasecmp( type, "Incollection" ) )-					nt = booktitle;-			}-			nd = bin->ref[ncross]->data[j].data;-			nl = bin->ref[ncross]->level[j] + 1;-			fields_add( bin->ref[i], nt, nd, nl );--		}-	}-}--static void-bibtexin_cleanref( fields *bibin, param *p )-{-	newstr *t, *d;-	int i, n;-	n = fields_num( bibin );-	for ( i=0; i<n; ++i ) {-		t = fields_tag( bibin, i, FIELDS_STRP_NOUSE );-		d = fields_value( bibin, i, FIELDS_STRP_NOUSE );-		bibtex_cleandata( t, d, bibin, p );-	}-}--void-bibtexin_cleanf( bibl *bin, param *p )-{-	long i;-        for ( i=0; i<bin->nrefs; ++i )-		bibtexin_cleanref( bin->ref[i], p );-	bibtexin_crossref( bin, p );-}--static int-bibtex_matches_asis_corps( fields *info, char *tag, newstr *data, int level,-	list *asis, list *corps )-{-	newstr newtag;-	int i;-	for ( i=0; i<asis->n; ++i ) {-		if ( !strcmp( data->data, list_getc( asis, i ) ) ) {-			newstr_initstr( &newtag, tag );-			newstr_strcat( &newtag, ":ASIS" );-			fields_add( info, newtag.data, data->data, level );-			newstr_free( &newtag );-			return 1;-		}-	}-	for ( i=0; i<corps->n; ++i ) {-		if ( !strcmp( data->data, list_getc( corps, i ) ) ) {-			newstr_initstr( &newtag, tag );-			newstr_strcat( &newtag, ":CORP" );-			fields_add( info, newtag.data, data->data, level );-			newstr_free( &newtag );-			return 1;-		}-	}-	return 0;-}--/*- * bibtex_names( info, newtag, field, level);- *- * split names in author list separated by and's (use '|' character)- * and add names- */-static int-bibtex_names( fields *info, char *tag, newstr *data, int level, list *asis,-	list *corps )-{-	int begin, end, ok, n, etal, i, ret = 1;-	list tokens;--	/* If we match the asis or corps list add and bail. */-	if ( bibtex_matches_asis_corps( info, tag, data, level, asis, corps ) )-		return 1;--	list_init( &tokens );--	bibtex_split( &tokens, data );-	for ( i=0; i<tokens.n; ++i )-		bibtex_cleantoken( list_get( &tokens, i ) );--	etal = name_findetal( &tokens );--	begin = 0;-	n = tokens.n - etal;-	while ( begin < n ) {--		end = begin + 1;--		while ( end < n && strcasecmp( list_getc( &tokens, end ), "and" ) )-			end++;--		if ( end - begin == 1 ) {-			ok = name_addsingleelement( info, tag, list_getc( &tokens, begin ), level, 0 );-			if ( !ok ) { ret = 0; goto out; }-		} else {-			ok = name_addmultielement( info, tag, &tokens, begin, end, level );-			if ( !ok ) { ret = 0; goto out; }-		}--		begin = end + 1;--		/* Handle repeated 'and' errors like: authors="G. F. Author and and B. K. Author" */-		while ( begin < n && !strcasecmp( list_getc( &tokens, begin ), "and" ) )-			begin++;-	}--	if ( etal ) {-		ret = name_addsingleelement( info, tag, "et al.", level, 0 );-	}--out:-	list_free( &tokens );-	return ret;-}--/* is_utf8_emdash()- *- * Internally pages="A---B" will convert --- to a UTF8- * emdash = 0xE2 (-30) 0x80 (-128) 0x94 (-108)- */-static int-is_utf8_emdash( char *p )-{-	static char emdash[3] = { -30, -128, -108 };-	if ( strncmp( p, emdash, 3 ) ) return 0;-	return 1;-}-/* is_utf8_endash()- *- * Internally pages="A--B" will convert -- to a UTF8- * endash = 0xE2 (-30) 0x80 (-128) 0x93 (-109)- */-static int-is_utf8_endash( char *p )-{-	static char endash[3] = { -30, -128, -109 };-	if ( strncmp( p, endash, 3 ) ) return 0;-	return 1;-}--static int-process_pages( fields *info, newstr *s, int level )-{-	newstr page;-	char *p;-	int ok;--	newstr_findreplace( s, " ", "" );-	if ( s->len==0 ) return 1;--	newstr_init( &page );-	p = skip_ws( s->data );-	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' && *p!=-30 )-		newstr_addchar( &page, *p++ );-	if ( page.len>0 ) {-		ok = fields_add( info, "PAGESTART", page.data, level );-		if ( !ok ) return 0;-	}--	while ( *p && (is_ws(*p) || *p=='-' ) ) p++;-	if ( *p && is_utf8_emdash( p ) ) p+=3;-	if ( *p && is_utf8_endash( p ) ) p+=3;--	newstr_empty( &page );-	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' )-		newstr_addchar( &page, *p++ );-	if ( page.len>0 ) {-		ok = fields_add( info, "PAGEEND", page.data, level );-		if ( !ok ) return 0;-	}--	newstr_free( &page );-	return 1;-}--static int-process_urlcore( fields *info, newstr *d, int level, char *default_tag )-{-	char *p = d->data;-	if ( !strncasecmp( p, "\\urllink", 8 ) )-		return fields_add( info, "URL", p+8, level );-	else if ( !strncasecmp( p, "\\url", 4 ) )-		return fields_add( info, "URL", p+4, level );-	else if ( !strncasecmp( p, "arXiv:", 6 ) )-		return fields_add( info, "ARXIV", p+6, level );-	else if ( !strncasecmp( p, "http://arxiv.org/abs/", 21 ) )-		return fields_add( info, "ARXIV", p+21, level );-	else if ( !strncasecmp( p, "http:", 5 ) )-		return fields_add( info, "URL", p, level );-	else return fields_add( info, default_tag, p, level );-}--static int-process_url( fields *info, newstr *d, int level )-{-	return process_urlcore( info, d, level, "URL" );-}--/* Split keywords="" with semicolons.- * Commas are also frequently used, but will break- * entries like:- *       keywords="Microscopy, Confocal"- */-static int-process_keywords( fields *info, newstr *d, int level )-{-	newstr keyword;-	char *p;-	int ok;--	if ( !d || d->len==0 ) return 1;--	p = d->data;-	newstr_init( &keyword );--	while ( *p ) {-		p = skip_ws( p );-		while ( *p && *p!=';' ) newstr_addchar( &keyword, *p++ );-		newstr_trimendingws( &keyword );-		if ( keyword.len ) {-			ok = fields_add( info, "KEYWORD", keyword.data, level );-			if ( !ok ) return 0;-			newstr_empty( &keyword );-		}-		if ( *p==';' ) p++;-	}-	newstr_free( &keyword );-	return 1;-}--/* proces_howpublished()- *- *    howpublished={},- *- * Normally indicates the manner in which something was- * published in lieu of a formal publisher, so typically- * 'howpublished' and 'publisher' will never be in the- * same reference.- *- * Occassionally, people put Diploma thesis information- * into the field, so check that first.- */-static int-process_howpublished( fields *info, newstr *d, int level )-{-	char *p = d->data;-	if ( !strncasecmp( p, "Diplom", 6 ) )-		return fields_replace_or_add( info, "GENRE", "Diploma thesis", level );-	else if ( !strncasecmp( p, "Habilitation", 13 ) )-		return fields_replace_or_add( info, "GENRE", "Habilitation thesis", level );-	else if ( !strncasecmp( d->data, "http:", 5 ) )-		return process_url( info, d, level );-	else if ( !strncasecmp( d->data, "arXiv:", 6 ) )-		return process_url( info, d, level );-	else -		return fields_add( info, "PUBLISHER", p, level );-}--/*- * sentelink = {file://localhost/full/path/to/file.pdf,Sente,PDF}- */-static int-process_sente( fields *info, newstr *d, int level )-{-	int ret = 1;-	newstr link;-	char *p = d->data;-	newstr_init( &link );-	while ( *p && *p!=',' ) newstr_addchar( &link, *p++ );-	newstr_trimstartingws( &link );-	newstr_trimendingws( &link );-	if ( link.len ) ret = fields_add( info, "FILEATTACH", link.data, level );-	newstr_free( &link );-	return ret;-}--/*- * BibTeX uses 'organization' in lieu of publisher if that field is missing.- * Otherwise output as- * <name type="corporate">- *    <namePart>The organization</namePart>- *    <role>- *       <roleTerm authority="marcrelator" type="text">organizer of meeting</roleTerm>- *    </role>- * </name>- */-static int-process_organization( fields *bibin, fields *info, newstr *d, int level )-{-	int n;-	n = fields_find( bibin, "publisher", LEVEL_ANY );-	if ( n==-1 )-		return fields_add( info, "PUBLISHER", d->data, level );-	else-		return fields_add( info, "ORGANIZER:CORP", d->data, level );-}--static int-count_colons( char *p )-{-	int n = 0;-	while ( *p ) {-		if ( *p==':' ) n++;-		p++;-	}-	return n;-}--static int-first_colon( char *p )-{-	int n = 0;-	while ( p[n] && p[n]!=':' ) n++;-	return n;-}--static int-last_colon( char *p )-{-	int n = strlen( p ) - 1;-	while ( n>0 && p[n]!=':' ) n--;-	return n;-}--/*- * file={Description:/full/path/to/file.pdf:PDF}- */-static int-process_file( fields *info, newstr *d, int level )-{-	char *p = d->data;-	newstr link;-	int i, n, n1, n2, ret = 1;--	n = count_colons( p );-	if ( n > 1 ) {-		/* A DOS file can contain a colon ":C:/....pdf:PDF" */-		/* Extract after 1st and up to last colons */-		n1 = first_colon( p ) + 1;-		n2 = last_colon( p );-		newstr_init( &link );-		for ( i=n1; i<n2; ++i ) {-			newstr_addchar( &link, p[i] );-		}-		newstr_trimstartingws( &link );-		newstr_trimendingws( &link );-		if ( link.len ) ret = fields_add( info, "FILEATTACH", link.data, level );-		newstr_free( &link );-	} else {-		/* This field isn't formatted properly, so just copy directly */-		ret = fields_add( info, "FILEATTACH", p, level );-	}-	return ret;-}--static int-process_note( fields *info, newstr *d, int level )-{-	if ( !strncasecmp( d->data, "http:", 5 ) ||-	     !strncasecmp( d->data, "arXiv:", 6 ) ) {-		return process_url( info, d, level );-	} else {-		return fields_add( info, "NOTES", d->data, level );-	}-}--int-bibtexin_typef( fields *bibin, char *filename, int nrefs, param *p,-		variants *all, int nall )-{-	char *refnum = "";-	int reftype, n, nrefnum;-	n = fields_find( bibin, "INTERNAL_TYPE", 0 );-	nrefnum = fields_find( bibin, "REFNUM", 0 );-	if ( nrefnum!=-1 ) refnum = (bibin->data[nrefnum]).data;-	if ( n!=-1 )-		/* figure out type */-		reftype = get_reftype( (bibin->data[n]).data, nrefs,-			p->progname, all, nall, refnum );-	else-		/* no type info, go for default */-		reftype = get_reftype( "", nrefs, p->progname, all, nall, refnum );-	return reftype;-}--static void-bibtexin_notag( param *p, char *tag )-{-	if ( p->verbose && strcmp( tag, "INTERNAL_TYPE" ) ) {-		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );-		fprintf( stderr, "Cannot find tag '%s'\n", tag );-	}-}--/* bibtexin_titleinbook_isbooktitle()- *- * Normally, the title field of inbook refers to the book.  The- * section in a @inbook reference is untitled.  If it's titled,- * the @incollection should be used.  For example, in:- *- * @inbook{- *    title="xxx"- * }- *- * the booktitle is "xxx".- *- * However, @inbook is frequently abused (and treated like- * @incollection) so that title and booktitle are present- * and title is now 'supposed' to refer to the section.  For example:- *- * @inbook{- *     title="yyy",- *     booktitle="xxx"- * }- *- * Therefore report whether or not booktitle is present as well- * as title in @inbook references.  If not, then make 'title'- * correspond to the title of the book, not the section.- *- */-static int-bibtexin_titleinbook_isbooktitle( char *intag, fields *bibin )-{-	int n;--	/* ...look only at 'title="xxx"' elements */-	if ( strcasecmp( intag, "TITLE" ) ) return 0;--	/* ...look only at '@inbook' references */-	n = fields_find( bibin, "INTERNAL_TYPE", -1 );-	if ( n==-1 ) return 0;-	if ( strcasecmp( fields_value( bibin, n, FIELDS_CHRP ), "INBOOK" ) ) return 0;--	/* ...look to see if 'booktitle="yyy"' exists */-	n = fields_find( bibin, "BOOKTITLE", -1 );-	if ( n==-1 ) return 0;-	else return 1;-}-static int-bibtexin_title_process( fields *info, char *outtag, fields *bibin, newstr *t, newstr *d, int level, int nosplittitle )-{-	char *intag = t->data;-	char *indata = d->data;-	if ( bibtexin_titleinbook_isbooktitle( intag, bibin ) ) level=LEVEL_MAIN;-	title_process( info, outtag, indata, level, nosplittitle );-	return 1;-}-static int-bibtex_simple( fields *info, char *outtag, newstr *d, int level )-{-	return fields_add( info, outtag, d->data, level );-}--int-bibtexin_convertf( fields *bibin, fields *info, int reftype, param *p,-		variants *all, int nall )-{-	int process, level, i, n, nfields, ok;-	newstr *t, *d;-	char *outtag;--	nfields = fields_num( bibin );-	for ( i=0; i<nfields; ++i ) {--		if ( fields_used( bibin, i ) ) continue; /* e.g. successful crossref */-		if ( fields_nodata( bibin, i ) ) continue;--		t = fields_tag( bibin, i, FIELDS_STRP );-		if ( t->len == 0 ) continue; /* Don't consider with null tags */-		n = process_findoldtag( t->data, reftype, all, nall );-		if ( n==-1 ) {-			bibtexin_notag( p, t->data );-			continue;-		}--		d = fields_value( bibin, i, FIELDS_STRP );--		process = ((all[reftype]).tags[n]).processingtype;-		level   = ((all[reftype]).tags[n]).level;-		outtag  = ((all[reftype]).tags[n]).newstr;--		switch( process ) {--		case SIMPLE:-			ok = bibtex_simple( info, outtag, d, level );-			break;--		case TITLE:-			ok = bibtexin_title_process( info, "TITLE", bibin, t, d, level, p->nosplittitle );-			break;--		case PERSON:-			ok = bibtex_names( info, outtag, d, level, &(p->asis), &(p->corps) );-			break;--		case PAGES:-			ok = process_pages( info, d, level );-			break;--		case KEYWORD:-			ok = process_keywords( info, d, level );-			break;--		case HOWPUBLISHED:-			ok = process_howpublished( info, d, level );-			break;--		case LINKEDFILE:-			ok = process_file( info, d, level );-			break;--		case BT_NOTE:-			ok = process_note( info, d, level );-			break;--		case BT_SENTE:-			ok = process_sente( info, d, level );-			break;--		case BT_URL:-			ok = process_url( info, d, level );-			break;--		case BT_ORG:-			ok = process_organization( bibin, info, d, level );-			break;--		default:-			ok = 1;-			break;-		}--		if ( !ok ) return BIBL_ERR_MEMERR;-	}-	return BIBL_OK;+ * Copyright (c) Chris Putnam 2003-2014+ *+ * Program and source code released under the GPL version 2+ *+ */+#include <stdio.h>+#include <stdlib.h>+#include <string.h>+#include <ctype.h>+#include "is_ws.h"+#include "strsearch.h"+#include "newstr.h"+#include "newstr_conv.h"+#include "fields.h"+#include "list.h"+#include "name.h"+#include "title.h"+#include "reftypes.h"+#include "bibtexin.h"++static list find    = { 0, 0, NULL, 0 };+static list replace = { 0, 0, NULL, 0 };++extern const char progname[];++/*****************************************************+ PUBLIC: void bibtexin_initparams()+*****************************************************/+void+bibtexin_initparams( param *p, const char *progname )+{+	p->readformat       = BIBL_BIBTEXIN;+	p->charsetin        = BIBL_CHARSET_DEFAULT;+	p->charsetin_src    = BIBL_SRC_DEFAULT;+	p->latexin          = 1;+	p->xmlin            = 0;+	p->utf8in           = 0;+	p->nosplittitle     = 0;+	p->verbose          = 0;+	p->addcount         = 0;+	p->output_raw       = 0;++	p->readf    = bibtexin_readf;+	p->processf = bibtexin_processf;+	p->cleanf   = bibtexin_cleanf;+	p->typef    = bibtexin_typef;+	p->convertf = bibtexin_convertf;+	p->all      = bibtex_all;+	p->nall     = bibtex_nall;++	list_init( &(p->asis) );+	list_init( &(p->corps) );++	if ( !progname ) p->progname = NULL;+	else p->progname = strdup( progname );+}++/*****************************************************+ PUBLIC: int bibtexin_readf()+*****************************************************/++/*+ * readf can "read too far", so we store this information in line, thus+ * the next new text is in line, either from having read too far or+ * from the next chunk obtained via newstr_fget()+ *+ * return 1 on success, 0 on error/end-of-file+ *+ */+static int+readmore( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line )+{+	if ( line->len ) return 1;+	else return newstr_fget( fp, buf, bufsize, bufpos, line );+}++/*+ * readf()+ *+ * returns zero if cannot get reference and hit end of-file+ * returns 1 if last reference in file, 2 if reference within file+ */+int+bibtexin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line, newstr *reference, int *fcharset )+{+	int haveref = 0;+	char *p;+	*fcharset = CHARSET_UNKNOWN;+	while ( haveref!=2 && readmore( fp, buf, bufsize, bufpos, line ) ) {+		if ( line->len == 0 ) continue; /* blank line */+		p = &(line->data[0]);+		/* Recognize UTF8 BOM */+		if ( line->len > 2 && +				(unsigned char)(p[0])==0xEF &&+				(unsigned char)(p[1])==0xBB &&+				(unsigned char)(p[2])==0xBF ) {+			*fcharset = CHARSET_UNICODE;+			p += 3;+		}+		p = skip_ws( p );+		if ( *p == '%' ) { /* commented out line */+			newstr_empty( line );+			continue;+		}+		if ( *p == '@' ) haveref++;+		if ( haveref && haveref<2 ) {+			newstr_strcat( reference, p );+			newstr_addchar( reference, '\n' );+			newstr_empty( line );+		} else if ( !haveref ) newstr_empty( line );+	+	}+	return haveref;+}++/*****************************************************+ PUBLIC: int bibtexin_processf()+*****************************************************/++static char*+process_bibtextype( char *p, newstr *type )+{+	newstr tmp;+	newstr_init( &tmp );++	if ( *p=='@' ) p++;+	p = newstr_cpytodelim( &tmp, p, "{( \t\r\n", 0 );+	p = skip_ws( p );+	if ( *p=='{' || *p=='(' ) p++;+	p = skip_ws( p );++	if ( tmp.len ) newstr_strcpy( type, tmp.data );+	else newstr_empty( type );++	newstr_free( &tmp );+	return p;+}++static char*+process_bibtexid( char *p, newstr *id )+{+	char *start_p = p;+	newstr tmp;++	newstr_init( &tmp );+	p = newstr_cpytodelim( &tmp, p, ",", 1 );++	if ( tmp.len ) {+		if ( strchr( tmp.data, '=' ) ) {+			/* Endnote writes bibtex files w/o fields, try to+			 * distinguish via presence of an equal sign.... if+			 * it's there, assume that it's a tag/data pair instead+			 * and roll back.+			 */+			p = start_p;+			newstr_empty( id );+		} else {+			newstr_strcpy( id, tmp.data );+		}+	} else {+		newstr_empty( id );+	}++	newstr_free( &tmp );+	return skip_ws( p );+}++static char *+bibtex_tag( char *p, newstr *tag )+{+	p = newstr_cpytodelim( tag, skip_ws( p ), "= \t\r\n", 0 );+	if ( newstr_memerr( tag ) ) return NULL;+	return skip_ws( p );+}++static char *+bibtex_data( char *p, fields *bibin, list *tokens )+{+	unsigned int nbracket = 0, nquotes = 0;+	char *startp = p;+	newstr tok, *t;++	newstr_init( &tok );+	while ( p && *p ) {+		if ( !nquotes && !nbracket ) {+			if ( *p==',' || *p=='=' || *p=='}' || *p==')' )+				goto out;+		}+		if ( *p=='\"' && nbracket==0 && ( p==startp || *(p-1)!='\\' ) ) {+			nquotes = !nquotes;+			newstr_addchar( &tok, *p );+			if ( !nquotes ) {+				if ( newstr_memerr( &tok ) ) { p=NULL; goto out; }+				t = list_add( tokens, &tok );+				if ( !t ) { p=NULL; goto out0; }+				newstr_empty( &tok );+			}+		} else if ( *p=='#' && !nquotes && !nbracket ) {+			if ( tok.len ) {+				if ( newstr_memerr( &tok ) ) { p=NULL; goto out; }+				t = list_add( tokens, &tok );+				if ( !t ) { p=NULL; goto out0; }+			}+			newstr_strcpy( &tok, "#" );+			t = list_add( tokens, &tok );+			if ( !t ) { p=NULL; goto out0; }+			newstr_empty( &tok );+		} else if ( *p=='{' && !nquotes && ( p==startp || *(p-1)!='\\' ) ) {+			nbracket++;+			newstr_addchar( &tok, *p );+		} else if ( *p=='}' && !nquotes && ( p==startp || *(p-1)!='\\' ) ) {+			nbracket--;+			newstr_addchar( &tok, *p );+			if ( nbracket==0 ) {+				if ( newstr_memerr( &tok ) ) { p=NULL; goto out; }+				t = list_add( tokens, &tok );+				if ( !t ) { p=NULL; goto out; }+				newstr_empty( &tok );+			}+		} else if ( !is_ws( *p ) || nquotes || nbracket ) {+			if ( !is_ws( *p ) ) newstr_addchar( &tok, *p );+			else {+				if ( tok.len!=0 && *p!='\n' && *p!='\r' )+					newstr_addchar( &tok, *p );+				else if ( tok.len!=0 && (*p=='\n' || *p=='\r')) {+					newstr_addchar( &tok, ' ' );+					while ( is_ws( *(p+1) ) ) p++;+				}+			}+		} else if ( is_ws( *p ) ) {+			if ( tok.len ) {+				if ( newstr_memerr( &tok ) ) { p=NULL; goto out; }+				t = list_add( tokens, &tok );+				if ( !t ) { p=NULL; goto out; }+				newstr_empty( &tok );+			}+		}+		p++;+	}+out:+	if ( nbracket!=0 ) {+		fprintf( stderr, "%s: Mismatch in number of brackets in reference.\n", progname );+	}+	if ( nquotes!=0 ) {+		fprintf( stderr, "%s: Mismatch in number of quotes in reference.\n", progname );+	}+	if ( tok.len ) {+		if ( newstr_memerr( &tok ) ) { p = NULL; goto out; }+		t = list_add( tokens, &tok );+		if ( !t ) p = NULL;+	}+out0:+	newstr_free( &tok );+	return p;+}++/* replace_strings()+ *+ * do string replacement -- only if unprotected by quotation marks or curly brackets+ */+static void+replace_strings( list *tokens, fields *bibin )+{+	int i, n, ok;+	newstr *s;+	char *q;+	i = 0;+	while ( i < tokens->n ) {+		s = list_get( tokens, i );+		if ( !strcmp( s->data, "#" ) ) {+		} else if ( s->data[0]!='\"' && s->data[0]!='{' ) {+			n = list_find( &find, s->data );+			if ( n!=-1 ) {+				newstr_newstrcpy( s, list_get( &replace, n ) );+			} else {+				q = s->data;+				ok = 1;+				while ( *q && ok ) {+					if ( !isdigit( *q ) ) ok = 0;+					q++;+				}+				if ( !ok ) {+					fprintf( stderr, "%s: Warning: Non-numeric "+					   "BibTeX elements should be in quotations or "+					   "curly brackets in reference.\n", progname );+				}+			}+		}+		i++;+	}+}++static int+string_concatenate( list *tokens, fields *bibin )+{+	newstr *s, *t;+	int i, status;+	i = 0;+	while ( i < tokens->n ) {+		s = list_get( tokens, i );+		if ( !strcmp( s->data, "#" ) ) {+			if ( i==0 || i==tokens->n-1 ) {+				fprintf( stderr, "%s: Warning: Stray string concatenation "+					"('#' character) in reference\n", progname );+				status = list_remove( tokens, i );+				if ( status!=LIST_OK ) return BIBL_ERR_MEMERR;+				continue;+			}+			s = list_get( tokens, i-1 );+			if ( s->data[0]!='\"' && s->data[s->len-1]!='\"' )+				fprintf( stderr, "%s: Warning: String concentation should "+					"be used in context of quotations marks.\n", progname );+			t = list_get( tokens, i+1 );+			if ( t->data[0]!='\"' && t->data[s->len-1]!='\"' )+				fprintf( stderr, "%s: Warning: String concentation should "+					"be used in context of quotations marks.\n", progname );+			if ( ( s->data[s->len-1]=='\"' && t->data[0]=='\"') || (s->data[s->len-1]=='}' && t->data[0]=='{') ) {+				newstr_trimend( s, 1 );+				newstr_trimbegin( t, 1 );+				newstr_newstrcat( s, t );+			} else {+				newstr_newstrcat( s, t );+			}+			status = list_remove( tokens, i );+			if ( status!=LIST_OK ) return BIBL_ERR_MEMERR;+			status = list_remove( tokens, i );+			if ( status!=LIST_OK ) return BIBL_ERR_MEMERR;+		} else i++;+	}+	return BIBL_OK;+}++/* return NULL on memory error */+static char *+process_bibtexline( char *p, newstr *tag, newstr *data, uchar stripquotes, fields *bibin )+{+	int i, status;+	list tokens;+	newstr *s;++	newstr_empty( data );++	p = bibtex_tag( p, tag );+	if ( p==NULL || tag->len==0 ) return p;++	list_init( &tokens );++	if ( *p=='=' ) {+		p = bibtex_data( p+1, bibin, &tokens );+		if ( p==NULL ) goto out;+	}++	replace_strings( &tokens, bibin );++	status = string_concatenate( &tokens, bibin );+	if ( status!=BIBL_OK ) {+		p = NULL;+		goto out;+	}++	for ( i=0; i<tokens.n; i++ ) {+		s = list_get( &tokens, i );+		if ( ( stripquotes && s->data[0]=='\"' && s->data[s->len-1]=='\"' ) ||+		     ( s->data[0]=='{' && s->data[s->len-1]=='}' ) ) {+			newstr_trimbegin( s, 1 );+			newstr_trimend( s, 1 );+		}+		newstr_newstrcat( data, list_get( &tokens, i ) );+	}+out:+	list_free( &tokens );+	return p;+}++/* process_cite()+ *+ */+static int+process_cite( fields *bibin, char *p, char *filename, long nref )+{+	int fstatus, status = BIBL_OK;+	newstr tag, data;++	newstrs_init( &tag, &data, NULL );++	p = process_bibtextype( p, &data );+	if ( data.len ) {+		fstatus = fields_add( bibin, "INTERNAL_TYPE", data.data, 0 );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+	}++	p = process_bibtexid( p, &data );+	if ( data.len ) {+		fstatus = fields_add( bibin, "REFNUM", data.data, 0 );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+	}++	while ( *p ) {+		p = process_bibtexline( p, &tag, &data, 1, bibin );+		if ( p==NULL ) { status = BIBL_ERR_MEMERR; goto out; }+		/* no anonymous or empty fields allowed */+		if ( tag.len && data.len ) {+			fstatus = fields_add( bibin, tag.data, data.data, 0 );+			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+		}+		newstrs_empty( &tag, &data, NULL );+	}+out:+	newstrs_free( &tag, &data, NULL );+	return status;+}++/* process_string()+ *+ * Handle lines like:+ *+ * '@STRING{TL = {Tetrahedron Lett.}}'+ *+ * p should point to just after '@STRING'+ *+ * In BibTeX, if a string is defined several times, the last one is kept.+ *+ */+static int+process_string( char *p )+{+	int n, status = BIBL_OK;+	newstr s1, s2, *t;+	newstrs_init( &s1, &s2, NULL );+	while ( *p && *p!='{' && *p!='(' ) p++;+	if ( *p=='{' || *p=='(' ) p++;+	p = process_bibtexline( skip_ws( p ), &s1, &s2, 0, NULL );+	if ( p==NULL ) { status = BIBL_ERR_MEMERR; goto out; }+	if ( s2.data ) {+		newstr_findreplace( &s2, "\\ ", " " );+	}+	if ( s1.data ) {+		n = list_find( &find, s1.data );+		if ( n==-1 ) {+			t = list_add( &find, &s1 );+			if ( t==NULL ) { status = BIBL_ERR_MEMERR; goto out; }+			if ( s2.data ) t = list_add( &replace, &s2 );+			else t = list_addc( &replace, "" );+			if ( t==NULL ) { status = BIBL_ERR_MEMERR; goto out; }+		} else {+			if ( s2.data ) t = list_set( &replace, n, &s2 );+			else t = list_setc( &replace, n, "" );+			if ( t==NULL ) { status = BIBL_ERR_MEMERR; goto out; }+		}+	}+out:+	newstrs_free( &s1, &s2, NULL );+	return status;+}++/* bibtexin_processf()+ *+ * Handle '@STRING', '@reftype', and ignore '@COMMENT'+ */+int+bibtexin_processf( fields *bibin, char *data, char *filename, long nref )+{+	if ( !strncasecmp( data, "@STRING", 7 ) ) {+		process_string( data+7 );+		return 0;+	} else if ( !strncasecmp( data, "@COMMENT", 8 ) ) {+		/* Not sure if these are real Bibtex, but not references */+		return 0;+	} else {+		process_cite( bibin, data, filename, nref );+		return 1;+	}+}++/*****************************************************+ PUBLIC: void bibtexin_cleanf()+*****************************************************/++static int+bibtex_protected( newstr *data )+{+	if ( data->data[0]=='{' && data->data[data->len-1]=='}' ) return 1;+	if ( data->data[0]=='\"' && data->data[data->len-1]=='\"' ) return 1;+	return 0;+}++static int+bibtex_split( list *tokens, newstr *s )+{+	int i, n = s->len, nbrackets = 0, status = BIBL_OK;+	newstr tok, *t;++	newstr_init( &tok );++	for ( i=0; i<n; ++i ) {+		if ( s->data[i]=='{' && ( i==0 || s->data[i-1]!='\\' ) ) {+			nbrackets++;+			newstr_addchar( &tok, '{' );+		} else if ( s->data[i]=='}' && ( i==0 || s->data[i-1]!='\\' ) ) {+			nbrackets--;+			newstr_addchar( &tok, '}' );+		} else if ( !is_ws( s->data[i] ) || nbrackets ) {+			newstr_addchar( &tok, s->data[i] );+		} else if ( is_ws( s->data[i] ) ) {+			if ( tok.len ) {+				t = list_add( tokens, &tok );+				if ( !t ) {+					status = BIBL_ERR_MEMERR;+					goto out;+				}+			}+			newstr_empty( &tok );+		}+	}+	if ( tok.len ) {+		t = list_add( tokens, &tok );+		if ( !t ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		}+	}++	for ( i=0; i<tokens->n; ++i ) {+		newstr_trimstartingws( list_get( tokens, i ) );+		newstr_trimendingws( list_get( tokens, i ) );+	}+out:+	newstr_free( &tok );+	return status;+}++static int+bibtex_addtitleurl( fields *info, newstr *in )+{+	int fstatus, status = BIBL_OK;+	newstr s;+	char *p;++	newstr_init( &s );++	/* ...skip past "\href{" and copy to "}" */+	p = newstr_cpytodelim( &s, in->data + 6, "}", 1 );+	if ( newstr_memerr( &s ) ) { status = BIBL_ERR_MEMERR; goto out; }++	/* ...add to URL */+	fstatus = fields_add( info, "URL", s.data, 0 );+	if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }++	/* ...return deleted fragment to newstr in */+	p = newstr_cpytodelim( &s, p, "", 0 );+	if ( newstr_memerr( &s ) ) { status = BIBL_ERR_MEMERR; goto out; }+	newstr_swapstrings( &s, in );++out:+	newstr_free( &s );+	return status;+}++static int+is_url_tag( newstr *tag )+{+	if ( tag->len ) {+		if ( !strcasecmp( tag->data, "url" ) ) return 1;+	}+	return 0;+}++static int+is_name_tag( newstr *tag )+{+	if ( tag->len ) {+		if ( !strcasecmp( tag->data, "author" ) ) return 1;+		if ( !strcasecmp( tag->data, "editor" ) ) return 1;+	}+	return 0;+}++static void+bibtex_process_tilde( newstr *s )+{+	char *p, *q;+	int n = 0;++	p = q = s->data;+	if ( !p ) return;+	while ( *p ) {+		if ( *p=='~' ) {+			*q = ' ';+		} else if ( *p=='\\' && *(p+1)=='~' ) {+			n++;+			p++;+			*q = '~';+		} else {+			*q = *p;+		}+		p++;+		q++;+	}+	*q = '\0';+	s->len -= n;+}++static void+bibtex_process_bracket( newstr *s )+{+	char *p, *q;+	int n = 0;++	p = q = s->data;+	if ( !p ) return;+	while ( *p ) {+		if ( *p=='\\' && ( *(p+1)=='{' || *(p+1)=='}' ) ) {+			n++;+			p++;+			*q = *p;+			q++;+		} else if ( *p=='{' || *p=='}' ) {+			n++;+		} else {+			*q = *p;+			q++;+		}+		p++;+	}+	*q = '\0';+	s->len -= n;+}++static void+bibtex_cleantoken( newstr *s )+{+	/* 'textcomp' annotations */+	newstr_findreplace( s, "\\textit", "" );+	newstr_findreplace( s, "\\textbf", "" );+	newstr_findreplace( s, "\\textsl", "" );+	newstr_findreplace( s, "\\textsc", "" );+	newstr_findreplace( s, "\\textsf", "" );+	newstr_findreplace( s, "\\texttt", "" );+	newstr_findreplace( s, "\\textsubscript", "" );+	newstr_findreplace( s, "\\textsuperscript", "" );+	newstr_findreplace( s, "\\emph", "" );+	newstr_findreplace( s, "\\url", "" );+	newstr_findreplace( s, "\\mbox", "" );++	/* Other text annotations */+	newstr_findreplace( s, "\\it ", "" );+	newstr_findreplace( s, "\\em ", "" );++	newstr_findreplace( s, "\\%", "%" );+	newstr_findreplace( s, "\\$", "$" );+	while ( newstr_findreplace( s, "  ", " " ) ) {}++	/* 'textcomp' annotations that we don't want to substitute on output*/+	newstr_findreplace( s, "\\textdollar", "$" );+	newstr_findreplace( s, "\\textunderscore", "_" );++	bibtex_process_bracket( s );+	bibtex_process_tilde( s );++}++static int+bibtex_cleandata( newstr *tag, newstr *s, fields *info, param *p )+{+	int i, status;+	list tokens;+	newstr *tok;+	if ( !s->len ) return BIBL_OK;+	/* protect url from undergoing any parsing */+	if ( is_url_tag( tag ) ) return BIBL_OK;+	list_init( &tokens );+	status = bibtex_split( &tokens, s );+	if ( status!=BIBL_OK ) goto out;+	for ( i=0; i<tokens.n; ++i ) {+		tok = list_get( &tokens, i );+		if ( bibtex_protected( tok ) ) {+			if (!strncasecmp(tok->data,"\\href{", 6)) {+				bibtex_addtitleurl( info, tok );+			}+		}+		if ( p->latexin && !is_name_tag( tag ) && !is_url_tag( tag ) )+			bibtex_cleantoken( tok );+	}+	newstr_empty( s );+	for ( i=0; i<tokens.n; ++i ) {+		tok = list_get( &tokens, i );+		if ( i>0 ) newstr_addchar( s, ' ' );+		newstr_newstrcat( s, tok );+	}+out:+	list_free( &tokens );+	return status;+}++static int+bibtexin_cleanref( fields *bibin, param *p )+{+	int i, n, status;+	newstr *t, *d;+	n = fields_num( bibin );+	for ( i=0; i<n; ++i ) {+		t = fields_tag( bibin, i, FIELDS_STRP_NOUSE );+		d = fields_value( bibin, i, FIELDS_STRP_NOUSE );+		status = bibtex_cleandata( t, d, bibin, p );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK;+}++static long+bibtexin_findref( bibl *bin, char *citekey )+{+	int n;+	long i;+	for ( i=0; i<bin->nrefs; ++i ) {+		n = fields_find( bin->ref[i], "refnum", -1 );+		if ( n==-1 ) continue;+		if ( !strcmp( bin->ref[i]->data[n].data, citekey ) ) return i;+	}+	return -1;+}++static void+bibtexin_nocrossref( bibl *bin, long i, int n, param *p )+{+	int n1 = fields_find( bin->ref[i], "REFNUM", -1 );+	if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+	fprintf( stderr, "Cannot find cross-reference '%s'",+			bin->ref[i]->data[n].data );+	if ( n1!=-1 ) fprintf( stderr, " for reference '%s'\n",+			bin->ref[i]->data[n1].data );+	fprintf( stderr, "\n" );+}++static int+bibtexin_crossref_oneref( fields *bibref, fields *bibcross )+{+	int j, n, nl, ntype, fstatus, status = BIBL_OK;+	char *type, *nt, *nv;++	ntype = fields_find( bibref, "INTERNAL_TYPE", -1 );+	type = ( char * ) fields_value( bibref, ntype, FIELDS_CHRP_NOUSE );++	n = fields_num( bibcross );+	for ( j=0; j<n; ++j ) {+		nt = ( char * ) fields_tag( bibcross, j, FIELDS_CHRP_NOUSE );+		if ( !strcasecmp( nt, "INTERNAL_TYPE" ) ) continue;+		if ( !strcasecmp( nt, "REFNUM" ) ) continue;+		if ( !strcasecmp( nt, "TITLE" ) ) {+			if ( !strcasecmp( type, "Inproceedings" ) ||+			     !strcasecmp( type, "Incollection" ) )+				nt = "booktitle";+		}+		nv = ( char * ) fields_value( bibcross, j, FIELDS_CHRP_NOUSE );+		nl = fields_level( bibcross, j ) + 1;+		fstatus = fields_add( bibref, nt, nv, nl );+		if ( fstatus!=FIELDS_OK ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		}+	}+out:+	return status;+}++static int+bibtexin_crossref( bibl *bin, param *p )+{+	int i, n, ncross, status = BIBL_OK;+	fields *bibref, *bibcross;++	for ( i=0; i<bin->nrefs; ++i ) {+		bibref = bin->ref[i];+		n = fields_find( bibref, "CROSSREF", -1 );+		if ( n==-1 ) continue;+		fields_setused( bibref, n );+		ncross = bibtexin_findref( bin, (char*) fields_value( bibref, n, FIELDS_CHRP ) );+		if ( ncross==-1 ) {+			bibtexin_nocrossref( bin, i, n, p );+			continue;+		}+		bibcross = bin->ref[ncross];+		status = bibtexin_crossref_oneref( bibref, bibcross );+		if ( status!=BIBL_OK ) goto out;+	}+out:+	return status;+}++int+bibtexin_cleanf( bibl *bin, param *p )+{+	int status = BIBL_OK;+	long i;++        for ( i=0; i<bin->nrefs; ++i )+		status = bibtexin_cleanref( bin->ref[i], p );+	bibtexin_crossref( bin, p );+	return status;+}++/*****************************************************+ PUBLIC: int bibtexin_typef()+*****************************************************/++int+bibtexin_typef( fields *bibin, char *filename, int nrefs, param *p,+		variants *all, int nall )+{+	char *refnum = "";+	int reftype, n, nrefnum;+	n = fields_find( bibin, "INTERNAL_TYPE", 0 );+	nrefnum = fields_find( bibin, "REFNUM", 0 );+	if ( nrefnum!=-1 ) refnum = (bibin->data[nrefnum]).data;+	if ( n!=-1 )+		/* figure out type */+		reftype = get_reftype( (bibin->data[n]).data, nrefs,+			p->progname, all, nall, refnum );+	else+		/* no type info, go for default */+		reftype = get_reftype( "", nrefs, p->progname, all, nall, refnum );+	return reftype;+}++/*****************************************************+ PUBLIC: int bibtexin_convertf(), returns BIBL_OK or BIBL_ERR_MEMERR+*****************************************************/++static int+bibtex_matches_list( fields *info, char *tag, char *suffix, newstr *data, int level,+		list *names, int *match )+{+	int i, fstatus, status = BIBL_OK;+	newstr newtag;++	*match = 0;+	if ( names->n==0 ) return status;++	newstr_init( &newtag );++	for ( i=0; i<names->n; ++i ) {+		if ( strcmp( data->data, list_getc( names, i ) ) ) continue;+		newstr_initstr( &newtag, tag );+		newstr_strcat( &newtag, suffix );+		fstatus = fields_add( info, newtag.data, data->data, level );+		if ( fstatus!=FIELDS_OK ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		}+		*match = 1;+		goto out;+	}++out:+	newstr_free( &newtag );+	return status;+}++/*+ * bibtex_names( info, newtag, field, level);+ *+ * split names in author list separated by and's (use '|' character)+ * and add names+ *+ * returns BIBL_OK on success, BIBL_ERR_MEMERR on memory error+ */+static int+bibtex_names( fields *info, char *tag, newstr *data, int level, list *asis,+	list *corps )+{+	int begin, end, ok, n, etal, i, status, match;+	list tokens;++	/* If we match the asis or corps list add and bail. */+	status = bibtex_matches_list( info, tag, ":ASIS", data, level, asis, &match );+	if ( match==1 || status!=BIBL_OK ) return status;+	status = bibtex_matches_list( info, tag, ":CORP", data, level, corps, &match );+	if ( match==1 || status!=BIBL_OK ) return status;++	list_init( &tokens );++	bibtex_split( &tokens, data );+	for ( i=0; i<tokens.n; ++i )+		bibtex_cleantoken( list_get( &tokens, i ) );++	etal = name_findetal( &tokens );++	begin = 0;+	n = tokens.n - etal;+	while ( begin < n ) {++		end = begin + 1;++		while ( end < n && strcasecmp( list_getc( &tokens, end ), "and" ) )+			end++;++		if ( end - begin == 1 ) {+			ok = name_addsingleelement( info, tag, list_getc( &tokens, begin ), level, 0 );+			if ( !ok ) { status = BIBL_ERR_MEMERR; goto out; }+		} else {+			ok = name_addmultielement( info, tag, &tokens, begin, end, level );+			if ( !ok ) { status = BIBL_ERR_MEMERR; goto out; }+		}++		begin = end + 1;++		/* Handle repeated 'and' errors: authors="G. F. Author and and B. K. Author" */+		while ( begin < n && !strcasecmp( list_getc( &tokens, begin ), "and" ) )+			begin++;+	}++	if ( etal ) {+		ok = name_addsingleelement( info, tag, "et al.", level, 0 );+		if ( !ok ) status = BIBL_ERR_MEMERR;+	}++out:+	list_free( &tokens );+	return status;+}++/* is_utf8_emdash()+ *+ * Internally pages="A---B" will convert --- to a UTF8+ * emdash = 0xE2 (-30) 0x80 (-128) 0x94 (-108)+ */+static int+is_utf8_emdash( char *p )+{+	static char emdash[3] = { -30, -128, -108 };+	if ( strncmp( p, emdash, 3 ) ) return 0;+	return 1;+}+/* is_utf8_endash()+ *+ * Internally pages="A--B" will convert -- to a UTF8+ * endash = 0xE2 (-30) 0x80 (-128) 0x93 (-109)+ */+static int+is_utf8_endash( char *p )+{+	static char endash[3] = { -30, -128, -109 };+	if ( strncmp( p, endash, 3 ) ) return 0;+	return 1;+}++static int+process_pages( fields *info, newstr *s, int level )+{+	int fstatus, status = BIBL_OK;+	newstr page;+	char *p;++	newstr_findreplace( s, " ", "" );+	if ( s->len==0 ) return 1;++	newstr_init( &page );+	p = skip_ws( s->data );+	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' && *p!=-30 )+		newstr_addchar( &page, *p++ );+	if ( page.len>0 ) {+		fstatus = fields_add( info, "PAGESTART", page.data, level );+		if ( fstatus!=FIELDS_OK ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		}+	}++	while ( *p && (is_ws(*p) || *p=='-' ) ) p++;+	if ( *p && is_utf8_emdash( p ) ) p+=3;+	if ( *p && is_utf8_endash( p ) ) p+=3;++	newstr_empty( &page );+	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' )+		newstr_addchar( &page, *p++ );+	if ( page.len>0 ) {+		fstatus = fields_add( info, "PAGEEND", page.data, level );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR; +	}++out:+	newstr_free( &page );+	return status;+}++static int+process_urlcore( fields *info, newstr *d, int level, char *default_tag )+{+	char *p = d->data;+	int fstatus;+	if ( !strncasecmp( p, "\\urllink", 8 ) )+		fstatus = fields_add( info, "URL", p+8, level );+	else if ( !strncasecmp( p, "\\url", 4 ) )+		fstatus = fields_add( info, "URL", p+4, level );+	else if ( !strncasecmp( p, "arXiv:", 6 ) )+		fstatus = fields_add( info, "ARXIV", p+6, level );+	else if ( !strncasecmp( p, "http://arxiv.org/abs/", 21 ) )+		fstatus = fields_add( info, "ARXIV", p+21, level );+	else if ( !strncasecmp( p, "http:", 5 ) )+		fstatus = fields_add( info, "URL", p, level );+	else+		fstatus = fields_add( info, default_tag, p, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}++static int+process_url( fields *info, newstr *d, int level )+{+	return process_urlcore( info, d, level, "URL" );+}++/* Split keywords="" with semicolons.+ * Commas are also frequently used, but will break+ * entries like:+ *       keywords="Microscopy, Confocal"+ * Returns BIBL_OK or BIBL_ERR_MEMERR+ */+static int+process_keywords( fields *info, newstr *d, int level )+{+	int fstatus, status = BIBL_OK;+	newstr keyword;+	char *p;++	if ( !d || d->len==0 ) return BIBL_OK;++	p = d->data;+	newstr_init( &keyword );++	while ( *p ) {+		p = newstr_cpytodelim( &keyword, skip_ws( p ), ";", 1 );+		newstr_trimendingws( &keyword );+		if ( newstr_memerr( &keyword ) ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		}+		if ( keyword.len ) {+			fstatus = fields_add( info, "KEYWORD", keyword.data, level );+			if ( fstatus!=FIELDS_OK ) {+				status = BIBL_ERR_MEMERR;+				goto out;+			}+		}+	}+out:+	newstr_free( &keyword );+	return status;+}++/* proces_howpublished()+ *+ *    howpublished={},+ *+ * Normally indicates the manner in which something was+ * published in lieu of a formal publisher, so typically+ * 'howpublished' and 'publisher' will never be in the+ * same reference.+ *+ * Occassionally, people put Diploma thesis information+ * into the field, so check that first.+ *+ * Returns BIBL_OK or BIBL_ERR_MEMERR+ */+static int+process_howpublished( fields *info, newstr *d, int level )+{+	int fstatus, status = BIBL_OK;+	char *p = d->data;+	if ( !strncasecmp( p, "Diplom", 6 ) ) {+		fstatus = fields_replace_or_add( info, "GENRE", "Diploma thesis", level );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+	} else if ( !strncasecmp( p, "Habilitation", 13 ) ) {+		fstatus = fields_replace_or_add( info, "GENRE", "Habilitation thesis", level );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+	} else if ( !strncasecmp( d->data, "http:", 5 ) ) {+		status = process_url( info, d, level );+	} else if ( !strncasecmp( d->data, "arXiv:", 6 ) ) {+		status = process_url( info, d, level );+	} else {+		fstatus = fields_add( info, "PUBLISHER", p, level );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+	}+	return status;+}++/*+ * sentelink = {file://localhost/full/path/to/file.pdf,Sente,PDF}+ */+static int+process_sente( fields *info, newstr *d, int level )+{+	int fstatus, status = BIBL_OK;+	newstr link;++	newstr_init( &link );+	newstr_cpytodelim( &link, skip_ws( d->data ), ",", 0 );+	newstr_trimendingws( &link );+	if ( newstr_memerr( &link ) ) status = BIBL_ERR_MEMERR;++	if ( status==BIBL_OK && link.len ) {+		fstatus = fields_add( info, "FILEATTACH", link.data, level );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+	}++	newstr_free( &link );+	return status;+}++/*+ * BibTeX uses 'organization' in lieu of publisher if that field is missing.+ * Otherwise output as+ * <name type="corporate">+ *    <namePart>The organization</namePart>+ *    <role>+ *       <roleTerm authority="marcrelator" type="text">organizer of meeting</roleTerm>+ *    </role>+ * </name>+ */+static int+process_organization( fields *bibin, fields *info, newstr *d, int level )+{+	int n, fstatus;+	n = fields_find( bibin, "publisher", LEVEL_ANY );+	if ( n==-1 )+		fstatus = fields_add( info, "PUBLISHER", d->data, level );+	else+		fstatus = fields_add( info, "ORGANIZER:CORP", d->data, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}++static int+count_colons( char *p )+{+	int n = 0;+	while ( *p ) {+		if ( *p==':' ) n++;+		p++;+	}+	return n;+}++static int+first_colon( char *p )+{+	int n = 0;+	while ( p[n] && p[n]!=':' ) n++;+	return n;+}++static int+last_colon( char *p )+{+	int n = strlen( p ) - 1;+	while ( n>0 && p[n]!=':' ) n--;+	return n;+}++/*+ * file={Description:/full/path/to/file.pdf:PDF}+ */+static int+process_file( fields *info, newstr *d, int level )+{+	int fstatus, status = BIBL_OK;+	char *p = d->data;+	int i, n, n1, n2;+	newstr link;++	n = count_colons( p );+	if ( n > 1 ) {+		/* A DOS file can contain a colon ":C:/....pdf:PDF" */+		/* Extract after 1st and up to last colons */+		n1 = first_colon( p ) + 1;+		n2 = last_colon( p );+		newstr_init( &link );+		for ( i=n1; i<n2; ++i ) {+			newstr_addchar( &link, p[i] );+		}+		newstr_trimstartingws( &link );+		newstr_trimendingws( &link );+		if ( newstr_memerr( &link ) ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		}+		if ( link.len ) {+			fstatus = fields_add( info, "FILEATTACH", link.data, level );+			if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+		}+out:+		newstr_free( &link );+	} else {+		/* This field isn't formatted properly, so just copy directly */+		fstatus = fields_add( info, "FILEATTACH", p, level );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+	}+	return status;+}++static int+process_note( fields *info, newstr *d, int level )+{+	int fstatus, status = BIBL_OK;+	if ( !strncasecmp( d->data, "http:", 5 ) ||+	     !strncasecmp( d->data, "arXiv:", 6 ) ) {+		status = process_url( info, d, level );+	} else {+		fstatus = fields_add( info, "NOTES", d->data, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	return status;+}++static void+bibtexin_notag( param *p, char *tag )+{+	if ( p->verbose && strcmp( tag, "INTERNAL_TYPE" ) ) {+		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+		fprintf( stderr, "Cannot find tag '%s'\n", tag );+	}+}++/* bibtexin_titleinbook_isbooktitle()+ *+ * Normally, the title field of inbook refers to the book.  The+ * section in a @inbook reference is untitled.  If it's titled,+ * the @incollection should be used.  For example, in:+ *+ * @inbook{+ *    title="xxx"+ * }+ *+ * the booktitle is "xxx".+ *+ * However, @inbook is frequently abused (and treated like+ * @incollection) so that title and booktitle are present+ * and title is now 'supposed' to refer to the section.  For example:+ *+ * @inbook{+ *     title="yyy",+ *     booktitle="xxx"+ * }+ *+ * Therefore report whether or not booktitle is present as well+ * as title in @inbook references.  If not, then make 'title'+ * correspond to the title of the book, not the section.+ *+ */+static int+bibtexin_titleinbook_isbooktitle( char *intag, fields *bibin )+{+	int n;++	/* ...look only at 'title="xxx"' elements */+	if ( strcasecmp( intag, "TITLE" ) ) return 0;++	/* ...look only at '@inbook' references */+	n = fields_find( bibin, "INTERNAL_TYPE", -1 );+	if ( n==-1 ) return 0;+	if ( strcasecmp( fields_value( bibin, n, FIELDS_CHRP ), "INBOOK" ) ) return 0;++	/* ...look to see if 'booktitle="yyy"' exists */+	n = fields_find( bibin, "BOOKTITLE", -1 );+	if ( n==-1 ) return 0;+	else return 1;+}+static int+bibtexin_title_process( fields *info, char *outtag, fields *bibin, newstr *t, newstr *d, int level, int nosplittitle )+{+	char *intag = t->data;+	char *indata = d->data;+	int ok;+	if ( bibtexin_titleinbook_isbooktitle( intag, bibin ) ) level=LEVEL_MAIN;+	ok = title_process( info, outtag, indata, level, nosplittitle );+	if ( ok ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}++static int+bibtex_simple( fields *info, char *outtag, newstr *d, int level )+{+	int fstatus;+	fstatus = fields_add( info, outtag, d->data, level );+	if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	return BIBL_OK;+}++int+bibtexin_convertf( fields *bibin, fields *info, int reftype, param *p,+		variants *all, int nall )+{+	int process, level, i, n, nfields, status;+	newstr *t, *d;+	char *outtag;++	nfields = fields_num( bibin );+	for ( i=0; i<nfields; ++i ) {++		if ( fields_used( bibin, i ) ) continue; /* e.g. successful crossref */+		if ( fields_nodata( bibin, i ) ) continue;++		t = fields_tag( bibin, i, FIELDS_STRP );+		if ( t->len == 0 ) continue; /* Don't consider with null tags */+		n = process_findoldtag( t->data, reftype, all, nall );+		if ( n==-1 ) {+			bibtexin_notag( p, t->data );+			continue;+		}++		d = fields_value( bibin, i, FIELDS_STRP );++		process = ((all[reftype]).tags[n]).processingtype;+		level   = ((all[reftype]).tags[n]).level;+		outtag  = ((all[reftype]).tags[n]).newstr;++		switch( process ) {++		case SIMPLE:+			status = bibtex_simple( info, outtag, d, level );+			break;++		case TITLE:+			status = bibtexin_title_process( info, "TITLE", bibin, t, d, level, p->nosplittitle );+			break;++		case PERSON:+			status = bibtex_names( info, outtag, d, level, &(p->asis), &(p->corps) );+			break;++		case PAGES:+			status = process_pages( info, d, level );+			break;++		case KEYWORD:+			status = process_keywords( info, d, level );+			break;++		case HOWPUBLISHED:+			status = process_howpublished( info, d, level );+			break;++		case LINKEDFILE:+			status = process_file( info, d, level );+			break;++		case BT_NOTE:+			status = process_note( info, d, level );+			break;++		case BT_SENTE:+			status = process_sente( info, d, level );+			break;++		case BT_URL:+			status = process_url( info, d, level );+			break;++		case BT_ORG:+			status = process_organization( bibin, info, d, level );+			break;++		default:+			status = BIBL_OK;+			break;+		}++		if ( status!=BIBL_OK ) return status;+	}+	return status; } 
bibutils/bibtexin.h view
@@ -1,7 +1,7 @@ /*  * bibtexin.h  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Source code released under the GPL version 2  *@@ -18,7 +18,7 @@  extern int  bibtexin_convertf( fields *bibin, fields *info, int reftype, param *p, variants *all, int nall ); extern int  bibtexin_processf( fields *bibin, char *data, char *filename, long nref );-extern void bibtexin_cleanf( bibl *bin, param *p );+extern int  bibtexin_cleanf( bibl *bin, param *p ); extern int  bibtexin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line, newstr *reference, int *fcharset ); extern int  bibtexin_typef( fields *bibin, char *filename, int nrefs,         param *p, variants *all, int nall );
bibutils/bibtexout.c view
@@ -1,7 +1,7 @@ /*  * bibtexout.c  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Program and source code released under the GPL version 2  *@@ -30,7 +30,7 @@ 	p->latexout         = 1; 	p->utf8out          = BIBL_CHARSET_UTF8_DEFAULT; 	p->utf8bom          = BIBL_CHARSET_BOM_DEFAULT;-	p->xmlout           = 0;+	p->xmlout           = BIBL_XMLOUT_FALSE; 	p->nosplittitle     = 0; 	p->verbose          = 0; 	p->addcount         = 0;
bibutils/bibtextypes.c view
@@ -664,6 +664,7 @@ 	REFTYPE( "manual", manual ), 	REFTYPE( "mastersthesis", masters ), 	REFTYPE( "misc", misc ),+	REFTYPE( "online", misc ), 	REFTYPE( "patent", patent ), 	REFTYPE( "phdthesis", phds ), 	REFTYPE( "periodical", periodical ),
bibutils/bibutils.h view
@@ -1,7 +1,7 @@ /*  * bibutils.h  *- * Copyright (c) Chris Putnam 2005-2013+ * Copyright (c) Chris Putnam 2005-2014  *  * Source code released under GPL version 2  *@@ -17,6 +17,7 @@ #include "bibl.h" #include "list.h" #include "charsets.h"+#include "newstr_conv.h"  #define BIBL_OK           (0) #define BIBL_ERR_BADINPUT (-1)@@ -63,6 +64,10 @@ #define BIBL_SRC_FILE    (1)  /* value from file, priority over default */ #define BIBL_SRC_USER    (2)  /* value from user, priority over file, default */ +#define BIBL_XMLOUT_FALSE    NEWSTR_CONV_XMLOUT_FALSE+#define BIBL_XMLOUT_TRUE     NEWSTR_CONV_XMLOUT_TRUE+#define BIBL_XMLOUT_ENTITIES NEWSTR_CONV_XMLOUT_ENTITIES+ typedef unsigned char uchar;  typedef struct param {@@ -98,7 +103,7 @@          int  (*readf)(FILE*,char*,int,int*,newstr*,newstr*,int*);         int  (*processf)(fields*,char*,char*,long);-        void (*cleanf)(bibl*,struct param*);+        int  (*cleanf)(bibl*,struct param*);         int  (*typef) (fields*,char*,int,struct param*,variants*,int);         int  (*convertf)(fields*,fields*,int,struct param*,variants*,int);         void (*headerf)(FILE*,struct param*);@@ -113,12 +118,12 @@ extern void bibl_initparams( param *p, int readmode, int writemode, 	char *progname ); extern void bibl_freeparams( param *p );-extern void bibl_readasis( param *p, char *filename );-extern void bibl_addtoasis( param *p, char *entry );-extern void bibl_readcorps( param *p, char *filename );-extern void bibl_addtocorps( param *p, char *entry );-extern int bibl_read( bibl *b, FILE *fp, char *filename, param *p );-extern int bibl_write( bibl *b, FILE *fp, param *p );+extern int  bibl_readasis( param *p, char *filename );+extern int  bibl_addtoasis( param *p, char *entry );+extern int  bibl_readcorps( param *p, char *filename );+extern int  bibl_addtocorps( param *p, char *entry );+extern int  bibl_read( bibl *b, FILE *fp, char *filename, param *p );+extern int  bibl_write( bibl *b, FILE *fp, param *p ); extern void bibl_reporterr( int err );  #ifdef __cplusplus
bibutils/bltypes.c view
@@ -18,1038 +18,1044 @@  * Article in a journal, newspaper, other periodical  */ static lookups article[] = {-	{ "author",          "AUTHOR",                 PERSON,      LEVEL_MAIN   },-	{ "editor",          "EDITOR",                 BLT_EDITOR,  LEVEL_MAIN   },-	{ "editora",         "EDITOR",                 BLT_EDITOR,  LEVEL_MAIN   },-	{ "editorb",         "EDITOR",                 BLT_EDITOR,  LEVEL_MAIN   },-	{ "editorc",         "EDITOR",                 BLT_EDITOR,  LEVEL_MAIN   },-	{ "editortype",      "",                       BLT_SKIP,    LEVEL_MAIN   },-	{ "editoratype",     "",                       BLT_SKIP,    LEVEL_MAIN   },-	{ "editorbtype",     "",                       BLT_SKIP,    LEVEL_MAIN   },-	{ "editorctype",     "",                       BLT_SKIP,    LEVEL_MAIN   },-	{ "director",        "DIRECTOR",               PERSON,      LEVEL_MAIN   },-	{ "producer",        "PRODUCER",               PERSON,      LEVEL_MAIN   },-	{ "execproducer",    "PRODUCER",               PERSON,      LEVEL_MAIN   },-	{ "writer",          "AUTHOR",                 PERSON,      LEVEL_MAIN   },-	{ "redactor",        "REDACTOR",               PERSON,      LEVEL_MAIN   },-	{ "annotator",       "ANNOTATOR",              PERSON,      LEVEL_MAIN   },-	{ "commentator",     "COMMENTATOR",            PERSON,      LEVEL_MAIN   },-	{ "translator",      "TRANSLATOR",             PERSON,      LEVEL_MAIN   },-	{ "title",           "TITLE",                  TITLE,       LEVEL_MAIN   },-	{ "subtitle",        "SUBTITLE",               TITLE,       LEVEL_MAIN   },-	{ "titleaddon",      "TITLEADDON",             TITLE,       LEVEL_MAIN   },-	{ "shorttitle",      "SHORTITLE",              SIMPLE,      LEVEL_MAIN   },-	{ "journal",         "TITLE",                  TITLE,       LEVEL_HOST   },-	{ "journaltitle",    "TITLE",                  TITLE,       LEVEL_HOST   },-	{ "journalsubtitle", "SUBTITLE",               TITLE,       LEVEL_HOST   },-	{ "shortjournal",    "SHORTTITLE",             SIMPLE,      LEVEL_HOST   },-	{ "issuetitle",      "TITLE",                  TITLE,       LEVEL_SERIES }, /*WRONG*/-	{ "issuesubtitle",   "SUBTITLE",               TITLE,       LEVEL_SERIES }, /*WRONG*/-	{ "language",        "LANGUAGE",               SIMPLE,      LEVEL_MAIN   },-	{ "origlanguage",    "LANGUAGE",               SIMPLE,      LEVEL_ORIG   },-	{ "origyear",        "YEAR",                   SIMPLE,      LEVEL_ORIG   },-	{ "origdate",        "DATE",                   SIMPLE,      LEVEL_ORIG   },-	{ "origtitle",       "TITLE",                  SIMPLE,      LEVEL_ORIG   },-	{ "origlocation",    "ADDRESS",                SIMPLE,      LEVEL_ORIG   },-	{ "origpublisher",   "PUBLISHER",              SIMPLE,      LEVEL_ORIG   },-	{ "series",          "PARTTITLE",              SIMPLE,      LEVEL_HOST   },-	{ "volume",          "VOLUME",                 SIMPLE,      LEVEL_MAIN   },-	{ "number",          "NUMBER",                 SIMPLE,      LEVEL_MAIN   },-	{ "eid",             "EID",                    SIMPLE,      LEVEL_MAIN   },-	{ "issue",           "ISSUE",                  SIMPLE,      LEVEL_MAIN   },-	{ "date",            "DATE",                   SIMPLE,      LEVEL_MAIN   },   /*WRONG*/-	{ "day",             "PARTDAY",                SIMPLE,      LEVEL_MAIN   },-	{ "month",           "PARTMONTH",              SIMPLE,      LEVEL_MAIN   },-	{ "year",            "PARTYEAR",               SIMPLE,      LEVEL_MAIN   },-	{ "pages",           "PAGES",                  PAGES,       LEVEL_MAIN   },-	{ "version",         "EDITION",                SIMPLE,      LEVEL_MAIN   },-	{ "note",            "NOTES",                  SIMPLE,      LEVEL_MAIN   },-	{ "annote",          "ANNOTATION",             SIMPLE,      LEVEL_MAIN   },-	{ "annotation",      "ANNOTATION",             SIMPLE,      LEVEL_MAIN   },-	{ "issn",            "ISSN",                   SIMPLE,      LEVEL_HOST   },-	{ "abstract",        "ABSTRACT",               SIMPLE,      LEVEL_MAIN   },-	{ "addendum",        "ADDENDUM",               SIMPLE,      LEVEL_MAIN   },-	{ "doi",             "DOI",                    SIMPLE,      LEVEL_MAIN   },-	{ "pubstate",        "PUBSTATE",               SIMPLE,      LEVEL_MAIN   },-	{ "eprint",          "",                       BT_EPRINT,   LEVEL_MAIN   },-	{ "eprinttype",      "",                       BT_EPRINT,   LEVEL_MAIN   },-	{ "url",             "",                       BT_URL,      LEVEL_MAIN   },-	{ "urldate",         "URLDATE",                SIMPLE,      LEVEL_MAIN   },-	{ "urlday",          "?urlday?",               SIMPLE,      LEVEL_MAIN   }, /* WRONG */-	{ "urlmonth",        "?urlmonth?",             SIMPLE,      LEVEL_MAIN   }, /* WRONG */-	{ "urlyear",         "?urlyear?",              SIMPLE,      LEVEL_MAIN   }, /* WRONG */-	{ "address",         "ADDRESS",                SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",                 SIMPLE,      LEVEL_MAIN   },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "entrysubtype",    "",                       BLT_SUBTYPE, LEVEL_MAIN   },-	{ "",                "INTERNAL_TYPE|ARTICLE",  ALWAYS,      LEVEL_MAIN   },-	{ "",                "ISSUANCE|continuing",    ALWAYS,      LEVEL_HOST   },-	{ "",                "RESOURCE|text",          ALWAYS,      LEVEL_MAIN   },-	{ "",                "NGENRE|journal article", DEFAULT,     LEVEL_MAIN   },-	{ "",                "GENRE|periodical",       DEFAULT,     LEVEL_HOST   }-};--/* Book */--static lookups book[] = {-	{ "author",          "AUTHOR",               PERSON,     LEVEL_MAIN },-	{ "editor",          "EDITOR",               BLT_EDITOR, LEVEL_MAIN },-	{ "editora",         "EDITOR",               BLT_EDITOR, LEVEL_MAIN },-	{ "editorb",         "EDITOR",               BLT_EDITOR, LEVEL_MAIN },-	{ "editorc",         "EDITOR",               BLT_EDITOR, LEVEL_MAIN },-	{ "editortype",      "",                     BLT_SKIP,   LEVEL_MAIN },-	{ "editoratype",     "",                     BLT_SKIP,   LEVEL_MAIN },-	{ "editorbtype",     "",                     BLT_SKIP,   LEVEL_MAIN },-	{ "editorctype",     "",                     BLT_SKIP,   LEVEL_MAIN },-	{ "director",        "DIRECTOR",             PERSON,     LEVEL_MAIN },-	{ "producer",        "PRODUCER",             PERSON,     LEVEL_MAIN },-	{ "execproducer",    "PRODUCER",             PERSON,     LEVEL_MAIN },-	{ "writer",          "AUTHOR",               PERSON,     LEVEL_MAIN },-	{ "redactor",        "REDACTOR",             PERSON,     LEVEL_MAIN },-	{ "annotator",       "ANNOTATOR",            PERSON,     LEVEL_MAIN },-	{ "commentator",     "COMMENTATOR",          PERSON,     LEVEL_MAIN },-	{ "translator",      "TRANSLATOR",           PERSON,     LEVEL_MAIN },-	{ "introduction",    "INTROAUTHOR",          PERSON,     LEVEL_MAIN },-	{ "foreword",        "INTROAUTHOR",          PERSON,     LEVEL_MAIN },-	{ "afterword",       "AFTERAUTHOR",          PERSON,     LEVEL_MAIN },-	{ "title",           "TITLE",                TITLE,      LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",             TITLE,      LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",           TITLE,      LEVEL_MAIN },-	{ "shorttitle",      "SHORTITLE",            SIMPLE,     LEVEL_MAIN  },-	{ "maintitle",       "TITLE",                TITLE,      LEVEL_HOST },-	{ "mainsubtitle",    "SUBTITLE",             TITLE,      LEVEL_HOST },-	{ "maintitleaddon",  "TITLEADDON",           TITLE,      LEVEL_HOST },-	{ "language",        "LANGUAGE",             SIMPLE,     LEVEL_MAIN },-	{ "year",            "YEAR",                 SIMPLE,     LEVEL_MAIN },-	{ "month",           "MONTH",                SIMPLE,     LEVEL_MAIN },-	{ "date",            "DATE",                 SIMPLE,     LEVEL_MAIN },   /*WRONG*/-	{ "origlanguage",    "LANGUAGE",             SIMPLE,     LEVEL_ORIG },-	{ "origyear",        "YEAR",                 SIMPLE,     LEVEL_ORIG },-	{ "origdate",        "DATE",                 SIMPLE,     LEVEL_ORIG },-	{ "origtitle",       "TITLE",                SIMPLE,     LEVEL_ORIG },-	{ "origlocation",    "ADDRESS",              SIMPLE,     LEVEL_ORIG },-	{ "origpublisher",   "PUBLISHER",            SIMPLE,     LEVEL_ORIG },-	{ "volume",          "VOLUME",               SIMPLE,     LEVEL_HOST },-	{ "part",            "PART",                 SIMPLE,     LEVEL_HOST },-	{ "edition",         "EDITION",              SIMPLE,     LEVEL_MAIN },-	{ "volumes",         "NUMVOLUMES",           SIMPLE,     LEVEL_HOST },-	{ "series",          "TITLE",                SIMPLE,     LEVEL_HOST }, /* WRONG */-	{ "number",          "NUMBER",               SIMPLE,     LEVEL_MAIN },-	{ "note",            "NOTES",                SIMPLE,     LEVEL_MAIN },-	{ "annote",          "ANNOTATION",           SIMPLE,     LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",           SIMPLE,     LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",            SIMPLE,     LEVEL_MAIN },-	{ "location",        "ADDRESS",              SIMPLE,     LEVEL_MAIN },-	{ "isbn",            "ISBN",                 SIMPLE,     LEVEL_MAIN },-	{ "chapter",         "CHAPTER",              SIMPLE,     LEVEL_MAIN },-	{ "pages",           "?pages?",              SIMPLE,     LEVEL_MAIN }, /* WRONG */-	{ "pagetotal",       "?pagetotal?",          SIMPLE,     LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",             SIMPLE,     LEVEL_MAIN },-	{ "doi",             "DOI",                  SIMPLE,     LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",             SIMPLE,     LEVEL_MAIN   },-	{ "eprint",          "",                     BT_EPRINT,  LEVEL_MAIN },-	{ "eprinttype",      "",                     BT_EPRINT,  LEVEL_MAIN },-	{ "url",             "",                     BT_URL,     LEVEL_MAIN },-	{ "urldate",         "URLDATE",              SIMPLE,     LEVEL_MAIN },-	{ "urlday",          "?urlday?",             SIMPLE,     LEVEL_MAIN },-	{ "urlmonth",        "?urlmonth?",           SIMPLE,     LEVEL_MAIN },-	{ "urlyear",         "?urlyear?",            SIMPLE,     LEVEL_MAIN },-	{ "address",         "ADDRESS",              SIMPLE,     LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",               SIMPLE,     LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|BOOK",   ALWAYS,     LEVEL_MAIN },-	{ "",                "RESOURCE|text",        ALWAYS,     LEVEL_MAIN },-	{ "",                "ISSUANCE|monographic", ALWAYS,     LEVEL_MAIN },-	{ "",                "GENRE|book",           ALWAYS,     LEVEL_MAIN }-};--/* Booklet */--static lookups booklet[] = {-	{ "author",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_MAIN },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTITLE",    SIMPLE, LEVEL_MAIN },-	{ "howpublished",    "",       HOWPUBLISHED, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },   /*WRONG*/-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "type",            "GENRE",  BT_GENRE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_MAIN },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "chapter",         "CHAPTER",      SIMPLE, LEVEL_MAIN },-	{ "pages",           "?pages?",      SIMPLE, LEVEL_MAIN }, /* WRONG */-	{ "pagetotal",       "?pagetotal?",  SIMPLE, LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN   },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?urlday?",    SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?urlmonth?",    SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?urlyear?",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|BOOK",    ALWAYS, LEVEL_MAIN },-	{ "",                "RESOURCE|text",ALWAYS, LEVEL_MAIN },-	{ "",                "ISSUANCE|monographic", ALWAYS, LEVEL_MAIN },-	{ "",                "GENRE|book",   ALWAYS, LEVEL_MAIN }-};--static lookups collection[] = {-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_MAIN },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "redactor",        "REDACTOR",     PERSON, LEVEL_MAIN },-	{ "annotator",       "ANNOTATOR",    PERSON, LEVEL_MAIN },-	{ "commentator",     "COMMENTATOR",  PERSON, LEVEL_MAIN },-	{ "translator",      "TRANSLATOR",   PERSON, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },   /*WRONG*/-	{ "introduction",    "INTROAUTHOR",  PERSON, LEVEL_MAIN },-	{ "foreword",        "INTROAUTHOR",  PERSON, LEVEL_MAIN },-	{ "afterword",       "AFTERAUTHOR",  PERSON, LEVEL_MAIN },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },-	{ "maintitle",       "TITLE",        TITLE,  LEVEL_HOST },-	{ "mainsubtitle",    "SUBTITLE",     TITLE,  LEVEL_HOST },-	{ "maintitleaddon",  "TITLEADDON",   TITLE,  LEVEL_HOST },-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "origlanguage",    "LANGUAGE",     SIMPLE, LEVEL_ORIG },-	{ "origyear",        "YEAR",         SIMPLE, LEVEL_ORIG },-	{ "origdate",        "DATE",         SIMPLE, LEVEL_ORIG },-	{ "origtitle",       "TITLE",        SIMPLE, LEVEL_ORIG },-	{ "origlocation",    "ADDRESS",      SIMPLE, LEVEL_ORIG },-	{ "origpublisher",   "PUBLISHER",    SIMPLE, LEVEL_ORIG },-	{ "volume",          "VOLUME",       SIMPLE, LEVEL_HOST },-	{ "part",            "PART",         SIMPLE, LEVEL_HOST },-	{ "edition",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "volumes",         "NUMVOLUMES",   SIMPLE, LEVEL_HOST },-	{ "series",          "?series?",     SIMPLE, LEVEL_HOST }, /* WRONG */-	{ "number",          "NUMBER",       SIMPLE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_MAIN },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "isbn",            "ISBN",         SIMPLE, LEVEL_MAIN },-	{ "chapter",         "CHAPTER",      SIMPLE, LEVEL_MAIN },-	{ "pages",           "?pages?",      SIMPLE, LEVEL_MAIN }, /* WRONG */-	{ "pagetotal",       "?pagetotal?",  SIMPLE, LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?urlday?",    SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?urlmonth?",    SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?urlyear?",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|BOOK",    ALWAYS, LEVEL_MAIN },-	{ "",                "RESOURCE|text",ALWAYS, LEVEL_MAIN },-	{ "",                "ISSUANCE|monographic", ALWAYS, LEVEL_MAIN },-	{ "",                "GENRE|book",   ALWAYS, LEVEL_MAIN }-};--/* Part of a book (e.g. chapter or section) */--static lookups inbook[] = {-	{ "author",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_HOST },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_HOST },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_HOST },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_HOST },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_HOST },-	{ "redactor",        "REDACTOR",     PERSON, LEVEL_HOST },-	{ "annotator",       "ANNOTATOR",    PERSON, LEVEL_HOST },-	{ "commentator",     "COMMENTATOR",  PERSON, LEVEL_HOST },-	{ "translator",      "TRANSLATOR",   PERSON, LEVEL_HOST },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },   /*WRONG*/-	{ "introduction",    "INTROAUTHOR",  PERSON, LEVEL_HOST },-	{ "foreword",        "INTROAUTHOR",  PERSON, LEVEL_HOST },-	{ "afterword",       "AFTERAUTHOR",  PERSON, LEVEL_HOST },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },-	{ "booktitle",       "TITLE",        TITLE,  LEVEL_HOST },-	{ "booksubtitle",    "SUBTITLE",     TITLE,  LEVEL_HOST },-	{ "booktitleaddon",  "TITLEADDON",   TITLE,  LEVEL_HOST },-	{ "bookauthor",      "AUTHOR",       PERSON, LEVEL_HOST },-	{ "maintitle",       "TITLE",        TITLE,  LEVEL_SERIES },-	{ "mainsubtitle",    "SUBTITLE",     TITLE,  LEVEL_SERIES },-	{ "maintitleaddon",  "TITLEADDON",   TITLE,  LEVEL_SERIES },-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "origlanguage",    "LANGUAGE",     SIMPLE, LEVEL_ORIG },-	{ "origyear",        "YEAR",         SIMPLE, LEVEL_ORIG },-	{ "origdate",        "DATE",         SIMPLE, LEVEL_ORIG },-	{ "origtitle",       "TITLE",        SIMPLE, LEVEL_ORIG },-	{ "origlocation",    "ADDRESS",      SIMPLE, LEVEL_ORIG },-	{ "origpublisher",   "PUBLISHER",    SIMPLE, LEVEL_ORIG },-	{ "volume",          "VOLUME",       SIMPLE, LEVEL_MAIN },-	{ "pages",           "PAGES",        PAGES,  LEVEL_MAIN },-	{ "part",            "PART",         SIMPLE, LEVEL_HOST },-	{ "edition",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "volumes",         "NUMVOLUMES",   SIMPLE, LEVEL_HOST },-	{ "series",          "TITLE",        SIMPLE, LEVEL_SERIES+1 }, /* WRONG */-	{ "number",          "NUMBER",       SIMPLE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_MAIN },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "isbn",            "ISBN",         SIMPLE, LEVEL_HOST },-	{ "chapter",         "CHAPTER",      SIMPLE, LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?urlday?",     SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?urlmonth?",   SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?urlyear?",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|INBOOK",    ALWAYS, LEVEL_MAIN },-	{ "",                "RESOURCE|text",ALWAYS, LEVEL_MAIN },-	{ "",                "ISSUANCE|monographic", ALWAYS, LEVEL_HOST },-        { "",                "NGENRE|book chapter",   ALWAYS, LEVEL_MAIN },-	{ "",                "GENRE|book",   ALWAYS, LEVEL_HOST }-};--/* incollection */--static lookups incollection[] = {--	{ "author",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },   /*WRONG*/-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "edition",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "number",          "NUMBER",       SIMPLE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "introduction",    "INTROAUTHOR",  PERSON, LEVEL_HOST },-	{ "foreword",        "INTROAUTHOR",  PERSON, LEVEL_HOST },-	{ "afterword",       "AFTERAUTHOR",  PERSON, LEVEL_HOST },-	{ "bookauthor",      "AUTHOR",       PERSON, LEVEL_HOST },-	{ "booktitle",       "TITLE",        TITLE,  LEVEL_HOST },-	{ "booksubtitle",    "SUBTITLE",     TITLE,  LEVEL_HOST },-	{ "booktitleaddon",  "TITLEADDON",   TITLE,  LEVEL_HOST },-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_HOST },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_HOST },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_HOST },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_HOST },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_HOST },-	{ "redactor",        "REDACTOR",     PERSON, LEVEL_HOST },-	{ "annotator",       "ANNOTATOR",    PERSON, LEVEL_HOST },-	{ "commentator",     "COMMENTATOR",  PERSON, LEVEL_HOST },-	{ "translator",      "TRANSLATOR",   PERSON, LEVEL_HOST },-	{ "volume",          "VOLUME",       SIMPLE, LEVEL_HOST },-	{ "part",            "PART",         SIMPLE, LEVEL_HOST },-	{ "volumes",         "NUMVOLUMES",   SIMPLE, LEVEL_HOST },-	-	{ "maintitle",       "TITLE",        TITLE,  LEVEL_SERIES },-	{ "mainsubtitle",    "SUBTITLE",     TITLE,  LEVEL_SERIES },-	{ "maintitleaddon",  "TITLEADDON",   TITLE,  LEVEL_SERIES },--	{ "series",          "TITLE",        SIMPLE, LEVEL_SERIES+1 }, /* WRONG */--	{ "origlanguage",    "LANGUAGE",     SIMPLE, LEVEL_ORIG },-	{ "origyear",        "YEAR",         SIMPLE, LEVEL_ORIG },-	{ "origdate",        "DATE",         SIMPLE, LEVEL_ORIG },-	{ "origtitle",       "TITLE",        SIMPLE, LEVEL_ORIG },-	{ "origlocation",    "ADDRESS",      SIMPLE, LEVEL_ORIG },-	{ "origpublisher",   "PUBLISHER",    SIMPLE, LEVEL_ORIG },--	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_HOST },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_HOST },-	{ "isbn",            "ISBN",         SIMPLE, LEVEL_MAIN },-	{ "chapter",         "CHAPTER",      SIMPLE, LEVEL_MAIN },-	{ "pages",           "PAGES",        PAGES,  LEVEL_MAIN }, /* WRONG */-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?urlday?",     SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?urlmonth?",   SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?urlyear?",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|INCOLLECTION",    ALWAYS, LEVEL_MAIN },-	{ "",                "RESOURCE|text",ALWAYS, LEVEL_MAIN },-	{ "",                "ISSUANCE|monographic", ALWAYS, LEVEL_MAIN },-	{ "",                "GENRE|collection",   ALWAYS, LEVEL_HOST }-};--/* inproceedings */--static lookups inproceedings[] = {-	{ "author",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_HOST },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_HOST },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_HOST },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_HOST },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_HOST },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_HOST },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_HOST },-	{ "redactor",        "REDACTOR",     PERSON, LEVEL_HOST },-	{ "annotator",       "ANNOTATOR",    PERSON, LEVEL_HOST },-	{ "commentator",     "COMMENTATOR",  PERSON, LEVEL_HOST },-	{ "translator",      "TRANSLATOR",   PERSON, LEVEL_HOST },-	{ "eventtitle",      "EVENT:CONF",   SIMPLE, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },   /*WRONG*/-	{ "introduction",    "INTROAUTHOR",  PERSON, LEVEL_HOST },-	{ "foreword",        "INTROAUTHOR",  PERSON, LEVEL_HOST },-	{ "afterword",       "AFTERAUTHOR",  PERSON, LEVEL_HOST },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },--	{ "booktitle",       "TITLE",        TITLE,  LEVEL_HOST },-	{ "booksubtitle",    "SUBTITLE",     TITLE,  LEVEL_HOST },-	{ "booktitleaddon",  "TITLEADDON",   TITLE,  LEVEL_HOST },--	{ "maintitle",       "TITLE",        TITLE,  LEVEL_SERIES },-	{ "mainsubtitle",    "SUBTITLE",     TITLE,  LEVEL_SERIES },-	{ "maintitleaddon",  "TITLEADDON",   TITLE,  LEVEL_SERIES },--	{ "series",          "TITLE",        SIMPLE, LEVEL_HOST+2 },--	{ "venue",           "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "organization",    "ORGANIZER:CORP", SIMPLE, LEVEL_MAIN },-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "origlanguage",    "LANGUAGE",     SIMPLE, LEVEL_ORIG },-	{ "origdate",        "DATE",         SIMPLE, LEVEL_ORIG },-	{ "origyear",        "YEAR",         SIMPLE, LEVEL_ORIG },-	{ "origtitle",       "TITLE",        SIMPLE, LEVEL_ORIG },-	{ "origlocation",    "ADDRESS",      SIMPLE, LEVEL_ORIG },-	{ "origpublisher",   "PUBLISHER",    SIMPLE, LEVEL_ORIG },-	{ "volume",          "VOLUME",       SIMPLE, LEVEL_HOST },-	{ "part",            "PART",         SIMPLE, LEVEL_HOST },-	{ "edition",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "volumes",         "NUMVOLUMES",   SIMPLE, LEVEL_HOST },-	{ "number",          "NUMBER",       SIMPLE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_HOST },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_HOST },-	{ "isbn",            "ISBN",         SIMPLE, LEVEL_MAIN },-	{ "chapter",         "CHAPTER",      SIMPLE, LEVEL_MAIN },-	{ "pages",           "PAGES",        PAGES,  LEVEL_MAIN }, /* WRONG */-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?urlday?",     SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?urlmonth?",   SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?urlyear?",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|INPROCEEDINGS",    ALWAYS, LEVEL_MAIN },-	{ "",                "RESOURCE|text",ALWAYS, LEVEL_MAIN },-	{ "",                "ISSUANCE|monographic", ALWAYS, LEVEL_MAIN },-	{ "",                "GENRE|conference publication",   ALWAYS, LEVEL_HOST }-};--static lookups manual[] = {-	{ "author",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_MAIN },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "redactor",        "REDACTOR",     PERSON, LEVEL_MAIN },-	{ "annotator",       "ANNOTATOR",    PERSON, LEVEL_MAIN },-	{ "commentator",     "COMMENTATOR",  PERSON, LEVEL_MAIN },-	{ "translator",      "TRANSLATOR",   PERSON, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN }, /*WRONG*/-	{ "introduction",    "INTROAUTHOR",  PERSON, LEVEL_MAIN },-	{ "foreword",        "INTROAUTHOR",  PERSON, LEVEL_MAIN },-	{ "afterword",       "AFTERAUTHOR",  PERSON, LEVEL_MAIN },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "edition",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "version",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "type",            "GENRE",  BT_GENRE, LEVEL_MAIN },-	{ "series",          "TITLE",        SIMPLE, LEVEL_HOST },-	{ "number",          "NUMBER",       SIMPLE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "organization",    "ORGANIZER:CORP", SIMPLE, LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_MAIN },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "isbn",            "ISBN",         SIMPLE, LEVEL_MAIN },-	{ "chapter",         "CHAPTER",      SIMPLE, LEVEL_MAIN },-	{ "pages",           "?????????",    SIMPLE, LEVEL_MAIN }, /* WRONG */-	{ "pagetotal",       "?????????",    SIMPLE, LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?????????",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|REPORT",       ALWAYS, LEVEL_MAIN },-	{ "",                "RESOURCE|text",     ALWAYS, LEVEL_MAIN },-	{ "",                "GENRE|instruction", ALWAYS, LEVEL_MAIN }-};--static lookups misc[] = {-	{ "author",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_MAIN },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },-	{ "day",             "DAY",          SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },   /*WRONG*/-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "howpublished",    "",       HOWPUBLISHED, LEVEL_MAIN },-	{ "version",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "type",            "GENRE",  BT_GENRE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "organization",    "ORGANIZER:CORP",SIMPLE, LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_MAIN },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?????????",    SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|MISC",       ALWAYS, LEVEL_MAIN },-};--static lookups online[] = {-	{ "author",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_MAIN },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },-	{ "day",             "DAY",          SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "version",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "type",            "GENRE",  BT_GENRE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "organization",    "ORGANIZER:CORP",    SIMPLE, LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_MAIN },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?????????",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-        { "",                "RESOURCE|software, multimedia",    ALWAYS, LEVEL_MAIN },-	{ "",                "NGENRE|web page",       ALWAYS, LEVEL_MAIN },-};--static lookups patent[] = {-	{ "author",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "holder",          "ASSIGNEE",     PERSON, LEVEL_MAIN },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },-	{ "day",             "DAY",          SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "version",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "type",            "GENRE",  BT_GENRE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "organization",    "ORGANIZER:CORP",    SIMPLE, LEVEL_MAIN },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "number",          "NUMBER",       SIMPLE, LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?????????",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "RESOURCE|text",   ALWAYS, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|PATENT",    ALWAYS, LEVEL_MAIN },-	{ "",                "GENRE|patent",    ALWAYS, LEVEL_MAIN },-};--/*- * An entire issue of a periodical- *- * "The title of the periodical is given in the title field. If the issue has - * its own title in addition to the main title of the periodical, it goes in - * the issuetitle field. The editor is omissible..."- */-static lookups periodical[] = {-	{ "editor",          "EDITOR",              BLT_EDITOR, LEVEL_MAIN   },-	{ "editora",         "EDITOR",              BLT_EDITOR, LEVEL_MAIN   },-	{ "editorb",         "EDITOR",              BLT_EDITOR, LEVEL_MAIN   },-	{ "editorc",         "EDITOR",              BLT_EDITOR, LEVEL_MAIN   },-	{ "editortype",      "",                    BLT_SKIP,   LEVEL_MAIN   },-	{ "editoratype",     "",                    BLT_SKIP,   LEVEL_MAIN   },-	{ "editorbtype",     "",                    BLT_SKIP,   LEVEL_MAIN   },-	{ "editorctype",     "",                    BLT_SKIP,   LEVEL_MAIN   },-	{ "director",        "DIRECTOR",            PERSON,     LEVEL_MAIN   },-	{ "producer",        "PRODUCER",            PERSON,     LEVEL_MAIN   },-	{ "execproducer",    "PRODUCER",            PERSON,     LEVEL_MAIN   },-	{ "writer",          "AUTHOR",              PERSON,     LEVEL_MAIN   },-	{ "title",           "TITLE",               TITLE,      LEVEL_HOST   },-	{ "subtitle",        "SUBTITLE",            TITLE,      LEVEL_HOST   },-	{ "titleaddon",      "TITLEADDON",          TITLE,      LEVEL_HOST   },-	{ "shorttitle",      "SHORTTITLE",          SIMPLE,     LEVEL_HOST   },-	{ "issuetitle",      "TITLE",               TITLE,      LEVEL_MAIN   },-	{ "issuesubtitle",   "SUBTITLE",            TITLE,      LEVEL_MAIN   },-	{ "issuetitleaddon", "TITLEADDON",          TITLE,      LEVEL_MAIN   },-	{ "series",          "TITLE",               SIMPLE,     LEVEL_SERIES },-	{ "volume",          "VOLUME",              SIMPLE,     LEVEL_MAIN   },-	{ "number",          "NUMBER",              SIMPLE,     LEVEL_MAIN   },-	{ "issue",           "ISSUE",               SIMPLE,     LEVEL_MAIN   },-	{ "date",            "DATE",                SIMPLE,     LEVEL_MAIN   },   /*WRONG*/-	{ "day",             "PARTDAY",             SIMPLE,     LEVEL_MAIN   },-	{ "month",           "PARTMONTH",           SIMPLE,     LEVEL_MAIN   },-	{ "year",            "PARTYEAR",            SIMPLE,     LEVEL_MAIN   },-	{ "pages",           "PAGES",               PAGES,      LEVEL_MAIN   },-	{ "note",            "NOTES",               SIMPLE,     LEVEL_MAIN   },-	{ "annote",          "ANNOTATION",          SIMPLE,     LEVEL_MAIN   },-	{ "annotation",      "ANNOTATION",          SIMPLE,     LEVEL_MAIN   },-	{ "issn",            "ISSN",                SIMPLE,     LEVEL_HOST   },-	{ "addendum",        "ADDENDUM",            SIMPLE,     LEVEL_MAIN   },-	{ "doi",             "DOI",                 SIMPLE,     LEVEL_MAIN   },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",                    BT_EPRINT,  LEVEL_MAIN   },-	{ "eprinttype",      "",                    BT_EPRINT,  LEVEL_MAIN   },-	{ "url",             "",                    BT_URL,     LEVEL_MAIN   },-	{ "urldate",         "URLDATE",             SIMPLE,     LEVEL_MAIN   },-	{ "urlday",          "?????",               SIMPLE,     LEVEL_MAIN   }, /* WRONG */-	{ "urlmonth",        "?????",               SIMPLE,     LEVEL_MAIN   }, /* WRONG */-	{ "urlyear",         "?????",               SIMPLE,     LEVEL_MAIN   }, /* WRONG */-	{ "address",         "ADDRESS",             SIMPLE,     LEVEL_MAIN   },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",              SIMPLE,     LEVEL_MAIN   },-	{ "",                "ISSUANCE|continuing", ALWAYS,     LEVEL_HOST   },-	{ "",                "RESOURCE|text",       ALWAYS,     LEVEL_MAIN   },-	{ "",                "GENRE|issue",         ALWAYS,     LEVEL_MAIN   },-	{ "",                "GENRE|periodical",    ALWAYS,     LEVEL_HOST   }-};--static lookups proceedings[] = {-	{ "editor",          "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editora",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorb",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editorc",         "EDITOR",       BLT_EDITOR, LEVEL_MAIN },-	{ "editortype",      "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editoratype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorbtype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "editorctype",     "",             BLT_SKIP,   LEVEL_MAIN },-	{ "director",        "DIRECTOR",     PERSON, LEVEL_MAIN },-	{ "producer",        "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "execproducer",    "PRODUCER",     PERSON, LEVEL_MAIN },-	{ "writer",          "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "redactor",        "REDACTOR",     PERSON, LEVEL_MAIN },-	{ "annotator",       "ANNOTATOR",    PERSON, LEVEL_MAIN },-	{ "commentator",     "COMMENTATOR",  PERSON, LEVEL_MAIN },-	{ "translator",      "TRANSLATOR",   PERSON, LEVEL_MAIN },-	{ "eventtitle",      "EVENT:CONF",   SIMPLE, LEVEL_MAIN },-	{ "year",            "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "month",           "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "date",            "DATE",         SIMPLE, LEVEL_MAIN },   /*WRONG*/-	{ "introduction",    "INTROAUTHOR",  PERSON, LEVEL_MAIN },-	{ "foreword",        "INTROAUTHOR",  PERSON, LEVEL_MAIN },-	{ "afterword",       "AFTERAUTHOR",  PERSON, LEVEL_MAIN },-	{ "title",           "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",        "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",      "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",      "SHORTTITLE",   SIMPLE, LEVEL_MAIN },-	{ "maintitle",       "TITLE",        TITLE,  LEVEL_HOST },-	{ "mainsubtitle",    "SUBTITLE",     TITLE,  LEVEL_HOST },-	{ "maintitleaddon",  "TITLEADDON",   TITLE,  LEVEL_HOST },-	{ "language",        "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "origlanguage",    "LANGUAGE",     SIMPLE, LEVEL_ORIG },-	{ "origdate",        "DATE",         SIMPLE, LEVEL_ORIG },-	{ "origyear",        "YEAR",         SIMPLE, LEVEL_ORIG },-	{ "origtitle",       "TITLE",        SIMPLE, LEVEL_ORIG },-	{ "origlocation",    "ADDRESS",      SIMPLE, LEVEL_ORIG },-	{ "origpublisher",   "PUBLISHER",    SIMPLE, LEVEL_ORIG },-	{ "volume",          "VOLUME",       SIMPLE, LEVEL_HOST },-	{ "part",            "PART",         SIMPLE, LEVEL_HOST },-	{ "edition",         "EDITION",      SIMPLE, LEVEL_MAIN },-	{ "volumes",         "NUMVOLUMES",   SIMPLE, LEVEL_HOST },-	{ "series",          "?????",        SIMPLE, LEVEL_HOST }, /* WRONG */-	{ "number",          "NUMBER",       SIMPLE, LEVEL_MAIN },-	{ "note",            "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",          "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",      "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "organization",    "ORGANIZER:CORP",SIMPLE, LEVEL_MAIN },-	{ "publisher",       "PUBLISHER",    SIMPLE, LEVEL_MAIN },-	{ "location",        "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "isbn",            "ISBN",         SIMPLE, LEVEL_MAIN },-	{ "chapter",         "CHAPTER",      SIMPLE, LEVEL_MAIN },-	{ "pages",           "?????????",    SIMPLE, LEVEL_MAIN }, /* WRONG */-	{ "pagetotal",       "?????????",    SIMPLE, LEVEL_MAIN },-	{ "addendum",        "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "doi",             "DOI",          SIMPLE, LEVEL_MAIN },-	{ "pubstate",        "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "eprint",          "",       BT_EPRINT, LEVEL_MAIN },-	{ "eprinttype",      "",   BT_EPRINT, LEVEL_MAIN },-	{ "url",             "",         BT_URL, LEVEL_MAIN },-	{ "urldate",         "URLDATE",      SIMPLE, LEVEL_MAIN },-	{ "urlday",          "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlmonth",        "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlyear",         "?????????",    SIMPLE, LEVEL_MAIN },-	{ "address",         "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",     "LANGCATALOG",            SIMPLE,      LEVEL_MAIN   },-	{ "refnum",          "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",                "INTERNAL_TYPE|BOOK",    ALWAYS, LEVEL_MAIN },-        { "",                "RESOURCE|text",       ALWAYS, LEVEL_MAIN },-        { "",                "GENRE|conference publication",   ALWAYS, LEVEL_MAIN }-};--/* Technical reports */-static lookups report[] = {-	{ "author",      "AUTHOR",               PERSON,        LEVEL_MAIN },-	{ "title",       "TITLE",                TITLE,         LEVEL_MAIN },-	{ "subtitle",    "SUBTITLE",             TITLE,         LEVEL_MAIN },-	{ "titleaddon",  "TITLEADDON",           TITLE,         LEVEL_MAIN },-	{ "shorttitle",  "SHORTTITLE",           SIMPLE,        LEVEL_MAIN },-	{ "series",      "TITLE",                TITLE,         LEVEL_HOST },-	{ "type",        "GENRE",                BT_GENRE,      LEVEL_MAIN },-	{ "institution", "SPONSOR:ASIS",         SIMPLE,        LEVEL_MAIN },-	{ "year",        "YEAR",                 SIMPLE,        LEVEL_MAIN },-	{ "month",       "MONTH",                SIMPLE,        LEVEL_MAIN },-	{ "date",        "DATE",                 SIMPLE,        LEVEL_MAIN },   /*WRONG*/-	{ "language",    "LANGUAGE",             SIMPLE,        LEVEL_MAIN },-	{ "number",      "REPORTNUMBER",         SIMPLE,        LEVEL_MAIN },-	{ "note",        "NOTES",                SIMPLE,        LEVEL_MAIN },-	{ "annote",      "ANNOTATION",           SIMPLE,        LEVEL_MAIN },-	{ "annotation",  "ANNOTATION",           SIMPLE,        LEVEL_MAIN },-	{ "version",     "EDITION",              SIMPLE,        LEVEL_MAIN },-	{ "location",    "ADDRESS",              SIMPLE,        LEVEL_MAIN },-	{ "isrn",        "ISRN",                 SIMPLE,        LEVEL_MAIN },-	{ "chapter",     "CHAPTER",              SIMPLE,        LEVEL_MAIN },-	{ "pages",       "?????????",            SIMPLE,        LEVEL_MAIN }, /* WRONG */-	{ "pagetotal",   "?????????",            SIMPLE,        LEVEL_MAIN },-	{ "addendum",    "ADDENDUM",             SIMPLE,        LEVEL_MAIN },-	{ "doi",         "DOI",                  SIMPLE,        LEVEL_MAIN },-	{ "pubstate",    "PUBSTATE",             SIMPLE,        LEVEL_MAIN },-	{ "eprint",      "",                     BT_EPRINT,     LEVEL_MAIN },-	{ "eprinttype",  "",                     BT_EPRINT,     LEVEL_MAIN },-	{ "url",         "",                     BT_URL,        LEVEL_MAIN },-	{ "urldate",     "URLDATE",              SIMPLE,        LEVEL_MAIN },-	{ "urlday",      "?????????",            SIMPLE,        LEVEL_MAIN },-	{ "urlmonth",    "?????????",            SIMPLE,        LEVEL_MAIN },-	{ "urlyear",     "?????????",            SIMPLE,        LEVEL_MAIN },-	{ "address",     "ADDRESS",              SIMPLE,        LEVEL_MAIN },-	{ "hyphenation", "LANGCATALOG",          SIMPLE,        LEVEL_MAIN },-	{ "refnum",      "REFNUM",               SIMPLE,        LEVEL_MAIN },-	{ "",            "INTERNAL_TYPE|REPORT", ALWAYS,        LEVEL_MAIN },-	{ "",            "RESOURCE|text",        ALWAYS,        LEVEL_MAIN },-	{ "",            "GENRE|report",         ALWAYS,        LEVEL_MAIN }-};--/* Unpublished */-static lookups unpublished[] = {-	{ "author",       "AUTHOR",       PERSON, LEVEL_MAIN },-	{ "title",        "TITLE",        TITLE,  LEVEL_MAIN },-	{ "subtitle",     "SUBTITLE",     TITLE,  LEVEL_MAIN },-	{ "titleaddon",   "TITLEADDON",   TITLE,  LEVEL_MAIN },-	{ "shorttitle",   "SHORTTITLE",           SIMPLE,        LEVEL_MAIN },-	{ "howpublished", "",       HOWPUBLISHED, LEVEL_MAIN },-	{ "year",         "YEAR",         SIMPLE, LEVEL_MAIN },-	{ "month",        "MONTH",        SIMPLE, LEVEL_MAIN },-	{ "day",          "DAY",          SIMPLE, LEVEL_MAIN },-	{ "date",         "DATE",         SIMPLE, LEVEL_MAIN },-	{ "url",          "",         BT_URL, LEVEL_MAIN },-	{ "urlday",       "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlmonth",     "?????????",    SIMPLE, LEVEL_MAIN },-	{ "urlyear",      "?????????",    SIMPLE, LEVEL_MAIN },-	{ "language",     "LANGUAGE",     SIMPLE, LEVEL_MAIN },-	{ "note",         "NOTES",        SIMPLE, LEVEL_MAIN },-	{ "annote",       "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "annotation",   "ANNOTATION",   SIMPLE, LEVEL_MAIN },-	{ "addendum",     "ADDENDUM",     SIMPLE, LEVEL_MAIN },-	{ "address",      "ADDRESS",      SIMPLE, LEVEL_MAIN },-	{ "hyphenation",  "LANGCATALOG",  SIMPLE, LEVEL_MAIN   },-	{ "pubstate",     "PUBSTATE",     SIMPLE, LEVEL_MAIN },-	{ "refnum",       "REFNUM",       SIMPLE, LEVEL_MAIN },-	{ "",             "INTERNAL_TYPE|BOOK",    ALWAYS, LEVEL_MAIN },-	{ "",             "RESOURCE|text",ALWAYS, LEVEL_MAIN },-	{ "",             "GENRE|unpublished",ALWAYS, LEVEL_MAIN }-};--static lookups thesis[] = {-	{ "author",       "AUTHOR",               PERSON,          LEVEL_MAIN },-	{ "title",        "TITLE",                TITLE,           LEVEL_MAIN },-	{ "subtitle",     "SUBTITLE",             TITLE,           LEVEL_MAIN },-	{ "titleaddon",   "TITLEADDON",           TITLE,           LEVEL_MAIN },-	{ "shorttitle",   "SHORTTITLE",           SIMPLE,          LEVEL_MAIN },-	{ "year",         "YEAR",                 SIMPLE,          LEVEL_MAIN },-	{ "month",        "MONTH",                SIMPLE,          LEVEL_MAIN },-	{ "day",          "DAY",                  SIMPLE,          LEVEL_MAIN },-	{ "date",         "DATE",                 SIMPLE,          LEVEL_MAIN },   /*WRONG*/-	{ "type",         "",                     BLT_THESIS_TYPE, LEVEL_MAIN },-	{ "institution",  "DEGREEGRANTOR:ASIS",   SIMPLE,          LEVEL_MAIN },-	{ "school",       "DEGREEGRANTOR:ASIS",   BLT_SCHOOL,      LEVEL_MAIN },-	{ "doi",          "DOI",                  SIMPLE,          LEVEL_MAIN },-	{ "howpublished", "",                     HOWPUBLISHED,    LEVEL_MAIN },-	{ "url",          "",                     BT_URL,      LEVEL_MAIN },-	{ "urldate",      "URLDATE",              SIMPLE,          LEVEL_MAIN },-	{ "urlday",       "?urlday?",             SIMPLE,          LEVEL_MAIN },-	{ "urlmonth",     "?urlmonth?",           SIMPLE,          LEVEL_MAIN },-	{ "urlyear",      "?urlyear?",            SIMPLE,          LEVEL_MAIN },-	{ "language",     "LANGUAGE",             SIMPLE,          LEVEL_MAIN },-	{ "location",     "ADDRESS",              SIMPLE,          LEVEL_MAIN },-	{ "note",         "NOTES",                SIMPLE,          LEVEL_MAIN },-	{ "annote",       "ANNOTATION",           SIMPLE,          LEVEL_MAIN },-	{ "annotation",   "ANNOTATION",           SIMPLE,          LEVEL_MAIN },-	{ "address",      "ADDRESS",              SIMPLE,          LEVEL_MAIN },-	{ "hyphenation",  "LANGCATALOG",          SIMPLE,          LEVEL_MAIN },-	{ "pubstate",     "PUBSTATE",             SIMPLE,          LEVEL_MAIN },-	{ "refnum",       "REFNUM",               SIMPLE,          LEVEL_MAIN },-	{ "",             "INTERNAL_TYPE|THESIS", ALWAYS,          LEVEL_MAIN },-	{ "",             "RESOURCE|text",        ALWAYS,          LEVEL_MAIN },-	{ "",             "GENRE|thesis",         ALWAYS,          LEVEL_MAIN },-};--static lookups phdthesis[] = {-	{ "author",       "AUTHOR",               PERSON,          LEVEL_MAIN },-	{ "title",        "TITLE",                TITLE,           LEVEL_MAIN },-	{ "subtitle",     "SUBTITLE",             TITLE,           LEVEL_MAIN },-	{ "titleaddon",   "TITLEADDON",           TITLE,           LEVEL_MAIN },-	{ "shorttitle",   "SHORTTITLE",           SIMPLE,          LEVEL_MAIN },-	{ "year",         "YEAR",                 SIMPLE,          LEVEL_MAIN },-	{ "month",        "MONTH",                SIMPLE,          LEVEL_MAIN },-	{ "day",          "DAY",                  SIMPLE,          LEVEL_MAIN },-	{ "date",         "DATE",                 SIMPLE,          LEVEL_MAIN },   /*WRONG*/-	{ "type",         "",                     BLT_THESIS_TYPE, LEVEL_MAIN },-	{ "institution",  "DEGREEGRANTOR:ASIS",   SIMPLE,          LEVEL_MAIN },-	{ "school",       "DEGREEGRANTOR:ASIS",   BLT_SCHOOL,      LEVEL_MAIN },-	{ "doi",          "DOI",                  SIMPLE,          LEVEL_MAIN },-	{ "howpublished", "",                     HOWPUBLISHED,    LEVEL_MAIN },-	{ "url",          "",                     BT_URL,      LEVEL_MAIN },-	{ "urldate",      "URLDATE",              SIMPLE,          LEVEL_MAIN },-	{ "urlday",       "?urlday?",             SIMPLE,          LEVEL_MAIN },-	{ "urlmonth",     "?urlmonth?",           SIMPLE,          LEVEL_MAIN },-	{ "urlyear",      "?urlyear?",            SIMPLE,          LEVEL_MAIN },-	{ "language",     "LANGUAGE",             SIMPLE,          LEVEL_MAIN },-	{ "location",     "ADDRESS",              SIMPLE,          LEVEL_MAIN },-	{ "note",         "NOTES",                SIMPLE,          LEVEL_MAIN },-	{ "annote",       "ANNOTATION",           SIMPLE,          LEVEL_MAIN },-	{ "annotation",   "ANNOTATION",           SIMPLE,          LEVEL_MAIN },-	{ "address",      "ADDRESS",              SIMPLE,          LEVEL_MAIN },-	{ "hyphenation",  "LANGCATALOG",          SIMPLE,          LEVEL_MAIN },-	{ "pubstate",     "PUBSTATE",             SIMPLE,          LEVEL_MAIN },-	{ "refnum",       "REFNUM",               SIMPLE,          LEVEL_MAIN },-	{ "",             "INTERNAL_TYPE|THESIS", ALWAYS,          LEVEL_MAIN },-	{ "",             "RESOURCE|text",        ALWAYS,          LEVEL_MAIN },-	{ "",             "GENRE|thesis",         ALWAYS,          LEVEL_MAIN },-	{ "",             "NGENRE|Ph.D. thesis",  DEFAULT,         LEVEL_MAIN },-};--static lookups mastersthesis[] = {-	{ "author",       "AUTHOR",                PERSON,          LEVEL_MAIN },-	{ "title",        "TITLE",                 TITLE,           LEVEL_MAIN },-	{ "subtitle",     "SUBTITLE",              TITLE,           LEVEL_MAIN },-	{ "titleaddon",   "TITLEADDON",            TITLE,           LEVEL_MAIN },-	{ "shorttitle",   "SHORTTITLE",            SIMPLE,          LEVEL_MAIN },-	{ "year",         "YEAR",                  SIMPLE,          LEVEL_MAIN },-	{ "month",        "MONTH",                 SIMPLE,          LEVEL_MAIN },-	{ "day",          "DAY",                   SIMPLE,          LEVEL_MAIN },-	{ "date",         "DATE",                  SIMPLE,          LEVEL_MAIN },   /*WRONG*/-	{ "type",         "",                      BLT_THESIS_TYPE, LEVEL_MAIN },-	{ "institution",  "DEGREEGRANTOR:ASIS",    SIMPLE,          LEVEL_MAIN },-	{ "school",       "DEGREEGRANTOR:ASIS",    BLT_SCHOOL,      LEVEL_MAIN },-	{ "doi",          "DOI",                   SIMPLE,          LEVEL_MAIN },-	{ "howpublished", "",                      HOWPUBLISHED,    LEVEL_MAIN },-	{ "url",          "",                      BT_URL,      LEVEL_MAIN },-	{ "urldate",      "URLDATE",               SIMPLE,          LEVEL_MAIN },-	{ "urlday",       "?urlday?",              SIMPLE,          LEVEL_MAIN },-	{ "urlmonth",     "?urlmonth?",            SIMPLE,          LEVEL_MAIN },-	{ "urlyear",      "?urlyear?",             SIMPLE,          LEVEL_MAIN },-	{ "language",     "LANGUAGE",              SIMPLE,          LEVEL_MAIN },-	{ "location",     "ADDRESS",               SIMPLE,          LEVEL_MAIN },-	{ "note",         "NOTES",                 SIMPLE,          LEVEL_MAIN },-	{ "annote",       "ANNOTATION",            SIMPLE,          LEVEL_MAIN },-	{ "annotation",   "ANNOTATION",            SIMPLE,          LEVEL_MAIN },-	{ "address",      "ADDRESS",               SIMPLE,          LEVEL_MAIN },-	{ "hyphenation",  "LANGCATALOG",           SIMPLE,          LEVEL_MAIN },-	{ "pubstate",     "PUBSTATE",              SIMPLE,          LEVEL_MAIN },-	{ "refnum",       "REFNUM",                SIMPLE,          LEVEL_MAIN },-	{ "",             "INTERNAL_TYPE|THESIS",  ALWAYS,          LEVEL_MAIN },-	{ "",             "RESOURCE|text",         ALWAYS,          LEVEL_MAIN },-	{ "",             "GENRE|thesis",          ALWAYS,          LEVEL_MAIN },-	{ "",             "NGENRE|Masters thesis", DEFAULT,         LEVEL_MAIN },-};--#define ORIG(a) ( &(a[0]) )-#define SIZE(a) ( sizeof( a ) / sizeof( lookups ) )-#define REFTYPE(a,b) { a, ORIG(b), SIZE(b) }--variants biblatex_all[] = {-	REFTYPE( "article", article ),-	REFTYPE( "booklet", booklet ),-	REFTYPE( "book", book ),-	REFTYPE( "collection", collection ),-	REFTYPE( "inbook", inbook ),-	REFTYPE( "incollection", incollection ),-	REFTYPE( "inproceedings", inproceedings ),-	REFTYPE( "conference", inproceedings ), /* legacy */-	REFTYPE( "manual", manual ),-	REFTYPE( "misc", misc ),-	REFTYPE( "online", online ),-	REFTYPE( "electronic", online ), /* legacy */-	REFTYPE( "www", online ),        /* jurabib compatibility */-	REFTYPE( "patent", patent ),-	REFTYPE( "periodical", periodical ),-	REFTYPE( "proceedings", proceedings ),+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "redactor",        "REDACTOR",               PERSON,          LEVEL_MAIN   },+	{ "annotator",       "ANNOTATOR",              PERSON,          LEVEL_MAIN   },+	{ "commentator",     "COMMENTATOR",            PERSON,          LEVEL_MAIN   },+	{ "translator",      "TRANSLATOR",             PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "journal",         "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "journaltitle",    "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "journalsubtitle", "SUBTITLE",               TITLE,           LEVEL_HOST   },+	{ "shortjournal",    "SHORTTITLE",             SIMPLE,          LEVEL_HOST   },+	{ "issuetitle",      "TITLE",                  TITLE,           LEVEL_SERIES }, /*WRONG*/+	{ "issuesubtitle",   "SUBTITLE",               TITLE,           LEVEL_SERIES }, /*WRONG*/+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "origlanguage",    "LANGUAGE",               SIMPLE,          LEVEL_ORIG   },+	{ "origyear",        "YEAR",                   SIMPLE,          LEVEL_ORIG   },+	{ "origdate",        "DATE",                   SIMPLE,          LEVEL_ORIG   },+	{ "origtitle",       "TITLE",                  SIMPLE,          LEVEL_ORIG   },+	{ "origlocation",    "ADDRESS",                SIMPLE,          LEVEL_ORIG   },+	{ "origpublisher",   "PUBLISHER",              SIMPLE,          LEVEL_ORIG   },+	{ "series",          "PARTTITLE",              SIMPLE,          LEVEL_HOST   },+	{ "volume",          "VOLUME",                 SIMPLE,          LEVEL_MAIN   },+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "eid",             "EID",                    SIMPLE,          LEVEL_MAIN   },+	{ "issue",           "ISSUE",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "day",             "PARTDAY",                SIMPLE,          LEVEL_MAIN   },+	{ "month",           "PARTMONTH",              SIMPLE,          LEVEL_MAIN   },+	{ "year",            "PARTYEAR",               SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   },+	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "issn",            "ISSN",                   SIMPLE,          LEVEL_HOST   },+	{ "abstract",        "ABSTRACT",               SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   }, /* WRONG */+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   }, /* WRONG */+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   }, /* WRONG */+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "entrysubtype",    "",                       BLT_SUBTYPE,     LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|ARTICLE",  ALWAYS,          LEVEL_MAIN   },+	{ "",                "ISSUANCE|continuing",    ALWAYS,          LEVEL_HOST   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "NGENRE|journal article", DEFAULT,         LEVEL_MAIN   },+	{ "",                "GENRE|periodical",       DEFAULT,         LEVEL_HOST   }+};++/* Book */++static lookups book[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "redactor",        "REDACTOR",               PERSON,          LEVEL_MAIN   },+	{ "annotator",       "ANNOTATOR",              PERSON,          LEVEL_MAIN   },+	{ "commentator",     "COMMENTATOR",            PERSON,          LEVEL_MAIN   },+	{ "translator",      "TRANSLATOR",             PERSON,          LEVEL_MAIN   },+	{ "introduction",    "INTROAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "foreword",        "INTROAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "afterword",       "AFTERAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "maintitle",       "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "mainsubtitle",    "SUBTITLE",               TITLE,           LEVEL_HOST   },+	{ "maintitleaddon",  "TITLEADDON",             TITLE,           LEVEL_HOST   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "origlanguage",    "LANGUAGE",               SIMPLE,          LEVEL_ORIG   },+	{ "origyear",        "YEAR",                   SIMPLE,          LEVEL_ORIG   },+	{ "origdate",        "DATE",                   SIMPLE,          LEVEL_ORIG   },+	{ "origtitle",       "TITLE",                  SIMPLE,          LEVEL_ORIG   },+	{ "origlocation",    "ADDRESS",                SIMPLE,          LEVEL_ORIG   },+	{ "origpublisher",   "PUBLISHER",              SIMPLE,          LEVEL_ORIG   },+	{ "volume",          "VOLUME",                 SIMPLE,          LEVEL_HOST   },+	{ "part",            "PART",                   SIMPLE,          LEVEL_HOST   },+	{ "edition",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "volumes",         "NUMVOLUMES",             SIMPLE,          LEVEL_HOST   },+	{ "series",          "TITLE",                  SIMPLE,          LEVEL_HOST   }, /* WRONG */+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "isbn",            "ISBN",                   SIMPLE,          LEVEL_MAIN   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   }, /* WRONG */+	{ "pagetotal",       "TOTALPAGES",             SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|book",             ALWAYS,          LEVEL_MAIN   }+};++/* Booklet */++static lookups booklet[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "howpublished",    "",                       HOWPUBLISHED,    LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   },+	{ "pagetotal",       "TOTALPAGES",             SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|book",             ALWAYS,          LEVEL_MAIN   }+};++static lookups collection[] = {+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "redactor",        "REDACTOR",               PERSON,          LEVEL_MAIN   },+	{ "annotator",       "ANNOTATOR",              PERSON,          LEVEL_MAIN   },+	{ "commentator",     "COMMENTATOR",            PERSON,          LEVEL_MAIN   },+	{ "translator",      "TRANSLATOR",             PERSON,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "introduction",    "INTROAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "foreword",        "INTROAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "afterword",       "AFTERAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "maintitle",       "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "mainsubtitle",    "SUBTITLE",               TITLE,           LEVEL_HOST   },+	{ "maintitleaddon",  "TITLEADDON",             TITLE,           LEVEL_HOST   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "origlanguage",    "LANGUAGE",               SIMPLE,          LEVEL_ORIG   },+	{ "origyear",        "YEAR",                   SIMPLE,          LEVEL_ORIG   },+	{ "origdate",        "DATE",                   SIMPLE,          LEVEL_ORIG   },+	{ "origtitle",       "TITLE",                  SIMPLE,          LEVEL_ORIG   },+	{ "origlocation",    "ADDRESS",                SIMPLE,          LEVEL_ORIG   },+	{ "origpublisher",   "PUBLISHER",              SIMPLE,          LEVEL_ORIG   },+	{ "volume",          "VOLUME",                 SIMPLE,          LEVEL_HOST   },+	{ "part",            "PART",                   SIMPLE,          LEVEL_HOST   },+	{ "edition",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "volumes",         "NUMVOLUMES",             SIMPLE,          LEVEL_HOST   },+	{ "series",          "TITLE",                  SIMPLE,          LEVEL_HOST   },+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "isbn",            "ISBN",                   SIMPLE,          LEVEL_MAIN   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   },+	{ "pagetotal",       "TOTALPAGES",             SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|book",             ALWAYS,          LEVEL_MAIN   }+};++/* Part of a book (e.g. chapter or section) */++static lookups inbook[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_HOST   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_HOST   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_HOST   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_HOST   },+	{ "redactor",        "REDACTOR",               PERSON,          LEVEL_HOST   },+	{ "annotator",       "ANNOTATOR",              PERSON,          LEVEL_HOST   },+	{ "commentator",     "COMMENTATOR",            PERSON,          LEVEL_HOST   },+	{ "translator",      "TRANSLATOR",             PERSON,          LEVEL_HOST   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "introduction",    "INTROAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "foreword",        "INTROAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "afterword",       "AFTERAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "booktitle",       "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "booksubtitle",    "SUBTITLE",               TITLE,           LEVEL_HOST   },+	{ "booktitleaddon",  "TITLEADDON",             TITLE,           LEVEL_HOST   },+	{ "bookauthor",      "AUTHOR",                 PERSON,          LEVEL_HOST   },+	{ "maintitle",       "TITLE",                  TITLE,           LEVEL_SERIES },+	{ "mainsubtitle",    "SUBTITLE",               TITLE,           LEVEL_SERIES },+	{ "maintitleaddon",  "TITLEADDON",             TITLE,           LEVEL_SERIES },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "origlanguage",    "LANGUAGE",               SIMPLE,          LEVEL_ORIG   },+	{ "origyear",        "YEAR",                   SIMPLE,          LEVEL_ORIG   },+	{ "origdate",        "DATE",                   SIMPLE,          LEVEL_ORIG   },+	{ "origtitle",       "TITLE",                  SIMPLE,          LEVEL_ORIG   },+	{ "origlocation",    "ADDRESS",                SIMPLE,          LEVEL_ORIG   },+	{ "origpublisher",   "PUBLISHER",              SIMPLE,          LEVEL_ORIG   },+	{ "volume",          "VOLUME",                 SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   },+	{ "part",            "PART",                   SIMPLE,          LEVEL_HOST   },+	{ "edition",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "volumes",         "NUMVOLUMES",             SIMPLE,          LEVEL_HOST   },+	{ "series",          "TITLE",                  SIMPLE,          LEVEL_SERIES+1 }, /* WRONG */+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "isbn",            "ISBN",                   SIMPLE,          LEVEL_HOST   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|INBOOK",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_HOST   },+        { "",                "NGENRE|book chapter",    ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|book",             ALWAYS,          LEVEL_HOST   }+};++/* incollection */++static lookups incollection[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "edition",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "introduction",    "INTROAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "foreword",        "INTROAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "afterword",       "AFTERAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "bookauthor",      "AUTHOR",                 PERSON,          LEVEL_HOST   },+	{ "booktitle",       "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "booksubtitle",    "SUBTITLE",               TITLE,           LEVEL_HOST   },+	{ "booktitleaddon",  "TITLEADDON",             TITLE,           LEVEL_HOST   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_HOST   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_HOST   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_HOST   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_HOST   },+	{ "redactor",        "REDACTOR",               PERSON,          LEVEL_HOST   },+	{ "annotator",       "ANNOTATOR",              PERSON,          LEVEL_HOST   },+	{ "commentator",     "COMMENTATOR",            PERSON,          LEVEL_HOST   },+	{ "translator",      "TRANSLATOR",             PERSON,          LEVEL_HOST   },+	{ "volume",          "VOLUME",                 SIMPLE,          LEVEL_HOST   },+	{ "part",            "PART",                   SIMPLE,          LEVEL_HOST   },+	{ "volumes",         "NUMVOLUMES",             SIMPLE,          LEVEL_HOST   },+	+	{ "maintitle",       "TITLE",                  TITLE,           LEVEL_SERIES },+	{ "mainsubtitle",    "SUBTITLE",               TITLE,           LEVEL_SERIES },+	{ "maintitleaddon",  "TITLEADDON",             TITLE,           LEVEL_SERIES },++	{ "series",          "TITLE",                  SIMPLE,          LEVEL_SERIES+1 }, /* WRONG */++	{ "origlanguage",    "LANGUAGE",               SIMPLE,          LEVEL_ORIG   },+	{ "origyear",        "YEAR",                   SIMPLE,          LEVEL_ORIG   },+	{ "origdate",        "DATE",                   SIMPLE,          LEVEL_ORIG   },+	{ "origtitle",       "TITLE",                  SIMPLE,          LEVEL_ORIG   },+	{ "origlocation",    "ADDRESS",                SIMPLE,          LEVEL_ORIG   },+	{ "origpublisher",   "PUBLISHER",              SIMPLE,          LEVEL_ORIG   },++	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_HOST   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_HOST   },+	{ "isbn",            "ISBN",                   SIMPLE,          LEVEL_MAIN   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   }, /* WRONG */+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|INCOLLECTION", ALWAYS,      LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|collection",       ALWAYS,          LEVEL_HOST   }+};++/* inproceedings */++static lookups inproceedings[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_HOST   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_HOST   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_HOST   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_HOST   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_HOST   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_HOST   },+	{ "redactor",        "REDACTOR",               PERSON,          LEVEL_HOST   },+	{ "annotator",       "ANNOTATOR",              PERSON,          LEVEL_HOST   },+	{ "commentator",     "COMMENTATOR",            PERSON,          LEVEL_HOST   },+	{ "translator",      "TRANSLATOR",             PERSON,          LEVEL_HOST   },+	{ "eventtitle",      "EVENT:CONF",             SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "introduction",    "INTROAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "foreword",        "INTROAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "afterword",       "AFTERAUTHOR",            PERSON,          LEVEL_HOST   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },++	{ "booktitle",       "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "booksubtitle",    "SUBTITLE",               TITLE,           LEVEL_HOST   },+	{ "booktitleaddon",  "TITLEADDON",             TITLE,           LEVEL_HOST   },++	{ "maintitle",       "TITLE",                  TITLE,           LEVEL_SERIES },+	{ "mainsubtitle",    "SUBTITLE",               TITLE,           LEVEL_SERIES },+	{ "maintitleaddon",  "TITLEADDON",             TITLE,           LEVEL_SERIES },++	{ "series",          "TITLE",                  SIMPLE,          LEVEL_SERIES+1 },++	{ "venue",           "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "organization",    "ORGANIZER:CORP",         SIMPLE,          LEVEL_MAIN   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "origlanguage",    "LANGUAGE",               SIMPLE,          LEVEL_ORIG   },+	{ "origdate",        "DATE",                   SIMPLE,          LEVEL_ORIG   },+	{ "origyear",        "YEAR",                   SIMPLE,          LEVEL_ORIG   },+	{ "origtitle",       "TITLE",                  SIMPLE,          LEVEL_ORIG   },+	{ "origlocation",    "ADDRESS",                SIMPLE,          LEVEL_ORIG   },+	{ "origpublisher",   "PUBLISHER",              SIMPLE,          LEVEL_ORIG   },+	{ "volume",          "VOLUME",                 SIMPLE,          LEVEL_HOST   },+	{ "part",            "PART",                   SIMPLE,          LEVEL_HOST   },+	{ "edition",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "volumes",         "NUMVOLUMES",             SIMPLE,          LEVEL_HOST   },+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_HOST   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_HOST   },+	{ "isbn",            "ISBN",                   SIMPLE,          LEVEL_MAIN   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   }, /* WRONG */+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|INPROCEEDINGS", ALWAYS,     LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|conference publication", ALWAYS,    LEVEL_HOST   }+};++static lookups manual[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "redactor",        "REDACTOR",               PERSON,          LEVEL_MAIN   },+	{ "annotator",       "ANNOTATOR",              PERSON,          LEVEL_MAIN   },+	{ "commentator",     "COMMENTATOR",            PERSON,          LEVEL_MAIN   },+	{ "translator",      "TRANSLATOR",             PERSON,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   }, /*WRONG*/+	{ "introduction",    "INTROAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "foreword",        "INTROAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "afterword",       "AFTERAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "edition",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },+	{ "series",          "TITLE",                  SIMPLE,          LEVEL_HOST   },+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "organization",    "ORGANIZER:CORP",         SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "isbn",            "ISBN",                   SIMPLE,          LEVEL_MAIN   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   },+	{ "pagetotal",       "TOTALPAGES",             SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|REPORT",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|instruction",      ALWAYS,          LEVEL_MAIN   }+};++static lookups misc[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "day",             "DAY",                    SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "howpublished",    "",                       HOWPUBLISHED,    LEVEL_MAIN   },+	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "organization",    "ORGANIZER:CORP",         SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|MISC",     ALWAYS,          LEVEL_MAIN   },+};++static lookups online[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },+	{ "day",             "DAY",                    SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "organization",    "ORGANIZER:CORP",         SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+        { "",                "RESOURCE|software, multimedia", ALWAYS,   LEVEL_MAIN   },+	{ "",                "NGENRE|web page",        ALWAYS,          LEVEL_MAIN   },+};++static lookups patent[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "holder",          "ASSIGNEE",               PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },+	{ "day",             "DAY",                    SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "organization",    "ORGANIZER:CORP",         SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|PATENT",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|patent",           ALWAYS,          LEVEL_MAIN   },+};++/*+ * An entire issue of a periodical+ *+ * "The title of the periodical is given in the title field. If the issue has + * its own title in addition to the main title of the periodical, it goes in + * the issuetitle field. The editor is omissible..."+ */+static lookups periodical[] = {+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_HOST   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_HOST   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_HOST   },+	{ "issuetitle",      "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "issuesubtitle",   "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "issuetitleaddon", "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "series",          "TITLE",                  SIMPLE,          LEVEL_SERIES },+	{ "volume",          "VOLUME",                 SIMPLE,          LEVEL_MAIN   },+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "issue",           "ISSUE",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "day",             "PARTDAY",                SIMPLE,          LEVEL_MAIN   },+	{ "month",           "PARTMONTH",              SIMPLE,          LEVEL_MAIN   },+	{ "year",            "PARTYEAR",               SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  PAGES,           LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "issn",            "ISSN",                   SIMPLE,          LEVEL_HOST   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?????",                  SIMPLE,          LEVEL_MAIN   }, /* WRONG */+	{ "urlmonth",        "?????",                  SIMPLE,          LEVEL_MAIN   }, /* WRONG */+	{ "urlyear",         "?????",                  SIMPLE,          LEVEL_MAIN   }, /* WRONG */+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "ISSUANCE|continuing",    ALWAYS,          LEVEL_HOST   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|issue",            ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|periodical",       ALWAYS,          LEVEL_HOST   }+};++static lookups proceedings[] = {+	{ "editor",          "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editora",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorb",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editorc",         "EDITOR",                 BLT_EDITOR,      LEVEL_MAIN   },+	{ "editortype",      "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editoratype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorbtype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "editorctype",     "",                       BLT_SKIP,        LEVEL_MAIN   },+	{ "director",        "DIRECTOR",               PERSON,          LEVEL_MAIN   },+	{ "producer",        "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "execproducer",    "PRODUCER",               PERSON,          LEVEL_MAIN   },+	{ "writer",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "redactor",        "REDACTOR",               PERSON,          LEVEL_MAIN   },+	{ "annotator",       "ANNOTATOR",              PERSON,          LEVEL_MAIN   },+	{ "commentator",     "COMMENTATOR",            PERSON,          LEVEL_MAIN   },+	{ "translator",      "TRANSLATOR",             PERSON,          LEVEL_MAIN   },+	{ "eventtitle",      "EVENT:CONF",             SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "introduction",    "INTROAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "foreword",        "INTROAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "afterword",       "AFTERAUTHOR",            PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "maintitle",       "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "mainsubtitle",    "SUBTITLE",               TITLE,           LEVEL_HOST   },+	{ "maintitleaddon",  "TITLEADDON",             TITLE,           LEVEL_HOST   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "origlanguage",    "LANGUAGE",               SIMPLE,          LEVEL_ORIG   },+	{ "origdate",        "DATE",                   SIMPLE,          LEVEL_ORIG   },+	{ "origyear",        "YEAR",                   SIMPLE,          LEVEL_ORIG   },+	{ "origtitle",       "TITLE",                  SIMPLE,          LEVEL_ORIG   },+	{ "origlocation",    "ADDRESS",                SIMPLE,          LEVEL_ORIG   },+	{ "origpublisher",   "PUBLISHER",              SIMPLE,          LEVEL_ORIG   },+	{ "volume",          "VOLUME",                 SIMPLE,          LEVEL_HOST   },+	{ "part",            "PART",                   SIMPLE,          LEVEL_HOST   },+	{ "edition",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "volumes",         "NUMVOLUMES",             SIMPLE,          LEVEL_HOST   },+	{ "series",          "TITLE",                  SIMPLE,          LEVEL_SERIES },+	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "organization",    "ORGANIZER:CORP",         SIMPLE,          LEVEL_MAIN   },+	{ "publisher",       "PUBLISHER",              SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "isbn",            "ISBN",                   SIMPLE,          LEVEL_MAIN   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  SIMPLE,          LEVEL_MAIN   },+	{ "pagetotal",       "TOTALPAGES",             SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },+        { "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+        { "",                "GENRE|conference publication", ALWAYS,    LEVEL_MAIN   }+};++/* Technical reports */+static lookups report[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "series",          "TITLE",                  TITLE,           LEVEL_HOST   },+	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },+	{ "institution",     "SPONSOR:ASIS",           SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "number",          "REPORTNUMBER",           SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "isrn",            "ISRN",                   SIMPLE,          LEVEL_MAIN   },+	{ "chapter",         "CHAPTER",                SIMPLE,          LEVEL_MAIN   },+	{ "pages",           "PAGES",                  SIMPLE,          LEVEL_MAIN   },+	{ "pagetotal",       "TOTALPAGES",             SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "eprint",          "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "eprinttype",      "",                       BT_EPRINT,       LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|REPORT",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|report",           ALWAYS,          LEVEL_MAIN   }+};++/* Unpublished */+static lookups unpublished[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "howpublished",    "",                       HOWPUBLISHED,    LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "day",             "DAY",                    SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urlday",          "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?????????",              SIMPLE,          LEVEL_MAIN   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "addendum",        "ADDENDUM",               SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|unpublished",      ALWAYS,          LEVEL_MAIN   }+};++static lookups thesis[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "day",             "DAY",                    SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "type",            "",                       BLT_THESIS_TYPE, LEVEL_MAIN   },+	{ "institution",     "DEGREEGRANTOR:ASIS",     SIMPLE,          LEVEL_MAIN   },+	{ "school",          "DEGREEGRANTOR:ASIS",     BLT_SCHOOL,      LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "howpublished",    "",                       HOWPUBLISHED,    LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|THESIS",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|thesis",           ALWAYS,          LEVEL_MAIN   },+};++static lookups phdthesis[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "day",             "DAY",                    SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "type",            "",                       BLT_THESIS_TYPE, LEVEL_MAIN   },+	{ "institution",     "DEGREEGRANTOR:ASIS",     SIMPLE,          LEVEL_MAIN   },+	{ "school",          "DEGREEGRANTOR:ASIS",     BLT_SCHOOL,      LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "howpublished",    "",                       HOWPUBLISHED,    LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|THESIS",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|thesis",           ALWAYS,          LEVEL_MAIN   },+	{ "",                "NGENRE|Ph.D. thesis",    DEFAULT,         LEVEL_MAIN   },+};++static lookups mastersthesis[] = {+	{ "author",          "AUTHOR",                 PERSON,          LEVEL_MAIN   },+	{ "title",           "TITLE",                  TITLE,           LEVEL_MAIN   },+	{ "subtitle",        "SUBTITLE",               TITLE,           LEVEL_MAIN   },+	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },+	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },+	{ "year",            "YEAR",                   SIMPLE,          LEVEL_MAIN   },+	{ "month",           "MONTH",                  SIMPLE,          LEVEL_MAIN   },+	{ "day",             "DAY",                    SIMPLE,          LEVEL_MAIN   },+	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/+	{ "type",            "",                       BLT_THESIS_TYPE, LEVEL_MAIN   },+	{ "institution",     "DEGREEGRANTOR:ASIS",     SIMPLE,          LEVEL_MAIN   },+	{ "school",          "DEGREEGRANTOR:ASIS",     BLT_SCHOOL,      LEVEL_MAIN   },+	{ "doi",             "DOI",                    SIMPLE,          LEVEL_MAIN   },+	{ "howpublished",    "",                       HOWPUBLISHED,    LEVEL_MAIN   },+	{ "url",             "",                       BT_URL,          LEVEL_MAIN   },+	{ "urldate",         "URLDATE",                SIMPLE,          LEVEL_MAIN   },+	{ "urlday",          "?urlday?",               SIMPLE,          LEVEL_MAIN   },+	{ "urlmonth",        "?urlmonth?",             SIMPLE,          LEVEL_MAIN   },+	{ "urlyear",         "?urlyear?",              SIMPLE,          LEVEL_MAIN   },+	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },+	{ "location",        "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "note",            "NOTES",                  SIMPLE,          LEVEL_MAIN   },+	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },+	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },+	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },+	{ "pubstate",        "PUBSTATE",               SIMPLE,          LEVEL_MAIN   },+	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },+	{ "",                "INTERNAL_TYPE|THESIS",   ALWAYS,          LEVEL_MAIN   },+	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },+	{ "",                "GENRE|thesis",           ALWAYS,          LEVEL_MAIN   },+	{ "",                "NGENRE|Masters thesis",  DEFAULT,         LEVEL_MAIN   },+};++#define ORIG(a) ( &(a[0]) )+#define SIZE(a) ( sizeof( a ) / sizeof( lookups ) )+#define REFTYPE(a,b) { a, ORIG(b), SIZE(b) }++variants biblatex_all[] = {+	REFTYPE( "article", article ),+	REFTYPE( "suppperiodical", article ),+	REFTYPE( "booklet", booklet ),+	REFTYPE( "book", book ),+	REFTYPE( "collection", collection ),+	REFTYPE( "reference", collection ),+	REFTYPE( "mvreference", collection ),+	REFTYPE( "inbook", inbook ),+	REFTYPE( "suppbook", inbook ),+	REFTYPE( "incollection", incollection ),+	REFTYPE( "inreference", incollection ),+	REFTYPE( "suppcollection", incollection ),+	REFTYPE( "inproceedings", inproceedings ),+	REFTYPE( "conference", inproceedings ), /* legacy */+	REFTYPE( "manual", manual ),+	REFTYPE( "misc", misc ),+	REFTYPE( "online", online ),+	REFTYPE( "electronic", online ), /* legacy */+	REFTYPE( "www", online ),        /* jurabib compatibility */+	REFTYPE( "patent", patent ),+	REFTYPE( "periodical", periodical ),+	REFTYPE( "proceedings", proceedings ),+	REFTYPE( "mvproceedings", proceedings ), 	REFTYPE( "report", report ), 	REFTYPE( "techreport", report ), /*	REFTYPE( "set", set ), */
bibutils/copacin.c view
@@ -1,7 +1,7 @@ /*  * copacin.c  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Program and source code released under the GPL version 2  *@@ -20,6 +20,9 @@ #include "serialno.h" #include "copacin.h" +/*****************************************************+ PUBLIC: void copacin_initparams()+*****************************************************/ void copacin_initparams( param *p, const char *progname ) {@@ -49,6 +52,10 @@ 	else p->progname = strdup( progname ); } +/*****************************************************+ PUBLIC: int copacin_readf()+*****************************************************/+ /* Endnote-Refer/Copac tag definition:     character 1 = alphabetic character     character 2 = alphabetic character@@ -114,6 +121,10 @@ 	return haveref; } +/*****************************************************+ PUBLIC: int copacin_processf()+*****************************************************/+ static char* copacin_addtag2( char *p, newstr *tag, newstr *data ) {@@ -145,6 +156,7 @@ copacin_processf( fields *copacin, char *p, char *filename, long nref ) { 	newstr tag, data;+	int status; 	newstr_init( &tag ); 	newstr_init( &data ); 	while ( *p ) {@@ -152,8 +164,10 @@ 		if ( copacin_istag( p ) ) { 			p = copacin_addtag2( p, &tag, &data ); 			/* don't add empty strings */-			if ( tag.len && data.len )-				fields_add( copacin, tag.data, data.data, 0 );+			if ( tag.len && data.len ) {+				status = fields_add( copacin, tag.data, data.data, 0 );+				if ( status!=FIELDS_OK ) return 0;+			} 			newstr_empty( &tag ); 			newstr_empty( &data ); 		}@@ -164,6 +178,10 @@ 	return 1; } +/*****************************************************+ PUBLIC: int copacin_convertf(), returns BIBL_OK or BIBL_ERR_MEMERR+*****************************************************/+ /* copac names appear to always start with last name first, but don't  * always seem to have a comma after the name  *@@ -176,17 +194,19 @@ 	char *usetag = tag, editor[]="EDITOR"; 	newstr usename, *s; 	list tokens;-	int comma = 0, i;+	int comma = 0, i, ok;  	if ( list_find( asis, name->data ) !=-1  || 	     list_find( corps, name->data ) !=-1 ) {-		return name_add( info, tag, name->data, level, asis, corps );+		ok = name_add( info, tag, name->data, level, asis, corps );+		if ( ok ) return BIBL_OK;+		else return BIBL_ERR_MEMERR; 	}  	list_init( &tokens ); 	newstr_init( &usename ); -	list_tokenize( &tokens, name, ' ', 1 );+	list_tokenize( &tokens, name, " ", 1 ); 	for ( i=0; i<tokens.n; ++i ) { 		s = list_get( &tokens, i ); 		if ( !strcmp( s->data, "[Editor]" ) ) {@@ -207,90 +227,11 @@ 		newstr_newstrcat( &usename, list_get( &tokens, i ) ); 	} -	return name_add( info, usetag, usename.data, level, asis, corps );-}--static int-copacin_addpage( fields *info, char *p, int level )-{-	newstr page;-	int ok;-	newstr_init( &page );-	p = skip_ws( p );-	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' ) -		newstr_addchar( &page, *p++ );-	if ( page.len>0 ) {-		ok = fields_add( info, "PAGESTART", page.data, level );-		if ( !ok ) return 0;-	}-	newstr_empty( &page );-	while ( *p && (is_ws(*p) || *p=='-' ) ) p++;-	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' ) -		newstr_addchar( &page, *p++ );-	if ( page.len>0 ) {-		ok = fields_add( info, "PAGEEND", page.data, level );-		if ( !ok ) return 0;-	}-	newstr_free( &page );-	return 1;-}+	list_free( &tokens ); -static int-copacin_adddate( fields *info, char *tag, char *newtag, char *p, int level )-{-	char *months[12]={ "January", "February", "March", "April",-		"May", "June", "July", "August", "September",-		"October", "November", "December" };-	char month[10];-	int found,i,part,ok;-	newstr date;-	newstr_init( &date );-	part = (!strncasecmp(newtag,"PART",4));-	if ( !strcasecmp( tag, "%D" ) ) {-		while ( *p ) newstr_addchar( &date, *p++ );-		if ( date.len>0 ) {-			if ( part ) -				ok = fields_add(info, "PARTYEAR", date.data, level);-			else-				ok = fields_add( info, "YEAR", date.data, level );-			if ( !ok ) return 0;-		}-	} else if ( !strcasecmp( tag, "%8" ) ) {-		while ( *p && *p!=' ' && *p!=',' ) newstr_addchar( &date, *p++ );-		if ( date.len>0 ) {-			found = -1;-			for ( i=0; i<12 && found==-1; ++i )-				if ( !strncasecmp( date.data, months[i], 3 ) )-					found = i;-			if ( found!=-1 ) {-				if (found>8) sprintf( month, "%d", found+1 );-				else sprintf( month, "0%d", found+1 );-				if ( part ) -					ok = fields_add( info, "PARTMONTH", month, level );-				else    ok = fields_add( info, "MONTH", month, level );-				if ( !ok ) return 0;-			} else {-				if ( part )-					ok = fields_add( info, "PARTMONTH", date.data, level );-				else-					ok = fields_add( info, "MONTH", date.data, level );-				if ( !ok ) return 0;-			}-		}-		newstr_empty( &date );-		p = skip_ws( p );-		while ( *p && *p!='\n' && *p!=',' )-			newstr_addchar( &date, *p++ );-		if ( date.len>0 && date.len<3 ) {-			if ( part )-				ok = fields_add( info, "PARTDAY", date.data, level );-			else-				ok = fields_add( info, "DAY", date.data, level );-			if ( !ok ) return 0;-		}-	}-	newstr_free( &date );-	return 1;+	ok = name_add( info, usetag, usename.data, level, asis, corps );+	if ( ok ) return BIBL_OK;+	else return BIBL_ERR_MEMERR; }  static void@@ -302,10 +243,18 @@ 	} } +static int+copacin_simple( fields *out, char *tag, char *value, int level )+{+	int fstatus = fields_add( out, tag, value, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}+ int copacin_convertf( fields *copacin, fields *out, int reftype, param *p, variants *all, int nall ) {-	int  process, level, i, n, nfields, ok;+	int  process, level, i, n, nfields, ok, status = BIBL_OK; 	newstr *tag, *data; 	char *newtag; @@ -326,39 +275,35 @@ 		switch ( process ) {  		case SIMPLE:-			ok = fields_add( out, newtag, data->data, level );+			status = copacin_simple( out, newtag, data->data, level ); 			break;  		case TITLE: 			ok = title_process( out, newtag, data->data, level, p->nosplittitle );+			if ( ok ) status = BIBL_OK;+			else status = BIBL_ERR_MEMERR; 			break;  		case PERSON:-			ok = copacin_addname( out, newtag, data, level, &(p->asis), &(p->corps) );-			break;--		case DATE:-			ok = copacin_adddate(out,all[reftype].  tags[i].oldstr,newtag,data->data,level);-			break;--		case PAGES:-			ok = copacin_addpage( out, data->data, level );+			status = copacin_addname( out, newtag, data, level, &(p->asis), &(p->corps) ); 			break;  		case SERIALNO: 			ok = addsn( out, data->data, level );+			if ( ok ) status = BIBL_OK;+			else status = BIBL_ERR_MEMERR; 			break;  		default: 			fprintf(stderr,"%s: internal error -- " "illegal process value %d\n", p->progname, process );-			ok = 1;+			status = BIBL_OK; 			break; 		} -		if ( !ok ) return BIBL_ERR_MEMERR;+		if ( status!=BIBL_OK ) return status;  	} -	return BIBL_OK;+	return status; } 
bibutils/copacin.h view
@@ -1,7 +1,7 @@ /*  * copacin.h  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL  *
bibutils/copactypes.c view
@@ -1,7 +1,7 @@ /*  * copactypes.c  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Program and source code released under the GPL version 2  *
bibutils/ebiin.c view
@@ -16,6 +16,9 @@ #include "xml_encoding.h" #include "ebiin.h" +/*****************************************************+ PUBLIC: void ebiin_initparams()+*****************************************************/ void ebiin_initparams( param *p, const char *progname ) {@@ -46,6 +49,9 @@ 	else p->progname = strdup( progname ); } +/*****************************************************+ PUBLIC: int ebiin_readf()+*****************************************************/ int ebiin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, newstr *line, newstr *reference, int *fcharset ) {@@ -78,27 +84,9 @@ 	return haveref; } --static inline int-xml_hasdata( xml *node )-{-	if ( node && node->value && node->value->data ) return 1;-	return 0;-}--static inline char *-xml_data( xml *node )-{-	return node->value->data;-}---static inline int-xml_tagwithdata( xml *node, char *tag )-{-	if ( !xml_hasdata( node ) ) return 0;-	return xml_tagexact( node, tag );-}+/*****************************************************+ PUBLIC: int ebiin_processf()+*****************************************************/  typedef struct xml_convert { 	char *in;       /* The input tag */@@ -108,72 +96,108 @@ } xml_convert;  static int-ebiin_doconvert( xml *node, fields *info, xml_convert *c, int nc )+ebiin_doconvert( xml *node, fields *info, xml_convert *c, int nc, int *found ) {-	int i, found = 0;+	int i, status; 	char *d;-	if ( !xml_hasdata( node ) ) return 0;++	if ( !xml_hasdata( node ) ) goto out;+ 	d = xml_data( node );-	for ( i=0; i<nc && found==0; ++i ) {+	for ( i=0; i<nc; ++i ) { 		if ( c[i].a==NULL ) { 			if ( xml_tagexact( node, c[i].in ) ) {-				found = 1;-				fields_add( info, c[i].out, d, c[i].level );+				*found = 1;+				status = fields_add( info, c[i].out, d, c[i].level );+				if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+				else return BIBL_OK; 			} 		} else { 			if ( xml_tag_attrib( node, c[i].in, c[i].a, c[i].aval)){-				found = 1;-				fields_add( info, c[i].out, d, c[i].level );+				*found = 1;+				status = fields_add( info, c[i].out, d, c[i].level );+				if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+				else return BIBL_OK; 			} 		} 	 	}-	return found;+out:+	*found = 0;+	return BIBL_OK; }  /* <ArticleTitle>Mechanism and.....</ArticleTitle>+ * and  * <Title>Mechanism and....</Title>  */-static void+static int ebiin_title( xml *node, fields *info, int title_level ) {-	if ( xml_hasdata( node ) )-		fields_add( info, "TITLE", xml_data( node ), title_level );+	int status;+	if ( xml_hasdata( node ) ) {+		status = fields_add( info, "TITLE", xml_data( node ), title_level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	return BIBL_OK; } -/*            <MedlineDate>2003 Jan-Feb</MedlineDate> */-static void-ebiin_medlinedate( fields *info, char *string, int level )+/* ebiin_medlinedate()+ *+ *   - extract medline information from entries like:+ *             <MedlineDate>2003 Jan-Feb</MedlineDate>+ */+static int+ebiin_medlinedate_year( fields *info, char *p, newstr *s, int level, char **end ) {-	newstr tmp;-	char *p, *q;-	newstr_init( &tmp );-	/* extract year */-	p = string;-	q = skip_notws( string );-	newstr_segcpy( &tmp, p, q );-	fields_add( info, "PARTYEAR", tmp.data, level );-	q = skip_ws( q );-	/* extract month */-	if ( q ) {-		p = q;-		newstr_empty( &tmp );-		q = skip_notws( q );-		newstr_segcpy( &tmp, p, q );-		newstr_findreplace( &tmp, "-", "/" );-		fields_add( info, "PARTMONTH", tmp.data, level );-		q = skip_ws( q );+	int status;+	*end = newstr_cpytodelim( s, p, " \t\n\r", 0 );+	if ( newstr_memerr( s ) ) return BIBL_ERR_MEMERR;+	if ( s->len ) {+		status = fields_add( info, "PARTYEAR", s->data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}-	/* extract day */-	if ( q ) {-		p = q;-		newstr_empty( &tmp );-		q = skip_notws( q );-		newstr_segcpy( &tmp, p, q );-		fields_add( info, "PARTDAY", tmp.data, level );+	return BIBL_OK;+}+static int+ebiin_medlinedate_month( fields *info, char *p, newstr *s, int level, char **end )+{+	int status;+	*end = newstr_cpytodelim( s, p, " \t\n\r", 0 );+	newstr_findreplace( s, "-", "/" );+	if ( newstr_memerr( s ) ) return BIBL_ERR_MEMERR;+	if ( s->len ) {+		status = fields_add( info, "PARTMONTH", s->data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}-	newstr_free( &tmp );+	return BIBL_OK; }+static int+ebiin_medlinedate_day( fields *info, char *p, newstr *s, int level, char **end )+{+	int status;+	*end = newstr_cpytodelim( s, p, " \t\n\r", 0 );+	if ( newstr_memerr( s ) ) return BIBL_ERR_MEMERR;+	if ( s->len ) {+		status = fields_add( info, "PARTDAY", s->data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	return BIBL_OK;+}+static int+ebiin_medlinedate( fields *info, char *p, int level )+{+	int status;+	newstr s;+	newstr_init( &s );+	status = ebiin_medlinedate_year( info, skip_ws( p ), &s, level, &p );+	if ( status==BIBL_OK && *p )+		status = ebiin_medlinedate_month( info, skip_ws( p ), &s, level, &p );+	if ( status==BIBL_OK && *p )+		status = ebiin_medlinedate_day( info, skip_ws( p ), &s, level, &p );+	newstr_free( &s );+	return status;+}  /* <Journal>  *    <ISSN>0027-8424</ISSN>@@ -203,7 +227,7 @@  *    <ISOAbbreviation>Alcohol Alcohol.</ISOAbbreviation>  * </Journal>  */-static void+static int ebiin_journal1( xml *node, fields *info ) { 	xml_convert c[] = {@@ -215,59 +239,112 @@ 		{ "Day",      NULL, NULL, "PARTDAY",   1 }, 		{ "Language", NULL, NULL, "LANGUAGE",  1 }, 	};-	int nc = sizeof( c ) / sizeof( c[0] );;-	if ( xml_hasdata( node ) && !ebiin_doconvert( node, info, c, nc ) ) {-		if ( xml_tagexact( node, "MedlineDate" ) )-			ebiin_medlinedate( info, xml_data( node ), 1 );+	int nc = sizeof( c ) / sizeof( c[0] ), status, found;+	if ( xml_hasdata( node ) ) {+		status = ebiin_doconvert( node, info, c, nc, &found );+		if ( status!=BIBL_OK ) return status;+		if ( !found ) {+			if ( xml_tagexact( node, "MedlineDate" ) ) {+				status = ebiin_medlinedate( info, xml_data( node ), 1 );+				if ( status!=BIBL_OK ) return status;+			}+		} 	}-	if ( node->down ) ebiin_journal1( node->down, info );-	if ( node->next ) ebiin_journal1( node->next, info );+	if ( node->down ) {+		status = ebiin_journal1( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = ebiin_journal1( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } - /* <Pagination>  *    <MedlinePgn>12111-6</MedlinePgn>  * </Pagination>  */-static void+static int+ebiin_pages( fields *info, char *p )+{+	int i, status, ret = BIBL_OK;+	const int level = 1;+	newstr sp, ep, *up;++	newstrs_init( &sp, &ep, NULL );++	/* ...start page */+	p = newstr_cpytodelim( &sp, skip_ws( p ), "-", 1 );+	if ( newstr_memerr( &sp ) ) {+		ret = BIBL_ERR_MEMERR;+		goto out;+	}++	/* ...end page */+	p = newstr_cpytodelim( &ep, skip_ws( p ), " \t\n\r", 0 );+	if ( newstr_memerr( &ep ) ) {+		ret = BIBL_ERR_MEMERR;+		goto out;+	}++	if ( sp.len ) {+		status = fields_add( info, "PAGESTART", sp.data, level );+		if ( status!=FIELDS_OK ) {+			ret = BIBL_ERR_MEMERR;+			goto out;+		}+	}+	if ( ep.len ) {+		if ( sp.len > ep.len ) {+			for ( i=sp.len-ep.len; i<sp.len; ++i )+				sp.data[i] = ep.data[i-sp.len+ep.len];+				up = &(sp);+		} else up = &(ep);+		status = fields_add( info, "PAGEEND", up->data, level );+		if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;+	}++out:+	newstrs_free( &sp, &ep, NULL );+	return ret;+}+static int ebiin_pagination( xml *node, fields *info ) {-	newstr sp, ep;-	char *p;-	int i;+	int status; 	if ( xml_tagexact( node, "Pages" ) && node->value ) {-		newstrs_init( &sp, &ep, NULL );-		p = xml_data( node );-		while ( *p && *p!='-' )-			newstr_addchar( &sp, *p++ );-		if ( *p=='-' ) p++;-		while ( *p )-			newstr_addchar( &ep, *p++ );-		if ( sp.len ) fields_add( info, "PAGESTART", sp.data, 1 );-		if ( ep.len ) {-			if ( sp.len > ep.len ) {-				for ( i=sp.len-ep.len; i<sp.len; ++i )-					sp.data[i] = ep.data[i-sp.len+ep.len];-				fields_add( info, "PAGEEND", sp.data, 1 );-			} else-				fields_add( info, "PAGEEND", ep.data, 1 );-		}-		newstrs_free( &sp, &ep, NULL );+		status = ebiin_pages( info, xml_data( node ) );+		if ( status!=BIBL_OK ) return status; 	}-	if ( node->down ) ebiin_pagination( node->down, info );-	if ( node->next ) ebiin_pagination( node->next, info );+	if ( node->down ) {+		status = ebiin_pagination( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = ebiin_pagination( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; }  /* <Abstract>  *    <AbstractText>ljwejrelr</AbstractText>  * </Abstract>  */-static void+static int ebiin_abstract( xml *node, fields *info ) {-	if ( xml_hasdata( node ) && xml_tagexact( node, "AbstractText" ) )-		fields_add( info, "ABSTRACT", xml_data( node ), 0 );-	else if ( node->next ) ebiin_abstract( node->next, info );+	int status;+	if ( xml_hasdata( node ) && xml_tagexact( node, "AbstractText" ) ) {+		status = fields_add( info, "ABSTRACT", xml_data( node ), 0 );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	else if ( node->next ) {+		status = ebiin_abstract( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; }  /* <AuthorList CompleteYN="Y">@@ -279,9 +356,10 @@  *    </Author>  * </AuthorList>  */-static void+static int ebiin_author( xml *node, newstr *name ) {+	int status; 	char *p; 	if ( xml_tagexact( node, "LastName" ) ) { 		if ( name->len ) {@@ -304,28 +382,42 @@ 			if ( !is_ws(*p ) ) newstr_addchar( name, *p++ ); 		} 	}+	if ( newstr_memerr( name ) ) return BIBL_ERR_MEMERR; 		 -	if ( node->down ) ebiin_author( node->down, name );-	if ( node->next ) ebiin_author( node->next, name );-}+	if ( node->down ) {+		status = ebiin_author( node->down, name );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = ebiin_author( node->next, name );+		if ( status!=BIBL_OK ) return status;+	} -static void+	return BIBL_OK;+}+static int ebiin_authorlist( xml *node, fields *info, int level ) {+	int fstatus, status = BIBL_OK; 	newstr name;+ 	newstr_init( &name ); 	node = node->down; 	while ( node ) { 		if ( xml_tagexact( node, "Author" ) && node->down ) {-			ebiin_author( node->down, &name );+			status = ebiin_author( node->down, &name );+			if ( status!=BIBL_OK ) goto out; 			if ( name.len ) {-				fields_add(info,"AUTHOR",name.data,level);+				fstatus = fields_add(info,"AUTHOR",name.data,level);+				if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; } 				newstr_empty( &name ); 			} 		} 		node = node->next; 	}+out: 	newstr_free( &name );+	return status; }  /* <PublicationTypeList>@@ -340,13 +432,23 @@  * </MedlineJournalInfo>  */ -static void+static int ebiin_journal2( xml *node, fields *info ) {-	if ( xml_tagwithdata( node, "TitleAbbreviation" ) )-		fields_add( info, "TITLE", xml_data( node ), 1 );-	if ( node->down ) ebiin_journal2( node->down, info );-	if ( node->next ) ebiin_journal2( node->next, info );+	int status;+	if ( xml_tagwithdata( node, "TitleAbbreviation" ) ) {+		status = fields_add( info, "TITLE", xml_data( node ), 1 );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	if ( node->down ) {+		status = ebiin_journal2( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = ebiin_journal2( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; }  /*@@ -359,23 +461,37 @@  *   </MeshHeading>  * </MeshHeadingList> */-static void+static int ebiin_meshheading( xml *node, fields *info ) {-	if ( xml_tagwithdata( node, "DescriptorName" ) )-		fields_add( info, "KEYWORD", xml_data( node ), 0 );-	if ( node->next ) ebiin_meshheading( node->next, info );+	int status;+	if ( xml_tagwithdata( node, "DescriptorName" ) ) {+		status = fields_add( info, "KEYWORD", xml_data( node ), 0 );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	if ( node->next ) {+		status = ebiin_meshheading( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int ebiin_meshheadinglist( xml *node, fields *info ) {-	if ( xml_tagexact( node, "MeshHeading" ) && node->down )-		ebiin_meshheading( node->down, info );-	if ( node->next ) ebiin_meshheadinglist( node->next, info );+	int status;+	if ( xml_tagexact( node, "MeshHeading" ) && node->down ) {+		status = ebiin_meshheading( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = ebiin_meshheadinglist( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int ebiin_book( xml *node, fields *info, int book_level ) { 	xml_convert book[] = {@@ -409,101 +525,175 @@ 	}; 	int ninbook = sizeof( inbook ) / sizeof( inbook[0] ); 	xml_convert *c;-	int nc;+	int nc, status, found; 	if ( book_level==0 ) { c = book; nc = nbook; } 	else { c = inbook; nc = ninbook; }-	if ( xml_hasdata( node ) && !ebiin_doconvert( node, info, c, nc ) ) {-		if ( xml_tagexact( node, "MedlineDate" ) )-			ebiin_medlinedate( info, xml_data( node ), book_level);-		else if ( xml_tagexact( node, "Title" ) )-			ebiin_title( node, info, book_level );-		else if ( xml_tagexact( node, "Pagination" ) && node->down )-			ebiin_pagination( node->down, info );-		else if ( xml_tagexact( node, "Abstract" ) && node->down )-			ebiin_abstract( node->down, info );-		else if ( xml_tagexact( node, "AuthorList" ) ) -			ebiin_authorlist( node, info, book_level );-		else if ( xml_tagexact( node, "PubDate" ) && node->down)-			ebiin_book( node->down, info, book_level );+	if ( xml_hasdata( node ) ) {+		status = ebiin_doconvert( node, info, c, nc, &found );+		if ( status!=BIBL_OK ) return status;+		if ( !found ) {+			status = BIBL_OK;+			if ( xml_tagexact( node, "MedlineDate" ) )+				status = ebiin_medlinedate( info, xml_data( node ), book_level);+			else if ( xml_tagexact( node, "Title" ) )+				status = ebiin_title( node, info, book_level );+			else if ( xml_tagexact( node, "Pagination" ) && node->down )+				status = ebiin_pagination( node->down, info );+			else if ( xml_tagexact( node, "Abstract" ) && node->down )+				status = ebiin_abstract( node->down, info );+			else if ( xml_tagexact( node, "AuthorList" ) )+				status = ebiin_authorlist( node, info, book_level );+			else if ( xml_tagexact( node, "PubDate" ) && node->down)+				status = ebiin_book( node->down, info, book_level );+			if ( status!=BIBL_OK ) return status;+		} 	}-	if ( node->next ) ebiin_book( node->next, info, book_level );+	if ( node->next ) {+		status = ebiin_book( node->next, info, book_level );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int ebiin_article( xml *node, fields *info ) {+	int status = BIBL_OK;+ 	if ( xml_tagexact( node, "Journal" ) ) -		ebiin_journal1( node, info );+		status = ebiin_journal1( node, info ); 	else if ( node->down && ( xml_tagexact( node, "Book" ) ||  			xml_tagexact(node, "Report") )) -		ebiin_book( node->down, info, 1 );+		status = ebiin_book( node->down, info, 1 ); 	else if ( xml_tagexact( node, "ArticleTitle" ) )-		ebiin_title( node, info, 0 );+		status = ebiin_title( node, info, 0 ); 	else if ( xml_tagexact( node, "Pagination" ) && node->down )-		ebiin_pagination( node->down, info );+		status = ebiin_pagination( node->down, info ); 	else if ( xml_tagexact( node, "Abstract" ) && node->down )-		ebiin_abstract( node->down, info );+		status = ebiin_abstract( node->down, info ); 	else if ( xml_tagexact( node, "AuthorList" ) )-		ebiin_authorlist( node, info, 0 );-	if ( node->next ) ebiin_article( node->next, info );+		status = ebiin_authorlist( node, info, 0 );+	if ( status!=BIBL_OK ) return status;++	if ( node->next ) {+		status = ebiin_article( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}++	return BIBL_OK; } -static void+static int ebiin_publication( xml *node, fields *info ) {+	int status; 	if ( node->down ) { 		if ( xml_tagexact( node, "Article" ) )-			ebiin_article( node->down, info );+			status = ebiin_article( node->down, info ); 		else if ( xml_tagexact( node, "Book" ) )-			ebiin_book( node->down, info, 0 );+			status = ebiin_book( node->down, info, 0 ); 		else if ( xml_tagexact( node, "Report" ) )-			ebiin_book( node->down, info, 0 );+			status = ebiin_book( node->down, info, 0 ); 		else if ( xml_tagexact( node, "JournalInfo" ) )-			ebiin_journal2( node->down, info );+			status = ebiin_journal2( node->down, info ); 		else if ( xml_tagexact( node, "MeshHeadingList" ) )-			ebiin_meshheadinglist( node->down, info );+			status = ebiin_meshheadinglist( node->down, info );+		if ( status!=BIBL_OK ) return status; 	}-	if ( node->next ) ebiin_publication( node->next, info );+	if ( node->next ) {+		status = ebiin_publication( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; }  /* Call with the "Publication" node */-static void+static int ebiin_fixtype( xml *node, fields *info ) {+	char *resource = NULL, *issuance = NULL, *genre1 = NULL, *genre2 = NULL; 	newstr *type;-	fields_add( info, "RESOURCE", "text", 0 );+	int reslvl, isslvl, gen1lvl, gen2lvl;+	int status;+ 	type = xml_getattrib( node, "Type" );-	if ( !type || type->len==0 ) return;+	if ( !type || type->len==0 ) return BIBL_OK;+ 	if ( !strcmp( type->data, "JournalArticle" ) ) {-		fields_add( info, "ISSUANCE", "continuing", 1 );-		fields_add( info, "GENRE", "periodical", 1 );-		fields_add( info, "GENRE", "academic journal", 1 );+		resource = "text";+		issuance = "continuing";+		genre1   = "periodical";+		genre2   = "academic journal";+		reslvl   = 0;+		isslvl   = 1;+		gen1lvl  = 1;+		gen2lvl  = 1; 	} else if ( !strcmp( type->data, "Book" ) ) {-		fields_add( info, "GENRE", "book", 0 );-		fields_add( info, "ISSUANCE", "monographic", 0 );+		resource = "text";+		issuance = "monographic";+		genre1   = "book";+		reslvl   = 0;+		isslvl   = 0;+		gen1lvl  = 0; 	} else if ( !strcmp( type->data, "BookArticle" ) ) {-		fields_add( info, "GENRE", "book", 1 );-		fields_add( info, "ISSUANCE", "monographic", 1 );+		resource = "text";+		issuance = "monographic";+		genre1   = "book";+		reslvl   = 0;+		isslvl   = 1;+		gen1lvl  = 1; 	}++	if ( resource ) {+		status = fields_add( info, "RESOURCE", resource, reslvl );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	if ( issuance ) {+		status = fields_add( info, "ISSUANCE", issuance, isslvl );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	if ( genre1 ) {+		status = fields_add( info, "GENRE", genre1, gen1lvl );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	if ( genre2 ) {+		status = fields_add( info, "GENRE", genre2, gen2lvl );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}++	return BIBL_OK; } -static void+static int ebiin_assembleref( xml *node, fields *info ) {-	if ( xml_tagexact( node, "Publication" ) && node->down) {-		ebiin_fixtype( node, info );-		ebiin_publication( node->down, info );-	} else if ( node->down ) ebiin_assembleref( node->down, info );-	if ( node->next ) ebiin_assembleref( node->next, info );+	int status;+	if ( xml_tagexact( node, "Publication" ) && node->down ) {+		status = ebiin_fixtype( node, info );+		if ( status!=BIBL_OK ) return status;+		status = ebiin_publication( node->down, info );+		if ( status!=BIBL_OK ) return status;+	} else if ( node->down ) {+		status = ebiin_assembleref( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = ebiin_assembleref( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; }  int ebiin_processf( fields *ebiin, char *data, char *filename, long nref ) {+	int status; 	xml top;+ 	xml_init( &top ); 	xml_tree( data, &top );-	ebiin_assembleref( &top, ebiin );+	status = ebiin_assembleref( &top, ebiin ); 	xml_free( &top );-	return 1;++	return ( status==BIBL_OK ) ? 1 : 0; }
bibutils/endin.c view
@@ -1,7 +1,7 @@ /*  * endin.c  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Program and source code released under the GPL version 2  *@@ -21,6 +21,9 @@ #include "reftypes.h" #include "endin.h" +/*****************************************************+ PUBLIC: void endin_initparams()+*****************************************************/ void endin_initparams( param *p, const char *progname ) {@@ -50,6 +53,11 @@ 	else p->progname = strdup( progname ); } ++/*****************************************************+ PUBLIC: int endin_readf()+*****************************************************/+ /* Endnote tag definition:     character 1 = '%'     character 2 = alphabetic character or digit (or other characters)@@ -113,6 +121,9 @@ 	return haveref; } +/*****************************************************+ PUBLIC: int endin_processf()+*****************************************************/ static char* process_endline( newstr *tag, newstr *data, char *p ) {@@ -149,159 +160,37 @@ endin_processf( fields *endin, char *p, char *filename, long nref ) { 	newstr tag, data;-	int n;+	int status, n; 	newstrs_init( &tag, &data, NULL ); 	while ( *p ) {+		newstrs_empty( &tag, &data, NULL ); 		if ( endin_istag( p ) ) { 			p = process_endline( &tag, &data, p );-			/* no empty fields allowed */-			if ( data.len ) {-				fields_add( endin, tag.data, data.data, 0 );-			}+			if ( data.len==0 ) continue;+			status = fields_add( endin, tag.data, data.data, 0 );+			if ( status!=FIELDS_OK ) return 0; 		} else { 			p = process_endline2( &tag, &data, p ); 			/* endnote puts %K only on 1st line of keywords */ 			n = fields_num( endin ); 			if ( n>0 && data.len ) { 			if ( !strncmp( endin->tag[n-1].data, "%K", 2 ) ) {-				fields_add( endin, "%K", data.data, 0 );+				status = fields_add( endin, "%K", data.data, 0 );+				if ( status!=FIELDS_OK ) return 0; 			} else { 				newstr_addchar( &(endin->data[n-1]), ' ' ); 				newstr_strcat( &(endin->data[n-1]), data.data ); 			} 			} 		}-		newstrs_empty( &tag, &data, NULL ); 	} 	newstrs_free( &tag, &data, NULL ); 	return 1; } -static int-endin_addtype( fields *info, char *data, int level )-{-	lookups types[] = {-		{ "GENERIC", "ARTICLE" },-		{ "BOOK", "BOOK" }, -		{ "MANUSCRIPT", "MANUSCRIPT" },-		{ "CONFERENCE PROCEEDINGS", "INPROCEEDINGS"},-		{ "REPORT", "REPORT" },-		{ "COMPUTER PROGRAM", "BOOK" },-		{ "AUDIOVISUAL MATERIAL", "AUDIOVISUAL" },-		{ "ARTWORK", "BOOK" },-		{ "PATENT", "BOOK" },-		{ "BILL", "BILL" },-		{ "CASE", "CASE" },-		{ "JOURNAL ARTICLE", "ARTICLE" }, -		{ "MAGAZINE ARTICLE", "ARTICLE" }, -		{ "BOOK SECTION", "INBOOK" },-		{ "EDITED BOOK", "BOOK" },-       		{ "NEWSPAPER ARTICLE",  "NEWSARTICLE" },-		{ "THESIS", "PHDTHESIS" },-		{ "PERSONAL COMMUNICATION", "COMMUNICATION" },-		{ "ELECTRONIC SOURCE", "TEXT" },-		{ "FILM OR BROADCAST", "AUDIOVISUAL" },-		{ "MAP", "MAP" },-		{ "HEARING", "HEARING" },-		{ "STATUTE", "STATUTE" },-		{ "CHART OR TABLE", "CHART" },-		{ "WEB PAGE", "WEBPAGE" },-	};-	int  ntypes = sizeof( types ) / sizeof( lookups );-	int  i, ok, found=0;-	for ( i=0; i<ntypes; ++i ) {-		if ( !strcasecmp( types[i].oldstr, data ) ) {-			found = 1;-			ok = fields_add( info, "INTERNAL_TYPE", types[i].newstr, level );-			if ( !ok ) return 0;-		}-	}-	if ( !found ) {-		fprintf( stderr, "Did not identify reference type '%s'\n",-			data );-		fprintf( stderr, "Defaulting to journal article type\n");-		ok = fields_add( info, "INTERNAL_TYPE", types[0].newstr, level );-		if ( !ok ) return 0;-	}-	return 1;-}--static int-endin_addpage( fields *info, char *p, int level )-{-	newstr page;-	int ok;-	newstr_init( &page );-	p = skip_ws( p );-	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' ) -		newstr_addchar( &page, *p++ );-	if ( page.len>0 ) {-		ok = fields_add( info, "PAGESTART", page.data, level );-		if ( !ok ) return 0;-	}-	newstr_empty( &page );-	while ( *p && (is_ws(*p) || *p=='-' ) ) p++;-	while ( *p && !is_ws(*p) && *p!='-' && *p!='\r' && *p!='\n' ) -		newstr_addchar( &page, *p++ );-	if ( page.len>0 ) {-		ok = fields_add( info, "PAGEEND", page.data, level );-		if ( !ok ) return 0;-	}-	newstr_free( &page );-	return 1;-}--static int-endin_adddate( fields *info, char *tag, char *newtag, char *p, int level )-{-	char *months[12]={ "January", "February", "March", "April",-		"May", "June", "July", "August", "September",-		"October", "November", "December" };-	char month[10];-	int found,i,part, ok;-	newstr date;-	newstr_init( &date );-	part = (!strncasecmp(newtag,"PART",4));-	if ( !strcasecmp( tag, "%D" ) ) {-		while ( *p ) newstr_addchar( &date, *p++ );-		if ( date.len>0 ) {-			if ( part ) ok = fields_add( info, "PARTYEAR", date.data, level );-			else        ok = fields_add( info, "YEAR",     date.data, level );-			if ( !ok ) return 0;-		}-	} else if ( !strcasecmp( tag, "%8" ) ) {-		while ( *p && *p!=' ' && *p!=',' ) newstr_addchar( &date, *p++ );-		if ( date.len>0 ) {-			found = -1;-			for ( i=0; i<12 && found==-1; ++i )-				if ( !strncasecmp( date.data, months[i], 3 ) )-					found = i;-			if ( found!=-1 ) {-				if (found>8) sprintf( month, "%d", found+1 );-				else sprintf( month, "0%d", found+1 );-				if ( part ) ok = fields_add( info, "PARTMONTH", month, level );-				else        ok = fields_add( info, "MONTH",     month, level );-				if ( !ok ) return 0;-			} else {-				if ( part )-					ok = fields_add( info, "PARTMONTH", date.data, level );-				else-					ok = fields_add( info, "MONTH", date.data, level );-				if ( !ok ) return 0;-			}-		}-		newstr_empty( &date );-		p = skip_ws( p );-		while ( *p && *p!='\n' && *p!=',' ) newstr_addchar( &date, *p++ );-		if ( date.len>0 && date.len<3 ) {-			if ( part ) ok = fields_add( info, "PARTDAY", date.data, level );-			else        ok = fields_add( info, "DAY",     date.data, level );-			if ( !ok ) return 0;-		}-	}-	newstr_free( &date );-	return 1;-}+/*****************************************************+ PUBLIC: int endin_typef()+*****************************************************/  /* Endnote defaults if no %0  *@@ -353,6 +242,10 @@ 	return reftype; } +/*****************************************************+ PUBLIC: void endin_cleanf()+*****************************************************/+ /* Wiley puts multiple authors separated by commas on the %A lines.  * We can detect this by finding the terminal comma in the data.  *@@ -370,51 +263,265 @@ 	return 1; } -static void+static int cleanup_wiley_author( fields *endin, int n ) {	-	newstr tmp, tmppart;-	int i, nauthor = 0;-	newstrs_init( &tmp, &tmppart, NULL );-	newstr_newstrcpy( &tmp, &( endin->data[n] ) );-	i = 0;-	while ( i<tmp.len ) {-		if ( tmp.data[i]==',' ) {-			if ( nauthor==0 )-				newstr_newstrcpy( &(endin->data[n]), &tmppart );-			else-				fields_add( endin, endin->tag[n].data,-					tmppart.data, endin->level[n] );-			newstr_empty( &tmppart );+	newstr *instring, copy, name;+	int status, nauthor = 0;+	char *p;++	newstrs_init( &copy, &name, NULL );++	instring = &( endin->data[n] );+	newstr_newstrcpy( &copy, instring );++	p = copy.data;+	while ( *p ) {+		if ( *p==',' ) {+			if ( newstr_memerr( &name ) )+				return BIBL_ERR_MEMERR;+			if ( nauthor==0 ) {+				/* ...replace the first author in the field */+				newstr_newstrcpy( instring, &name );+				if ( newstr_memerr( instring ) )+					return BIBL_ERR_MEMERR;+			} else {+				status = fields_add( endin, endin->tag[n].data,+					name.data, endin->level[n] );+				if ( status!=FIELDS_OK )+					return BIBL_ERR_MEMERR;+			}+			newstr_empty( &name ); 			nauthor++;-			while ( i<tmp.len && is_ws( tmp.data[i] ) ) i++;+			p++;+			while ( is_ws( *p ) ) p++; 		} else {-			newstr_addchar( &tmppart, tmp.data[i] );+			newstr_addchar( &name, *p );+			p++; 		}-		i++; 	}-	newstrs_free( &tmp, &tmppart, NULL );++	newstrs_free( &copy, &name, NULL );+	return BIBL_OK; } -static void+static int endin_cleanref( fields *endin ) {-	int i, n;+	int i, n, status; 	n = fields_num( endin ); 	for ( i=0; i<n; ++i ) {-		if ( is_wiley_author( endin, i ) )-			cleanup_wiley_author( endin, i );+		if ( is_wiley_author( endin, i ) ) {+			status = cleanup_wiley_author( endin, i );+			if ( status!=BIBL_OK ) return status;+		} 	}+	return BIBL_OK; } -void+int endin_cleanf( bibl *bin, param *p ) {         long i;         for ( i=0; i<bin->nrefs; ++i )                 endin_cleanref( bin->ref[i] );+	return BIBL_OK; } +/*****************************************************+ PUBLIC: int endin_convertf(), returns BIBL_OK or BIBL_ERR_MEMERR+*****************************************************/++static int+endin_addpage( fields *info, char *p, int level )+{+	newstr page;+	int status;++	newstr_init( &page );++	p = newstr_cpytodelim( &page, skip_ws( p ), "- \t\r\n", 0 );+	if ( newstr_memerr( &page ) ) return BIBL_ERR_MEMERR;+	if ( page.len>0 ) {+		status = fields_add( info, "PAGESTART", page.data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}++	while ( *p && (is_ws(*p) || *p=='-' ) ) p++;++	p = newstr_cpytodelim( &page, p, "- \t\r\n", 0 );+	if ( newstr_memerr( &page ) ) return BIBL_ERR_MEMERR;+	if ( page.len>0 ) {+		status = fields_add( info, "PAGEEND", page.data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}++	newstr_free( &page );++	return BIBL_OK;+}++/* month_convert()+ * convert month name to number in format MM, e.g. "January" -> "01"+ * if converted, return 1+ * otherwise return 0+ */+static int+month_convert( char *in, char *out )+{+	char *month1[12]={+		"January",   "February",+		"March",     "April",+		"May",       "June",+		"July",      "August",+		"September", "October",+		"November",  "December"+	};+	char *month2[12]={+		"Jan", "Feb",+		"Mar", "Apr",+		"May", "Jun",+		"Jul", "Aug",+		"Sep", "Oct",+		"Nov", "Dec"+	};+	int i, found = -1;++	for ( i=0; i<12 && found==-1; ++i ) {+		if ( !strcasecmp( in, month1[i] ) ) found = i;+		if ( !strcasecmp( in, month2[i] ) ) found = i;+	}++	if ( found==-1 ) return 0;++	if ( found > 8 )+		sprintf( out, "%d", found+1 );+	else+		sprintf( out, "0%d", found+1 );++	return 1;+}++static int+endin_adddate( fields *info, char *tag, char *newtag, char *p, int level )+{+	char *tags[3][2] = {+		{ "YEAR",  "PARTYEAR" },+		{ "MONTH", "PARTMONTH" },+		{ "DAY",   "PARTDAY" }+	};+	char month[10], *m;+	int part, status;+	newstr date;++	newstr_init( &date );++	if ( !strncasecmp( newtag, "PART", 4 ) ) part = 1;+	else part = 0;++	/* %D YEAR */+	if ( !strcasecmp( tag, "%D" ) ) {+		newstr_cpytodelim( &date, skip_ws( p ), "", 0 );+		if ( newstr_memerr( &date ) ) return BIBL_ERR_MEMERR;+		if ( date.len>0 ) {+			status = fields_add( info, tags[0][part], date.data, level );+			if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		}+	}++	/* %8 MONTH DAY, YEAR */+	/* %8 MONTH, YEAR */+	/* %8 MONTH YEAR */+	else if ( !strcasecmp( tag, "%8" ) ) {++		/* ...get month */+		p = newstr_cpytodelim( &date, skip_ws( p ), " ,\n", 0 );+		if ( newstr_memerr( &date ) ) return BIBL_ERR_MEMERR;+		if ( date.len>0 ) {+			if ( month_convert( date.data, month ) ) m = month;+			else m = date.data;+			status = fields_add( info, tags[1][part], m, level );+			if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		}++		p = skip_ws( p );+		if ( *p==',' ) p++;++		/* ...get days */+		p = newstr_cpytodelim( &date, skip_ws( p ), ",\n", 0 );+		if ( newstr_memerr( &date ) ) return BIBL_ERR_MEMERR;+		if ( date.len>0 && date.len<3 ) {+			status = fields_add( info, tags[2][part], date.data, level );+			if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		} else if ( date.len==4 ) {+			status = fields_add( info, tags[0][part], date.data, level );+			if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		}++		p = skip_ws( p );+		if ( *p==',' ) p++;++		/* ...get year */+		p = newstr_cpytodelim( &date, skip_ws( p ), " \t\n\r", 0 );+		if ( newstr_memerr( &date ) ) return BIBL_ERR_MEMERR;+		if ( date.len > 0 ) {+			status = fields_add( info, tags[0][part], date.data, level );+			if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		}+	}+	newstr_free( &date );+	return BIBL_OK;+}++static int+endin_addtype( fields *info, char *data, int level )+{+	lookups types[] = {+		{ "GENERIC",                "ARTICLE" },+		{ "BOOK",                   "BOOK" },+		{ "MANUSCRIPT",             "MANUSCRIPT" },+		{ "CONFERENCE PROCEEDINGS", "INPROCEEDINGS"},+		{ "REPORT",                 "REPORT" },+		{ "COMPUTER PROGRAM",       "BOOK" },+		{ "AUDIOVISUAL MATERIAL",   "AUDIOVISUAL" },+		{ "ARTWORK",                "BOOK" },+		{ "PATENT",                 "BOOK" },+		{ "BILL",                   "BILL" },+		{ "CASE",                   "CASE" },+		{ "JOURNAL ARTICLE",        "ARTICLE" },+		{ "MAGAZINE ARTICLE",       "ARTICLE" },+		{ "BOOK SECTION",           "INBOOK" },+		{ "EDITED BOOK",            "BOOK" },+		{ "NEWSPAPER ARTICLE",      "NEWSARTICLE" },+		{ "THESIS",                 "PHDTHESIS" },+		{ "PERSONAL COMMUNICATION", "COMMUNICATION" },+		{ "ELECTRONIC SOURCE",      "TEXT" },+		{ "FILM OR BROADCAST",      "AUDIOVISUAL" },+		{ "MAP",                    "MAP" },+		{ "HEARING",                "HEARING" },+		{ "STATUTE",                "STATUTE" },+		{ "CHART OR TABLE",         "CHART" },+		{ "WEB PAGE",               "WEBPAGE" },+	};+	int  ntypes = sizeof( types ) / sizeof( lookups );+	int  i, status, found=0;+	for ( i=0; i<ntypes; ++i ) {+		if ( !strcasecmp( types[i].oldstr, data ) ) {+			found = 1;+			status = fields_add( info, "INTERNAL_TYPE", types[i].newstr, level );+			if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		}+	}+	if ( !found ) {+		fprintf( stderr, "Did not identify reference type '%s'\n",+			data );+		fprintf( stderr, "Defaulting to journal article type\n");+		status = fields_add( info, "INTERNAL_TYPE", types[0].newstr, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	return BIBL_OK;+}+ static void endin_notag( param *p, char *tag, char *data ) {@@ -426,19 +533,30 @@  /* Wiley's EndNote download has DOI's in "%1" tag */ static int-endin_addnotes( fields *info, char *tag, char *data, int level )+endin_addnotes( fields *info, char *tag, char *value, int level ) {-	int doi = is_doi( data );+	int fstatus, doi;+	doi = is_doi( value ); 	if ( doi!=-1 )-		return fields_add( info, "DOI", &(data[doi]), level );+		fstatus = fields_add( info, "DOI", &(value[doi]), level ); 	else-		return fields_add( info, tag, data, level );+		fstatus = fields_add( info, tag, value, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR; } +static int+endin_simple( fields *info, char *tag, char *value, int level )+{+	int fstatus = fields_add( info, tag, value, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}+ int endin_convertf( fields *endin, fields *info, int reftype, param *p, variants *all, int nall ) {-	int i, level, n, process, nfields, ok;+	int i, level, n, process, nfields, ok, fstatus, status = BIBL_OK; 	char *newtag, *t; 	newstr *d; @@ -457,7 +575,8 @@ 		 */ 		t = fields_tag( endin, i, FIELDS_CHRP ); 		if ( t[0]!='%' ) {-			fields_add( info, t, d->data, endin->level[i] );+			fstatus = fields_add( info, t, d->data, endin->level[i] );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 			continue; 		} @@ -473,46 +592,52 @@ 		switch ( process ) {  		case SIMPLE:-			ok = fields_add( info, newtag, d->data, level );+			status = endin_simple( info, newtag, d->data, level ); 			break;  		case TYPE:-			ok = endin_addtype( info, d->data, level );+			status = endin_addtype( info, d->data, level ); 			break;  		case TITLE: 			ok = title_process( info, newtag, d->data, level, p->nosplittitle );+			if ( !ok ) status = BIBL_ERR_MEMERR;+			status = BIBL_OK; 			break;  		case PERSON: 			ok = name_add( info, newtag, d->data, level, &(p->asis), &(p->corps) );+			if ( !ok ) status = BIBL_ERR_MEMERR;+			status = BIBL_OK; 			break;  		case DATE:-			ok = endin_adddate( info, t, newtag,d->data,level);+			status = endin_adddate( info, t, newtag,d->data,level); 			break;  		case PAGES:-			ok = endin_addpage( info, d->data, level );+			status = endin_addpage( info, d->data, level ); 			break;  		case SERIALNO: 			ok = addsn( info, d->data, level );+			if ( !ok ) status = BIBL_ERR_MEMERR;+			status = BIBL_OK; 			break;  		case NOTES:-			ok = endin_addnotes( info, newtag, d->data, level );+			status = endin_addnotes( info, newtag, d->data, level ); 			break;  		default: 			fprintf(stderr,"%s: internal error -- illegal process number %d\n", p->progname, process );-			ok = 1;+			status = BIBL_OK; 			break; 		} -		if ( !ok ) return BIBL_ERR_MEMERR;+		if ( status!=BIBL_OK ) return status;  	} -	return BIBL_OK;+	return status; }
bibutils/endin.h view
@@ -1,7 +1,7 @@ /*  * endin.h  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Source code released under the GPL version 2  *@@ -18,7 +18,7 @@ extern int endin_processf( fields *endin, char *p, char *filename, long nref ); extern int endin_typef( fields *endin, char *filename, int nrefs, param *p, variants *all, int nall ); extern int endin_convertf( fields *endin, fields *info, int reftype, param *p, variants *all, int nall );-extern void endin_cleanf( bibl *bin, param *p );+extern int endin_cleanf( bibl *bin, param *p );  extern void endin_initparams( param *p, const char *progname ); 
bibutils/endout.c view
@@ -28,7 +28,7 @@ 	p->latexout         = 0; 	p->utf8out          = BIBL_CHARSET_UTF8_DEFAULT; 	p->utf8bom          = BIBL_CHARSET_BOM_DEFAULT;-	p->xmlout           = 0;+	p->xmlout           = BIBL_XMLOUT_FALSE; 	p->nosplittitle     = 0; 	p->verbose          = 0; 	p->addcount         = 0;@@ -87,13 +87,62 @@ 	TYPE_UNPUBLISHED,                 /* Unpublished Work */ }; +static void+write_type( FILE *fp, int type )+{+	switch( type ) {+	case TYPE_UNKNOWN:           fprintf( fp, "TYPE_UNKNOWN" );            break;+	case TYPE_GENERIC:           fprintf( fp, "TYPE_GENERIC" );            break;+	case TYPE_ARTWORK:           fprintf( fp, "TYPE_ARTWORK" );            break;+	case TYPE_AUDIOVISUAL:       fprintf( fp, "TYPE_AUDIOVISUAL" );        break;+	case TYPE_BILL:              fprintf( fp, "TYPE_BILL" );               break;+	case TYPE_BOOK:              fprintf( fp, "TYPE_BOOK" );               break;+	case TYPE_INBOOK:            fprintf( fp, "TYPE_INBOOK" );             break;+	case TYPE_CASE:              fprintf( fp, "TYPE_CASE" );               break;+	case TYPE_CHARTTABLE:        fprintf( fp, "TYPE_CHARITABLE" );         break;+	case TYPE_CLASSICALWORK:     fprintf( fp, "TYPE_CLASSICALWORK" );      break;+	case TYPE_PROGRAM:           fprintf( fp, "TYPE_PROGRAM" );            break;+	case TYPE_INPROCEEDINGS:     fprintf( fp, "TYPE_INPROCEEDINGS" );      break;+	case TYPE_PROCEEDINGS:       fprintf( fp, "TYPE_PROCEEDINGS" );        break;+	case TYPE_EDITEDBOOK:        fprintf( fp, "TYPE_EDITEDBOOK" );         break;+	case TYPE_EQUATION:          fprintf( fp, "TYPE_EQUATION" );           break;+	case TYPE_ELECTRONICARTICLE: fprintf( fp, "TYPE_ELECTRONICARTICLE" );  break;+	case TYPE_ELECTRONICBOOK:    fprintf( fp, "TYPE_ELECTRONICBOOK" );     break;+	case TYPE_ELECTRONIC:        fprintf( fp, "TYPE_ELECTRONIC" );         break;+	case TYPE_FIGURE:            fprintf( fp, "TYPE_FIGURE" );             break;+	case TYPE_FILMBROADCAST:     fprintf( fp, "TYPE_FILMBROADCAST" );      break;+	case TYPE_GOVERNMENT:        fprintf( fp, "TYPE_GOVERNMENT" );         break;+	case TYPE_HEARING:           fprintf( fp, "TYPE_HEARING" );            break;+	case TYPE_ARTICLE:           fprintf( fp, "TYPE_ARTICLE" );            break;+	case TYPE_LEGALRULE:         fprintf( fp, "TYPE_LEGALRULE" );          break;+	case TYPE_MAGARTICLE:        fprintf( fp, "TYPE_MAGARTICLE" );         break;+	case TYPE_MANUSCRIPT:        fprintf( fp, "TYPE_MANUSCRIPT" );         break;+	case TYPE_MAP:               fprintf( fp, "TYPE_MAP" );                break;+	case TYPE_NEWSARTICLE:       fprintf( fp, "TYPE_NEWSARTICLE" );        break;+	case TYPE_ONLINEDATABASE:    fprintf( fp, "TYPE_ONLINEDATABASE" );     break;+	case TYPE_ONLINEMULTIMEDIA:  fprintf( fp, "TYPE_ONLINEMULTIMEDIA" );   break;+	case TYPE_PATENT:            fprintf( fp, "TYPE_PATENT" );             break;+	case TYPE_COMMUNICATION:     fprintf( fp, "TYPE_COMMUNICATION" );      break;+	case TYPE_REPORT:            fprintf( fp, "TYPE_REPORT" );             break;+	case TYPE_STATUTE:           fprintf( fp, "TYPE_STATUTE" );            break;+	case TYPE_THESIS:            fprintf( fp, "TYPE_THESIS" );             break;+	case TYPE_MASTERSTHESIS:     fprintf( fp, "TYPE_MASTERSTHESIS" );      break;+	case TYPE_PHDTHESIS:         fprintf( fp, "TYPE_PHDTHESIS" );          break;+	case TYPE_DIPLOMATHESIS:     fprintf( fp, "TYPE_DIPLOMATHESIS" );      break;+	case TYPE_DOCTORALTHESIS:    fprintf( fp, "TYPE_DOCTORALTHESIS" );     break;+	case TYPE_HABILITATIONTHESIS:fprintf( fp, "TYPE_HABILITATIONTHESIS" ); break;+	case TYPE_UNPUBLISHED:       fprintf( fp, "TYPE_UNPUBLISHED" );        break;+	default:                     fprintf( fp, "Error - type not in enum" );break;+	}+}+ typedef struct match_type { 	char *name; 	int type; } match_type;  static int-get_type( fields *info )+get_type( fields *info, param *p, unsigned long refnum ) { 	/* Comment out TYPE_GENERIC entries as that is default, but          * keep in source as record of mapping decision. */@@ -107,8 +156,10 @@ /*		{ "bibliography",              TYPE_GENERIC },*/ 		{ "biography",                 TYPE_BOOK }, 		{ "book",                      TYPE_BOOK },+/*		{ "calendar",                  TYPE_GENERIC },*/ /*		{ "catalog",                   TYPE_GENERIC },*/ 		{ "chart",                     TYPE_CHARTTABLE },+/*		{ "comic or graphic novel",    TYPE_GENERIC },*/ /*		{ "comic strip",               TYPE_GENERIC },*/ 		{ "conference publication",    TYPE_PROCEEDINGS }, 		{ "database",                  TYPE_ONLINEDATABASE },@@ -175,6 +226,7 @@ /*		{ "slide",                     TYPE_GENERIC },*/ 		{ "sound",                     TYPE_AUDIOVISUAL }, /*		{ "speech",                    TYPE_GENERIC },*/+/*		{ "standard or specification", TYPE_GENERIC },*/ /*		{ "statistics",                TYPE_GENERIC },*/ /*		{ "survey of literature",      TYPE_GENERIC },*/ 		{ "technical drawing",         TYPE_ARTWORK },@@ -201,9 +253,10 @@ 	}; 	int nmatch_genres = sizeof( match_genres ) / sizeof( match_genres[0] ); +	int i, j, n, maxlevel, type = TYPE_UNKNOWN; 	char *tag, *data;-	int i, j, type = TYPE_UNKNOWN; +	/* Determine type from genre information */ 	for ( i=0; i<info->n; ++i ) { 		tag = info->tag[i].data; 		if ( strcasecmp( tag, "GENRE" )!=0 &&@@ -215,6 +268,12 @@ 				fields_setused( info, i ); 			} 		}+		if ( p->verbose ) {+			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+			fprintf( stderr, "Type from tag '%s' data '%s': ", info->tag[i].data, info->data[i].data );+			write_type( stderr, type );+			fprintf( stderr, "\n" );+		} 		if ( type==TYPE_UNKNOWN ) { 			if ( !strcasecmp( data, "periodical" ) ) 				type = TYPE_ARTICLE;@@ -231,10 +290,16 @@ 			if ( type!=TYPE_UNKNOWN ) fields_setused( info, i ); 		} 		/* the inbook type should be defined if 'book' in host */-		if ( type==TYPE_BOOK && info->level[i]!=0 ) type = TYPE_INBOOK;-		/* the article types should be defined if it's the host */-		if ( ( type==TYPE_ARTICLE || type==TYPE_MAGARTICLE || type==TYPE_NEWSARTICLE ) && info->level[i]<1 ) type=TYPE_UNKNOWN;+		if ( type==TYPE_BOOK && info->level[i]>0 ) type = TYPE_INBOOK; 	}+	if ( p->verbose ) {+		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+		fprintf( stderr, "Type from genre element: " );+		write_type( stderr, type );+		fprintf( stderr, "\n" );+	}++	/* Determine from resource information */ 	if ( type==TYPE_UNKNOWN ) { 		for ( i=0; i<info->n; ++i ) { 			if ( strcasecmp( info->tag[i].data, "RESOURCE" ) )@@ -246,10 +311,54 @@ 				type = TYPE_PROGRAM; 			if ( type!=TYPE_UNKNOWN ) fields_setused( info, i ); 		}+		if ( p->verbose ) {+			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+			fprintf( stderr, "Type from resource element: " );+			write_type( stderr, type );+			fprintf( stderr, "\n" );+		} 	} -	/* default to generic */-	if ( type==TYPE_UNKNOWN ) type = TYPE_GENERIC;+	/* Determine from issuance information */+	if ( type==TYPE_UNKNOWN ) {+		for ( i=0; i<info->n; ++i ) {+			if ( strcasecmp( info->tag[i].data, "ISSUANCE" ) )+				continue;+			data = info->data[i].data;+			if ( !strcasecmp( data, "monographic" ) ) {+				if ( info->level[i]==0 ) type = TYPE_BOOK;+				else type = TYPE_INBOOK;+			}+		}+		if ( p->verbose ) {+			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+			fprintf( stderr, "Type from issuance element: " );+			write_type( stderr, type );+			fprintf( stderr, "\n" );+		}+	}++	/* default to generic or book chapter, depending on maxlevel */+	if ( type==TYPE_UNKNOWN ) {+		maxlevel = fields_maxlevel( info );+		if ( maxlevel > 0 ) type = TYPE_INBOOK;+		else {+			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+			fprintf( stderr, "Cannot identify TYPE in reference %lu ", refnum+1 );+			n = fields_find( info, "REFNUM", -1 );+			if ( n!=-1 )+				fprintf( stderr, " %s", info->data[n].data );+			fprintf( stderr, " (defaulting to generic)\n" );+			type = TYPE_GENERIC;+		}+	}++	if ( p->verbose ) {+		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+		fprintf( stderr, "Final type: " );+		write_type( stderr, type );+		fprintf( stderr, "\n" );+	} 	 	return type; }@@ -524,7 +633,7 @@  	fields_clearused( info ); -	type = get_type( info );+	type = get_type( info, p, refnum );  	output_type( fp, type, p ); @@ -597,6 +706,7 @@ 	output_easyall( fp, info, "KEYWORD",         "%K", LEVEL_ANY ); 	output_easyall( fp, info, "NGENRE",          "%9", LEVEL_ANY ); 	output_thesishint( fp, type );+	output_easyall( fp, info, "DOI",             "%R", LEVEL_ANY ); 	output_easyall( fp, info, "URL",             "%U", LEVEL_ANY );  	output_easyall( fp, info, "FILEATTACH",      "%U", LEVEL_ANY );  	output_doi( fp, info );
bibutils/endxmlin.c view
@@ -1,7 +1,7 @@ /*  * endxmlin.c  *- * Copyright (c) Chris Putnam 2006-2013+ * Copyright (c) Chris Putnam 2006-2014  *  * Program and source code released under the GPL version 2  *@@ -23,6 +23,9 @@ 	char *internal; } attribs; +/*****************************************************+ PUBLIC: void endxmlin_initparams()+*****************************************************/ void endxmlin_initparams( param *p, const char *progname ) {@@ -52,6 +55,10 @@ 	else p->progname = strdup( progname ); } +/*****************************************************+ PUBLIC: int endxmlin_readf()+*****************************************************/+ static int xml_readmore( FILE *fp, char *buf, int bufsize, int *bufpos ) {@@ -110,6 +117,10 @@ 	return haveref; } +/*****************************************************+ PUBLIC: int endxmlin_processf()+*****************************************************/+ /*  * add data to fields  */@@ -127,26 +138,39 @@  *          <style>aaa</style><style>aaaa</style>  *   </datatype>  */-void+static int endxmlin_datar( xml *node, newstr *s ) {-	if ( node->value && node->value->len )+	int status;+	if ( node->value && node->value->len ) { 		newstr_strcat( s, node->value->data );-	if ( node->down && xml_tagexact( node->down, "style" ) )-		endxmlin_datar( node->down, s );-	if ( xml_tagexact( node, "style" ) && node->next )-		endxmlin_datar( node->next, s );+		if ( newstr_memerr( s ) ) return BIBL_ERR_MEMERR;+	}+	if ( node->down && xml_tagexact( node->down, "style" ) ) {+		status = endxmlin_datar( node->down, s );+		if ( status!=BIBL_OK ) return status;+	}+	if ( xml_tagexact( node, "style" ) && node->next ) {+		status = endxmlin_datar( node->next, s );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -void+static int endxmlin_data( xml *node, char *inttag, fields *info, int level ) {+	int status; 	newstr s; 	newstr_init( &s );-	endxmlin_datar( node, &s );-	if ( s.len )-		fields_add( info, inttag, s.data, level );+	status = endxmlin_datar( node, &s );+	if ( status!=BIBL_OK ) return status;+	if ( s.len ) {+		status = fields_add( info, inttag, s.data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	} 	newstr_free( &s );+	return BIBL_OK; }  /* <titles>@@ -155,7 +179,7 @@  *    </title>  * </titles>  */-void+static int endxmlin_titles( xml *node, fields *info ) { 	attribs a[] = {@@ -165,20 +189,26 @@ 		{ "alt-title", "%!" }, 		{ "short-title", "SHORTTITLE" }, 	};-	int i, n = sizeof( a ) / sizeof ( a[0] );+	int i, status, n = sizeof( a ) / sizeof ( a[0] ); 	newstr title; 	newstr_init( &title ); 	for ( i=0; i<n; ++i ) { 		if ( xml_tagexact( node, a[i].attrib ) && node->down ) { 			newstr_empty( &title );-			endxmlin_datar( node, &title );+			status = endxmlin_datar( node, &title );+			if ( status!=BIBL_OK ) return BIBL_ERR_MEMERR; 			newstr_trimstartingws( &title ); 			newstr_trimendingws( &title );-			fields_add( info, a[i].internal, title.data, 0);+			status = fields_add( info, a[i].internal, title.data, 0);+			if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR; 		} 	}-	if ( node->next ) endxmlin_titles( node->next, info );+	if ( node->next ) {+		status = endxmlin_titles( node->next, info );+		if ( status!=BIBL_OK ) return status;+	} 	newstr_free( &title );+	return BIBL_OK; }  /* <contributors>@@ -202,65 +232,84 @@  * >  *  */-void+static int endxmlin_contributor( xml *node, fields *info, char *int_tag, int level ) {-	endxmlin_data( node, int_tag, info, level );-	if ( node->next )-		endxmlin_contributor( node->next, info, int_tag, level );+	int status;+	status = endxmlin_data( node, int_tag, info, level );+	if ( status!=BIBL_OK ) return status;+	if ( node->next ) {+		status = endxmlin_contributor( node->next, info, int_tag, level );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int endxmlin_contributors( xml *node, fields *info ) {-	attribs contrib[] = {+	attribs a[] = { 		{ "authors", "%A" }, 		{ "secondary-authors", "%E" }, 		{ "tertiary-authors", "%Y" }, 		{ "subsidiary-authors", "%?" }, 		{ "translated-authors", "%?" }, 	};-	int i, n = sizeof( contrib ) / sizeof ( contrib[0] );+	int i, status, n = sizeof( a ) / sizeof ( a[0] ); 	for ( i=0; i<n; ++i ) {-		if ( xml_tagexact( node, contrib[i].attrib ) && node->down )-			endxmlin_contributor( node->down, info, contrib[i].internal, 0 );+		if ( xml_tagexact( node, a[i].attrib ) && node->down ) {+			status = endxmlin_contributor( node->down, info, a[i].internal, 0 );+			if ( status!=BIBL_OK ) return status;+		} 	}-	if ( node->next )-		endxmlin_contributors( node->next, info );+	if ( node->next ) {+		status = endxmlin_contributors( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int endxmlin_keyword( xml *node, fields *info ) {-	if ( xml_tagexact( node, "keyword" ) )-		endxmlin_data( node, "%K", info, 0 );-	if ( node->next )-		endxmlin_keyword( node->next, info );+	int status;+	if ( xml_tagexact( node, "keyword" ) ) {+		status = endxmlin_data( node, "%K", info, 0 );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = endxmlin_keyword( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int endxmlin_keywords( xml *node, fields *info ) { 	if ( node->down && xml_tagexact( node->down, "keyword" ) )-		endxmlin_keyword( node->down, info );+		return endxmlin_keyword( node->down, info );+	return BIBL_OK; }  /*  *<electronic-resource-num><style face="normal" font="default"   * size="100%">10.1007/BF00356334</style></electronic-resource-num>  */-static void+static int endxmlin_ern( xml *node, fields *info ) { 	if ( xml_tagexact( node, "electronic-resource-num" ) )-		endxmlin_data( node, "DOI", info, 0 );+		return endxmlin_data( node, "DOI", info, 0 );+	return BIBL_OK; } -static void+static int endxmlin_language( xml *node, fields *info ) { 	if ( xml_tagexact( node, "language" ) )-		endxmlin_data( node, "%G", info, 0 );+		return endxmlin_data( node, "%G", info, 0 );+	return BIBL_OK; }  /*@@ -270,77 +319,108 @@  *    </pdf-urls>  * </urls>  */-static void+static int endxmlin_fileattach( xml *node, fields *info ) {-	if ( xml_tagexact( node, "url" ) )-		endxmlin_data( node, "FILEATTACH", info, 0 );-	if ( node->down ) endxmlin_fileattach( node->down, info );-	if ( node->next ) endxmlin_fileattach( node->next, info );+	int status;+	if ( xml_tagexact( node, "url" ) ) {+		status = endxmlin_data( node, "FILEATTACH", info, 0 );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->down ) {+		status = endxmlin_fileattach( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = endxmlin_fileattach( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int endxmlin_urls( xml *node, fields *info ) {-	if ( xml_tagexact( node, "pdf-urls" ) && node->down )-		endxmlin_fileattach( node->down, info );-	else if ( xml_tagexact( node, "url" ) )-		endxmlin_data( node, "%U", info, 0 );-	else {+	int status;+	if ( xml_tagexact( node, "pdf-urls" ) && node->down ) {+		status = endxmlin_fileattach( node->down, info );+		if ( status!=BIBL_OK ) return status;+	} else if ( xml_tagexact( node, "url" ) ) {+		status = endxmlin_data( node, "%U", info, 0 );+		if ( status!=BIBL_OK ) return status;+	} else { 		if ( node->down ) { 			if ( xml_tagexact( node->down, "related-urls" ) || 			     xml_tagexact( node->down, "pdf-urls" ) ||-			     xml_tagexact( node->down, "url" ) )-				endxmlin_urls( node->down, info );+			     xml_tagexact( node->down, "url" ) ) {+				status = endxmlin_urls( node->down, info );+				if ( status!=BIBL_OK ) return status;+			} 		} 	}-	if ( node->next )-		endxmlin_urls( node->next, info );+	if ( node->next ) {+		status = endxmlin_urls( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int endxmlin_pubdates( xml *node, fields *info ) { 	if ( xml_tagexact( node, "date" ) )-		endxmlin_data( node, "%8", info, 0 );+		return endxmlin_data( node, "%8", info, 0 ); 	else { 		if ( node->down && xml_tagexact( node->down, "date" ) )-			endxmlin_pubdates( node->down, info );+			return endxmlin_pubdates( node->down, info ); 	}+	return BIBL_OK; } -static void+static int endxmlin_dates( xml *node, fields *info ) {-	if ( xml_tagexact( node, "year" ) )-		endxmlin_data( node, "%D", info, 0 );-	else {+	int status;+	if ( xml_tagexact( node, "year" ) ) {+		status = endxmlin_data( node, "%D", info, 0 );+		if ( status!=BIBL_OK ) return status;+	} else { 		if ( node->down ) {-			if ( xml_tagexact( node->down, "year" ) )-				endxmlin_dates( node->down, info );-			if ( xml_tagexact( node->down, "pub-dates" ) )-				endxmlin_pubdates( node->down, info );+			if ( xml_tagexact( node->down, "year" ) ) {+				status = endxmlin_dates( node->down, info );+				if ( status!=BIBL_OK ) return status;+			}+			if ( xml_tagexact( node->down, "pub-dates" ) ) {+				status = endxmlin_pubdates( node->down, info );+				if ( status!=BIBL_OK );+			} 		} 	}-	if ( node->next )-		endxmlin_dates( node->next, info );+	if ( node->next ) {+		status = endxmlin_dates( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; }  /*  * <ref-type name="Journal Article">17</ref-type>  */-static void+static int endxmlin_reftype( xml *node, fields *info ) {+	int status; 	newstr *s; 	s = xml_getattrib( node, "name" );-	if ( s && s->dim ) {-		fields_add( info, "%0", s->data, 0 );+	if ( s && s->len ) {+		status = fields_add( info, "%0", s->data, 0 ); 		newstr_free( s );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}+	return BIBL_OK; } -static void+static int endxmlin_record( xml *node, fields *info ) { 	attribs a[] = {@@ -369,28 +449,35 @@ 		{ "custom5", "%#" }, 		{ "custom6", "%$" }, 	};-	int i, n = sizeof ( a ) / sizeof( a[0] );+	int i, status, n = sizeof ( a ) / sizeof( a[0] ); 	if ( xml_tagexact( node, "DATABASE" ) ) {-/*		endxmlin_database( node, info );*/ 	} else if ( xml_tagexact( node, "SOURCE-APP" ) ) {-/*		endxmlin_sourceapp( node, info );*/ 	} else if ( xml_tagexact( node, "REC-NUMBER" ) ) { 	} else if ( xml_tagexact( node, "ref-type" ) ) {-		endxmlin_reftype( node, info );+		status = endxmlin_reftype( node, info );+		if ( status!=BIBL_OK ) return status; 	} else if ( xml_tagexact( node, "contributors" ) ) {-		if ( node->down ) endxmlin_contributors( node->down, info );+		if ( node->down ) {+			status = endxmlin_contributors( node->down, info );+			if ( status!=BIBL_OK ) return status;+		} 	} else if ( xml_tagexact( node, "titles" ) ) { 		if ( node->down ) endxmlin_titles( node->down, info ); 	} else if ( xml_tagexact( node, "keywords" ) ) {-		endxmlin_keywords( node, info );+		status = endxmlin_keywords( node, info );+		if ( status!=BIBL_OK ) return status; 	} else if ( xml_tagexact( node, "urls" ) ) {-		endxmlin_urls( node, info );+		status = endxmlin_urls( node, info );+		if ( status!=BIBL_OK ) return status; 	} else if ( xml_tagexact( node, "electronic-resource-num" ) ) {-		endxmlin_ern( node, info );+		status = endxmlin_ern( node, info );+		if ( status!=BIBL_OK ) return status; 	} else if ( xml_tagexact( node, "dates" ) ) {-		endxmlin_dates( node, info );+		status = endxmlin_dates( node, info );+		if ( status!=BIBL_OK ) return status; 	} else if ( xml_tagexact( node, "language" ) ) {-		endxmlin_language( node, info );+		status = endxmlin_language( node, info );+		if ( status!=BIBL_OK ) return status; 	} else if ( xml_tagexact( node, "periodical" ) ) { 	} else if ( xml_tagexact( node, "secondary-volume" ) ) { 	} else if ( xml_tagexact( node, "secondary-issue" ) ) {@@ -419,22 +506,33 @@ 	} else if ( xml_tagexact( node, "misc3" ) ) { 	} else { 		for ( i=0; i<n; ++i ) {-			if ( xml_tagexact( node, a[i].attrib ) ) -				endxmlin_data( node, a[i].internal, info, 0 );+			if ( xml_tagexact( node, a[i].attrib ) ) {+				status = endxmlin_data( node, a[i].internal, info, 0 );+				if ( status!=BIBL_OK ) return status;+			} 		} 	}-	if ( node->next ) endxmlin_record( node->next, info );+	if ( node->next ) {+		status = endxmlin_record( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int endxmlin_assembleref( xml *node, fields *info ) {+	int status; 	if ( node->tag->len==0 ) {-		if ( node->down ) endxmlin_assembleref( node->down, info );-		return;+		if ( node->down )+			return endxmlin_assembleref( node->down, info ); 	} else if ( xml_tagexact( node, "RECORD" ) ) {-		if ( node->down ) endxmlin_record( node->down, info );+		if ( node->down ) {+			status = endxmlin_record( node->down, info );+			if ( status!=BIBL_OK ) return status;+		} 	}+	return BIBL_OK; }  /* endxmlin_processf first operates by converting to endnote input@@ -446,10 +544,14 @@ int endxmlin_processf( fields *fin, char *data, char *filename, long nref ) {+	int status; 	xml top;+ 	xml_init( &top ); 	xml_tree( data, &top );-	endxmlin_assembleref( &top, fin );+	status = endxmlin_assembleref( &top, fin ); 	xml_free( &top );-	return 1;++	if ( status==BIBL_OK ) return 1;+	return 0; }
bibutils/endxmlin.h view
@@ -1,7 +1,7 @@ /*  * endxmlin.h  *- * Copyright (c) Chris Putnam 2006-2013+ * Copyright (c) Chris Putnam 2006-2014  *  * Source code released under the GPL version 2  *
bibutils/fields.c view
@@ -10,7 +10,6 @@ #include <stdlib.h> #include <stdint.h> #include <string.h>-#include <assert.h> #include "fields.h"  fields*@@ -24,8 +23,6 @@ void fields_init( fields *f ) {-	assert( f );- 	f->used  = NULL; 	f->level = NULL; 	f->tag   = NULL;@@ -38,8 +35,6 @@ { 	int i; -	assert( f );- 	for ( i=0; i<f->max; ++i ) { 		newstr_free( &(f->tag[i]) ); 		newstr_free( &(f->data[i]) );@@ -67,7 +62,7 @@ 		if ( f->used )  free( f->used ); 		if ( f->level ) free( f->level ); 		fields_init( f );-		return 0;+		return FIELDS_ERR; 	}  	f->max = alloc;@@ -76,7 +71,7 @@ 		newstr_init( &(f->tag[i]) ); 		newstr_init( &(f->data[i]) ); 	}-	return 1;+	return FIELDS_OK; }  static int@@ -97,7 +92,7 @@ 	if ( newlevel ) f->level = newlevel; 	 	if ( !newtags || !newdata || !newused || !newlevel )-		return 0;+		return FIELDS_ERR;  	f->max = alloc; @@ -106,22 +101,22 @@ 		newstr_init( &(f->data[i]) ); 	} -	return 1;+	return FIELDS_OK; }  int fields_add( fields *f, char *tag, char *data, int level ) {-	int i, found;--	assert( f );+	int i, status, found; -	if ( !tag || !data ) return 1;+	if ( !tag || !data ) return FIELDS_OK;  	if ( f->max==0 ) {-		if ( !fields_alloc( f ) ) return 0;+		status = fields_alloc( f );+		if ( status!=FIELDS_OK ) return status; 	} else if ( f->n >= f->max ) {-		if ( !fields_realloc( f ) ) return 0;+		status = fields_realloc( f );+		if ( status!=FIELDS_OK ) return status; 	}  	/* Don't duplicate identical entries */@@ -132,13 +127,16 @@ 		     !strcasecmp( f->data[i].data, data ) ) found = 1; 	} 	if ( !found ) {+		f->used[ f->n ]  = 0;+		f->level[ f->n ] = level; 		newstr_strcpy( &(f->tag[f->n]), tag ); 		newstr_strcpy( &(f->data[f->n]), data );-		f->used[ f->n ] = 0;-		f->level[ f->n ] = level;+		if ( newstr_memerr( &(f->tag[f->n]) ) ||+		     newstr_memerr( &(f->data[f->n] ) ) )+			return FIELDS_ERR; 		f->n++; 	}-	return 1;+	return FIELDS_OK; }  int@@ -148,44 +146,26 @@ 	newstr newtag; 	int ret; -	assert( f );-	assert( tag );-	assert( suffix );- 	newstr_init( &newtag ); 	newstr_mergestrs( &newtag, tag, suffix, NULL );-	ret = fields_add( f, newtag.data, data, level );+	if ( newstr_memerr( &newtag ) ) ret = FIELDS_ERR;+	else ret = fields_add( f, newtag.data, data, level ); 	newstr_free( &newtag );  	return ret; } -/* fields_get_level()- *- */-inline int-fields_get_level( fields *f, int n )-{-	assert( f );-	assert( n>=0 );-	assert( n<f->n );--	return f->level[n];-}- /* fields_match_level()  *  * returns 1 if level matched, 0 if not  *- * level==-1 is a special flag meaning any level can match+ * level==LEVEL_ANY is a special flag meaning any level can match  */ inline int fields_match_level( fields *f, int n, int level ) {-	assert( f );- 	if ( level==LEVEL_ANY ) return 1;-	if ( fields_get_level( f, n )==level ) return 1;+	if ( fields_level( f, n )==level ) return 1; 	return 0; } @@ -232,9 +212,6 @@ { 	int i; -	assert( f );-	assert( tag );- 	for ( i=0; i<f->n; ++i ) { 		if ( !fields_match_casetag_level( f, i, tag, level ) ) 			continue;@@ -254,11 +231,12 @@ { 	int i, max = 0; -	assert( f );--	for ( i=0; i<f->n; ++i ) {-		if ( f->level[i] > max )-			max = f->level[i];+	if ( f->n ) {+		max = f->level[0];+		for ( i=1; i<f->n; ++i ) {+			if ( f->level[i] > max )+				max = f->level[i];+		} 	}  	return max;@@ -269,8 +247,6 @@ { 	int i; -	assert( f );- 	for ( i=0; i<f->n; ++i ) 		f->used[i] = 0; }@@ -278,15 +254,13 @@ void fields_setused( fields *f, int n ) {-	assert( f );--	if ( n < f->n )+	if ( n >= 0 && n < f->n ) 		f->used[n] = 1; }  /* fields_replace_or_add()  *- * return 1 on success, 0 on memory error+ * return FIELDS_OK on success, FIELDS_ERR on memory error  */ int fields_replace_or_add( fields *f, char *tag, char *data, int level )@@ -295,7 +269,8 @@ 	if ( n==-1 ) return fields_add( f, tag, data, level ); 	else { 		newstr_strcpy( &(f->data[n]), data );-		return 1;+		if ( newstr_memerr( &(f->data[n]) ) ) return FIELDS_ERR;+		return FIELDS_OK; 	} } @@ -304,7 +279,7 @@ inline int fields_used( fields *f, int n ) {-	if ( n < f->n ) return f->used[n];+	if ( n >= 0 && n < f->n ) return f->used[n]; 	else return 0; } @@ -312,7 +287,7 @@ fields_nodata( fields *f, int n ) { 	newstr *d;-	if ( n < f->n ) {+	if ( n >= 0 && n < f->n ) { 		d = &( f->data[n] ); 		if ( d->len > 0 ) return 0; 		return 1;@@ -324,7 +299,6 @@ inline int fields_num( fields *f ) {-	assert( f ); 	return f->n; } @@ -346,9 +320,7 @@ { 	intptr_t retn; -	assert( f );-	assert( n >= 0 );-	assert( n < f->n );+	if ( n<0 || n>= f->n ) return NULL;  	if ( mode & FIELDS_SETUSE_FLAG ) 		fields_setused( f, n );@@ -371,9 +343,7 @@ { 	intptr_t retn; -	assert( f );-	assert( n >= 0 );-	assert( n < f->n );+	if ( n<0 || n>= f->n ) return NULL;  	if ( mode & FIELDS_STRP_FLAG ) 		return &(f->tag[n]);@@ -391,10 +361,7 @@ int fields_level( fields *f, int n ) {-	assert( f );-	assert( n >= 0 );-	assert( n < f->n );-+	if ( n<0 || n>= f->n ) return 0; 	return f->level[n]; } @@ -404,9 +371,6 @@ 	int i, found = -1; 	intptr_t retn; -	assert( f );-	assert( tag );- 	for ( i=0; i<f->n && found==-1; ++i ) {  		if ( !fields_match_level( f, i, level ) ) continue;@@ -442,8 +406,6 @@ 	char *tag, *value; 	va_list argp; -	assert( f );- 	va_start( argp, mode ); 	while ( ( tag = ( char * ) va_arg( argp, char * ) ) ) { 		value = fields_findv( f, level, mode, tag );@@ -462,10 +424,7 @@ { 	intptr_t retn; -	assert( a );-	assert( f );-	assert( n >= 0 );-	assert( n < f->n );+	if ( n<0 || n>= f->n ) return;  	if ( mode & FIELDS_SETUSE_FLAG ) 		fields_setused( f, n );@@ -485,10 +444,6 @@ { 	int i; -	assert( a );-	assert( tag );-	assert( f );- 	for ( i=0; i<f->n; ++i ) {  		if ( !fields_match_level( f, i, level ) ) continue;@@ -514,9 +469,6 @@ 	vplist tags; 	char *tag; 	int i, j, found;--	assert( f );-	assert( a );  	vplist_init( &tags ); 
bibutils/fields.h view
@@ -1,7 +1,7 @@ /*  * fields.h  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Source code released under the GPL version 2  *@@ -9,6 +9,9 @@ #ifndef FIELDS_H #define FIELDS_H +#define FIELDS_OK     (1)+#define FIELDS_ERR    (0)+ #define LEVEL_ANY    (-1) #define LEVEL_MAIN    (0) #define LEVEL_HOST    (1)@@ -45,7 +48,6 @@ extern inline int fields_num( fields *f ); extern inline int fields_used( fields *f, int n ); extern inline int fields_nodata( fields *f, int n );-extern inline int fields_get_level( fields *f, int n );  extern inline int fields_match_level( fields *f, int n, int level ); extern inline int fields_match_tag( fields *f, int n, char *tag );
bibutils/intlist.c view
@@ -3,6 +3,8 @@  *  * Copyright (c) Chris Putnam 2007-2013  *+ * Version 9/5/2013+ *  * Source code released under the GPL version 2  *  * Implements a simple managed array of ints@@ -10,55 +12,75 @@  */ #include "intlist.h" -static void-memerr( const char *f )-{-	fprintf( stderr, "Memory error in %s\n", f );-	exit( EXIT_FAILURE );-}--static void+static int intlist_alloc( intlist *il ) { 	int alloc = 20, i; 	il->data = ( int * ) malloc( sizeof( int ) * alloc );-	if ( !(il->data) ) memerr( __FUNCTION__ );+	if ( !(il->data) ) return 0; 	for ( i=0; i<alloc; ++i ) 		il->data[i] = 0; 	il->max = alloc; 	il->n = 0;+	return 1; } -static void+static int intlist_realloc( intlist *il ) { 	int *more; 	int alloc = il->max * 2, i; 	more = ( int * ) realloc( il->data, sizeof( int ) * alloc );-	if ( !more ) memerr( __FUNCTION__ );+	if ( !more ) return 0; 	il->data = more; 	for ( i=il->max; i<alloc; ++i ) 		il->data[i] = 0; 	il->max = alloc;+	return 1; } +/* intlist_add()+ *+ * Returns position of newly added value in range [0,n), -1 on error+ */ int intlist_add( intlist *il, int value ) {-	if ( il->max==0 ) intlist_alloc( il );-	else if ( il->n >= il->max ) intlist_realloc( il );+	if ( il->max==0 ) {+		if ( !intlist_alloc( il ) ) return -1;+	} else if ( il->n >= il->max ) {+		if ( !intlist_realloc( il ) ) return -1;+	} 	il->data[ il->n ] = value; 	il->n++; 	return il->n - 1; } +/* intlist_add_unique()+ *+ * Returns position of newly added (or previously added) value+ * Returns -1 on (memory) error+ */ int intlist_add_unique( intlist *il, int value ) {-	if ( intlist_find( il, value )!=-1 ) return il->n - 1;-	else return intlist_add( il, value );+	int n;+	n = intlist_find( il, value );+	if ( n==-1 )+		n = intlist_add( il, value );+	return n; }+int+intlist_find_or_add( intlist *il, int value )+{+	return intlist_add_unique( il, value );+} +/* intlist_find()+ *+ * Returns position of value in range [0,n), or -1 if+ * value cannot be found+ */ int intlist_find( intlist *il, int value ) {@@ -68,7 +90,6 @@ 	return -1; } -/* Here we know that pos is valid */ static void intlist_remove_pos_core( intlist *il, int pos ) {@@ -78,32 +99,30 @@ 	il->n -= 1; } -void+/* intlist_remove_pos()+ *+ * Returns 1 on success, 0 on failure.+ */+int intlist_remove_pos( intlist *il, int pos ) {-	if ( pos < 0 || pos >= il->n ) return;+	if ( pos < 0 || pos >= il->n ) return 0; 	intlist_remove_pos_core( il, pos );+	return 1; } -void+/* intlist_remove()+ *+ * Removes first instance of value from the intlist.+ * Returns 1 on success, 0 on error.+ */+int intlist_remove( intlist *il, int value ) { 	int pos = intlist_find( il, value );-	if ( pos==-1 ) return;+	if ( pos==-1 ) return 0; 	intlist_remove_pos_core( il, pos );-}--/* Return the index of searched-for string.- * If cannot find string, add to list and then- * return the index- */-int-intlist_find_or_add( intlist *il, int value )-{-	int n = intlist_find( il, value );-	if ( n==-1 )-		n = intlist_add( il, value );-	return n;+	return 1; }  /* don't actually free space, just reset counter */@@ -121,6 +140,13 @@ }  void+intlist_delete( intlist *il )+{+	intlist_free( il );+	free( il );+}++void intlist_init( intlist *il  ) { 	il->data = NULL;@@ -128,15 +154,28 @@ 	il->n = 0; } -void+/* intlist_init_range()+ *+ * Initializes intlist to values from [low,high) with step step.+ * Returns -1 on failure, number of elements on success.+ */+int intlist_init_range( intlist *il, int low, int high, int step ) {-	int i;+	int i, n; 	intlist_init( il );-	for ( i=low; i<high; i+= step )-		intlist_add( il, i );+	for ( i=low; i<high; i+= step ) {+		n = intlist_add( il, i );+		if ( n==-1 ) return -1;+	}+	return il->n; } +/* intlist_new()+ *+ * Allocates an empty intlist.+ * Returns pointer to intlist on success, NULL on memory error.+ */ intlist * intlist_new( void ) {@@ -145,11 +184,25 @@ 	return il; } +/* intlist_new_range()+ *+ * Allocates a intlist initialized to values from [low,high) with step step.+ * Returns pointer to intlist on success, NULL on memory error;+ */ intlist * intlist_new_range( int low, int high, int step ) {-	intlist *il = ( intlist * ) malloc( sizeof( intlist ) );-	if ( il ) intlist_init_range( il, low, high, step );+	intlist *il;+	int n;+	il = ( intlist * ) malloc( sizeof( intlist ) );+	if ( il ) {+		n = intlist_init_range( il, low, high, step );+		if ( n==-1 ) {+			intlist_free( il );+			free( il );+			il = NULL;+		}+	} 	return il; } @@ -198,47 +251,66 @@ 	} } -void+/* Returns 1 on success, 0 on error */+int intlist_copy( intlist *to, intlist *from ) { 	int i; 	intlist_free( to ); 	to->data = ( int* ) malloc( sizeof( int ) * from->n );-	if ( !to->data ) return;+	if ( !to->data ) return 0; 	to->n = to->max = from->n; 	for ( i=0; i<from->n; ++i )  		to->data[i] = from->data[i];+	return 1; } +/* Returns pointer on success, NULL on error */ intlist * intlist_dup( intlist *il ) { 	intlist *l;-	l = ( intlist* ) malloc( sizeof( intlist ) );-	if ( !l ) goto err0;-	intlist_copy( l, il );-	return l;-	free( l );-err0:+	int n;++	l = intlist_new();+	if ( l ) {+		n = intlist_copy( l, il );+		if ( !n ) {+			intlist_delete( l );+			l = NULL;+		}+	}+ 	return l; } -void+int intlist_append( intlist *to, intlist *from ) {-	int i;-	for ( i=0; i<from->n; ++i )-		intlist_add( to, from->data[i] );+	int i, n, nsave = to->n;+	for ( i=0; i<from->n; ++i ) {+		n = intlist_add( to, from->data[i] );+		if ( n==-1 ) {+			to->n = nsave;+			return -1;+		}+	}+	return to->n; } -void+int intlist_append_unique( intlist *to, intlist *from ) {-	int i;+	int i, n, nsave = to->n; 	for ( i=0; i<from->n; ++i ) { 		if ( intlist_find( to, from->data[i] )!=-1 ) continue;-		intlist_add( to, from->data[i] );+		n = intlist_add( to, from->data[i] );+		if ( n==-1 ) {+			to->n = nsave;+			return -1;+		} 	}+	return to->n; }  int@@ -248,3 +320,55 @@ 	else return il->data[pos]; } +/* intlist_set()+ *+ *   Returns 1 on success, 0 on failure+ */+int+intlist_set( intlist *il, int pos, int value )+{+	if ( pos<0 || pos>=il->n ) return 0;+	il->data[pos] = value;+	return 1;+}++float+intlist_median( intlist *il )+{+	intlist *tmp;+	float median;+	int m1, m2;++	if ( il->n==0 ) return 0.0;++	tmp = intlist_dup( il );+	if ( !tmp ) return 0.0;++	intlist_sort( tmp );++	if ( tmp->n % 2 == 1 ) {+		median = intlist_get( tmp, tmp->n / 2 );+	} else {+		m1 = intlist_get( tmp, tmp->n / 2 );+		m2 = intlist_get( tmp, tmp->n / 2 + 1);+		median = ( m1 + m2 ) / 2.0;+	}++	intlist_delete( tmp );++	return median;+}++float+intlist_mean( intlist *il )+{+	float sum = 0.0;+	int i;++	if ( il->n==0 ) return 0.0;++	for ( i=0; i<il->n; ++i )+		sum += intlist_get( il, i );++	return sum / il->n;+}
bibutils/intlist.h view
@@ -3,6 +3,8 @@  *  * Copyright (c) Chris Putnam 2007-2013  *+ * Version 9/5/2013+ *  * Source code released under the GPL version 2  *  */@@ -18,23 +20,27 @@ 	int *data; } intlist; -extern void intlist_init( intlist *info );-extern void intlist_init_range( intlist *info, int low, int high, int step );-extern intlist* intlist_new( void );-extern intlist* intlist_new_range( int low, int high, int step );-extern void intlist_sort( intlist *info );-extern void intlist_randomize( intlist *info );-extern int  intlist_add(  intlist *info, int value );-extern int  intlist_add_unique(  intlist *info, int value );-extern int  intlist_find( intlist *info, int searchvalue );-extern int  intlist_find_or_add( intlist *info, int searchvalue );-extern void intlist_empty( intlist *info );-extern void intlist_free( intlist *info );-extern void intlist_copy( intlist *to, intlist *from );-extern int  intlist_get( intlist *info, int pos );-extern void intlist_remove( intlist *info, int searchvalue );-extern void intlist_remove_pos( intlist *info, int pos );-extern void intlist_append( intlist *to, intlist *from );-extern void intlist_append_unique( intlist *to, intlist *from );+extern void      intlist_init( intlist *il );+extern int       intlist_init_range( intlist *il, int low, int high, int step );+extern intlist * intlist_new( void );+extern intlist * intlist_new_range( int low, int high, int step );+extern void      intlist_delete( intlist *il );+extern void      intlist_sort( intlist *il );+extern void      intlist_randomize( intlist *il );+extern int       intlist_add( intlist *il, int value );+extern int       intlist_add_unique( intlist *il, int value );+extern int       intlist_find( intlist *il, int searchvalue );+extern int       intlist_find_or_add( intlist *il, int searchvalue );+extern void      intlist_empty( intlist *il );+extern void      intlist_free( intlist *il );+extern int       intlist_copy( intlist *to, intlist *from );+extern int       intlist_get( intlist *il, int pos );+extern int       intlist_set( intlist *il, int pos, int value );+extern int       intlist_remove( intlist *il, int searchvalue );+extern int       intlist_remove_pos( intlist *il, int pos );+extern int       intlist_append( intlist *to, intlist *from );+extern int       intlist_append_unique( intlist *to, intlist *from );+extern float     intlist_median( intlist *il );+extern float     intlist_mean( intlist *il );  #endif
bibutils/isiin.c view
@@ -19,6 +19,9 @@ #include "reftypes.h" #include "isiin.h" +/*****************************************************+ PUBLIC: void isiin_initparams()+*****************************************************/ void isiin_initparams( param *p, const char *progname ) {@@ -48,6 +51,10 @@ 	else p->progname = strdup( progname ); } +/*****************************************************+ PUBLIC: int isiin_readf()+*****************************************************/+ /* ISI definition of a tag is strict:  *   char 1 = uppercase alphabetic character  *   char 2 = uppercase alphabetic character or digit@@ -116,6 +123,10 @@ 	return haveref; } +/*****************************************************+ PUBLIC: int isiin_processf()+*****************************************************/+ static char * process_isiline( newstr *tag, newstr *data, char *p ) {@@ -138,56 +149,48 @@ int isiin_processf( fields *isiin, char *p, char *filename, long nref ) {+	int status, n, ret = 1; 	newstr tag, data;-	int n; 	newstrs_init( &tag, &data, NULL ); 	while ( *p ) { 		newstrs_empty( &tag, &data, NULL ); 		p = process_isiline( &tag, &data, p ); 		if ( !data.len ) continue; 		if ( (tag.len>1) && isiin_istag( tag.data ) ) {-			fields_add( isiin, tag.data, data.data, 0 );+			status = fields_add( isiin, tag.data, data.data, 0 );+			if ( status!=FIELDS_OK ) {+				ret = 0;+				goto out;+			} 		} else { 			n = fields_num( isiin ); 			if ( n>0 ) { 				/* only one AU or AF for list of authors */ 				if ( !strcmp( isiin->tag[n-1].data,"AU") ){-					fields_add( isiin, "AU", data.data, 0);+					status = fields_add( isiin, "AU", data.data, 0);+					if ( status!=FIELDS_OK ) ret = 0; 				} else if ( !strcmp( isiin->tag[n-1].data,"AF") ){-					fields_add( isiin, "AF", data.data, 0);+					status = fields_add( isiin, "AF", data.data, 0);+					if ( status!=FIELDS_OK ) ret = 0; 				} 				/* otherwise append multiline data */ 				else { 					newstr_addchar( &(isiin->data[n-1]),' '); 					newstr_strcat( &(isiin->data[n-1]), data.data );+					if ( newstr_memerr( &(isiin->data[n-1]) ) ) ret = 0; 				}+				if ( ret==0 ) goto out; 			} 		} 	}+out: 	newstrs_free( &data, &tag, NULL );-	return 1;-}--static int-keyword_process( fields *info, char *newtag, char *p, int level )-{-	newstr keyword;-	int ok;-	newstr_init( &keyword );-	while ( *p ) {-		p = skip_ws( p );-		while ( *p && *p!=';' ) newstr_addchar( &keyword, *p++ );-		if ( keyword.len ) {-			ok = fields_add( info, newtag, keyword.data, level );-			if ( !ok ) return 0;-			newstr_empty( &keyword );-		}-		if ( *p==';' ) p++;-	}-	newstr_free( &keyword );-	return 1;+	return ret; } +/*****************************************************+ PUBLIC: int isiin_typef()+*****************************************************/ int isiin_typef( fields *isiin, char *filename, int nref, param *p, variants *all, int nall ) {@@ -203,6 +206,29 @@ 	return reftype; } +/*****************************************************+ PUBLIC: int isiin_convertf(), returns BIBL_OK or BIBL_ERR_MEMERR+*****************************************************/++static int+isiin_keyword_process( fields *info, char *newtag, char *p, int level )+{+	int fstatus, status = BIBL_OK;+	newstr keyword;+	newstr_init( &keyword );+	while ( *p ) {+		p = newstr_cpytodelim( &keyword, skip_ws( p ), ";", 1 );+		if ( newstr_memerr( &keyword ) ) { status = BIBL_ERR_MEMERR; goto out; }+		if ( keyword.len ) {+			fstatus = fields_add( info, newtag, keyword.data, level );+			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+		}+	}+out:+	newstr_free( &keyword );+	return status;+}+ /* pull off authors first--use AF before AU */ static int isiin_addauthors( fields *isiin, fields *info, int reftype, variants *all, int nall, list *asis, list *corps )@@ -228,9 +254,9 @@ 		level = ((all[reftype]).tags[n]).level; 		newtag = all[reftype].tags[n].newstr; 		ok = name_add( info, newtag, d->data, level, asis, corps );-		if ( !ok ) return 0;+		if ( !ok ) return BIBL_ERR_MEMERR; 	}-	return 1;+	return BIBL_OK; }  static void@@ -242,15 +268,23 @@ 	} } +static int+isiin_simple( fields *info, char *tag, char *value, int level )+{+	int fstatus = fields_add( info, tag, value, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}+ int isiin_convertf( fields *isiin, fields *info, int reftype, param *p, variants *all, int nall ) {-	int process, level, i, n, nfields, ok;+	int process, level, i, n, nfields, ok, status; 	newstr *t, *d; 	char *newtag; -	ok = isiin_addauthors( isiin, info, reftype, all, nall, &(p->asis), &(p->corps) );-	if ( !ok ) return BIBL_ERR_MEMERR;+	status = isiin_addauthors( isiin, info, reftype, all, nall, &(p->asis), &(p->corps) );+	if ( status!=BIBL_OK ) return status;  	nfields = fields_num( isiin ); 	for ( i=0; i<nfields; ++i ) {@@ -268,42 +302,46 @@  		d = fields_value( isiin, i, FIELDS_STRP ); +		ok = 1;+ 		switch ( process ) {  		case SIMPLE:-			ok = fields_add( info, newtag, d->data, level );-			break;- 		case DATE:-			ok = fields_add( info, newtag, d->data, level );+			status = isiin_simple( info, newtag, d->data, level ); 			break;  		case PERSON: 			ok = name_add( info, newtag, d->data, level, &(p->asis), &(p->corps) );+			if ( ok ) status = BIBL_OK;+			else status = BIBL_ERR_MEMERR; 			break;  		case TITLE: 			ok = title_process( info, newtag, d->data, level, p->nosplittitle );+			if ( ok ) status = BIBL_OK;+			else status = BIBL_ERR_MEMERR; 			break;  		case KEYWORD:-			ok = keyword_process( info, newtag, d->data, level );+			status = isiin_keyword_process( info, newtag, d->data, level ); 			break;  		case SERIALNO: 			ok = addsn( info, d->data, level );+			if ( ok ) status = BIBL_OK;+			else status = BIBL_ERR_MEMERR; 			break; +		/* do nothing if process==TYPE || process==ALWAYS */ 		default:-			ok = 1;+			status = BIBL_OK; 			break;  		} -		/* do nothing if process==TYPE || process==ALWAYS */--		if ( !ok ) return BIBL_ERR_MEMERR;+		if ( status!=BIBL_OK ) return status; 	} -	return BIBL_OK;+	return status; }
bibutils/isiout.c view
@@ -27,7 +27,7 @@ 	p->latexout         = 0; 	p->utf8out          = BIBL_CHARSET_UTF8_DEFAULT; 	p->utf8bom          = BIBL_CHARSET_BOM_DEFAULT;-	p->xmlout           = 0;+	p->xmlout           = BIBL_XMLOUT_FALSE; 	p->nosplittitle     = 0; 	p->verbose          = 0; 	p->addcount         = 0;
+ bibutils/iso639_1.c view
@@ -0,0 +1,211 @@+/*+ * iso639_1.c+ */+#include <string.h>+#include "iso639_1.h"++typedef struct {+        char *code;+        char *language;+} iso639_1_t;++static iso639_1_t iso639_1[] = {+	{ "aa", "Afar" },+	{ "ab", "Abkhazian" },+	{ "ae", "Avestan" },+	{ "af", "Afrikaans" },+	{ "ak", "Akan" },+	{ "am", "Amharic" },+	{ "an", "Aragonese" },+	{ "ar", "Arabic" },+	{ "as", "Assamese" },+	{ "av", "Avaric" },+	{ "ay", "Aymara" },+	{ "az", "Azerbaijani" },+	{ "ba", "Bashkir" },+	{ "be", "Belarusian" },+	{ "bg", "Bulgarian" },+	{ "bh", "Bihari languages" },+	{ "bi", "Bislama" },+	{ "bm", "Bambara" },+	{ "bn", "Bengali" },+	{ "bo", "Tibetan" },+	{ "br", "Breton" },+	{ "bs", "Bosnian" },+	{ "ca", "Catalan" },+	{ "ce", "Chechen" },+	{ "ch", "Chamorro" },+	{ "co", "Corsican" },+	{ "cr", "Cree" },+	{ "cs", "Czech" },+	{ "cu", "Church Slavic" },+	{ "cv", "Chuvash" },+	{ "cy", "Welsh" },+	{ "da", "Danish" },+	{ "de", "German" },+	{ "dv", "Dhivehi" },+	{ "dz", "Dzongkha" },+	{ "ee", "Ewe" },+	{ "el", "Modern Greek" },+	{ "en", "English" },+	{ "eo", "Esperanto" },+	{ "es", "Spanish" },+	{ "et", "Estonian" },+	{ "eu", "Basque" },+	{ "fa", "Persian" },+	{ "ff", "Fulah" },+	{ "fi", "Finnish" },+	{ "fj", "Fijian" },+	{ "fo", "Faroese" },+	{ "fr", "French" },+	{ "fy", "Western Frisian" },+	{ "ga", "Irish" },+	{ "gd", "Scottish Gaelic" },+	{ "gl", "Galician" },+	{ "gn", "Guarani" },+	{ "gu", "Gujarati" },+	{ "gv", "Manx" },+	{ "ha", "Hausa" },+	{ "he", "Hebrew" },+	{ "hi", "Hindi" },+	{ "ho", "Hiri Motu" },+	{ "hr", "Croatian" },+	{ "ht", "Haitian" },+	{ "hu", "Hungarian" },+	{ "hy", "Armenian" },+	{ "hz", "Herero" },+	{ "ia", "Interlingua" },+	{ "id", "Indonesian" },+	{ "ie", "Interlingue" },+	{ "ig", "Igbo" },+	{ "ii", "Sichuan Yi" },+	{ "ik", "Inupiaq" },+	{ "io", "Ido" },+	{ "is", "Icelandic" },+	{ "it", "Italian" },+	{ "iu", "Inuktitut" },+	{ "ja", "Japanese" },+	{ "jv", "Javanese" },+	{ "ka", "Georgian" },+	{ "kg", "Kongo" },+	{ "ki", "Kikuyu" },+	{ "kj", "Kuanyama" },+	{ "kk", "Kazakh" },+	{ "kl", "Kalaallisut" },+	{ "km", "Central Khmer" },+	{ "kn", "Kannada" },+	{ "ko", "Korean" },+	{ "kr", "Kanuri" },+	{ "ks", "Kashmiri" },+	{ "ku", "Kurdish" },+	{ "kv", "Komi" },+	{ "kw", "Cornish" },+	{ "ky", "Kirghiz" },+	{ "la", "Latin" },+	{ "lb", "Luxembourgish" },+	{ "lg", "Ganda" },+	{ "li", "Limburgan" },+	{ "ln", "Lingala" },+	{ "lo", "Lao" },+	{ "lt", "Lithuanian" },+	{ "lu", "Luba-Katanga" },+	{ "lv", "Latvian" },+	{ "mg", "Malagasy" },+	{ "mh", "Marshallese" },+	{ "mi", "Maori" },+	{ "mk", "Macedonian" },+	{ "ml", "Malayalam" },+	{ "mn", "Mongolian" },+	{ "mr", "Marathi" },+	{ "ms", "Malay" },+	{ "mt", "Maltese" },+	{ "my", "Burmese" },+	{ "na", "Nauru" },+	{ "nb", "Norwegian Bokmål" },+	{ "nd", "North Ndebele" },+	{ "ne", "Nepali" },+	{ "ng", "Ndonga" },+	{ "nl", "Dutch" },+	{ "nn", "Norwegian Nynorsk" },+	{ "no", "Norwegian" },+	{ "nr", "South Ndebele" },+	{ "nv", "Navajo" },+	{ "ny", "Nyanja" },+	{ "oc", "Occitan" },+	{ "oj", "Ojibwa" },+	{ "om", "Oromo" },+	{ "or", "Oriya" },+	{ "os", "Ossetian" },+	{ "pa", "Panjabi" },+	{ "pi", "Pali" },+	{ "pl", "Polish" },+	{ "ps", "Pushto" },+	{ "pt", "Portuguese" },+	{ "qu", "Quechua" },+	{ "rm", "Romansh" },+	{ "rn", "Rundi" },+	{ "ro", "Romanian" },+	{ "ru", "Russian" },+	{ "rw", "Kinyarwanda" },+	{ "sa", "Sanskrit" },+	{ "sc", "Sardinian" },+	{ "sd", "Sindhi" },+	{ "se", "Northern Sami" },+	{ "sg", "Sango" },+	{ "sh", "Serbo-Croatian" },+	{ "si", "Sinhala" },+	{ "sk", "Slovak" },+	{ "sl", "Slovenian" },+	{ "sm", "Samoan" },+	{ "sn", "Shona" },+	{ "so", "Somali" },+	{ "sq", "Albanian" },+	{ "sr", "Serbian" },+	{ "ss", "Swati" },+	{ "st", "Southern Sotho" },+	{ "su", "Sundanese" },+	{ "sv", "Swedish" },+	{ "sw", "Swahili" },+	{ "ta", "Tamil" },+	{ "te", "Telugu" },+	{ "tg", "Tajik" },+	{ "th", "Thai" },+	{ "ti", "Tigrinya" },+	{ "tk", "Turkmen" },+	{ "tl", "Tagalog" },+	{ "tn", "Tswana" },+	{ "to", "Tonga" },+	{ "tr", "Turkish" },+	{ "ts", "Tsonga" },+	{ "tt", "Tatar" },+	{ "tw", "Twi" },+	{ "ty", "Tahitian" },+	{ "ug", "Uighur" },+	{ "uk", "Ukrainian" },+	{ "ur", "Urdu" },+	{ "uz", "Uzbek" },+	{ "ve", "Venda" },+	{ "vi", "Vietnamese" },+	{ "vo", "Volapük" },+	{ "wa", "Walloon" },+	{ "wo", "Wolof" },+	{ "xh", "Xhosa" },+	{ "yi", "Yiddish" },+	{ "yo", "Yoruba" },+	{ "za", "Zhuang" },+	{ "zh", "Chinese" },+	{ "zu", "Zulu" },+};+static int niso639_1= sizeof( iso639_1 ) / sizeof( iso639_1[0] );++char *+iso639_1_from_code( const char *code )+{+	int i;+	for ( i=0; i<niso639_1; ++i ) {+		if ( !strcasecmp( iso639_1[i].code, code ) )+			return iso639_1[i].language;+	}+	return NULL;+}+
+ bibutils/iso639_1.h view
@@ -0,0 +1,9 @@+/*+ * iso639_1.h+ */+#ifndef ISO639_1_H+#define iSO639_1_H++extern char * iso639_1_from_code( const char *code );++#endif
+ bibutils/iso639_3.c view
@@ -0,0 +1,8419 @@+/*+ * iso639_3.c+ */+#include <string.h>+#include "iso639_3.h"++typedef struct {+        char *code;+        char *language;+} iso639_3_t;++static iso639_3_t iso639_3[] = {+	{ "aaa", "Ghotuo" },+	{ "aab", "Alumu-Tesu" },+	{ "aac", "Ari" },+	{ "aad", "Amal" },+	{ "aae", "Arbëreshë Albanian" },+	{ "aaf", "Aranadan" },+	{ "aag", "Ambrak" },+	{ "aah", "Abu' Arapesh" },+	{ "aai", "Arifama-Miniafia" },+	{ "aak", "Ankave" },+	{ "aal", "Afade" },+	{ "aam", "Aramanik" },+	{ "aan", "Anambé" },+	{ "aao", "Algerian Saharan Arabic" },+	{ "aap", "Pará Arára" },+	{ "aaq", "Eastern Abnaki" },+	{ "aar", "Afar" },+	{ "aas", "Aasáx" },+	{ "aat", "Arvanitika Albanian" },+	{ "aau", "Abau" },+	{ "aaw", "Solong" },+	{ "aax", "Mandobo Atas" },+	{ "aaz", "Amarasi" },+	{ "aba", "Abé" },+	{ "abb", "Bankon" },+	{ "abc", "Ambala Ayta" },+	{ "abd", "Manide" },+	{ "abe", "Western Abnaki" },+	{ "abf", "Abai Sungai" },+	{ "abg", "Abaga" },+	{ "abh", "Tajiki Arabic" },+	{ "abi", "Abidji" },+	{ "abj", "Aka-Bea" },+	{ "abk", "Abkhazian" },+	{ "abl", "Lampung Nyo" },+	{ "abm", "Abanyom" },+	{ "abn", "Abua" },+	{ "abo", "Abon" },+	{ "abp", "Abellen Ayta" },+	{ "abq", "Abaza" },+	{ "abr", "Abron" },+	{ "abs", "Ambonese Malay" },+	{ "abt", "Ambulas" },+	{ "abu", "Abure" },+	{ "abv", "Baharna Arabic" },+	{ "abw", "Pal" },+	{ "abx", "Inabaknon" },+	{ "aby", "Aneme Wake" },+	{ "abz", "Abui" },+	{ "aca", "Achagua" },+	{ "acb", "Áncá" },+	{ "acd", "Gikyode" },+	{ "ace", "Achinese" },+	{ "acf", "Saint Lucian Creole French" },+	{ "ach", "Acoli" },+	{ "aci", "Aka-Cari" },+	{ "ack", "Aka-Kora" },+	{ "acl", "Akar-Bale" },+	{ "acm", "Mesopotamian Arabic" },+	{ "acn", "Achang" },+	{ "acp", "Eastern Acipa" },+	{ "acq", "Ta'izzi-Adeni Arabic" },+	{ "acr", "Achi" },+	{ "acs", "Acroá" },+	{ "act", "Achterhoeks" },+	{ "acu", "Achuar-Shiwiar" },+	{ "acv", "Achumawi" },+	{ "acw", "Hijazi Arabic" },+	{ "acx", "Omani Arabic" },+	{ "acy", "Cypriot Arabic" },+	{ "acz", "Acheron" },+	{ "ada", "Adangme" },+	{ "adb", "Adabe" },+	{ "add", "Dzodinka" },+	{ "ade", "Adele" },+	{ "adf", "Dhofari Arabic" },+	{ "adg", "Andegerebinha" },+	{ "adh", "Adhola" },+	{ "adi", "Adi" },+	{ "adj", "Adioukrou" },+	{ "adl", "Galo" },+	{ "adn", "Adang" },+	{ "ado", "Abu" },+	{ "adp", "Adap" },+	{ "adq", "Adangbe" },+	{ "adr", "Adonara" },+	{ "ads", "Adamorobe Sign Language" },+	{ "adt", "Adnyamathanha" },+	{ "adu", "Aduge" },+	{ "adw", "Amundava" },+	{ "adx", "Amdo Tibetan" },+	{ "ady", "Adyghe" },+	{ "adz", "Adzera" },+	{ "aea", "Areba" },+	{ "aeb", "Tunisian Arabic" },+	{ "aec", "Saidi Arabic" },+	{ "aed", "Argentine Sign Language" },+	{ "aee", "Northeast Pashayi" },+	{ "aek", "Haeke" },+	{ "ael", "Ambele" },+	{ "aem", "Arem" },+	{ "aen", "Armenian Sign Language" },+	{ "aeq", "Aer" },+	{ "aer", "Eastern Arrernte" },+	{ "aes", "Alsea" },+	{ "aeu", "Akeu" },+	{ "aew", "Ambakich" },+	{ "aey", "Amele" },+	{ "aez", "Aeka" },+	{ "afb", "Gulf Arabic" },+	{ "afd", "Andai" },+	{ "afe", "Putukwam" },+	{ "afg", "Afghan Sign Language" },+	{ "afh", "Afrihili" },+	{ "afi", "Akrukay" },+	{ "afk", "Nanubae" },+	{ "afn", "Defaka" },+	{ "afo", "Eloyi" },+	{ "afp", "Tapei" },+	{ "afr", "Afrikaans" },+	{ "afs", "Afro-Seminole Creole" },+	{ "aft", "Afitti" },+	{ "afu", "Awutu" },+	{ "afz", "Obokuitai" },+	{ "aga", "Aguano" },+	{ "agb", "Legbo" },+	{ "agc", "Agatu" },+	{ "agd", "Agarabi" },+	{ "age", "Angal" },+	{ "agf", "Arguni" },+	{ "agg", "Angor" },+	{ "agh", "Ngelima" },+	{ "agi", "Agariya" },+	{ "agj", "Argobba" },+	{ "agk", "Isarog Agta" },+	{ "agl", "Fembe" },+	{ "agm", "Angaataha" },+	{ "agn", "Agutaynen" },+	{ "ago", "Tainae" },+	{ "agq", "Aghem" },+	{ "agr", "Aguaruna" },+	{ "ags", "Esimbi" },+	{ "agt", "Central Cagayan Agta" },+	{ "agu", "Aguacateco" },+	{ "agv", "Remontado Dumagat" },+	{ "agw", "Kahua" },+	{ "agx", "Aghul" },+	{ "agy", "Southern Alta" },+	{ "agz", "Mt. Iriga Agta" },+	{ "aha", "Ahanta" },+	{ "ahb", "Axamb" },+	{ "ahg", "Qimant" },+	{ "ahh", "Aghu" },+	{ "ahi", "Tiagbamrin Aizi" },+	{ "ahk", "Akha" },+	{ "ahl", "Igo" },+	{ "ahm", "Mobumrin Aizi" },+	{ "ahn", "Àhàn" },+	{ "aho", "Ahom" },+	{ "ahp", "Aproumu Aizi" },+	{ "ahr", "Ahirani" },+	{ "ahs", "Ashe" },+	{ "aht", "Ahtena" },+	{ "aia", "Arosi" },+	{ "aib", "Ainu (China)" },+	{ "aic", "Ainbai" },+	{ "aid", "Alngith" },+	{ "aie", "Amara" },+	{ "aif", "Agi" },+	{ "aig", "Antigua and Barbuda Creole English" },+	{ "aih", "Ai-Cham" },+	{ "aii", "Assyrian Neo-Aramaic" },+	{ "aij", "Lishanid Noshan" },+	{ "aik", "Ake" },+	{ "ail", "Aimele" },+	{ "aim", "Aimol" },+	{ "ain", "Ainu (Japan)" },+	{ "aio", "Aiton" },+	{ "aip", "Burumakok" },+	{ "aiq", "Aimaq" },+	{ "air", "Airoran" },+	{ "ais", "Nataoran Amis" },+	{ "ait", "Arikem" },+	{ "aiw", "Aari" },+	{ "aix", "Aighon" },+	{ "aiy", "Ali" },+	{ "aja", "Aja (Sudan)" },+	{ "ajg", "Aja (Benin)" },+	{ "aji", "Ajië" },+	{ "ajn", "Andajin" },+	{ "ajp", "South Levantine Arabic" },+	{ "ajt", "Judeo-Tunisian Arabic" },+	{ "aju", "Judeo-Moroccan Arabic" },+	{ "ajw", "Ajawa" },+	{ "ajz", "Amri Karbi" },+	{ "aka", "Akan" },+	{ "akb", "Batak Angkola" },+	{ "akc", "Mpur" },+	{ "akd", "Ukpet-Ehom" },+	{ "ake", "Akawaio" },+	{ "akf", "Akpa" },+	{ "akg", "Anakalangu" },+	{ "akh", "Angal Heneng" },+	{ "aki", "Aiome" },+	{ "akj", "Aka-Jeru" },+	{ "akk", "Akkadian" },+	{ "akl", "Aklanon" },+	{ "akm", "Aka-Bo" },+	{ "ako", "Akurio" },+	{ "akp", "Siwu" },+	{ "akq", "Ak" },+	{ "akr", "Araki" },+	{ "aks", "Akaselem" },+	{ "akt", "Akolet" },+	{ "aku", "Akum" },+	{ "akv", "Akhvakh" },+	{ "akw", "Akwa" },+	{ "akx", "Aka-Kede" },+	{ "aky", "Aka-Kol" },+	{ "akz", "Alabama" },+	{ "ala", "Alago" },+	{ "alc", "Qawasqar" },+	{ "ald", "Alladian" },+	{ "ale", "Aleut" },+	{ "alf", "Alege" },+	{ "alh", "Alawa" },+	{ "ali", "Amaimon" },+	{ "alj", "Alangan" },+	{ "alk", "Alak" },+	{ "all", "Allar" },+	{ "alm", "Amblong" },+	{ "aln", "Gheg Albanian" },+	{ "alo", "Larike-Wakasihu" },+	{ "alp", "Alune" },+	{ "alq", "Algonquin" },+	{ "alr", "Alutor" },+	{ "als", "Tosk Albanian" },+	{ "alt", "Southern Altai" },+	{ "alu", "'Are'are" },+	{ "alw", "Alaba-K’abeena" },+	{ "alx", "Amol" },+	{ "aly", "Alyawarr" },+	{ "alz", "Alur" },+	{ "ama", "Amanayé" },+	{ "amb", "Ambo" },+	{ "amc", "Amahuaca" },+	{ "ame", "Yanesha'" },+	{ "amf", "Hamer-Banna" },+	{ "amg", "Amurdak" },+	{ "amh", "Amharic" },+	{ "ami", "Amis" },+	{ "amj", "Amdang" },+	{ "amk", "Ambai" },+	{ "aml", "War-Jaintia" },+	{ "amm", "Ama (Papua New Guinea)" },+	{ "amn", "Amanab" },+	{ "amo", "Amo" },+	{ "amp", "Alamblak" },+	{ "amq", "Amahai" },+	{ "amr", "Amarakaeri" },+	{ "ams", "Southern Amami-Oshima" },+	{ "amt", "Amto" },+	{ "amu", "Guerrero Amuzgo" },+	{ "amv", "Ambelau" },+	{ "amw", "Western Neo-Aramaic" },+	{ "amx", "Anmatyerre" },+	{ "amy", "Ami" },+	{ "amz", "Atampaya" },+	{ "ana", "Andaqui" },+	{ "anb", "Andoa" },+	{ "anc", "Ngas" },+	{ "and", "Ansus" },+	{ "ane", "Xârâcùù" },+	{ "anf", "Animere" },+	{ "ang", "Old English (ca. 450-1100)" },+	{ "anh", "Nend" },+	{ "ani", "Andi" },+	{ "anj", "Anor" },+	{ "ank", "Goemai" },+	{ "anl", "Anu-Hkongso Chin" },+	{ "anm", "Anal" },+	{ "ann", "Obolo" },+	{ "ano", "Andoque" },+	{ "anp", "Angika" },+	{ "anq", "Jarawa (India)" },+	{ "anr", "Andh" },+	{ "ans", "Anserma" },+	{ "ant", "Antakarinya" },+	{ "anu", "Anuak" },+	{ "anv", "Denya" },+	{ "anw", "Anaang" },+	{ "anx", "Andra-Hus" },+	{ "any", "Anyin" },+	{ "anz", "Anem" },+	{ "aoa", "Angolar" },+	{ "aob", "Abom" },+	{ "aoc", "Pemon" },+	{ "aod", "Andarum" },+	{ "aoe", "Angal Enen" },+	{ "aof", "Bragat" },+	{ "aog", "Angoram" },+	{ "aoh", "Arma" },+	{ "aoi", "Anindilyakwa" },+	{ "aoj", "Mufian" },+	{ "aok", "Arhö" },+	{ "aol", "Alor" },+	{ "aom", "Ömie" },+	{ "aon", "Bumbita Arapesh" },+	{ "aor", "Aore" },+	{ "aos", "Taikat" },+	{ "aot", "A'tong" },+	{ "aou", "A'ou" },+	{ "aox", "Atorada" },+	{ "aoz", "Uab Meto" },+	{ "apb", "Sa'a" },+	{ "apc", "North Levantine Arabic" },+	{ "apd", "Sudanese Arabic" },+	{ "ape", "Bukiyip" },+	{ "apf", "Pahanan Agta" },+	{ "apg", "Ampanang" },+	{ "aph", "Athpariya" },+	{ "api", "Apiaká" },+	{ "apj", "Jicarilla Apache" },+	{ "apk", "Kiowa Apache" },+	{ "apl", "Lipan Apache" },+	{ "apm", "Mescalero-Chiricahua Apache" },+	{ "apn", "Apinayé" },+	{ "apo", "Ambul" },+	{ "app", "Apma" },+	{ "apq", "A-Pucikwar" },+	{ "apr", "Arop-Lokep" },+	{ "aps", "Arop-Sissano" },+	{ "apt", "Apatani" },+	{ "apu", "Apurinã" },+	{ "apv", "Alapmunte" },+	{ "apw", "Western Apache" },+	{ "apx", "Aputai" },+	{ "apy", "Apalaí" },+	{ "apz", "Safeyoka" },+	{ "aqc", "Archi" },+	{ "aqd", "Ampari Dogon" },+	{ "aqg", "Arigidi" },+	{ "aqm", "Atohwaim" },+	{ "aqn", "Northern Alta" },+	{ "aqp", "Atakapa" },+	{ "aqr", "Arhâ" },+	{ "aqz", "Akuntsu" },+	{ "ara", "Arabic" },+	{ "arb", "Standard Arabic" },+	{ "arc", "Official Aramaic (700-300 BCE)" },+	{ "ard", "Arabana" },+	{ "are", "Western Arrarnta" },+	{ "arg", "Aragonese" },+	{ "arh", "Arhuaco" },+	{ "ari", "Arikara" },+	{ "arj", "Arapaso" },+	{ "ark", "Arikapú" },+	{ "arl", "Arabela" },+	{ "arn", "Mapudungun" },+	{ "aro", "Araona" },+	{ "arp", "Arapaho" },+	{ "arq", "Algerian Arabic" },+	{ "arr", "Karo (Brazil)" },+	{ "ars", "Najdi Arabic" },+	{ "aru", "Aruá (Amazonas State)" },+	{ "arv", "Arbore" },+	{ "arw", "Arawak" },+	{ "arx", "Aruá (Rodonia State)" },+	{ "ary", "Moroccan Arabic" },+	{ "arz", "Egyptian Arabic" },+	{ "asa", "Asu (Tanzania)" },+	{ "asb", "Assiniboine" },+	{ "asc", "Casuarina Coast Asmat" },+	{ "asd", "Asas" },+	{ "ase", "American Sign Language" },+	{ "asf", "Australian Sign Language" },+	{ "asg", "Cishingini" },+	{ "ash", "Abishira" },+	{ "asi", "Buruwai" },+	{ "asj", "Sari" },+	{ "ask", "Ashkun" },+	{ "asl", "Asilulu" },+	{ "asm", "Assamese" },+	{ "asn", "Xingú Asuriní" },+	{ "aso", "Dano" },+	{ "asp", "Algerian Sign Language" },+	{ "asq", "Austrian Sign Language" },+	{ "asr", "Asuri" },+	{ "ass", "Ipulo" },+	{ "ast", "Asturian" },+	{ "asu", "Tocantins Asurini" },+	{ "asv", "Asoa" },+	{ "asw", "Australian Aborigines Sign Language" },+	{ "asx", "Muratayak" },+	{ "asy", "Yaosakor Asmat" },+	{ "asz", "As" },+	{ "ata", "Pele-Ata" },+	{ "atb", "Zaiwa" },+	{ "atc", "Atsahuaca" },+	{ "atd", "Ata Manobo" },+	{ "ate", "Atemble" },+	{ "atg", "Ivbie North-Okpela-Arhe" },+	{ "ati", "Attié" },+	{ "atj", "Atikamekw" },+	{ "atk", "Ati" },+	{ "atl", "Mt. Iraya Agta" },+	{ "atm", "Ata" },+	{ "atn", "Ashtiani" },+	{ "ato", "Atong" },+	{ "atp", "Pudtol Atta" },+	{ "atq", "Aralle-Tabulahan" },+	{ "atr", "Waimiri-Atroari" },+	{ "ats", "Gros Ventre" },+	{ "att", "Pamplona Atta" },+	{ "atu", "Reel" },+	{ "atv", "Northern Altai" },+	{ "atw", "Atsugewi" },+	{ "atx", "Arutani" },+	{ "aty", "Aneityum" },+	{ "atz", "Arta" },+	{ "aua", "Asumboa" },+	{ "aub", "Alugu" },+	{ "auc", "Waorani" },+	{ "aud", "Anuta" },+	{ "aue", "=Kx'au'ein" },+	{ "aug", "Aguna" },+	{ "auh", "Aushi" },+	{ "aui", "Anuki" },+	{ "auj", "Awjilah" },+	{ "auk", "Heyo" },+	{ "aul", "Aulua" },+	{ "aum", "Asu (Nigeria)" },+	{ "aun", "Molmo One" },+	{ "auo", "Auyokawa" },+	{ "aup", "Makayam" },+	{ "auq", "Anus" },+	{ "aur", "Aruek" },+	{ "aut", "Austral" },+	{ "auu", "Auye" },+	{ "auw", "Awyi" },+	{ "aux", "Aurá" },+	{ "auy", "Awiyaana" },+	{ "auz", "Uzbeki Arabic" },+	{ "ava", "Avaric" },+	{ "avb", "Avau" },+	{ "avd", "Alviri-Vidari" },+	{ "ave", "Avestan" },+	{ "avi", "Avikam" },+	{ "avk", "Kotava" },+	{ "avl", "Eastern Egyptian Bedawi Arabic" },+	{ "avm", "Angkamuthi" },+	{ "avn", "Avatime" },+	{ "avo", "Agavotaguerra" },+	{ "avs", "Aushiri" },+	{ "avt", "Au" },+	{ "avu", "Avokaya" },+	{ "avv", "Avá-Canoeiro" },+	{ "awa", "Awadhi" },+	{ "awb", "Awa (Papua New Guinea)" },+	{ "awc", "Cicipu" },+	{ "awe", "Awetí" },+	{ "awg", "Anguthimri" },+	{ "awh", "Awbono" },+	{ "awi", "Aekyom" },+	{ "awk", "Awabakal" },+	{ "awm", "Arawum" },+	{ "awn", "Awngi" },+	{ "awo", "Awak" },+	{ "awr", "Awera" },+	{ "aws", "South Awyu" },+	{ "awt", "Araweté" },+	{ "awu", "Central Awyu" },+	{ "awv", "Jair Awyu" },+	{ "aww", "Awun" },+	{ "awx", "Awara" },+	{ "awy", "Edera Awyu" },+	{ "axb", "Abipon" },+	{ "axe", "Ayerrerenge" },+	{ "axg", "Mato Grosso Arára" },+	{ "axk", "Yaka (Central African Republic)" },+	{ "axl", "Lower Southern Aranda" },+	{ "axm", "Middle Armenian" },+	{ "axx", "Xârâgurè" },+	{ "aya", "Awar" },+	{ "ayb", "Ayizo Gbe" },+	{ "ayc", "Southern Aymara" },+	{ "ayd", "Ayabadhu" },+	{ "aye", "Ayere" },+	{ "ayg", "Ginyanga" },+	{ "ayh", "Hadrami Arabic" },+	{ "ayi", "Leyigha" },+	{ "ayk", "Akuku" },+	{ "ayl", "Libyan Arabic" },+	{ "aym", "Aymara" },+	{ "ayn", "Sanaani Arabic" },+	{ "ayo", "Ayoreo" },+	{ "ayp", "North Mesopotamian Arabic" },+	{ "ayq", "Ayi (Papua New Guinea)" },+	{ "ayr", "Central Aymara" },+	{ "ays", "Sorsogon Ayta" },+	{ "ayt", "Magbukun Ayta" },+	{ "ayu", "Ayu" },+	{ "ayy", "Tayabas Ayta" },+	{ "ayz", "Mai Brat" },+	{ "aza", "Azha" },+	{ "azb", "South Azerbaijani" },+	{ "azd", "Eastern Durango Nahuatl" },+	{ "aze", "Azerbaijani" },+	{ "azg", "San Pedro Amuzgos Amuzgo" },+	{ "azj", "North Azerbaijani" },+	{ "azm", "Ipalapa Amuzgo" },+	{ "azn", "Western Durango Nahuatl" },+	{ "azo", "Awing" },+	{ "azt", "Faire Atta" },+	{ "azz", "Highland Puebla Nahuatl" },+	{ "baa", "Babatana" },+	{ "bab", "Bainouk-Gunyuño" },+	{ "bac", "Badui" },+	{ "bae", "Baré" },+	{ "baf", "Nubaca" },+	{ "bag", "Tuki" },+	{ "bah", "Bahamas Creole English" },+	{ "baj", "Barakai" },+	{ "bak", "Bashkir" },+	{ "bal", "Baluchi" },+	{ "bam", "Bambara" },+	{ "ban", "Balinese" },+	{ "bao", "Waimaha" },+	{ "bap", "Bantawa" },+	{ "bar", "Bavarian" },+	{ "bas", "Basa (Cameroon)" },+	{ "bau", "Bada (Nigeria)" },+	{ "bav", "Vengo" },+	{ "baw", "Bambili-Bambui" },+	{ "bax", "Bamun" },+	{ "bay", "Batuley" },+	{ "bba", "Baatonum" },+	{ "bbb", "Barai" },+	{ "bbc", "Batak Toba" },+	{ "bbd", "Bau" },+	{ "bbe", "Bangba" },+	{ "bbf", "Baibai" },+	{ "bbg", "Barama" },+	{ "bbh", "Bugan" },+	{ "bbi", "Barombi" },+	{ "bbj", "Ghomálá'" },+	{ "bbk", "Babanki" },+	{ "bbl", "Bats" },+	{ "bbm", "Babango" },+	{ "bbn", "Uneapa" },+	{ "bbo", "Northern Bobo Madaré" },+	{ "bbp", "West Central Banda" },+	{ "bbq", "Bamali" },+	{ "bbr", "Girawa" },+	{ "bbs", "Bakpinka" },+	{ "bbt", "Mburku" },+	{ "bbu", "Kulung (Nigeria)" },+	{ "bbv", "Karnai" },+	{ "bbw", "Baba" },+	{ "bbx", "Bubia" },+	{ "bby", "Befang" },+	{ "bbz", "Babalia Creole Arabic" },+	{ "bca", "Central Bai" },+	{ "bcb", "Bainouk-Samik" },+	{ "bcc", "Southern Balochi" },+	{ "bcd", "North Babar" },+	{ "bce", "Bamenyam" },+	{ "bcf", "Bamu" },+	{ "bcg", "Baga Binari" },+	{ "bch", "Bariai" },+	{ "bci", "Baoulé" },+	{ "bcj", "Bardi" },+	{ "bck", "Bunaba" },+	{ "bcl", "Central Bikol" },+	{ "bcm", "Bannoni" },+	{ "bcn", "Bali (Nigeria)" },+	{ "bco", "Kaluli" },+	{ "bcp", "Bali (Democratic Republic of Congo)" },+	{ "bcq", "Bench" },+	{ "bcr", "Babine" },+	{ "bcs", "Kohumono" },+	{ "bct", "Bendi" },+	{ "bcu", "Awad Bing" },+	{ "bcv", "Shoo-Minda-Nye" },+	{ "bcw", "Bana" },+	{ "bcy", "Bacama" },+	{ "bcz", "Bainouk-Gunyaamolo" },+	{ "bda", "Bayot" },+	{ "bdb", "Basap" },+	{ "bdc", "Emberá-Baudó" },+	{ "bdd", "Bunama" },+	{ "bde", "Bade" },+	{ "bdf", "Biage" },+	{ "bdg", "Bonggi" },+	{ "bdh", "Baka (Sudan)" },+	{ "bdi", "Burun" },+	{ "bdj", "Bai" },+	{ "bdk", "Budukh" },+	{ "bdl", "Indonesian Bajau" },+	{ "bdm", "Buduma" },+	{ "bdn", "Baldemu" },+	{ "bdo", "Morom" },+	{ "bdp", "Bende" },+	{ "bdq", "Bahnar" },+	{ "bdr", "West Coast Bajau" },+	{ "bds", "Burunge" },+	{ "bdt", "Bokoto" },+	{ "bdu", "Oroko" },+	{ "bdv", "Bodo Parja" },+	{ "bdw", "Baham" },+	{ "bdx", "Budong-Budong" },+	{ "bdy", "Bandjalang" },+	{ "bdz", "Badeshi" },+	{ "bea", "Beaver" },+	{ "beb", "Bebele" },+	{ "bec", "Iceve-Maci" },+	{ "bed", "Bedoanas" },+	{ "bee", "Byangsi" },+	{ "bef", "Benabena" },+	{ "beg", "Belait" },+	{ "beh", "Biali" },+	{ "bei", "Bekati'" },+	{ "bej", "Beja" },+	{ "bek", "Bebeli" },+	{ "bel", "Belarusian" },+	{ "bem", "Bemba (Zambia)" },+	{ "ben", "Bengali" },+	{ "beo", "Beami" },+	{ "bep", "Besoa" },+	{ "beq", "Beembe" },+	{ "bes", "Besme" },+	{ "bet", "Guiberoua Béte" },+	{ "beu", "Blagar" },+	{ "bev", "Daloa Bété" },+	{ "bew", "Betawi" },+	{ "bex", "Jur Modo" },+	{ "bey", "Beli (Papua New Guinea)" },+	{ "bez", "Bena (Tanzania)" },+	{ "bfa", "Bari" },+	{ "bfb", "Pauri Bareli" },+	{ "bfc", "Northern Bai" },+	{ "bfd", "Bafut" },+	{ "bfe", "Betaf" },+	{ "bff", "Bofi" },+	{ "bfg", "Busang Kayan" },+	{ "bfh", "Blafe" },+	{ "bfi", "British Sign Language" },+	{ "bfj", "Bafanji" },+	{ "bfk", "Ban Khor Sign Language" },+	{ "bfl", "Banda-Ndélé" },+	{ "bfm", "Mmen" },+	{ "bfn", "Bunak" },+	{ "bfo", "Malba Birifor" },+	{ "bfp", "Beba" },+	{ "bfq", "Badaga" },+	{ "bfr", "Bazigar" },+	{ "bfs", "Southern Bai" },+	{ "bft", "Balti" },+	{ "bfu", "Gahri" },+	{ "bfw", "Bondo" },+	{ "bfx", "Bantayanon" },+	{ "bfy", "Bagheli" },+	{ "bfz", "Mahasu Pahari" },+	{ "bga", "Gwamhi-Wuri" },+	{ "bgb", "Bobongko" },+	{ "bgc", "Haryanvi" },+	{ "bgd", "Rathwi Bareli" },+	{ "bge", "Bauria" },+	{ "bgf", "Bangandu" },+	{ "bgg", "Bugun" },+	{ "bgi", "Giangan" },+	{ "bgj", "Bangolan" },+	{ "bgk", "Bit" },+	{ "bgl", "Bo (Laos)" },+	{ "bgm", "Baga Mboteni" },+	{ "bgn", "Western Balochi" },+	{ "bgo", "Baga Koga" },+	{ "bgp", "Eastern Balochi" },+	{ "bgq", "Bagri" },+	{ "bgr", "Bawm Chin" },+	{ "bgs", "Tagabawa" },+	{ "bgt", "Bughotu" },+	{ "bgu", "Mbongno" },+	{ "bgv", "Warkay-Bipim" },+	{ "bgw", "Bhatri" },+	{ "bgx", "Balkan Gagauz Turkish" },+	{ "bgy", "Benggoi" },+	{ "bgz", "Banggai" },+	{ "bha", "Bharia" },+	{ "bhb", "Bhili" },+	{ "bhc", "Biga" },+	{ "bhd", "Bhadrawahi" },+	{ "bhe", "Bhaya" },+	{ "bhf", "Odiai" },+	{ "bhg", "Binandere" },+	{ "bhh", "Bukharic" },+	{ "bhi", "Bhilali" },+	{ "bhj", "Bahing" },+	{ "bhl", "Bimin" },+	{ "bhm", "Bathari" },+	{ "bhn", "Bohtan Neo-Aramaic" },+	{ "bho", "Bhojpuri" },+	{ "bhp", "Bima" },+	{ "bhq", "Tukang Besi South" },+	{ "bhr", "Bara Malagasy" },+	{ "bhs", "Buwal" },+	{ "bht", "Bhattiyali" },+	{ "bhu", "Bhunjia" },+	{ "bhv", "Bahau" },+	{ "bhw", "Biak" },+	{ "bhx", "Bhalay" },+	{ "bhy", "Bhele" },+	{ "bhz", "Bada (Indonesia)" },+	{ "bia", "Badimaya" },+	{ "bib", "Bissa" },+	{ "bic", "Bikaru" },+	{ "bid", "Bidiyo" },+	{ "bie", "Bepour" },+	{ "bif", "Biafada" },+	{ "big", "Biangai" },+	{ "bij", "Vaghat-Ya-Bijim-Legeri" },+	{ "bik", "Bikol" },+	{ "bil", "Bile" },+	{ "bim", "Bimoba" },+	{ "bin", "Bini" },+	{ "bio", "Nai" },+	{ "bip", "Bila" },+	{ "biq", "Bipi" },+	{ "bir", "Bisorio" },+	{ "bis", "Bislama" },+	{ "bit", "Berinomo" },+	{ "biu", "Biete" },+	{ "biv", "Southern Birifor" },+	{ "biw", "Kol (Cameroon)" },+	{ "bix", "Bijori" },+	{ "biy", "Birhor" },+	{ "biz", "Baloi" },+	{ "bja", "Budza" },+	{ "bjb", "Banggarla" },+	{ "bjc", "Bariji" },+	{ "bje", "Biao-Jiao Mien" },+	{ "bjf", "Barzani Jewish Neo-Aramaic" },+	{ "bjg", "Bidyogo" },+	{ "bjh", "Bahinemo" },+	{ "bji", "Burji" },+	{ "bjj", "Kanauji" },+	{ "bjk", "Barok" },+	{ "bjl", "Bulu (Papua New Guinea)" },+	{ "bjm", "Bajelani" },+	{ "bjn", "Banjar" },+	{ "bjo", "Mid-Southern Banda" },+	{ "bjp", "Fanamaket" },+	{ "bjr", "Binumarien" },+	{ "bjs", "Bajan" },+	{ "bjt", "Balanta-Ganja" },+	{ "bju", "Busuu" },+	{ "bjv", "Bedjond" },+	{ "bjw", "Bakwé" },+	{ "bjx", "Banao Itneg" },+	{ "bjy", "Bayali" },+	{ "bjz", "Baruga" },+	{ "bka", "Kyak" },+	{ "bkc", "Baka (Cameroon)" },+	{ "bkd", "Binukid" },+	{ "bkf", "Beeke" },+	{ "bkg", "Buraka" },+	{ "bkh", "Bakoko" },+	{ "bki", "Baki" },+	{ "bkj", "Pande" },+	{ "bkk", "Brokskat" },+	{ "bkl", "Berik" },+	{ "bkm", "Kom (Cameroon)" },+	{ "bkn", "Bukitan" },+	{ "bko", "Kwa'" },+	{ "bkp", "Boko (Democratic Republic of Congo)" },+	{ "bkq", "Bakairí" },+	{ "bkr", "Bakumpai" },+	{ "bks", "Northern Sorsoganon" },+	{ "bkt", "Boloki" },+	{ "bku", "Buhid" },+	{ "bkv", "Bekwarra" },+	{ "bkw", "Bekwel" },+	{ "bkx", "Baikeno" },+	{ "bky", "Bokyi" },+	{ "bkz", "Bungku" },+	{ "bla", "Siksika" },+	{ "blb", "Bilua" },+	{ "blc", "Bella Coola" },+	{ "bld", "Bolango" },+	{ "ble", "Balanta-Kentohe" },+	{ "blf", "Buol" },+	{ "blg", "Balau" },+	{ "blh", "Kuwaa" },+	{ "bli", "Bolia" },+	{ "blj", "Bolongan" },+	{ "blk", "Pa'o Karen" },+	{ "bll", "Biloxi" },+	{ "blm", "Beli (Sudan)" },+	{ "bln", "Southern Catanduanes Bikol" },+	{ "blo", "Anii" },+	{ "blp", "Blablanga" },+	{ "blq", "Baluan-Pam" },+	{ "blr", "Blang" },+	{ "bls", "Balaesang" },+	{ "blt", "Tai Dam" },+	{ "blv", "Bolo" },+	{ "blw", "Balangao" },+	{ "blx", "Mag-Indi Ayta" },+	{ "bly", "Notre" },+	{ "blz", "Balantak" },+	{ "bma", "Lame" },+	{ "bmb", "Bembe" },+	{ "bmc", "Biem" },+	{ "bmd", "Baga Manduri" },+	{ "bme", "Limassa" },+	{ "bmf", "Bom" },+	{ "bmg", "Bamwe" },+	{ "bmh", "Kein" },+	{ "bmi", "Bagirmi" },+	{ "bmj", "Bote-Majhi" },+	{ "bmk", "Ghayavi" },+	{ "bml", "Bomboli" },+	{ "bmm", "Northern Betsimisaraka Malagasy" },+	{ "bmn", "Bina (Papua New Guinea)" },+	{ "bmo", "Bambalang" },+	{ "bmp", "Bulgebi" },+	{ "bmq", "Bomu" },+	{ "bmr", "Muinane" },+	{ "bms", "Bilma Kanuri" },+	{ "bmt", "Biao Mon" },+	{ "bmu", "Somba-Siawari" },+	{ "bmv", "Bum" },+	{ "bmw", "Bomwali" },+	{ "bmx", "Baimak" },+	{ "bmy", "Bemba (Democratic Republic of Congo)" },+	{ "bmz", "Baramu" },+	{ "bna", "Bonerate" },+	{ "bnb", "Bookan" },+	{ "bnc", "Bontok" },+	{ "bnd", "Banda (Indonesia)" },+	{ "bne", "Bintauna" },+	{ "bnf", "Masiwang" },+	{ "bng", "Benga" },+	{ "bni", "Bangi" },+	{ "bnj", "Eastern Tawbuid" },+	{ "bnk", "Bierebo" },+	{ "bnl", "Boon" },+	{ "bnm", "Batanga" },+	{ "bnn", "Bunun" },+	{ "bno", "Bantoanon" },+	{ "bnp", "Bola" },+	{ "bnq", "Bantik" },+	{ "bnr", "Butmas-Tur" },+	{ "bns", "Bundeli" },+	{ "bnu", "Bentong" },+	{ "bnv", "Bonerif" },+	{ "bnw", "Bisis" },+	{ "bnx", "Bangubangu" },+	{ "bny", "Bintulu" },+	{ "bnz", "Beezen" },+	{ "boa", "Bora" },+	{ "bob", "Aweer" },+	{ "bod", "Tibetan" },+	{ "boe", "Mundabli" },+	{ "bof", "Bolon" },+	{ "bog", "Bamako Sign Language" },+	{ "boh", "Boma" },+	{ "boi", "Barbareño" },+	{ "boj", "Anjam" },+	{ "bok", "Bonjo" },+	{ "bol", "Bole" },+	{ "bom", "Berom" },+	{ "bon", "Bine" },+	{ "boo", "Tiemacèwè Bozo" },+	{ "bop", "Bonkiman" },+	{ "boq", "Bogaya" },+	{ "bor", "Borôro" },+	{ "bos", "Bosnian" },+	{ "bot", "Bongo" },+	{ "bou", "Bondei" },+	{ "bov", "Tuwuli" },+	{ "bow", "Rema" },+	{ "box", "Buamu" },+	{ "boy", "Bodo (Central African Republic)" },+	{ "boz", "Tiéyaxo Bozo" },+	{ "bpa", "Daakaka" },+	{ "bpb", "Barbacoas" },+	{ "bpd", "Banda-Banda" },+	{ "bpg", "Bonggo" },+	{ "bph", "Botlikh" },+	{ "bpi", "Bagupi" },+	{ "bpj", "Binji" },+	{ "bpk", "Orowe" },+	{ "bpl", "Broome Pearling Lugger Pidgin" },+	{ "bpm", "Biyom" },+	{ "bpn", "Dzao Min" },+	{ "bpo", "Anasi" },+	{ "bpp", "Kaure" },+	{ "bpq", "Banda Malay" },+	{ "bpr", "Koronadal Blaan" },+	{ "bps", "Sarangani Blaan" },+	{ "bpt", "Barrow Point" },+	{ "bpu", "Bongu" },+	{ "bpv", "Bian Marind" },+	{ "bpw", "Bo (Papua New Guinea)" },+	{ "bpx", "Palya Bareli" },+	{ "bpy", "Bishnupriya" },+	{ "bpz", "Bilba" },+	{ "bqa", "Tchumbuli" },+	{ "bqb", "Bagusa" },+	{ "bqc", "Boko (Benin)" },+	{ "bqd", "Bung" },+	{ "bqf", "Baga Kaloum" },+	{ "bqg", "Bago-Kusuntu" },+	{ "bqh", "Baima" },+	{ "bqi", "Bakhtiari" },+	{ "bqj", "Bandial" },+	{ "bqk", "Banda-Mbrès" },+	{ "bql", "Bilakura" },+	{ "bqm", "Wumboko" },+	{ "bqn", "Bulgarian Sign Language" },+	{ "bqo", "Balo" },+	{ "bqp", "Busa" },+	{ "bqq", "Biritai" },+	{ "bqr", "Burusu" },+	{ "bqs", "Bosngun" },+	{ "bqt", "Bamukumbit" },+	{ "bqu", "Boguru" },+	{ "bqv", "Koro Wachi" },+	{ "bqw", "Buru (Nigeria)" },+	{ "bqx", "Baangi" },+	{ "bqy", "Bengkala Sign Language" },+	{ "bqz", "Bakaka" },+	{ "bra", "Braj" },+	{ "brb", "Lave" },+	{ "brc", "Berbice Creole Dutch" },+	{ "brd", "Baraamu" },+	{ "bre", "Breton" },+	{ "brf", "Bera" },+	{ "brg", "Baure" },+	{ "brh", "Brahui" },+	{ "bri", "Mokpwe" },+	{ "brj", "Bieria" },+	{ "brk", "Birked" },+	{ "brl", "Birwa" },+	{ "brm", "Barambu" },+	{ "brn", "Boruca" },+	{ "bro", "Brokkat" },+	{ "brp", "Barapasi" },+	{ "brq", "Breri" },+	{ "brr", "Birao" },+	{ "brs", "Baras" },+	{ "brt", "Bitare" },+	{ "bru", "Eastern Bru" },+	{ "brv", "Western Bru" },+	{ "brw", "Bellari" },+	{ "brx", "Bodo (India)" },+	{ "bry", "Burui" },+	{ "brz", "Bilbil" },+	{ "bsa", "Abinomn" },+	{ "bsb", "Brunei Bisaya" },+	{ "bsc", "Bassari" },+	{ "bse", "Wushi" },+	{ "bsf", "Bauchi" },+	{ "bsg", "Bashkardi" },+	{ "bsh", "Kati" },+	{ "bsi", "Bassossi" },+	{ "bsj", "Bangwinji" },+	{ "bsk", "Burushaski" },+	{ "bsl", "Basa-Gumna" },+	{ "bsm", "Busami" },+	{ "bsn", "Barasana-Eduria" },+	{ "bso", "Buso" },+	{ "bsp", "Baga Sitemu" },+	{ "bsq", "Bassa" },+	{ "bsr", "Bassa-Kontagora" },+	{ "bss", "Akoose" },+	{ "bst", "Basketo" },+	{ "bsu", "Bahonsuai" },+	{ "bsv", "Baga Sobané" },+	{ "bsw", "Baiso" },+	{ "bsx", "Yangkam" },+	{ "bsy", "Sabah Bisaya" },+	{ "bta", "Bata" },+	{ "btc", "Bati (Cameroon)" },+	{ "btd", "Batak Dairi" },+	{ "bte", "Gamo-Ningi" },+	{ "btf", "Birgit" },+	{ "btg", "Gagnoa Bété" },+	{ "bth", "Biatah Bidayuh" },+	{ "bti", "Burate" },+	{ "btj", "Bacanese Malay" },+	{ "btl", "Bhatola" },+	{ "btm", "Batak Mandailing" },+	{ "btn", "Ratagnon" },+	{ "bto", "Rinconada Bikol" },+	{ "btp", "Budibud" },+	{ "btq", "Batek" },+	{ "btr", "Baetora" },+	{ "bts", "Batak Simalungun" },+	{ "btt", "Bete-Bendi" },+	{ "btu", "Batu" },+	{ "btv", "Bateri" },+	{ "btw", "Butuanon" },+	{ "btx", "Batak Karo" },+	{ "bty", "Bobot" },+	{ "btz", "Batak Alas-Kluet" },+	{ "bua", "Buriat" },+	{ "bub", "Bua" },+	{ "buc", "Bushi" },+	{ "bud", "Ntcham" },+	{ "bue", "Beothuk" },+	{ "buf", "Bushoong" },+	{ "bug", "Buginese" },+	{ "buh", "Younuo Bunu" },+	{ "bui", "Bongili" },+	{ "buj", "Basa-Gurmana" },+	{ "buk", "Bugawac" },+	{ "bul", "Bulgarian" },+	{ "bum", "Bulu (Cameroon)" },+	{ "bun", "Sherbro" },+	{ "buo", "Terei" },+	{ "bup", "Busoa" },+	{ "buq", "Brem" },+	{ "bus", "Bokobaru" },+	{ "but", "Bungain" },+	{ "buu", "Budu" },+	{ "buv", "Bun" },+	{ "buw", "Bubi" },+	{ "bux", "Boghom" },+	{ "buy", "Bullom So" },+	{ "buz", "Bukwen" },+	{ "bva", "Barein" },+	{ "bvb", "Bube" },+	{ "bvc", "Baelelea" },+	{ "bvd", "Baeggu" },+	{ "bve", "Berau Malay" },+	{ "bvf", "Boor" },+	{ "bvg", "Bonkeng" },+	{ "bvh", "Bure" },+	{ "bvi", "Belanda Viri" },+	{ "bvj", "Baan" },+	{ "bvk", "Bukat" },+	{ "bvl", "Bolivian Sign Language" },+	{ "bvm", "Bamunka" },+	{ "bvn", "Buna" },+	{ "bvo", "Bolgo" },+	{ "bvp", "Bumang" },+	{ "bvq", "Birri" },+	{ "bvr", "Burarra" },+	{ "bvt", "Bati (Indonesia)" },+	{ "bvu", "Bukit Malay" },+	{ "bvv", "Baniva" },+	{ "bvw", "Boga" },+	{ "bvx", "Dibole" },+	{ "bvy", "Baybayanon" },+	{ "bvz", "Bauzi" },+	{ "bwa", "Bwatoo" },+	{ "bwb", "Namosi-Naitasiri-Serua" },+	{ "bwc", "Bwile" },+	{ "bwd", "Bwaidoka" },+	{ "bwe", "Bwe Karen" },+	{ "bwf", "Boselewa" },+	{ "bwg", "Barwe" },+	{ "bwh", "Bishuo" },+	{ "bwi", "Baniwa" },+	{ "bwj", "Láá Láá Bwamu" },+	{ "bwk", "Bauwaki" },+	{ "bwl", "Bwela" },+	{ "bwm", "Biwat" },+	{ "bwn", "Wunai Bunu" },+	{ "bwo", "Boro (Ethiopia)" },+	{ "bwp", "Mandobo Bawah" },+	{ "bwq", "Southern Bobo Madaré" },+	{ "bwr", "Bura-Pabir" },+	{ "bws", "Bomboma" },+	{ "bwt", "Bafaw-Balong" },+	{ "bwu", "Buli (Ghana)" },+	{ "bww", "Bwa" },+	{ "bwx", "Bu-Nao Bunu" },+	{ "bwy", "Cwi Bwamu" },+	{ "bwz", "Bwisi" },+	{ "bxa", "Tairaha" },+	{ "bxb", "Belanda Bor" },+	{ "bxc", "Molengue" },+	{ "bxd", "Pela" },+	{ "bxe", "Birale" },+	{ "bxf", "Bilur" },+	{ "bxg", "Bangala" },+	{ "bxh", "Buhutu" },+	{ "bxi", "Pirlatapa" },+	{ "bxj", "Bayungu" },+	{ "bxk", "Bukusu" },+	{ "bxl", "Jalkunan" },+	{ "bxm", "Mongolia Buriat" },+	{ "bxn", "Burduna" },+	{ "bxo", "Barikanchi" },+	{ "bxp", "Bebil" },+	{ "bxq", "Beele" },+	{ "bxr", "Russia Buriat" },+	{ "bxs", "Busam" },+	{ "bxu", "China Buriat" },+	{ "bxv", "Berakou" },+	{ "bxw", "Bankagooma" },+	{ "bxx", "Borna (Democratic Republic of Congo)" },+	{ "bxz", "Binahari" },+	{ "bya", "Batak" },+	{ "byb", "Bikya" },+	{ "byc", "Ubaghara" },+	{ "byd", "Benyadu'" },+	{ "bye", "Pouye" },+	{ "byf", "Bete" },+	{ "byg", "Baygo" },+	{ "byh", "Bhujel" },+	{ "byi", "Buyu" },+	{ "byj", "Bina (Nigeria)" },+	{ "byk", "Biao" },+	{ "byl", "Bayono" },+	{ "bym", "Bidyara" },+	{ "byn", "Bilin" },+	{ "byo", "Biyo" },+	{ "byp", "Bumaji" },+	{ "byq", "Basay" },+	{ "byr", "Baruya" },+	{ "bys", "Burak" },+	{ "byt", "Berti" },+	{ "byv", "Medumba" },+	{ "byw", "Belhariya" },+	{ "byx", "Qaqet" },+	{ "byy", "Buya" },+	{ "byz", "Banaro" },+	{ "bza", "Bandi" },+	{ "bzb", "Andio" },+	{ "bzc", "Southern Betsimisaraka Malagasy" },+	{ "bzd", "Bribri" },+	{ "bze", "Jenaama Bozo" },+	{ "bzf", "Boikin" },+	{ "bzg", "Babuza" },+	{ "bzh", "Mapos Buang" },+	{ "bzi", "Bisu" },+	{ "bzj", "Belize Kriol English" },+	{ "bzk", "Nicaragua Creole English" },+	{ "bzl", "Boano (Sulawesi)" },+	{ "bzm", "Bolondo" },+	{ "bzn", "Boano (Maluku)" },+	{ "bzo", "Bozaba" },+	{ "bzp", "Kemberano" },+	{ "bzq", "Buli (Indonesia)" },+	{ "bzr", "Biri" },+	{ "bzs", "Brazilian Sign Language" },+	{ "bzt", "Brithenig" },+	{ "bzu", "Burmeso" },+	{ "bzv", "Naami" },+	{ "bzw", "Basa (Nigeria)" },+	{ "bzx", "Kɛlɛngaxo Bozo" },+	{ "bzy", "Obanliku" },+	{ "bzz", "Evant" },+	{ "caa", "Chortí" },+	{ "cab", "Garifuna" },+	{ "cac", "Chuj" },+	{ "cad", "Caddo" },+	{ "cae", "Lehar" },+	{ "caf", "Southern Carrier" },+	{ "cag", "Nivaclé" },+	{ "cah", "Cahuarano" },+	{ "caj", "Chané" },+	{ "cak", "Kaqchikel" },+	{ "cal", "Carolinian" },+	{ "cam", "Cemuhî" },+	{ "can", "Chambri" },+	{ "cao", "Chácobo" },+	{ "cap", "Chipaya" },+	{ "caq", "Car Nicobarese" },+	{ "car", "Galibi Carib" },+	{ "cas", "Tsimané" },+	{ "cat", "Catalan" },+	{ "cav", "Cavineña" },+	{ "caw", "Callawalla" },+	{ "cax", "Chiquitano" },+	{ "cay", "Cayuga" },+	{ "caz", "Canichana" },+	{ "cbb", "Cabiyarí" },+	{ "cbc", "Carapana" },+	{ "cbd", "Carijona" },+	{ "cbe", "Chipiajes" },+	{ "cbg", "Chimila" },+	{ "cbh", "Cagua" },+	{ "cbi", "Chachi" },+	{ "cbj", "Ede Cabe" },+	{ "cbk", "Chavacano" },+	{ "cbl", "Bualkhaw Chin" },+	{ "cbn", "Nyahkur" },+	{ "cbo", "Izora" },+	{ "cbr", "Cashibo-Cacataibo" },+	{ "cbs", "Cashinahua" },+	{ "cbt", "Chayahuita" },+	{ "cbu", "Candoshi-Shapra" },+	{ "cbv", "Cacua" },+	{ "cbw", "Kinabalian" },+	{ "cby", "Carabayo" },+	{ "cca", "Cauca" },+	{ "ccc", "Chamicuro" },+	{ "ccd", "Cafundo Creole" },+	{ "cce", "Chopi" },+	{ "ccg", "Samba Daka" },+	{ "cch", "Atsam" },+	{ "ccj", "Kasanga" },+	{ "ccl", "Cutchi-Swahili" },+	{ "ccm", "Malaccan Creole Malay" },+	{ "cco", "Comaltepec Chinantec" },+	{ "ccp", "Chakma" },+	{ "ccr", "Cacaopera" },+	{ "cda", "Choni" },+	{ "cde", "Chenchu" },+	{ "cdf", "Chiru" },+	{ "cdg", "Chamari" },+	{ "cdh", "Chambeali" },+	{ "cdi", "Chodri" },+	{ "cdj", "Churahi" },+	{ "cdm", "Chepang" },+	{ "cdn", "Chaudangsi" },+	{ "cdo", "Min Dong Chinese" },+	{ "cdr", "Cinda-Regi-Tiyal" },+	{ "cds", "Chadian Sign Language" },+	{ "cdy", "Chadong" },+	{ "cdz", "Koda" },+	{ "cea", "Lower Chehalis" },+	{ "ceb", "Cebuano" },+	{ "ceg", "Chamacoco" },+	{ "cek", "Eastern Khumi Chin" },+	{ "cen", "Cen" },+	{ "ces", "Czech" },+	{ "cet", "Centúúm" },+	{ "cfa", "Dijim-Bwilim" },+	{ "cfd", "Cara" },+	{ "cfg", "Como Karim" },+	{ "cfm", "Falam Chin" },+	{ "cga", "Changriwa" },+	{ "cgc", "Kagayanen" },+	{ "cgg", "Chiga" },+	{ "cgk", "Chocangacakha" },+	{ "cha", "Chamorro" },+	{ "chb", "Chibcha" },+	{ "chc", "Catawba" },+	{ "chd", "Highland Oaxaca Chontal" },+	{ "che", "Chechen" },+	{ "chf", "Tabasco Chontal" },+	{ "chg", "Chagatai" },+	{ "chh", "Chinook" },+	{ "chj", "Ojitlán Chinantec" },+	{ "chk", "Chuukese" },+	{ "chl", "Cahuilla" },+	{ "chm", "Mari (Russia)" },+	{ "chn", "Chinook jargon" },+	{ "cho", "Choctaw" },+	{ "chp", "Chipewyan" },+	{ "chq", "Quiotepec Chinantec" },+	{ "chr", "Cherokee" },+	{ "cht", "Cholón" },+	{ "chu", "Church Slavic" },+	{ "chv", "Chuvash" },+	{ "chw", "Chuwabu" },+	{ "chx", "Chantyal" },+	{ "chy", "Cheyenne" },+	{ "chz", "Ozumacín Chinantec" },+	{ "cia", "Cia-Cia" },+	{ "cib", "Ci Gbe" },+	{ "cic", "Chickasaw" },+	{ "cid", "Chimariko" },+	{ "cie", "Cineni" },+	{ "cih", "Chinali" },+	{ "cik", "Chitkuli Kinnauri" },+	{ "cim", "Cimbrian" },+	{ "cin", "Cinta Larga" },+	{ "cip", "Chiapanec" },+	{ "cir", "Tiri" },+	{ "ciw", "Chippewa" },+	{ "ciy", "Chaima" },+	{ "cja", "Western Cham" },+	{ "cje", "Chru" },+	{ "cjh", "Upper Chehalis" },+	{ "cji", "Chamalal" },+	{ "cjk", "Chokwe" },+	{ "cjm", "Eastern Cham" },+	{ "cjn", "Chenapian" },+	{ "cjo", "Ashéninka Pajonal" },+	{ "cjp", "Cabécar" },+	{ "cjs", "Shor" },+	{ "cjv", "Chuave" },+	{ "cjy", "Jinyu Chinese" },+	{ "ckb", "Central Kurdish" },+	{ "ckh", "Chak" },+	{ "ckl", "Cibak" },+	{ "ckn", "Kaang Chin" },+	{ "cko", "Anufo" },+	{ "ckq", "Kajakse" },+	{ "ckr", "Kairak" },+	{ "cks", "Tayo" },+	{ "ckt", "Chukot" },+	{ "cku", "Koasati" },+	{ "ckv", "Kavalan" },+	{ "ckx", "Caka" },+	{ "cky", "Cakfem-Mushere" },+	{ "ckz", "Cakchiquel-Quiché Mixed Language" },+	{ "cla", "Ron" },+	{ "clc", "Chilcotin" },+	{ "cld", "Chaldean Neo-Aramaic" },+	{ "cle", "Lealao Chinantec" },+	{ "clh", "Chilisso" },+	{ "cli", "Chakali" },+	{ "clj", "Laitu Chin" },+	{ "clk", "Idu-Mishmi" },+	{ "cll", "Chala" },+	{ "clm", "Clallam" },+	{ "clo", "Lowland Oaxaca Chontal" },+	{ "clt", "Lautu Chin" },+	{ "clu", "Caluyanun" },+	{ "clw", "Chulym" },+	{ "cly", "Eastern Highland Chatino" },+	{ "cma", "Maa" },+	{ "cme", "Cerma" },+	{ "cmg", "Classical Mongolian" },+	{ "cmi", "Emberá-Chamí" },+	{ "cml", "Campalagian" },+	{ "cmm", "Michigamea" },+	{ "cmn", "Mandarin Chinese" },+	{ "cmo", "Central Mnong" },+	{ "cmr", "Mro-Khimi Chin" },+	{ "cms", "Messapic" },+	{ "cmt", "Camtho" },+	{ "cna", "Changthang" },+	{ "cnb", "Chinbon Chin" },+	{ "cnc", "Côông" },+	{ "cng", "Northern Qiang" },+	{ "cnh", "Haka Chin" },+	{ "cni", "Asháninka" },+	{ "cnk", "Khumi Chin" },+	{ "cnl", "Lalana Chinantec" },+	{ "cno", "Con" },+	{ "cns", "Central Asmat" },+	{ "cnt", "Tepetotutla Chinantec" },+	{ "cnu", "Chenoua" },+	{ "cnw", "Ngawn Chin" },+	{ "cnx", "Middle Cornish" },+	{ "coa", "Cocos Islands Malay" },+	{ "cob", "Chicomuceltec" },+	{ "coc", "Cocopa" },+	{ "cod", "Cocama-Cocamilla" },+	{ "coe", "Koreguaje" },+	{ "cof", "Colorado" },+	{ "cog", "Chong" },+	{ "coh", "Chonyi-Dzihana-Kauma" },+	{ "coj", "Cochimi" },+	{ "cok", "Santa Teresa Cora" },+	{ "col", "Columbia-Wenatchi" },+	{ "com", "Comanche" },+	{ "con", "Cofán" },+	{ "coo", "Comox" },+	{ "cop", "Coptic" },+	{ "coq", "Coquille" },+	{ "cor", "Cornish" },+	{ "cos", "Corsican" },+	{ "cot", "Caquinte" },+	{ "cou", "Wamey" },+	{ "cov", "Cao Miao" },+	{ "cow", "Cowlitz" },+	{ "cox", "Nanti" },+	{ "coy", "Coyaima" },+	{ "coz", "Chochotec" },+	{ "cpa", "Palantla Chinantec" },+	{ "cpb", "Ucayali-Yurúa Ashéninka" },+	{ "cpc", "Ajyíninka Apurucayali" },+	{ "cpg", "Cappadocian Greek" },+	{ "cpi", "Chinese Pidgin English" },+	{ "cpn", "Cherepon" },+	{ "cpo", "Kpeego" },+	{ "cps", "Capiznon" },+	{ "cpu", "Pichis Ashéninka" },+	{ "cpx", "Pu-Xian Chinese" },+	{ "cpy", "South Ucayali Ashéninka" },+	{ "cqd", "Chuanqiandian Cluster Miao" },+	{ "cqu", "Chilean Quechua" },+	{ "cra", "Chara" },+	{ "crb", "Island Carib" },+	{ "crc", "Lonwolwol" },+	{ "crd", "Coeur d'Alene" },+	{ "cre", "Cree" },+	{ "crf", "Caramanta" },+	{ "crg", "Michif" },+	{ "crh", "Crimean Tatar" },+	{ "cri", "Sãotomense" },+	{ "crj", "Southern East Cree" },+	{ "crk", "Plains Cree" },+	{ "crl", "Northern East Cree" },+	{ "crm", "Moose Cree" },+	{ "crn", "El Nayar Cora" },+	{ "cro", "Crow" },+	{ "crq", "Iyo'wujwa Chorote" },+	{ "crr", "Carolina Algonquian" },+	{ "crs", "Seselwa Creole French" },+	{ "crt", "Iyojwa'ja Chorote" },+	{ "crv", "Chaura" },+	{ "crw", "Chrau" },+	{ "crx", "Carrier" },+	{ "cry", "Cori" },+	{ "crz", "Cruzeño" },+	{ "csa", "Chiltepec Chinantec" },+	{ "csb", "Kashubian" },+	{ "csc", "Catalan Sign Language" },+	{ "csd", "Chiangmai Sign Language" },+	{ "cse", "Czech Sign Language" },+	{ "csf", "Cuba Sign Language" },+	{ "csg", "Chilean Sign Language" },+	{ "csh", "Asho Chin" },+	{ "csi", "Coast Miwok" },+	{ "csj", "Songlai Chin" },+	{ "csk", "Jola-Kasa" },+	{ "csl", "Chinese Sign Language" },+	{ "csm", "Central Sierra Miwok" },+	{ "csn", "Colombian Sign Language" },+	{ "cso", "Sochiapam Chinantec" },+	{ "csq", "Croatia Sign Language" },+	{ "csr", "Costa Rican Sign Language" },+	{ "css", "Southern Ohlone" },+	{ "cst", "Northern Ohlone" },+	{ "csv", "Sumtu Chin" },+	{ "csw", "Swampy Cree" },+	{ "csy", "Siyin Chin" },+	{ "csz", "Coos" },+	{ "cta", "Tataltepec Chatino" },+	{ "ctc", "Chetco" },+	{ "ctd", "Tedim Chin" },+	{ "cte", "Tepinapa Chinantec" },+	{ "ctg", "Chittagonian" },+	{ "cth", "Thaiphum Chin" },+	{ "ctl", "Tlacoatzintepec Chinantec" },+	{ "ctm", "Chitimacha" },+	{ "ctn", "Chhintange" },+	{ "cto", "Emberá-Catío" },+	{ "ctp", "Western Highland Chatino" },+	{ "cts", "Northern Catanduanes Bikol" },+	{ "ctt", "Wayanad Chetti" },+	{ "ctu", "Chol" },+	{ "ctz", "Zacatepec Chatino" },+	{ "cua", "Cua" },+	{ "cub", "Cubeo" },+	{ "cuc", "Usila Chinantec" },+	{ "cug", "Cung" },+	{ "cuh", "Chuka" },+	{ "cui", "Cuiba" },+	{ "cuj", "Mashco Piro" },+	{ "cuk", "San Blas Kuna" },+	{ "cul", "Culina" },+	{ "cum", "Cumeral" },+	{ "cuo", "Cumanagoto" },+	{ "cup", "Cupeño" },+	{ "cuq", "Cun" },+	{ "cur", "Chhulung" },+	{ "cut", "Teutila Cuicatec" },+	{ "cuu", "Tai Ya" },+	{ "cuv", "Cuvok" },+	{ "cuw", "Chukwa" },+	{ "cux", "Tepeuxila Cuicatec" },+	{ "cvg", "Chug" },+	{ "cvn", "Valle Nacional Chinantec" },+	{ "cwa", "Kabwa" },+	{ "cwb", "Maindo" },+	{ "cwd", "Woods Cree" },+	{ "cwe", "Kwere" },+	{ "cwg", "Chewong" },+	{ "cwt", "Kuwaataay" },+	{ "cya", "Nopala Chatino" },+	{ "cyb", "Cayubaba" },+	{ "cym", "Welsh" },+	{ "cyo", "Cuyonon" },+	{ "czh", "Huizhou Chinese" },+	{ "czk", "Knaanic" },+	{ "czn", "Zenzontepec Chatino" },+	{ "czo", "Min Zhong Chinese" },+	{ "czt", "Zotung Chin" },+	{ "daa", "Dangaléat" },+	{ "dac", "Dambi" },+	{ "dad", "Marik" },+	{ "dae", "Duupa" },+	{ "dag", "Dagbani" },+	{ "dah", "Gwahatike" },+	{ "dai", "Day" },+	{ "daj", "Dar Fur Daju" },+	{ "dak", "Dakota" },+	{ "dal", "Dahalo" },+	{ "dam", "Damakawa" },+	{ "dan", "Danish" },+	{ "dao", "Daai Chin" },+	{ "daq", "Dandami Maria" },+	{ "dar", "Dargwa" },+	{ "das", "Daho-Doo" },+	{ "dau", "Dar Sila Daju" },+	{ "dav", "Taita" },+	{ "daw", "Davawenyo" },+	{ "dax", "Dayi" },+	{ "daz", "Dao" },+	{ "dba", "Bangime" },+	{ "dbb", "Deno" },+	{ "dbd", "Dadiya" },+	{ "dbe", "Dabe" },+	{ "dbf", "Edopi" },+	{ "dbg", "Dogul Dom Dogon" },+	{ "dbi", "Doka" },+	{ "dbj", "Ida'an" },+	{ "dbl", "Dyirbal" },+	{ "dbm", "Duguri" },+	{ "dbn", "Duriankere" },+	{ "dbo", "Dulbu" },+	{ "dbp", "Duwai" },+	{ "dbq", "Daba" },+	{ "dbr", "Dabarre" },+	{ "dbt", "Ben Tey Dogon" },+	{ "dbu", "Bondum Dom Dogon" },+	{ "dbv", "Dungu" },+	{ "dbw", "Bankan Tey Dogon" },+	{ "dby", "Dibiyaso" },+	{ "dcc", "Deccan" },+	{ "dcr", "Negerhollands" },+	{ "dda", "Dadi Dadi" },+	{ "ddd", "Dongotono" },+	{ "dde", "Doondo" },+	{ "ddg", "Fataluku" },+	{ "ddi", "West Goodenough" },+	{ "ddj", "Jaru" },+	{ "ddn", "Dendi (Benin)" },+	{ "ddo", "Dido" },+	{ "ddr", "Dhudhuroa" },+	{ "dds", "Donno So Dogon" },+	{ "ddw", "Dawera-Daweloor" },+	{ "dec", "Dagik" },+	{ "ded", "Dedua" },+	{ "dee", "Dewoin" },+	{ "def", "Dezfuli" },+	{ "deg", "Degema" },+	{ "deh", "Dehwari" },+	{ "dei", "Demisa" },+	{ "dek", "Dek" },+	{ "del", "Delaware" },+	{ "dem", "Dem" },+	{ "den", "Slave (Athapascan)" },+	{ "dep", "Pidgin Delaware" },+	{ "deq", "Dendi (Central African Republic)" },+	{ "der", "Deori" },+	{ "des", "Desano" },+	{ "deu", "German" },+	{ "dev", "Domung" },+	{ "dez", "Dengese" },+	{ "dga", "Southern Dagaare" },+	{ "dgb", "Bunoge Dogon" },+	{ "dgc", "Casiguran Dumagat Agta" },+	{ "dgd", "Dagaari Dioula" },+	{ "dge", "Degenan" },+	{ "dgg", "Doga" },+	{ "dgh", "Dghwede" },+	{ "dgi", "Northern Dagara" },+	{ "dgk", "Dagba" },+	{ "dgl", "Andaandi" },+	{ "dgn", "Dagoman" },+	{ "dgo", "Dogri (individual language)" },+	{ "dgr", "Dogrib" },+	{ "dgs", "Dogoso" },+	{ "dgt", "Ndra'ngith" },+	{ "dgu", "Degaru" },+	{ "dgw", "Daungwurrung" },+	{ "dgx", "Doghoro" },+	{ "dgz", "Daga" },+	{ "dhd", "Dhundari" },+	{ "dhg", "Djangu" },+	{ "dhi", "Dhimal" },+	{ "dhl", "Dhalandji" },+	{ "dhm", "Zemba" },+	{ "dhn", "Dhanki" },+	{ "dho", "Dhodia" },+	{ "dhr", "Dhargari" },+	{ "dhs", "Dhaiso" },+	{ "dhu", "Dhurga" },+	{ "dhv", "Dehu" },+	{ "dhw", "Dhanwar (Nepal)" },+	{ "dhx", "Dhungaloo" },+	{ "dia", "Dia" },+	{ "dib", "South Central Dinka" },+	{ "dic", "Lakota Dida" },+	{ "did", "Didinga" },+	{ "dif", "Dieri" },+	{ "dig", "Digo" },+	{ "dih", "Kumiai" },+	{ "dii", "Dimbong" },+	{ "dij", "Dai" },+	{ "dik", "Southwestern Dinka" },+	{ "dil", "Dilling" },+	{ "dim", "Dime" },+	{ "din", "Dinka" },+	{ "dio", "Dibo" },+	{ "dip", "Northeastern Dinka" },+	{ "diq", "Dimli (individual language)" },+	{ "dir", "Dirim" },+	{ "dis", "Dimasa" },+	{ "dit", "Dirari" },+	{ "diu", "Diriku" },+	{ "div", "Dhivehi" },+	{ "diw", "Northwestern Dinka" },+	{ "dix", "Dixon Reef" },+	{ "diy", "Diuwe" },+	{ "diz", "Ding" },+	{ "dja", "Djadjawurrung" },+	{ "djb", "Djinba" },+	{ "djc", "Dar Daju Daju" },+	{ "djd", "Djamindjung" },+	{ "dje", "Zarma" },+	{ "djf", "Djangun" },+	{ "dji", "Djinang" },+	{ "djj", "Djeebbana" },+	{ "djk", "Eastern Maroon Creole" },+	{ "djm", "Jamsay Dogon" },+	{ "djn", "Djauan" },+	{ "djo", "Jangkang" },+	{ "djr", "Djambarrpuyngu" },+	{ "dju", "Kapriman" },+	{ "djw", "Djawi" },+	{ "dka", "Dakpakha" },+	{ "dkk", "Dakka" },+	{ "dkr", "Kuijau" },+	{ "dks", "Southeastern Dinka" },+	{ "dkx", "Mazagway" },+	{ "dlg", "Dolgan" },+	{ "dlk", "Dahalik" },+	{ "dlm", "Dalmatian" },+	{ "dln", "Darlong" },+	{ "dma", "Duma" },+	{ "dmb", "Mombo Dogon" },+	{ "dmc", "Gavak" },+	{ "dmd", "Madhi Madhi" },+	{ "dme", "Dugwor" },+	{ "dmg", "Upper Kinabatangan" },+	{ "dmk", "Domaaki" },+	{ "dml", "Dameli" },+	{ "dmm", "Dama" },+	{ "dmo", "Kemedzung" },+	{ "dmr", "East Damar" },+	{ "dms", "Dampelas" },+	{ "dmu", "Dubu" },+	{ "dmv", "Dumpas" },+	{ "dmw", "Mudburra" },+	{ "dmx", "Dema" },+	{ "dmy", "Demta" },+	{ "dna", "Upper Grand Valley Dani" },+	{ "dnd", "Daonda" },+	{ "dne", "Ndendeule" },+	{ "dng", "Dungan" },+	{ "dni", "Lower Grand Valley Dani" },+	{ "dnj", "Dan" },+	{ "dnk", "Dengka" },+	{ "dnn", "Dzùùngoo" },+	{ "dnr", "Danaru" },+	{ "dnt", "Mid Grand Valley Dani" },+	{ "dnu", "Danau" },+	{ "dnv", "Danu" },+	{ "dnw", "Western Dani" },+	{ "dny", "Dení" },+	{ "doa", "Dom" },+	{ "dob", "Dobu" },+	{ "doc", "Northern Dong" },+	{ "doe", "Doe" },+	{ "dof", "Domu" },+	{ "doh", "Dong" },+	{ "doi", "Dogri (macrolanguage)" },+	{ "dok", "Dondo" },+	{ "dol", "Doso" },+	{ "don", "Toura (Papua New Guinea)" },+	{ "doo", "Dongo" },+	{ "dop", "Lukpa" },+	{ "doq", "Dominican Sign Language" },+	{ "dor", "Dori'o" },+	{ "dos", "Dogosé" },+	{ "dot", "Dass" },+	{ "dov", "Dombe" },+	{ "dow", "Doyayo" },+	{ "dox", "Bussa" },+	{ "doy", "Dompo" },+	{ "doz", "Dorze" },+	{ "dpp", "Papar" },+	{ "drb", "Dair" },+	{ "drc", "Minderico" },+	{ "drd", "Darmiya" },+	{ "dre", "Dolpo" },+	{ "drg", "Rungus" },+	{ "dri", "C'lela" },+	{ "drl", "Paakantyi" },+	{ "drn", "West Damar" },+	{ "dro", "Daro-Matu Melanau" },+	{ "drq", "Dura" },+	{ "drr", "Dororo" },+	{ "drs", "Gedeo" },+	{ "drt", "Drents" },+	{ "dru", "Rukai" },+	{ "dry", "Darai" },+	{ "dsb", "Lower Sorbian" },+	{ "dse", "Dutch Sign Language" },+	{ "dsh", "Daasanach" },+	{ "dsi", "Disa" },+	{ "dsl", "Danish Sign Language" },+	{ "dsn", "Dusner" },+	{ "dso", "Desiya" },+	{ "dsq", "Tadaksahak" },+	{ "dta", "Daur" },+	{ "dtb", "Labuk-Kinabatangan Kadazan" },+	{ "dtd", "Ditidaht" },+	{ "dth", "Adithinngithigh" },+	{ "dti", "Ana Tinga Dogon" },+	{ "dtk", "Tene Kan Dogon" },+	{ "dtm", "Tomo Kan Dogon" },+	{ "dto", "Tommo So Dogon" },+	{ "dtp", "Central Dusun" },+	{ "dtr", "Lotud" },+	{ "dts", "Toro So Dogon" },+	{ "dtt", "Toro Tegu Dogon" },+	{ "dtu", "Tebul Ure Dogon" },+	{ "dty", "Dotyali" },+	{ "dua", "Duala" },+	{ "dub", "Dubli" },+	{ "duc", "Duna" },+	{ "dud", "Hun-Saare" },+	{ "due", "Umiray Dumaget Agta" },+	{ "duf", "Dumbea" },+	{ "dug", "Duruma" },+	{ "duh", "Dungra Bhil" },+	{ "dui", "Dumun" },+	{ "duj", "Dhuwal" },+	{ "duk", "Uyajitaya" },+	{ "dul", "Alabat Island Agta" },+	{ "dum", "Middle Dutch (ca. 1050-1350)" },+	{ "dun", "Dusun Deyah" },+	{ "duo", "Dupaninan Agta" },+	{ "dup", "Duano" },+	{ "duq", "Dusun Malang" },+	{ "dur", "Dii" },+	{ "dus", "Dumi" },+	{ "duu", "Drung" },+	{ "duv", "Duvle" },+	{ "duw", "Dusun Witu" },+	{ "dux", "Duungooma" },+	{ "duy", "Dicamay Agta" },+	{ "duz", "Duli" },+	{ "dva", "Duau" },+	{ "dwa", "Diri" },+	{ "dwr", "Dawro" },+	{ "dws", "Dutton World Speedwords" },+	{ "dww", "Dawawa" },+	{ "dya", "Dyan" },+	{ "dyb", "Dyaberdyaber" },+	{ "dyd", "Dyugun" },+	{ "dyg", "Villa Viciosa Agta" },+	{ "dyi", "Djimini Senoufo" },+	{ "dym", "Yanda Dom Dogon" },+	{ "dyn", "Dyangadi" },+	{ "dyo", "Jola-Fonyi" },+	{ "dyu", "Dyula" },+	{ "dyy", "Dyaabugay" },+	{ "dza", "Tunzu" },+	{ "dzd", "Daza" },+	{ "dze", "Djiwarli" },+	{ "dzg", "Dazaga" },+	{ "dzl", "Dzalakha" },+	{ "dzn", "Dzando" },+	{ "dzo", "Dzongkha" },+	{ "eaa", "Karenggapa" },+	{ "ebg", "Ebughu" },+	{ "ebk", "Eastern Bontok" },+	{ "ebo", "Teke-Ebo" },+	{ "ebr", "Ebrié" },+	{ "ebu", "Embu" },+	{ "ecr", "Eteocretan" },+	{ "ecs", "Ecuadorian Sign Language" },+	{ "ecy", "Eteocypriot" },+	{ "eee", "E" },+	{ "efa", "Efai" },+	{ "efe", "Efe" },+	{ "efi", "Efik" },+	{ "ega", "Ega" },+	{ "egl", "Emilian" },+	{ "ego", "Eggon" },+	{ "egy", "Egyptian (Ancient)" },+	{ "ehu", "Ehueun" },+	{ "eip", "Eipomek" },+	{ "eit", "Eitiep" },+	{ "eiv", "Askopan" },+	{ "eja", "Ejamat" },+	{ "eka", "Ekajuk" },+	{ "ekc", "Eastern Karnic" },+	{ "eke", "Ekit" },+	{ "ekg", "Ekari" },+	{ "eki", "Eki" },+	{ "ekk", "Standard Estonian" },+	{ "ekl", "Kol (Bangladesh)" },+	{ "ekm", "Elip" },+	{ "eko", "Koti" },+	{ "ekp", "Ekpeye" },+	{ "ekr", "Yace" },+	{ "eky", "Eastern Kayah" },+	{ "ele", "Elepi" },+	{ "elh", "El Hugeirat" },+	{ "eli", "Nding" },+	{ "elk", "Elkei" },+	{ "ell", "Modern Greek (1453-)" },+	{ "elm", "Eleme" },+	{ "elo", "El Molo" },+	{ "elu", "Elu" },+	{ "elx", "Elamite" },+	{ "ema", "Emai-Iuleha-Ora" },+	{ "emb", "Embaloh" },+	{ "eme", "Emerillon" },+	{ "emg", "Eastern Meohang" },+	{ "emi", "Mussau-Emira" },+	{ "emk", "Eastern Maninkakan" },+	{ "emm", "Mamulique" },+	{ "emn", "Eman" },+	{ "emo", "Emok" },+	{ "emp", "Northern Emberá" },+	{ "ems", "Pacific Gulf Yupik" },+	{ "emu", "Eastern Muria" },+	{ "emw", "Emplawas" },+	{ "emx", "Erromintxela" },+	{ "emy", "Epigraphic Mayan" },+	{ "ena", "Apali" },+	{ "enb", "Markweeta" },+	{ "enc", "En" },+	{ "end", "Ende" },+	{ "enf", "Forest Enets" },+	{ "eng", "English" },+	{ "enh", "Tundra Enets" },+	{ "enm", "Middle English (1100-1500)" },+	{ "enn", "Engenni" },+	{ "eno", "Enggano" },+	{ "enq", "Enga" },+	{ "enr", "Emumu" },+	{ "enu", "Enu" },+	{ "env", "Enwan (Edu State)" },+	{ "enw", "Enwan (Akwa Ibom State)" },+	{ "eot", "Beti (Côte d'Ivoire)" },+	{ "epi", "Epie" },+	{ "epo", "Esperanto" },+	{ "era", "Eravallan" },+	{ "erg", "Sie" },+	{ "erh", "Eruwa" },+	{ "eri", "Ogea" },+	{ "erk", "South Efate" },+	{ "ero", "Horpa" },+	{ "err", "Erre" },+	{ "ers", "Ersu" },+	{ "ert", "Eritai" },+	{ "erw", "Erokwanas" },+	{ "ese", "Ese Ejja" },+	{ "esh", "Eshtehardi" },+	{ "esi", "North Alaskan Inupiatun" },+	{ "esk", "Northwest Alaska Inupiatun" },+	{ "esl", "Egypt Sign Language" },+	{ "esm", "Esuma" },+	{ "esn", "Salvadoran Sign Language" },+	{ "eso", "Estonian Sign Language" },+	{ "esq", "Esselen" },+	{ "ess", "Central Siberian Yupik" },+	{ "est", "Estonian" },+	{ "esu", "Central Yupik" },+	{ "etb", "Etebi" },+	{ "etc", "Etchemin" },+	{ "eth", "Ethiopian Sign Language" },+	{ "etn", "Eton (Vanuatu)" },+	{ "eto", "Eton (Cameroon)" },+	{ "etr", "Edolo" },+	{ "ets", "Yekhee" },+	{ "ett", "Etruscan" },+	{ "etu", "Ejagham" },+	{ "etx", "Eten" },+	{ "etz", "Semimi" },+	{ "eus", "Basque" },+	{ "eve", "Even" },+	{ "evh", "Uvbie" },+	{ "evn", "Evenki" },+	{ "ewe", "Ewe" },+	{ "ewo", "Ewondo" },+	{ "ext", "Extremaduran" },+	{ "eya", "Eyak" },+	{ "eyo", "Keiyo" },+	{ "eza", "Ezaa" },+	{ "eze", "Uzekwe" },+	{ "faa", "Fasu" },+	{ "fab", "Fa d'Ambu" },+	{ "fad", "Wagi" },+	{ "faf", "Fagani" },+	{ "fag", "Finongan" },+	{ "fah", "Baissa Fali" },+	{ "fai", "Faiwol" },+	{ "faj", "Faita" },+	{ "fak", "Fang (Cameroon)" },+	{ "fal", "South Fali" },+	{ "fam", "Fam" },+	{ "fan", "Fang (Equatorial Guinea)" },+	{ "fao", "Faroese" },+	{ "fap", "Palor" },+	{ "far", "Fataleka" },+	{ "fas", "Persian" },+	{ "fat", "Fanti" },+	{ "fau", "Fayu" },+	{ "fax", "Fala" },+	{ "fay", "Southwestern Fars" },+	{ "faz", "Northwestern Fars" },+	{ "fbl", "West Albay Bikol" },+	{ "fcs", "Quebec Sign Language" },+	{ "fer", "Feroge" },+	{ "ffi", "Foia Foia" },+	{ "ffm", "Maasina Fulfulde" },+	{ "fgr", "Fongoro" },+	{ "fia", "Nobiin" },+	{ "fie", "Fyer" },+	{ "fij", "Fijian" },+	{ "fil", "Filipino" },+	{ "fin", "Finnish" },+	{ "fip", "Fipa" },+	{ "fir", "Firan" },+	{ "fit", "Tornedalen Finnish" },+	{ "fiw", "Fiwaga" },+	{ "fkk", "Kirya-Konzəl" },+	{ "fkv", "Kven Finnish" },+	{ "fla", "Kalispel-Pend d'Oreille" },+	{ "flh", "Foau" },+	{ "fli", "Fali" },+	{ "fll", "North Fali" },+	{ "fln", "Flinders Island" },+	{ "flr", "Fuliiru" },+	{ "fly", "Tsotsitaal" },+	{ "fmp", "Fe'fe'" },+	{ "fmu", "Far Western Muria" },+	{ "fng", "Fanagalo" },+	{ "fni", "Fania" },+	{ "fod", "Foodo" },+	{ "foi", "Foi" },+	{ "fom", "Foma" },+	{ "fon", "Fon" },+	{ "for", "Fore" },+	{ "fos", "Siraya" },+	{ "fpe", "Fernando Po Creole English" },+	{ "fqs", "Fas" },+	{ "fra", "French" },+	{ "frc", "Cajun French" },+	{ "frd", "Fordata" },+	{ "frk", "Frankish" },+	{ "frm", "Middle French (ca. 1400-1600)" },+	{ "fro", "Old French (842-ca. 1400)" },+	{ "frp", "Arpitan" },+	{ "frq", "Forak" },+	{ "frr", "Northern Frisian" },+	{ "frs", "Eastern Frisian" },+	{ "frt", "Fortsenal" },+	{ "fry", "Western Frisian" },+	{ "fse", "Finnish Sign Language" },+	{ "fsl", "French Sign Language" },+	{ "fss", "Finland-Swedish Sign Language" },+	{ "fub", "Adamawa Fulfulde" },+	{ "fuc", "Pulaar" },+	{ "fud", "East Futuna" },+	{ "fue", "Borgu Fulfulde" },+	{ "fuf", "Pular" },+	{ "fuh", "Western Niger Fulfulde" },+	{ "fui", "Bagirmi Fulfulde" },+	{ "fuj", "Ko" },+	{ "ful", "Fulah" },+	{ "fum", "Fum" },+	{ "fun", "Fulniô" },+	{ "fuq", "Central-Eastern Niger Fulfulde" },+	{ "fur", "Friulian" },+	{ "fut", "Futuna-Aniwa" },+	{ "fuu", "Furu" },+	{ "fuv", "Nigerian Fulfulde" },+	{ "fuy", "Fuyug" },+	{ "fvr", "Fur" },+	{ "fwa", "Fwâi" },+	{ "fwe", "Fwe" },+	{ "gaa", "Ga" },+	{ "gab", "Gabri" },+	{ "gac", "Mixed Great Andamanese" },+	{ "gad", "Gaddang" },+	{ "gae", "Guarequena" },+	{ "gaf", "Gende" },+	{ "gag", "Gagauz" },+	{ "gah", "Alekano" },+	{ "gai", "Borei" },+	{ "gaj", "Gadsup" },+	{ "gak", "Gamkonora" },+	{ "gal", "Galolen" },+	{ "gam", "Kandawo" },+	{ "gan", "Gan Chinese" },+	{ "gao", "Gants" },+	{ "gap", "Gal" },+	{ "gaq", "Gata'" },+	{ "gar", "Galeya" },+	{ "gas", "Adiwasi Garasia" },+	{ "gat", "Kenati" },+	{ "gau", "Mudhili Gadaba" },+	{ "gaw", "Nobonob" },+	{ "gax", "Borana-Arsi-Guji Oromo" },+	{ "gay", "Gayo" },+	{ "gaz", "West Central Oromo" },+	{ "gba", "Gbaya (Central African Republic)" },+	{ "gbb", "Kaytetye" },+	{ "gbd", "Karadjeri" },+	{ "gbe", "Niksek" },+	{ "gbf", "Gaikundi" },+	{ "gbg", "Gbanziri" },+	{ "gbh", "Defi Gbe" },+	{ "gbi", "Galela" },+	{ "gbj", "Bodo Gadaba" },+	{ "gbk", "Gaddi" },+	{ "gbl", "Gamit" },+	{ "gbm", "Garhwali" },+	{ "gbn", "Mo'da" },+	{ "gbo", "Northern Grebo" },+	{ "gbp", "Gbaya-Bossangoa" },+	{ "gbq", "Gbaya-Bozoum" },+	{ "gbr", "Gbagyi" },+	{ "gbs", "Gbesi Gbe" },+	{ "gbu", "Gagadu" },+	{ "gbv", "Gbanu" },+	{ "gbw", "Gabi-Gabi" },+	{ "gbx", "Eastern Xwla Gbe" },+	{ "gby", "Gbari" },+	{ "gbz", "Zoroastrian Dari" },+	{ "gcc", "Mali" },+	{ "gcd", "Ganggalida" },+	{ "gce", "Galice" },+	{ "gcf", "Guadeloupean Creole French" },+	{ "gcl", "Grenadian Creole English" },+	{ "gcn", "Gaina" },+	{ "gcr", "Guianese Creole French" },+	{ "gct", "Colonia Tovar German" },+	{ "gda", "Gade Lohar" },+	{ "gdb", "Pottangi Ollar Gadaba" },+	{ "gdc", "Gugu Badhun" },+	{ "gdd", "Gedaged" },+	{ "gde", "Gude" },+	{ "gdf", "Guduf-Gava" },+	{ "gdg", "Ga'dang" },+	{ "gdh", "Gadjerawang" },+	{ "gdi", "Gundi" },+	{ "gdj", "Gurdjar" },+	{ "gdk", "Gadang" },+	{ "gdl", "Dirasha" },+	{ "gdm", "Laal" },+	{ "gdn", "Umanakaina" },+	{ "gdo", "Ghodoberi" },+	{ "gdq", "Mehri" },+	{ "gdr", "Wipi" },+	{ "gds", "Ghandruk Sign Language" },+	{ "gdt", "Kungardutyi" },+	{ "gdu", "Gudu" },+	{ "gdx", "Godwari" },+	{ "gea", "Geruma" },+	{ "geb", "Kire" },+	{ "gec", "Gboloo Grebo" },+	{ "ged", "Gade" },+	{ "geg", "Gengle" },+	{ "geh", "Hutterite German" },+	{ "gei", "Gebe" },+	{ "gej", "Gen" },+	{ "gek", "Yiwom" },+	{ "gel", "ut-Ma'in" },+	{ "geq", "Geme" },+	{ "ges", "Geser-Gorom" },+	{ "gew", "Gera" },+	{ "gex", "Garre" },+	{ "gey", "Enya" },+	{ "gez", "Geez" },+	{ "gfk", "Patpatar" },+	{ "gft", "Gafat" },+	{ "gfx", "Mangetti Dune !Xung" },+	{ "gga", "Gao" },+	{ "ggb", "Gbii" },+	{ "ggd", "Gugadj" },+	{ "gge", "Guragone" },+	{ "ggg", "Gurgula" },+	{ "ggk", "Kungarakany" },+	{ "ggl", "Ganglau" },+	{ "ggm", "Gugu Mini" },+	{ "ggn", "Eastern Gurung" },+	{ "ggo", "Southern Gondi" },+	{ "ggt", "Gitua" },+	{ "ggu", "Gagu" },+	{ "ggw", "Gogodala" },+	{ "gha", "Ghadamès" },+	{ "ghc", "Hiberno-Scottish Gaelic" },+	{ "ghe", "Southern Ghale" },+	{ "ghh", "Northern Ghale" },+	{ "ghk", "Geko Karen" },+	{ "ghl", "Ghulfan" },+	{ "ghn", "Ghanongga" },+	{ "gho", "Ghomara" },+	{ "ghr", "Ghera" },+	{ "ghs", "Guhu-Samane" },+	{ "ght", "Kuke" },+	{ "gia", "Kitja" },+	{ "gib", "Gibanawa" },+	{ "gic", "Gail" },+	{ "gid", "Gidar" },+	{ "gig", "Goaria" },+	{ "gih", "Githabul" },+	{ "gil", "Gilbertese" },+	{ "gim", "Gimi (Eastern Highlands)" },+	{ "gin", "Hinukh" },+	{ "gip", "Gimi (West New Britain)" },+	{ "giq", "Green Gelao" },+	{ "gir", "Red Gelao" },+	{ "gis", "North Giziga" },+	{ "git", "Gitxsan" },+	{ "giu", "Mulao" },+	{ "giw", "White Gelao" },+	{ "gix", "Gilima" },+	{ "giy", "Giyug" },+	{ "giz", "South Giziga" },+	{ "gji", "Geji" },+	{ "gjk", "Kachi Koli" },+	{ "gjm", "Gunditjmara" },+	{ "gjn", "Gonja" },+	{ "gju", "Gujari" },+	{ "gka", "Guya" },+	{ "gke", "Ndai" },+	{ "gkn", "Gokana" },+	{ "gko", "Kok-Nar" },+	{ "gkp", "Guinea Kpelle" },+	{ "gla", "Scottish Gaelic" },+	{ "glc", "Bon Gula" },+	{ "gld", "Nanai" },+	{ "gle", "Irish" },+	{ "glg", "Galician" },+	{ "glh", "Northwest Pashayi" },+	{ "gli", "Guliguli" },+	{ "glj", "Gula Iro" },+	{ "glk", "Gilaki" },+	{ "gll", "Garlali" },+	{ "glo", "Galambu" },+	{ "glr", "Glaro-Twabo" },+	{ "glu", "Gula (Chad)" },+	{ "glv", "Manx" },+	{ "glw", "Glavda" },+	{ "gly", "Gule" },+	{ "gma", "Gambera" },+	{ "gmb", "Gula'alaa" },+	{ "gmd", "Mághdì" },+	{ "gmh", "Middle High German (ca. 1050-1500)" },+	{ "gml", "Middle Low German" },+	{ "gmm", "Gbaya-Mbodomo" },+	{ "gmn", "Gimnime" },+	{ "gmu", "Gumalu" },+	{ "gmv", "Gamo" },+	{ "gmx", "Magoma" },+	{ "gmy", "Mycenaean Greek" },+	{ "gmz", "Mgbolizhia" },+	{ "gna", "Kaansa" },+	{ "gnb", "Gangte" },+	{ "gnc", "Guanche" },+	{ "gnd", "Zulgo-Gemzek" },+	{ "gne", "Ganang" },+	{ "gng", "Ngangam" },+	{ "gnh", "Lere" },+	{ "gni", "Gooniyandi" },+	{ "gnk", "Gana" },+	{ "gnl", "Gangulu" },+	{ "gnm", "Ginuman" },+	{ "gnn", "Gumatj" },+	{ "gno", "Northern Gondi" },+	{ "gnq", "Gana" },+	{ "gnr", "Gureng Gureng" },+	{ "gnt", "Guntai" },+	{ "gnu", "Gnau" },+	{ "gnw", "Western Bolivian Guaraní" },+	{ "gnz", "Ganzi" },+	{ "goa", "Guro" },+	{ "gob", "Playero" },+	{ "goc", "Gorakor" },+	{ "god", "Godié" },+	{ "goe", "Gongduk" },+	{ "gof", "Gofa" },+	{ "gog", "Gogo" },+	{ "goh", "Old High German (ca. 750-1050)" },+	{ "goi", "Gobasi" },+	{ "goj", "Gowlan" },+	{ "gok", "Gowli" },+	{ "gol", "Gola" },+	{ "gom", "Goan Konkani" },+	{ "gon", "Gondi" },+	{ "goo", "Gone Dau" },+	{ "gop", "Yeretuar" },+	{ "goq", "Gorap" },+	{ "gor", "Gorontalo" },+	{ "gos", "Gronings" },+	{ "got", "Gothic" },+	{ "gou", "Gavar" },+	{ "gow", "Gorowa" },+	{ "gox", "Gobu" },+	{ "goy", "Goundo" },+	{ "goz", "Gozarkhani" },+	{ "gpa", "Gupa-Abawa" },+	{ "gpe", "Ghanaian Pidgin English" },+	{ "gpn", "Taiap" },+	{ "gqa", "Ga'anda" },+	{ "gqi", "Guiqiong" },+	{ "gqn", "Guana (Brazil)" },+	{ "gqr", "Gor" },+	{ "gqu", "Qau" },+	{ "gra", "Rajput Garasia" },+	{ "grb", "Grebo" },+	{ "grc", "Ancient Greek (to 1453)" },+	{ "grd", "Guruntum-Mbaaru" },+	{ "grg", "Madi" },+	{ "grh", "Gbiri-Niragu" },+	{ "gri", "Ghari" },+	{ "grj", "Southern Grebo" },+	{ "grm", "Kota Marudu Talantang" },+	{ "grn", "Guarani" },+	{ "gro", "Groma" },+	{ "grq", "Gorovu" },+	{ "grr", "Taznatit" },+	{ "grs", "Gresi" },+	{ "grt", "Garo" },+	{ "gru", "Kistane" },+	{ "grv", "Central Grebo" },+	{ "grw", "Gweda" },+	{ "grx", "Guriaso" },+	{ "gry", "Barclayville Grebo" },+	{ "grz", "Guramalum" },+	{ "gse", "Ghanaian Sign Language" },+	{ "gsg", "German Sign Language" },+	{ "gsl", "Gusilay" },+	{ "gsm", "Guatemalan Sign Language" },+	{ "gsn", "Gusan" },+	{ "gso", "Southwest Gbaya" },+	{ "gsp", "Wasembo" },+	{ "gss", "Greek Sign Language" },+	{ "gsw", "Swiss German" },+	{ "gta", "Guató" },+	{ "gti", "Gbati-ri" },+	{ "gtu", "Aghu-Tharnggala" },+	{ "gua", "Shiki" },+	{ "gub", "Guajajára" },+	{ "guc", "Wayuu" },+	{ "gud", "Yocoboué Dida" },+	{ "gue", "Gurinji" },+	{ "guf", "Gupapuyngu" },+	{ "gug", "Paraguayan Guaraní" },+	{ "guh", "Guahibo" },+	{ "gui", "Eastern Bolivian Guaraní" },+	{ "guj", "Gujarati" },+	{ "guk", "Gumuz" },+	{ "gul", "Sea Island Creole English" },+	{ "gum", "Guambiano" },+	{ "gun", "Mbyá Guaraní" },+	{ "guo", "Guayabero" },+	{ "gup", "Gunwinggu" },+	{ "guq", "Aché" },+	{ "gur", "Farefare" },+	{ "gus", "Guinean Sign Language" },+	{ "gut", "Maléku Jaíka" },+	{ "guu", "Yanomamö" },+	{ "guv", "Gey" },+	{ "guw", "Gun" },+	{ "gux", "Gourmanchéma" },+	{ "guz", "Gusii" },+	{ "gva", "Guana (Paraguay)" },+	{ "gvc", "Guanano" },+	{ "gve", "Duwet" },+	{ "gvf", "Golin" },+	{ "gvj", "Guajá" },+	{ "gvl", "Gulay" },+	{ "gvm", "Gurmana" },+	{ "gvn", "Kuku-Yalanji" },+	{ "gvo", "Gavião Do Jiparaná" },+	{ "gvp", "Pará Gavião" },+	{ "gvr", "Western Gurung" },+	{ "gvs", "Gumawana" },+	{ "gvy", "Guyani" },+	{ "gwa", "Mbato" },+	{ "gwb", "Gwa" },+	{ "gwc", "Kalami" },+	{ "gwd", "Gawwada" },+	{ "gwe", "Gweno" },+	{ "gwf", "Gowro" },+	{ "gwg", "Moo" },+	{ "gwi", "Gwichʼin" },+	{ "gwj", "Gwi" },+	{ "gwm", "Awngthim" },+	{ "gwn", "Gwandara" },+	{ "gwr", "Gwere" },+	{ "gwt", "Gawar-Bati" },+	{ "gwu", "Guwamu" },+	{ "gww", "Kwini" },+	{ "gwx", "Gua" },+	{ "gxx", "Wè Southern" },+	{ "gya", "Northwest Gbaya" },+	{ "gyb", "Garus" },+	{ "gyd", "Kayardild" },+	{ "gye", "Gyem" },+	{ "gyf", "Gungabula" },+	{ "gyg", "Gbayi" },+	{ "gyi", "Gyele" },+	{ "gyl", "Gayil" },+	{ "gym", "Ngäbere" },+	{ "gyn", "Guyanese Creole English" },+	{ "gyr", "Guarayu" },+	{ "gyy", "Gunya" },+	{ "gza", "Ganza" },+	{ "gzi", "Gazi" },+	{ "gzn", "Gane" },+	{ "haa", "Han" },+	{ "hab", "Hanoi Sign Language" },+	{ "hac", "Gurani" },+	{ "had", "Hatam" },+	{ "hae", "Eastern Oromo" },+	{ "haf", "Haiphong Sign Language" },+	{ "hag", "Hanga" },+	{ "hah", "Hahon" },+	{ "hai", "Haida" },+	{ "haj", "Hajong" },+	{ "hak", "Hakka Chinese" },+	{ "hal", "Halang" },+	{ "ham", "Hewa" },+	{ "han", "Hangaza" },+	{ "hao", "Hakö" },+	{ "hap", "Hupla" },+	{ "haq", "Ha" },+	{ "har", "Harari" },+	{ "has", "Haisla" },+	{ "hat", "Haitian" },+	{ "hau", "Hausa" },+	{ "hav", "Havu" },+	{ "haw", "Hawaiian" },+	{ "hax", "Southern Haida" },+	{ "hay", "Haya" },+	{ "haz", "Hazaragi" },+	{ "hba", "Hamba" },+	{ "hbb", "Huba" },+	{ "hbn", "Heiban" },+	{ "hbo", "Ancient Hebrew" },+	{ "hbs", "Serbo-Croatian" },+	{ "hbu", "Habu" },+	{ "hca", "Andaman Creole Hindi" },+	{ "hch", "Huichol" },+	{ "hdn", "Northern Haida" },+	{ "hds", "Honduras Sign Language" },+	{ "hdy", "Hadiyya" },+	{ "hea", "Northern Qiandong Miao" },+	{ "heb", "Hebrew" },+	{ "hed", "Herdé" },+	{ "heg", "Helong" },+	{ "heh", "Hehe" },+	{ "hei", "Heiltsuk" },+	{ "hem", "Hemba" },+	{ "her", "Herero" },+	{ "hgm", "Haiom" },+	{ "hgw", "Haigwai" },+	{ "hhi", "Hoia Hoia" },+	{ "hhr", "Kerak" },+	{ "hhy", "Hoyahoya" },+	{ "hia", "Lamang" },+	{ "hib", "Hibito" },+	{ "hid", "Hidatsa" },+	{ "hif", "Fiji Hindi" },+	{ "hig", "Kamwe" },+	{ "hih", "Pamosu" },+	{ "hii", "Hinduri" },+	{ "hij", "Hijuk" },+	{ "hik", "Seit-Kaitetu" },+	{ "hil", "Hiligaynon" },+	{ "hin", "Hindi" },+	{ "hio", "Tsoa" },+	{ "hir", "Himarimã" },+	{ "hit", "Hittite" },+	{ "hiw", "Hiw" },+	{ "hix", "Hixkaryána" },+	{ "hji", "Haji" },+	{ "hka", "Kahe" },+	{ "hke", "Hunde" },+	{ "hkk", "Hunjara-Kaina Ke" },+	{ "hks", "Hong Kong Sign Language" },+	{ "hla", "Halia" },+	{ "hlb", "Halbi" },+	{ "hld", "Halang Doan" },+	{ "hle", "Hlersu" },+	{ "hlt", "Matu Chin" },+	{ "hlu", "Hieroglyphic Luwian" },+	{ "hma", "Southern Mashan Hmong" },+	{ "hmb", "Humburi Senni Songhay" },+	{ "hmc", "Central Huishui Hmong" },+	{ "hmd", "Large Flowery Miao" },+	{ "hme", "Eastern Huishui Hmong" },+	{ "hmf", "Hmong Don" },+	{ "hmg", "Southwestern Guiyang Hmong" },+	{ "hmh", "Southwestern Huishui Hmong" },+	{ "hmi", "Northern Huishui Hmong" },+	{ "hmj", "Ge" },+	{ "hmk", "Maek" },+	{ "hml", "Luopohe Hmong" },+	{ "hmm", "Central Mashan Hmong" },+	{ "hmn", "Hmong" },+	{ "hmo", "Hiri Motu" },+	{ "hmp", "Northern Mashan Hmong" },+	{ "hmq", "Eastern Qiandong Miao" },+	{ "hmr", "Hmar" },+	{ "hms", "Southern Qiandong Miao" },+	{ "hmt", "Hamtai" },+	{ "hmu", "Hamap" },+	{ "hmv", "Hmong Dô" },+	{ "hmw", "Western Mashan Hmong" },+	{ "hmy", "Southern Guiyang Hmong" },+	{ "hmz", "Hmong Shua" },+	{ "hna", "Mina (Cameroon)" },+	{ "hnd", "Southern Hindko" },+	{ "hne", "Chhattisgarhi" },+	{ "hnh", "Ani" },+	{ "hni", "Hani" },+	{ "hnj", "Hmong Njua" },+	{ "hnn", "Hanunoo" },+	{ "hno", "Northern Hindko" },+	{ "hns", "Caribbean Hindustani" },+	{ "hnu", "Hung" },+	{ "hoa", "Hoava" },+	{ "hob", "Mari (Madang Province)" },+	{ "hoc", "Ho" },+	{ "hod", "Holma" },+	{ "hoe", "Horom" },+	{ "hoh", "Hobyót" },+	{ "hoi", "Holikachuk" },+	{ "hoj", "Hadothi" },+	{ "hol", "Holu" },+	{ "hom", "Homa" },+	{ "hoo", "Holoholo" },+	{ "hop", "Hopi" },+	{ "hor", "Horo" },+	{ "hos", "Ho Chi Minh City Sign Language" },+	{ "hot", "Hote" },+	{ "hov", "Hovongan" },+	{ "how", "Honi" },+	{ "hoy", "Holiya" },+	{ "hoz", "Hozo" },+	{ "hpo", "Hpon" },+	{ "hps", "Hawai'i Pidgin Sign Language" },+	{ "hra", "Hrangkhol" },+	{ "hrc", "Niwer Mil" },+	{ "hre", "Hre" },+	{ "hrk", "Haruku" },+	{ "hrm", "Horned Miao" },+	{ "hro", "Haroi" },+	{ "hrp", "Nhirrpi" },+	{ "hrt", "Hértevin" },+	{ "hru", "Hruso" },+	{ "hrv", "Croatian" },+	{ "hrw", "Warwar Feni" },+	{ "hrx", "Hunsrik" },+	{ "hrz", "Harzani" },+	{ "hsb", "Upper Sorbian" },+	{ "hsh", "Hungarian Sign Language" },+	{ "hsl", "Hausa Sign Language" },+	{ "hsn", "Xiang Chinese" },+	{ "hss", "Harsusi" },+	{ "hti", "Hoti" },+	{ "hto", "Minica Huitoto" },+	{ "hts", "Hadza" },+	{ "htu", "Hitu" },+	{ "htx", "Middle Hittite" },+	{ "hub", "Huambisa" },+	{ "huc", "=Hua" },+	{ "hud", "Huaulu" },+	{ "hue", "San Francisco Del Mar Huave" },+	{ "huf", "Humene" },+	{ "hug", "Huachipaeri" },+	{ "huh", "Huilliche" },+	{ "hui", "Huli" },+	{ "huj", "Northern Guiyang Hmong" },+	{ "huk", "Hulung" },+	{ "hul", "Hula" },+	{ "hum", "Hungana" },+	{ "hun", "Hungarian" },+	{ "huo", "Hu" },+	{ "hup", "Hupa" },+	{ "huq", "Tsat" },+	{ "hur", "Halkomelem" },+	{ "hus", "Huastec" },+	{ "hut", "Humla" },+	{ "huu", "Murui Huitoto" },+	{ "huv", "San Mateo Del Mar Huave" },+	{ "huw", "Hukumina" },+	{ "hux", "Nüpode Huitoto" },+	{ "huy", "Hulaulá" },+	{ "huz", "Hunzib" },+	{ "hvc", "Haitian Vodoun Culture Language" },+	{ "hve", "San Dionisio Del Mar Huave" },+	{ "hvk", "Haveke" },+	{ "hvn", "Sabu" },+	{ "hvv", "Santa María Del Mar Huave" },+	{ "hwa", "Wané" },+	{ "hwc", "Hawai'i Creole English" },+	{ "hwo", "Hwana" },+	{ "hya", "Hya" },+	{ "hye", "Armenian" },+	{ "iai", "Iaai" },+	{ "ian", "Iatmul" },+	{ "iap", "Iapama" },+	{ "iar", "Purari" },+	{ "iba", "Iban" },+	{ "ibb", "Ibibio" },+	{ "ibd", "Iwaidja" },+	{ "ibe", "Akpes" },+	{ "ibg", "Ibanag" },+	{ "ibl", "Ibaloi" },+	{ "ibm", "Agoi" },+	{ "ibn", "Ibino" },+	{ "ibo", "Igbo" },+	{ "ibr", "Ibuoro" },+	{ "ibu", "Ibu" },+	{ "iby", "Ibani" },+	{ "ica", "Ede Ica" },+	{ "ich", "Etkywan" },+	{ "icl", "Icelandic Sign Language" },+	{ "icr", "Islander Creole English" },+	{ "ida", "Idakho-Isukha-Tiriki" },+	{ "idb", "Indo-Portuguese" },+	{ "idc", "Idon" },+	{ "idd", "Ede Idaca" },+	{ "ide", "Idere" },+	{ "idi", "Idi" },+	{ "ido", "Ido" },+	{ "idr", "Indri" },+	{ "ids", "Idesa" },+	{ "idt", "Idaté" },+	{ "idu", "Idoma" },+	{ "ifa", "Amganad Ifugao" },+	{ "ifb", "Batad Ifugao" },+	{ "ife", "Ifè" },+	{ "iff", "Ifo" },+	{ "ifk", "Tuwali Ifugao" },+	{ "ifm", "Teke-Fuumu" },+	{ "ifu", "Mayoyao Ifugao" },+	{ "ify", "Keley-I Kallahan" },+	{ "igb", "Ebira" },+	{ "ige", "Igede" },+	{ "igg", "Igana" },+	{ "igl", "Igala" },+	{ "igm", "Kanggape" },+	{ "ign", "Ignaciano" },+	{ "igo", "Isebe" },+	{ "igs", "Interglossa" },+	{ "igw", "Igwe" },+	{ "ihb", "Iha Based Pidgin" },+	{ "ihi", "Ihievbe" },+	{ "ihp", "Iha" },+	{ "ihw", "Bidhawal" },+	{ "iii", "Sichuan Yi" },+	{ "iin", "Thiin" },+	{ "ijc", "Izon" },+	{ "ije", "Biseni" },+	{ "ijj", "Ede Ije" },+	{ "ijn", "Kalabari" },+	{ "ijs", "Southeast Ijo" },+	{ "ike", "Eastern Canadian Inuktitut" },+	{ "iki", "Iko" },+	{ "ikk", "Ika" },+	{ "ikl", "Ikulu" },+	{ "iko", "Olulumo-Ikom" },+	{ "ikp", "Ikpeshi" },+	{ "ikr", "Ikaranggal" },+	{ "ikt", "Inuinnaqtun" },+	{ "iku", "Inuktitut" },+	{ "ikv", "Iku-Gora-Ankwa" },+	{ "ikw", "Ikwere" },+	{ "ikx", "Ik" },+	{ "ikz", "Ikizu" },+	{ "ila", "Ile Ape" },+	{ "ilb", "Ila" },+	{ "ile", "Interlingue" },+	{ "ilg", "Garig-Ilgar" },+	{ "ili", "Ili Turki" },+	{ "ilk", "Ilongot" },+	{ "ill", "Iranun" },+	{ "ilo", "Iloko" },+	{ "ils", "International Sign" },+	{ "ilu", "Ili'uun" },+	{ "ilv", "Ilue" },+	{ "ima", "Mala Malasar" },+	{ "ime", "Imeraguen" },+	{ "imi", "Anamgura" },+	{ "iml", "Miluk" },+	{ "imn", "Imonda" },+	{ "imo", "Imbongu" },+	{ "imr", "Imroing" },+	{ "ims", "Marsian" },+	{ "imy", "Milyan" },+	{ "ina", "Interlingua (International Auxiliary Language Association)" },+	{ "inb", "Inga" },+	{ "ind", "Indonesian" },+	{ "ing", "Degexit'an" },+	{ "inh", "Ingush" },+	{ "inj", "Jungle Inga" },+	{ "inl", "Indonesian Sign Language" },+	{ "inm", "Minaean" },+	{ "inn", "Isinai" },+	{ "ino", "Inoke-Yate" },+	{ "inp", "Iñapari" },+	{ "ins", "Indian Sign Language" },+	{ "int", "Intha" },+	{ "inz", "Ineseño" },+	{ "ior", "Inor" },+	{ "iou", "Tuma-Irumu" },+	{ "iow", "Iowa-Oto" },+	{ "ipi", "Ipili" },+	{ "ipk", "Inupiaq" },+	{ "ipo", "Ipiko" },+	{ "iqu", "Iquito" },+	{ "iqw", "Ikwo" },+	{ "ire", "Iresim" },+	{ "irh", "Irarutu" },+	{ "iri", "Irigwe" },+	{ "irk", "Iraqw" },+	{ "irn", "Irántxe" },+	{ "irr", "Ir" },+	{ "iru", "Irula" },+	{ "irx", "Kamberau" },+	{ "iry", "Iraya" },+	{ "isa", "Isabi" },+	{ "isc", "Isconahua" },+	{ "isd", "Isnag" },+	{ "ise", "Italian Sign Language" },+	{ "isg", "Irish Sign Language" },+	{ "ish", "Esan" },+	{ "isi", "Nkem-Nkum" },+	{ "isk", "Ishkashimi" },+	{ "isl", "Icelandic" },+	{ "ism", "Masimasi" },+	{ "isn", "Isanzu" },+	{ "iso", "Isoko" },+	{ "isr", "Israeli Sign Language" },+	{ "ist", "Istriot" },+	{ "isu", "Isu (Menchum Division)" },+	{ "ita", "Italian" },+	{ "itb", "Binongan Itneg" },+	{ "ite", "Itene" },+	{ "iti", "Inlaod Itneg" },+	{ "itk", "Judeo-Italian" },+	{ "itl", "Itelmen" },+	{ "itm", "Itu Mbon Uzo" },+	{ "ito", "Itonama" },+	{ "itr", "Iteri" },+	{ "its", "Isekiri" },+	{ "itt", "Maeng Itneg" },+	{ "itv", "Itawit" },+	{ "itw", "Ito" },+	{ "itx", "Itik" },+	{ "ity", "Moyadan Itneg" },+	{ "itz", "Itzá" },+	{ "ium", "Iu Mien" },+	{ "ivb", "Ibatan" },+	{ "ivv", "Ivatan" },+	{ "iwk", "I-Wak" },+	{ "iwm", "Iwam" },+	{ "iwo", "Iwur" },+	{ "iws", "Sepik Iwam" },+	{ "ixc", "Ixcatec" },+	{ "ixl", "Ixil" },+	{ "iya", "Iyayu" },+	{ "iyo", "Mesaka" },+	{ "iyx", "Yaka (Congo)" },+	{ "izh", "Ingrian" },+	{ "izr", "Izere" },+	{ "izz", "Izii" },+	{ "jaa", "Jamamadí" },+	{ "jab", "Hyam" },+	{ "jac", "Popti'" },+	{ "jad", "Jahanka" },+	{ "jae", "Yabem" },+	{ "jaf", "Jara" },+	{ "jah", "Jah Hut" },+	{ "jaj", "Zazao" },+	{ "jak", "Jakun" },+	{ "jal", "Yalahatan" },+	{ "jam", "Jamaican Creole English" },+	{ "jan", "Jandai" },+	{ "jao", "Yanyuwa" },+	{ "jaq", "Yaqay" },+	{ "jas", "New Caledonian Javanese" },+	{ "jat", "Jakati" },+	{ "jau", "Yaur" },+	{ "jav", "Javanese" },+	{ "jax", "Jambi Malay" },+	{ "jay", "Yan-nhangu" },+	{ "jaz", "Jawe" },+	{ "jbe", "Judeo-Berber" },+	{ "jbi", "Badjiri" },+	{ "jbj", "Arandai" },+	{ "jbk", "Barikewa" },+	{ "jbn", "Nafusi" },+	{ "jbo", "Lojban" },+	{ "jbr", "Jofotek-Bromnya" },+	{ "jbt", "Jabutí" },+	{ "jbu", "Jukun Takum" },+	{ "jbw", "Yawijibaya" },+	{ "jcs", "Jamaican Country Sign Language" },+	{ "jct", "Krymchak" },+	{ "jda", "Jad" },+	{ "jdg", "Jadgali" },+	{ "jdt", "Judeo-Tat" },+	{ "jeb", "Jebero" },+	{ "jee", "Jerung" },+	{ "jeg", "Jeng" },+	{ "jeh", "Jeh" },+	{ "jei", "Yei" },+	{ "jek", "Jeri Kuo" },+	{ "jel", "Yelmek" },+	{ "jen", "Dza" },+	{ "jer", "Jere" },+	{ "jet", "Manem" },+	{ "jeu", "Jonkor Bourmataguil" },+	{ "jgb", "Ngbee" },+	{ "jge", "Judeo-Georgian" },+	{ "jgk", "Gwak" },+	{ "jgo", "Ngomba" },+	{ "jhi", "Jehai" },+	{ "jhs", "Jhankot Sign Language" },+	{ "jia", "Jina" },+	{ "jib", "Jibu" },+	{ "jic", "Tol" },+	{ "jid", "Bu" },+	{ "jie", "Jilbe" },+	{ "jig", "Djingili" },+	{ "jih", "sTodsde" },+	{ "jii", "Jiiddu" },+	{ "jil", "Jilim" },+	{ "jim", "Jimi (Cameroon)" },+	{ "jio", "Jiamao" },+	{ "jiq", "Guanyinqiao" },+	{ "jit", "Jita" },+	{ "jiu", "Youle Jinuo" },+	{ "jiv", "Shuar" },+	{ "jiy", "Buyuan Jinuo" },+	{ "jjr", "Bankal" },+	{ "jkm", "Mobwa Karen" },+	{ "jko", "Kubo" },+	{ "jkp", "Paku Karen" },+	{ "jkr", "Koro (India)" },+	{ "jku", "Labir" },+	{ "jle", "Ngile" },+	{ "jls", "Jamaican Sign Language" },+	{ "jma", "Dima" },+	{ "jmb", "Zumbun" },+	{ "jmc", "Machame" },+	{ "jmd", "Yamdena" },+	{ "jmi", "Jimi (Nigeria)" },+	{ "jml", "Jumli" },+	{ "jmn", "Makuri Naga" },+	{ "jmr", "Kamara" },+	{ "jms", "Mashi (Nigeria)" },+	{ "jmw", "Mouwase" },+	{ "jmx", "Western Juxtlahuaca Mixtec" },+	{ "jna", "Jangshung" },+	{ "jnd", "Jandavra" },+	{ "jng", "Yangman" },+	{ "jni", "Janji" },+	{ "jnj", "Yemsa" },+	{ "jnl", "Rawat" },+	{ "jns", "Jaunsari" },+	{ "job", "Joba" },+	{ "jod", "Wojenaka" },+	{ "jor", "Jorá" },+	{ "jos", "Jordanian Sign Language" },+	{ "jow", "Jowulu" },+	{ "jpa", "Jewish Palestinian Aramaic" },+	{ "jpn", "Japanese" },+	{ "jpr", "Judeo-Persian" },+	{ "jqr", "Jaqaru" },+	{ "jra", "Jarai" },+	{ "jrb", "Judeo-Arabic" },+	{ "jrr", "Jiru" },+	{ "jrt", "Jorto" },+	{ "jru", "Japrería" },+	{ "jsl", "Japanese Sign Language" },+	{ "jua", "Júma" },+	{ "jub", "Wannu" },+	{ "juc", "Jurchen" },+	{ "jud", "Worodougou" },+	{ "juh", "Hõne" },+	{ "jui", "Ngadjuri" },+	{ "juk", "Wapan" },+	{ "jul", "Jirel" },+	{ "jum", "Jumjum" },+	{ "jun", "Juang" },+	{ "juo", "Jiba" },+	{ "jup", "Hupdë" },+	{ "jur", "Jurúna" },+	{ "jus", "Jumla Sign Language" },+	{ "jut", "Jutish" },+	{ "juu", "Ju" },+	{ "juw", "Wãpha" },+	{ "juy", "Juray" },+	{ "jvd", "Javindo" },+	{ "jvn", "Caribbean Javanese" },+	{ "jwi", "Jwira-Pepesa" },+	{ "jya", "Jiarong" },+	{ "jye", "Judeo-Yemeni Arabic" },+	{ "jyy", "Jaya" },+	{ "kaa", "Kara-Kalpak" },+	{ "kab", "Kabyle" },+	{ "kac", "Kachin" },+	{ "kad", "Adara" },+	{ "kae", "Ketangalan" },+	{ "kaf", "Katso" },+	{ "kag", "Kajaman" },+	{ "kah", "Kara (Central African Republic)" },+	{ "kai", "Karekare" },+	{ "kaj", "Jju" },+	{ "kak", "Kayapa Kallahan" },+	{ "kal", "Kalaallisut" },+	{ "kam", "Kamba (Kenya)" },+	{ "kan", "Kannada" },+	{ "kao", "Xaasongaxango" },+	{ "kap", "Bezhta" },+	{ "kaq", "Capanahua" },+	{ "kas", "Kashmiri" },+	{ "kat", "Georgian" },+	{ "kau", "Kanuri" },+	{ "kav", "Katukína" },+	{ "kaw", "Kawi" },+	{ "kax", "Kao" },+	{ "kay", "Kamayurá" },+	{ "kaz", "Kazakh" },+	{ "kba", "Kalarko" },+	{ "kbb", "Kaxuiâna" },+	{ "kbc", "Kadiwéu" },+	{ "kbd", "Kabardian" },+	{ "kbe", "Kanju" },+	{ "kbf", "Kakauhua" },+	{ "kbg", "Khamba" },+	{ "kbh", "Camsá" },+	{ "kbi", "Kaptiau" },+	{ "kbj", "Kari" },+	{ "kbk", "Grass Koiari" },+	{ "kbl", "Kanembu" },+	{ "kbm", "Iwal" },+	{ "kbn", "Kare (Central African Republic)" },+	{ "kbo", "Keliko" },+	{ "kbp", "Kabiyè" },+	{ "kbq", "Kamano" },+	{ "kbr", "Kafa" },+	{ "kbs", "Kande" },+	{ "kbt", "Abadi" },+	{ "kbu", "Kabutra" },+	{ "kbv", "Dera (Indonesia)" },+	{ "kbw", "Kaiep" },+	{ "kbx", "Ap Ma" },+	{ "kby", "Manga Kanuri" },+	{ "kbz", "Duhwa" },+	{ "kca", "Khanty" },+	{ "kcb", "Kawacha" },+	{ "kcc", "Lubila" },+	{ "kcd", "Ngkâlmpw Kanum" },+	{ "kce", "Kaivi" },+	{ "kcf", "Ukaan" },+	{ "kcg", "Tyap" },+	{ "kch", "Vono" },+	{ "kci", "Kamantan" },+	{ "kcj", "Kobiana" },+	{ "kck", "Kalanga" },+	{ "kcl", "Kela (Papua New Guinea)" },+	{ "kcm", "Gula (Central African Republic)" },+	{ "kcn", "Nubi" },+	{ "kco", "Kinalakna" },+	{ "kcp", "Kanga" },+	{ "kcq", "Kamo" },+	{ "kcr", "Katla" },+	{ "kcs", "Koenoem" },+	{ "kct", "Kaian" },+	{ "kcu", "Kami (Tanzania)" },+	{ "kcv", "Kete" },+	{ "kcw", "Kabwari" },+	{ "kcx", "Kachama-Ganjule" },+	{ "kcy", "Korandje" },+	{ "kcz", "Konongo" },+	{ "kda", "Worimi" },+	{ "kdc", "Kutu" },+	{ "kdd", "Yankunytjatjara" },+	{ "kde", "Makonde" },+	{ "kdf", "Mamusi" },+	{ "kdg", "Seba" },+	{ "kdh", "Tem" },+	{ "kdi", "Kumam" },+	{ "kdj", "Karamojong" },+	{ "kdk", "Numèè" },+	{ "kdl", "Tsikimba" },+	{ "kdm", "Kagoma" },+	{ "kdn", "Kunda" },+	{ "kdp", "Kaningdon-Nindem" },+	{ "kdq", "Koch" },+	{ "kdr", "Karaim" },+	{ "kdt", "Kuy" },+	{ "kdu", "Kadaru" },+	{ "kdw", "Koneraw" },+	{ "kdx", "Kam" },+	{ "kdy", "Keder" },+	{ "kdz", "Kwaja" },+	{ "kea", "Kabuverdianu" },+	{ "keb", "Kélé" },+	{ "kec", "Keiga" },+	{ "ked", "Kerewe" },+	{ "kee", "Eastern Keres" },+	{ "kef", "Kpessi" },+	{ "keg", "Tese" },+	{ "keh", "Keak" },+	{ "kei", "Kei" },+	{ "kej", "Kadar" },+	{ "kek", "Kekchí" },+	{ "kel", "Kela (Democratic Republic of Congo)" },+	{ "kem", "Kemak" },+	{ "ken", "Kenyang" },+	{ "keo", "Kakwa" },+	{ "kep", "Kaikadi" },+	{ "keq", "Kamar" },+	{ "ker", "Kera" },+	{ "kes", "Kugbo" },+	{ "ket", "Ket" },+	{ "keu", "Akebu" },+	{ "kev", "Kanikkaran" },+	{ "kew", "West Kewa" },+	{ "kex", "Kukna" },+	{ "key", "Kupia" },+	{ "kez", "Kukele" },+	{ "kfa", "Kodava" },+	{ "kfb", "Northwestern Kolami" },+	{ "kfc", "Konda-Dora" },+	{ "kfd", "Korra Koraga" },+	{ "kfe", "Kota (India)" },+	{ "kff", "Koya" },+	{ "kfg", "Kudiya" },+	{ "kfh", "Kurichiya" },+	{ "kfi", "Kannada Kurumba" },+	{ "kfj", "Kemiehua" },+	{ "kfk", "Kinnauri" },+	{ "kfl", "Kung" },+	{ "kfm", "Khunsari" },+	{ "kfn", "Kuk" },+	{ "kfo", "Koro (Côte d'Ivoire)" },+	{ "kfp", "Korwa" },+	{ "kfq", "Korku" },+	{ "kfr", "Kachchi" },+	{ "kfs", "Bilaspuri" },+	{ "kft", "Kanjari" },+	{ "kfu", "Katkari" },+	{ "kfv", "Kurmukar" },+	{ "kfw", "Kharam Naga" },+	{ "kfx", "Kullu Pahari" },+	{ "kfy", "Kumaoni" },+	{ "kfz", "Koromfé" },+	{ "kga", "Koyaga" },+	{ "kgb", "Kawe" },+	{ "kgc", "Kasseng" },+	{ "kgd", "Kataang" },+	{ "kge", "Komering" },+	{ "kgf", "Kube" },+	{ "kgg", "Kusunda" },+	{ "kgi", "Selangor Sign Language" },+	{ "kgj", "Gamale Kham" },+	{ "kgk", "Kaiwá" },+	{ "kgl", "Kunggari" },+	{ "kgm", "Karipúna" },+	{ "kgn", "Karingani" },+	{ "kgo", "Krongo" },+	{ "kgp", "Kaingang" },+	{ "kgq", "Kamoro" },+	{ "kgr", "Abun" },+	{ "kgs", "Kumbainggar" },+	{ "kgt", "Somyev" },+	{ "kgu", "Kobol" },+	{ "kgv", "Karas" },+	{ "kgw", "Karon Dori" },+	{ "kgx", "Kamaru" },+	{ "kgy", "Kyerung" },+	{ "kha", "Khasi" },+	{ "khb", "Lü" },+	{ "khc", "Tukang Besi North" },+	{ "khd", "Bädi Kanum" },+	{ "khe", "Korowai" },+	{ "khf", "Khuen" },+	{ "khg", "Khams Tibetan" },+	{ "khh", "Kehu" },+	{ "khj", "Kuturmi" },+	{ "khk", "Halh Mongolian" },+	{ "khl", "Lusi" },+	{ "khm", "Central Khmer" },+	{ "khn", "Khandesi" },+	{ "kho", "Khotanese" },+	{ "khp", "Kapori" },+	{ "khq", "Koyra Chiini Songhay" },+	{ "khr", "Kharia" },+	{ "khs", "Kasua" },+	{ "kht", "Khamti" },+	{ "khu", "Nkhumbi" },+	{ "khv", "Khvarshi" },+	{ "khw", "Khowar" },+	{ "khx", "Kanu" },+	{ "khy", "Kele (Democratic Republic of Congo)" },+	{ "khz", "Keapara" },+	{ "kia", "Kim" },+	{ "kib", "Koalib" },+	{ "kic", "Kickapoo" },+	{ "kid", "Koshin" },+	{ "kie", "Kibet" },+	{ "kif", "Eastern Parbate Kham" },+	{ "kig", "Kimaama" },+	{ "kih", "Kilmeri" },+	{ "kii", "Kitsai" },+	{ "kij", "Kilivila" },+	{ "kik", "Kikuyu" },+	{ "kil", "Kariya" },+	{ "kim", "Karagas" },+	{ "kin", "Kinyarwanda" },+	{ "kio", "Kiowa" },+	{ "kip", "Sheshi Kham" },+	{ "kiq", "Kosadle" },+	{ "kir", "Kirghiz" },+	{ "kis", "Kis" },+	{ "kit", "Agob" },+	{ "kiu", "Kirmanjki (individual language)" },+	{ "kiv", "Kimbu" },+	{ "kiw", "Northeast Kiwai" },+	{ "kix", "Khiamniungan Naga" },+	{ "kiy", "Kirikiri" },+	{ "kiz", "Kisi" },+	{ "kja", "Mlap" },+	{ "kjb", "Q'anjob'al" },+	{ "kjc", "Coastal Konjo" },+	{ "kjd", "Southern Kiwai" },+	{ "kje", "Kisar" },+	{ "kjf", "Khalaj" },+	{ "kjg", "Khmu" },+	{ "kjh", "Khakas" },+	{ "kji", "Zabana" },+	{ "kjj", "Khinalugh" },+	{ "kjk", "Highland Konjo" },+	{ "kjl", "Western Parbate Kham" },+	{ "kjm", "Kháng" },+	{ "kjn", "Kunjen" },+	{ "kjo", "Harijan Kinnauri" },+	{ "kjp", "Pwo Eastern Karen" },+	{ "kjq", "Western Keres" },+	{ "kjr", "Kurudu" },+	{ "kjs", "East Kewa" },+	{ "kjt", "Phrae Pwo Karen" },+	{ "kju", "Kashaya" },+	{ "kjx", "Ramopa" },+	{ "kjy", "Erave" },+	{ "kjz", "Bumthangkha" },+	{ "kka", "Kakanda" },+	{ "kkb", "Kwerisa" },+	{ "kkc", "Odoodee" },+	{ "kkd", "Kinuku" },+	{ "kke", "Kakabe" },+	{ "kkf", "Kalaktang Monpa" },+	{ "kkg", "Mabaka Valley Kalinga" },+	{ "kkh", "Khün" },+	{ "kki", "Kagulu" },+	{ "kkj", "Kako" },+	{ "kkk", "Kokota" },+	{ "kkl", "Kosarek Yale" },+	{ "kkm", "Kiong" },+	{ "kkn", "Kon Keu" },+	{ "kko", "Karko" },+	{ "kkp", "Gugubera" },+	{ "kkq", "Kaiku" },+	{ "kkr", "Kir-Balar" },+	{ "kks", "Giiwo" },+	{ "kkt", "Koi" },+	{ "kku", "Tumi" },+	{ "kkv", "Kangean" },+	{ "kkw", "Teke-Kukuya" },+	{ "kkx", "Kohin" },+	{ "kky", "Guguyimidjir" },+	{ "kkz", "Kaska" },+	{ "kla", "Klamath-Modoc" },+	{ "klb", "Kiliwa" },+	{ "klc", "Kolbila" },+	{ "kld", "Gamilaraay" },+	{ "kle", "Kulung (Nepal)" },+	{ "klf", "Kendeje" },+	{ "klg", "Tagakaulo" },+	{ "klh", "Weliki" },+	{ "kli", "Kalumpang" },+	{ "klj", "Turkic Khalaj" },+	{ "klk", "Kono (Nigeria)" },+	{ "kll", "Kagan Kalagan" },+	{ "klm", "Migum" },+	{ "kln", "Kalenjin" },+	{ "klo", "Kapya" },+	{ "klp", "Kamasa" },+	{ "klq", "Rumu" },+	{ "klr", "Khaling" },+	{ "kls", "Kalasha" },+	{ "klt", "Nukna" },+	{ "klu", "Klao" },+	{ "klv", "Maskelynes" },+	{ "klw", "Lindu" },+	{ "klx", "Koluwawa" },+	{ "kly", "Kalao" },+	{ "klz", "Kabola" },+	{ "kma", "Konni" },+	{ "kmb", "Kimbundu" },+	{ "kmc", "Southern Dong" },+	{ "kmd", "Majukayang Kalinga" },+	{ "kme", "Bakole" },+	{ "kmf", "Kare (Papua New Guinea)" },+	{ "kmg", "Kâte" },+	{ "kmh", "Kalam" },+	{ "kmi", "Kami (Nigeria)" },+	{ "kmj", "Kumarbhag Paharia" },+	{ "kmk", "Limos Kalinga" },+	{ "kml", "Tanudan Kalinga" },+	{ "kmm", "Kom (India)" },+	{ "kmn", "Awtuw" },+	{ "kmo", "Kwoma" },+	{ "kmp", "Gimme" },+	{ "kmq", "Kwama" },+	{ "kmr", "Northern Kurdish" },+	{ "kms", "Kamasau" },+	{ "kmt", "Kemtuik" },+	{ "kmu", "Kanite" },+	{ "kmv", "Karipúna Creole French" },+	{ "kmw", "Komo (Democratic Republic of Congo)" },+	{ "kmx", "Waboda" },+	{ "kmy", "Koma" },+	{ "kmz", "Khorasani Turkish" },+	{ "kna", "Dera (Nigeria)" },+	{ "knb", "Lubuagan Kalinga" },+	{ "knc", "Central Kanuri" },+	{ "knd", "Konda" },+	{ "kne", "Kankanaey" },+	{ "knf", "Mankanya" },+	{ "kng", "Koongo" },+	{ "kni", "Kanufi" },+	{ "knj", "Western Kanjobal" },+	{ "knk", "Kuranko" },+	{ "knl", "Keninjal" },+	{ "knm", "Kanamarí" },+	{ "knn", "Konkani (individual language)" },+	{ "kno", "Kono (Sierra Leone)" },+	{ "knp", "Kwanja" },+	{ "knq", "Kintaq" },+	{ "knr", "Kaningra" },+	{ "kns", "Kensiu" },+	{ "knt", "Panoan Katukína" },+	{ "knu", "Kono (Guinea)" },+	{ "knv", "Tabo" },+	{ "knw", "Kung-Ekoka" },+	{ "knx", "Kendayan" },+	{ "kny", "Kanyok" },+	{ "knz", "Kalamsé" },+	{ "koa", "Konomala" },+	{ "koc", "Kpati" },+	{ "kod", "Kodi" },+	{ "koe", "Kacipo-Balesi" },+	{ "kof", "Kubi" },+	{ "kog", "Cogui" },+	{ "koh", "Koyo" },+	{ "koi", "Komi-Permyak" },+	{ "koj", "Sara Dunjo" },+	{ "kok", "Konkani (macrolanguage)" },+	{ "kol", "Kol (Papua New Guinea)" },+	{ "kom", "Komi" },+	{ "kon", "Kongo" },+	{ "koo", "Konzo" },+	{ "kop", "Waube" },+	{ "koq", "Kota (Gabon)" },+	{ "kor", "Korean" },+	{ "kos", "Kosraean" },+	{ "kot", "Lagwan" },+	{ "kou", "Koke" },+	{ "kov", "Kudu-Camo" },+	{ "kow", "Kugama" },+	{ "kox", "Coxima" },+	{ "koy", "Koyukon" },+	{ "koz", "Korak" },+	{ "kpa", "Kutto" },+	{ "kpb", "Mullu Kurumba" },+	{ "kpc", "Curripaco" },+	{ "kpd", "Koba" },+	{ "kpe", "Kpelle" },+	{ "kpf", "Komba" },+	{ "kpg", "Kapingamarangi" },+	{ "kph", "Kplang" },+	{ "kpi", "Kofei" },+	{ "kpj", "Karajá" },+	{ "kpk", "Kpan" },+	{ "kpl", "Kpala" },+	{ "kpm", "Koho" },+	{ "kpn", "Kepkiriwát" },+	{ "kpo", "Ikposo" },+	{ "kpq", "Korupun-Sela" },+	{ "kpr", "Korafe-Yegha" },+	{ "kps", "Tehit" },+	{ "kpt", "Karata" },+	{ "kpu", "Kafoa" },+	{ "kpv", "Komi-Zyrian" },+	{ "kpw", "Kobon" },+	{ "kpx", "Mountain Koiali" },+	{ "kpy", "Koryak" },+	{ "kpz", "Kupsabiny" },+	{ "kqa", "Mum" },+	{ "kqb", "Kovai" },+	{ "kqc", "Doromu-Koki" },+	{ "kqd", "Koy Sanjaq Surat" },+	{ "kqe", "Kalagan" },+	{ "kqf", "Kakabai" },+	{ "kqg", "Khe" },+	{ "kqh", "Kisankasa" },+	{ "kqi", "Koitabu" },+	{ "kqj", "Koromira" },+	{ "kqk", "Kotafon Gbe" },+	{ "kql", "Kyenele" },+	{ "kqm", "Khisa" },+	{ "kqn", "Kaonde" },+	{ "kqo", "Eastern Krahn" },+	{ "kqp", "Kimré" },+	{ "kqq", "Krenak" },+	{ "kqr", "Kimaragang" },+	{ "kqs", "Northern Kissi" },+	{ "kqt", "Klias River Kadazan" },+	{ "kqu", "Seroa" },+	{ "kqv", "Okolod" },+	{ "kqw", "Kandas" },+	{ "kqx", "Mser" },+	{ "kqy", "Koorete" },+	{ "kqz", "Korana" },+	{ "kra", "Kumhali" },+	{ "krb", "Karkin" },+	{ "krc", "Karachay-Balkar" },+	{ "krd", "Kairui-Midiki" },+	{ "kre", "Panará" },+	{ "krf", "Koro (Vanuatu)" },+	{ "krh", "Kurama" },+	{ "kri", "Krio" },+	{ "krj", "Kinaray-A" },+	{ "krk", "Kerek" },+	{ "krl", "Karelian" },+	{ "krm", "Krim" },+	{ "krn", "Sapo" },+	{ "krp", "Korop" },+	{ "krr", "Kru'ng 2" },+	{ "krs", "Gbaya (Sudan)" },+	{ "krt", "Tumari Kanuri" },+	{ "kru", "Kurukh" },+	{ "krv", "Kavet" },+	{ "krw", "Western Krahn" },+	{ "krx", "Karon" },+	{ "kry", "Kryts" },+	{ "krz", "Sota Kanum" },+	{ "ksa", "Shuwa-Zamani" },+	{ "ksb", "Shambala" },+	{ "ksc", "Southern Kalinga" },+	{ "ksd", "Kuanua" },+	{ "kse", "Kuni" },+	{ "ksf", "Bafia" },+	{ "ksg", "Kusaghe" },+	{ "ksh", "Kölsch" },+	{ "ksi", "Krisa" },+	{ "ksj", "Uare" },+	{ "ksk", "Kansa" },+	{ "ksl", "Kumalu" },+	{ "ksm", "Kumba" },+	{ "ksn", "Kasiguranin" },+	{ "kso", "Kofa" },+	{ "ksp", "Kaba" },+	{ "ksq", "Kwaami" },+	{ "ksr", "Borong" },+	{ "kss", "Southern Kisi" },+	{ "kst", "Winyé" },+	{ "ksu", "Khamyang" },+	{ "ksv", "Kusu" },+	{ "ksw", "S'gaw Karen" },+	{ "ksx", "Kedang" },+	{ "ksy", "Kharia Thar" },+	{ "ksz", "Kodaku" },+	{ "kta", "Katua" },+	{ "ktb", "Kambaata" },+	{ "ktc", "Kholok" },+	{ "ktd", "Kokata" },+	{ "kte", "Nubri" },+	{ "ktf", "Kwami" },+	{ "ktg", "Kalkutung" },+	{ "kth", "Karanga" },+	{ "kti", "North Muyu" },+	{ "ktj", "Plapo Krumen" },+	{ "ktk", "Kaniet" },+	{ "ktl", "Koroshi" },+	{ "ktm", "Kurti" },+	{ "ktn", "Karitiâna" },+	{ "kto", "Kuot" },+	{ "ktp", "Kaduo" },+	{ "ktq", "Katabaga" },+	{ "ktr", "Kota Marudu Tinagas" },+	{ "kts", "South Muyu" },+	{ "ktt", "Ketum" },+	{ "ktu", "Kituba (Democratic Republic of Congo)" },+	{ "ktv", "Eastern Katu" },+	{ "ktw", "Kato" },+	{ "ktx", "Kaxararí" },+	{ "kty", "Kango (Bas-Uélé District)" },+	{ "ktz", "Ju'hoan" },+	{ "kua", "Kuanyama" },+	{ "kub", "Kutep" },+	{ "kuc", "Kwinsu" },+	{ "kud", "'Auhelawa" },+	{ "kue", "Kuman" },+	{ "kuf", "Western Katu" },+	{ "kug", "Kupa" },+	{ "kuh", "Kushi" },+	{ "kui", "Kuikúro-Kalapálo" },+	{ "kuj", "Kuria" },+	{ "kuk", "Kepo'" },+	{ "kul", "Kulere" },+	{ "kum", "Kumyk" },+	{ "kun", "Kunama" },+	{ "kuo", "Kumukio" },+	{ "kup", "Kunimaipa" },+	{ "kuq", "Karipuna" },+	{ "kur", "Kurdish" },+	{ "kus", "Kusaal" },+	{ "kut", "Kutenai" },+	{ "kuu", "Upper Kuskokwim" },+	{ "kuv", "Kur" },+	{ "kuw", "Kpagua" },+	{ "kux", "Kukatja" },+	{ "kuy", "Kuuku-Ya'u" },+	{ "kuz", "Kunza" },+	{ "kva", "Bagvalal" },+	{ "kvb", "Kubu" },+	{ "kvc", "Kove" },+	{ "kvd", "Kui (Indonesia)" },+	{ "kve", "Kalabakan" },+	{ "kvf", "Kabalai" },+	{ "kvg", "Kuni-Boazi" },+	{ "kvh", "Komodo" },+	{ "kvi", "Kwang" },+	{ "kvj", "Psikye" },+	{ "kvk", "Korean Sign Language" },+	{ "kvl", "Kayaw" },+	{ "kvm", "Kendem" },+	{ "kvn", "Border Kuna" },+	{ "kvo", "Dobel" },+	{ "kvp", "Kompane" },+	{ "kvq", "Geba Karen" },+	{ "kvr", "Kerinci" },+	{ "kvs", "Kunggara" },+	{ "kvt", "Lahta Karen" },+	{ "kvu", "Yinbaw Karen" },+	{ "kvv", "Kola" },+	{ "kvw", "Wersing" },+	{ "kvx", "Parkari Koli" },+	{ "kvy", "Yintale Karen" },+	{ "kvz", "Tsakwambo" },+	{ "kwa", "Dâw" },+	{ "kwb", "Kwa" },+	{ "kwc", "Likwala" },+	{ "kwd", "Kwaio" },+	{ "kwe", "Kwerba" },+	{ "kwf", "Kwara'ae" },+	{ "kwg", "Sara Kaba Deme" },+	{ "kwh", "Kowiai" },+	{ "kwi", "Awa-Cuaiquer" },+	{ "kwj", "Kwanga" },+	{ "kwk", "Kwakiutl" },+	{ "kwl", "Kofyar" },+	{ "kwm", "Kwambi" },+	{ "kwn", "Kwangali" },+	{ "kwo", "Kwomtari" },+	{ "kwp", "Kodia" },+	{ "kwq", "Kwak" },+	{ "kwr", "Kwer" },+	{ "kws", "Kwese" },+	{ "kwt", "Kwesten" },+	{ "kwu", "Kwakum" },+	{ "kwv", "Sara Kaba Náà" },+	{ "kww", "Kwinti" },+	{ "kwx", "Khirwar" },+	{ "kwy", "San Salvador Kongo" },+	{ "kwz", "Kwadi" },+	{ "kxa", "Kairiru" },+	{ "kxb", "Krobu" },+	{ "kxc", "Konso" },+	{ "kxd", "Brunei" },+	{ "kxe", "Kakihum" },+	{ "kxf", "Manumanaw Karen" },+	{ "kxh", "Karo (Ethiopia)" },+	{ "kxi", "Keningau Murut" },+	{ "kxj", "Kulfa" },+	{ "kxk", "Zayein Karen" },+	{ "kxl", "Nepali Kurux" },+	{ "kxm", "Northern Khmer" },+	{ "kxn", "Kanowit-Tanjong Melanau" },+	{ "kxo", "Kanoé" },+	{ "kxp", "Wadiyara Koli" },+	{ "kxq", "Smärky Kanum" },+	{ "kxr", "Koro (Papua New Guinea)" },+	{ "kxs", "Kangjia" },+	{ "kxt", "Koiwat" },+	{ "kxu", "Kui (India)" },+	{ "kxv", "Kuvi" },+	{ "kxw", "Konai" },+	{ "kxx", "Likuba" },+	{ "kxy", "Kayong" },+	{ "kxz", "Kerewo" },+	{ "kya", "Kwaya" },+	{ "kyb", "Butbut Kalinga" },+	{ "kyc", "Kyaka" },+	{ "kyd", "Karey" },+	{ "kye", "Krache" },+	{ "kyf", "Kouya" },+	{ "kyg", "Keyagana" },+	{ "kyh", "Karok" },+	{ "kyi", "Kiput" },+	{ "kyj", "Karao" },+	{ "kyk", "Kamayo" },+	{ "kyl", "Kalapuya" },+	{ "kym", "Kpatili" },+	{ "kyn", "Northern Binukidnon" },+	{ "kyo", "Kelon" },+	{ "kyp", "Kang" },+	{ "kyq", "Kenga" },+	{ "kyr", "Kuruáya" },+	{ "kys", "Baram Kayan" },+	{ "kyt", "Kayagar" },+	{ "kyu", "Western Kayah" },+	{ "kyv", "Kayort" },+	{ "kyw", "Kudmali" },+	{ "kyx", "Rapoisi" },+	{ "kyy", "Kambaira" },+	{ "kyz", "Kayabí" },+	{ "kza", "Western Karaboro" },+	{ "kzb", "Kaibobo" },+	{ "kzc", "Bondoukou Kulango" },+	{ "kzd", "Kadai" },+	{ "kze", "Kosena" },+	{ "kzf", "Da'a Kaili" },+	{ "kzg", "Kikai" },+	{ "kzi", "Kelabit" },+	{ "kzj", "Coastal Kadazan" },+	{ "kzk", "Kazukuru" },+	{ "kzl", "Kayeli" },+	{ "kzm", "Kais" },+	{ "kzn", "Kokola" },+	{ "kzo", "Kaningi" },+	{ "kzp", "Kaidipang" },+	{ "kzq", "Kaike" },+	{ "kzr", "Karang" },+	{ "kzs", "Sugut Dusun" },+	{ "kzt", "Tambunan Dusun" },+	{ "kzu", "Kayupulau" },+	{ "kzv", "Komyandaret" },+	{ "kzw", "Karirí-Xocó" },+	{ "kzx", "Kamarian" },+	{ "kzy", "Kango (Tshopo District)" },+	{ "kzz", "Kalabra" },+	{ "laa", "Southern Subanen" },+	{ "lab", "Linear A" },+	{ "lac", "Lacandon" },+	{ "lad", "Ladino" },+	{ "lae", "Pattani" },+	{ "laf", "Lafofa" },+	{ "lag", "Langi" },+	{ "lah", "Lahnda" },+	{ "lai", "Lambya" },+	{ "laj", "Lango (Uganda)" },+	{ "lak", "Laka (Nigeria)" },+	{ "lal", "Lalia" },+	{ "lam", "Lamba" },+	{ "lan", "Laru" },+	{ "lao", "Lao" },+	{ "lap", "Laka (Chad)" },+	{ "laq", "Qabiao" },+	{ "lar", "Larteh" },+	{ "las", "Lama (Togo)" },+	{ "lat", "Latin" },+	{ "lau", "Laba" },+	{ "lav", "Latvian" },+	{ "law", "Lauje" },+	{ "lax", "Tiwa" },+	{ "lay", "Lama (Myanmar)" },+	{ "laz", "Aribwatsa" },+	{ "lba", "Lui" },+	{ "lbb", "Label" },+	{ "lbc", "Lakkia" },+	{ "lbe", "Lak" },+	{ "lbf", "Tinani" },+	{ "lbg", "Laopang" },+	{ "lbi", "La'bi" },+	{ "lbj", "Ladakhi" },+	{ "lbk", "Central Bontok" },+	{ "lbl", "Libon Bikol" },+	{ "lbm", "Lodhi" },+	{ "lbn", "Lamet" },+	{ "lbo", "Laven" },+	{ "lbq", "Wampar" },+	{ "lbr", "Lohorung" },+	{ "lbs", "Libyan Sign Language" },+	{ "lbt", "Lachi" },+	{ "lbu", "Labu" },+	{ "lbv", "Lavatbura-Lamusong" },+	{ "lbw", "Tolaki" },+	{ "lbx", "Lawangan" },+	{ "lby", "Lamu-Lamu" },+	{ "lbz", "Lardil" },+	{ "lcc", "Legenyem" },+	{ "lcd", "Lola" },+	{ "lce", "Loncong" },+	{ "lcf", "Lubu" },+	{ "lch", "Luchazi" },+	{ "lcl", "Lisela" },+	{ "lcm", "Tungag" },+	{ "lcp", "Western Lawa" },+	{ "lcq", "Luhu" },+	{ "lcs", "Lisabata-Nuniali" },+	{ "lda", "Kla-Dan" },+	{ "ldb", "Dũya" },+	{ "ldd", "Luri" },+	{ "ldg", "Lenyima" },+	{ "ldh", "Lamja-Dengsa-Tola" },+	{ "ldi", "Laari" },+	{ "ldj", "Lemoro" },+	{ "ldk", "Leelau" },+	{ "ldl", "Kaan" },+	{ "ldm", "Landoma" },+	{ "ldn", "Láadan" },+	{ "ldo", "Loo" },+	{ "ldp", "Tso" },+	{ "ldq", "Lufu" },+	{ "lea", "Lega-Shabunda" },+	{ "leb", "Lala-Bisa" },+	{ "lec", "Leco" },+	{ "led", "Lendu" },+	{ "lee", "Lyélé" },+	{ "lef", "Lelemi" },+	{ "leg", "Lengua" },+	{ "leh", "Lenje" },+	{ "lei", "Lemio" },+	{ "lej", "Lengola" },+	{ "lek", "Leipon" },+	{ "lel", "Lele (Democratic Republic of Congo)" },+	{ "lem", "Nomaande" },+	{ "len", "Lenca" },+	{ "leo", "Leti (Cameroon)" },+	{ "lep", "Lepcha" },+	{ "leq", "Lembena" },+	{ "ler", "Lenkau" },+	{ "les", "Lese" },+	{ "let", "Lesing-Gelimi" },+	{ "leu", "Kara (Papua New Guinea)" },+	{ "lev", "Lamma" },+	{ "lew", "Ledo Kaili" },+	{ "lex", "Luang" },+	{ "ley", "Lemolang" },+	{ "lez", "Lezghian" },+	{ "lfa", "Lefa" },+	{ "lfn", "Lingua Franca Nova" },+	{ "lga", "Lungga" },+	{ "lgb", "Laghu" },+	{ "lgg", "Lugbara" },+	{ "lgh", "Laghuu" },+	{ "lgi", "Lengilu" },+	{ "lgk", "Lingarak" },+	{ "lgl", "Wala" },+	{ "lgm", "Lega-Mwenga" },+	{ "lgn", "Opuuo" },+	{ "lgq", "Logba" },+	{ "lgr", "Lengo" },+	{ "lgt", "Pahi" },+	{ "lgu", "Longgu" },+	{ "lgz", "Ligenza" },+	{ "lha", "Laha (Viet Nam)" },+	{ "lhh", "Laha (Indonesia)" },+	{ "lhi", "Lahu Shi" },+	{ "lhl", "Lahul Lohar" },+	{ "lhm", "Lhomi" },+	{ "lhn", "Lahanan" },+	{ "lhp", "Lhokpu" },+	{ "lhs", "Mlahsö" },+	{ "lht", "Lo-Toga" },+	{ "lhu", "Lahu" },+	{ "lia", "West-Central Limba" },+	{ "lib", "Likum" },+	{ "lic", "Hlai" },+	{ "lid", "Nyindrou" },+	{ "lie", "Likila" },+	{ "lif", "Limbu" },+	{ "lig", "Ligbi" },+	{ "lih", "Lihir" },+	{ "lii", "Lingkhim" },+	{ "lij", "Ligurian" },+	{ "lik", "Lika" },+	{ "lil", "Lillooet" },+	{ "lim", "Limburgan" },+	{ "lin", "Lingala" },+	{ "lio", "Liki" },+	{ "lip", "Sekpele" },+	{ "liq", "Libido" },+	{ "lir", "Liberian English" },+	{ "lis", "Lisu" },+	{ "lit", "Lithuanian" },+	{ "liu", "Logorik" },+	{ "liv", "Liv" },+	{ "liw", "Col" },+	{ "lix", "Liabuku" },+	{ "liy", "Banda-Bambari" },+	{ "liz", "Libinza" },+	{ "lja", "Golpa" },+	{ "lje", "Rampi" },+	{ "lji", "Laiyolo" },+	{ "ljl", "Li'o" },+	{ "ljp", "Lampung Api" },+	{ "ljw", "Yirandali" },+	{ "ljx", "Yuru" },+	{ "lka", "Lakalei" },+	{ "lkb", "Kabras" },+	{ "lkc", "Kucong" },+	{ "lkd", "Lakondê" },+	{ "lke", "Kenyi" },+	{ "lkh", "Lakha" },+	{ "lki", "Laki" },+	{ "lkj", "Remun" },+	{ "lkl", "Laeko-Libuat" },+	{ "lkm", "Kalaamaya" },+	{ "lkn", "Lakon" },+	{ "lko", "Khayo" },+	{ "lkr", "Päri" },+	{ "lks", "Kisa" },+	{ "lkt", "Lakota" },+	{ "lku", "Kungkari" },+	{ "lky", "Lokoya" },+	{ "lla", "Lala-Roba" },+	{ "llb", "Lolo" },+	{ "llc", "Lele (Guinea)" },+	{ "lld", "Ladin" },+	{ "lle", "Lele (Papua New Guinea)" },+	{ "llf", "Hermit" },+	{ "llg", "Lole" },+	{ "llh", "Lamu" },+	{ "lli", "Teke-Laali" },+	{ "llj", "Ladji Ladji" },+	{ "llk", "Lelak" },+	{ "lll", "Lilau" },+	{ "llm", "Lasalimu" },+	{ "lln", "Lele (Chad)" },+	{ "llo", "Khlor" },+	{ "llp", "North Efate" },+	{ "llq", "Lolak" },+	{ "lls", "Lithuanian Sign Language" },+	{ "llu", "Lau" },+	{ "llx", "Lauan" },+	{ "lma", "East Limba" },+	{ "lmb", "Merei" },+	{ "lmc", "Limilngan" },+	{ "lmd", "Lumun" },+	{ "lme", "Pévé" },+	{ "lmf", "South Lembata" },+	{ "lmg", "Lamogai" },+	{ "lmh", "Lambichhong" },+	{ "lmi", "Lombi" },+	{ "lmj", "West Lembata" },+	{ "lmk", "Lamkang" },+	{ "lml", "Hano" },+	{ "lmm", "Lamam" },+	{ "lmn", "Lambadi" },+	{ "lmo", "Lombard" },+	{ "lmp", "Limbum" },+	{ "lmq", "Lamatuka" },+	{ "lmr", "Lamalera" },+	{ "lmu", "Lamenu" },+	{ "lmv", "Lomaiviti" },+	{ "lmw", "Lake Miwok" },+	{ "lmx", "Laimbue" },+	{ "lmy", "Lamboya" },+	{ "lmz", "Lumbee" },+	{ "lna", "Langbashe" },+	{ "lnb", "Mbalanhu" },+	{ "lnd", "Lundayeh" },+	{ "lng", "Langobardic" },+	{ "lnh", "Lanoh" },+	{ "lni", "Daantanai'" },+	{ "lnj", "Leningitij" },+	{ "lnl", "South Central Banda" },+	{ "lnm", "Langam" },+	{ "lnn", "Lorediakarkar" },+	{ "lno", "Lango (Sudan)" },+	{ "lns", "Lamnso'" },+	{ "lnu", "Longuda" },+	{ "lnw", "Lanima" },+	{ "lnz", "Lonzo" },+	{ "loa", "Loloda" },+	{ "lob", "Lobi" },+	{ "loc", "Inonhan" },+	{ "loe", "Saluan" },+	{ "lof", "Logol" },+	{ "log", "Logo" },+	{ "loh", "Narim" },+	{ "loi", "Loma (Côte d'Ivoire)" },+	{ "loj", "Lou" },+	{ "lok", "Loko" },+	{ "lol", "Mongo" },+	{ "lom", "Loma (Liberia)" },+	{ "lon", "Malawi Lomwe" },+	{ "loo", "Lombo" },+	{ "lop", "Lopa" },+	{ "loq", "Lobala" },+	{ "lor", "Téén" },+	{ "los", "Loniu" },+	{ "lot", "Otuho" },+	{ "lou", "Louisiana Creole French" },+	{ "lov", "Lopi" },+	{ "low", "Tampias Lobu" },+	{ "lox", "Loun" },+	{ "loy", "Loke" },+	{ "loz", "Lozi" },+	{ "lpa", "Lelepa" },+	{ "lpe", "Lepki" },+	{ "lpn", "Long Phuri Naga" },+	{ "lpo", "Lipo" },+	{ "lpx", "Lopit" },+	{ "lra", "Rara Bakati'" },+	{ "lrc", "Northern Luri" },+	{ "lre", "Laurentian" },+	{ "lrg", "Laragia" },+	{ "lri", "Marachi" },+	{ "lrk", "Loarki" },+	{ "lrl", "Lari" },+	{ "lrm", "Marama" },+	{ "lrn", "Lorang" },+	{ "lro", "Laro" },+	{ "lrr", "Southern Yamphu" },+	{ "lrt", "Larantuka Malay" },+	{ "lrv", "Larevat" },+	{ "lrz", "Lemerig" },+	{ "lsa", "Lasgerdi" },+	{ "lsd", "Lishana Deni" },+	{ "lse", "Lusengo" },+	{ "lsg", "Lyons Sign Language" },+	{ "lsh", "Lish" },+	{ "lsi", "Lashi" },+	{ "lsl", "Latvian Sign Language" },+	{ "lsm", "Saamia" },+	{ "lso", "Laos Sign Language" },+	{ "lsp", "Panamanian Sign Language" },+	{ "lsr", "Aruop" },+	{ "lss", "Lasi" },+	{ "lst", "Trinidad and Tobago Sign Language" },+	{ "lsy", "Mauritian Sign Language" },+	{ "ltc", "Late Middle Chinese" },+	{ "ltg", "Latgalian" },+	{ "lti", "Leti (Indonesia)" },+	{ "ltn", "Latundê" },+	{ "lto", "Tsotso" },+	{ "lts", "Tachoni" },+	{ "ltu", "Latu" },+	{ "ltz", "Luxembourgish" },+	{ "lua", "Luba-Lulua" },+	{ "lub", "Luba-Katanga" },+	{ "luc", "Aringa" },+	{ "lud", "Ludian" },+	{ "lue", "Luvale" },+	{ "luf", "Laua" },+	{ "lug", "Ganda" },+	{ "lui", "Luiseno" },+	{ "luj", "Luna" },+	{ "luk", "Lunanakha" },+	{ "lul", "Olu'bo" },+	{ "lum", "Luimbi" },+	{ "lun", "Lunda" },+	{ "luo", "Luo (Kenya and Tanzania)" },+	{ "lup", "Lumbu" },+	{ "luq", "Lucumi" },+	{ "lur", "Laura" },+	{ "lus", "Lushai" },+	{ "lut", "Lushootseed" },+	{ "luu", "Lumba-Yakkha" },+	{ "luv", "Luwati" },+	{ "luw", "Luo (Cameroon)" },+	{ "luy", "Luyia" },+	{ "luz", "Southern Luri" },+	{ "lva", "Maku'a" },+	{ "lvk", "Lavukaleve" },+	{ "lvs", "Standard Latvian" },+	{ "lvu", "Levuka" },+	{ "lwa", "Lwalu" },+	{ "lwe", "Lewo Eleng" },+	{ "lwg", "Wanga" },+	{ "lwh", "White Lachi" },+	{ "lwl", "Eastern Lawa" },+	{ "lwm", "Laomian" },+	{ "lwo", "Luwo" },+	{ "lwt", "Lewotobi" },+	{ "lwu", "Lawu" },+	{ "lww", "Lewo" },+	{ "lya", "Layakha" },+	{ "lyg", "Lyngngam" },+	{ "lyn", "Luyana" },+	{ "lzh", "Literary Chinese" },+	{ "lzl", "Litzlitz" },+	{ "lzn", "Leinong Naga" },+	{ "lzz", "Laz" },+	{ "maa", "San Jerónimo Tecóatl Mazatec" },+	{ "mab", "Yutanduchi Mixtec" },+	{ "mad", "Madurese" },+	{ "mae", "Bo-Rukul" },+	{ "maf", "Mafa" },+	{ "mag", "Magahi" },+	{ "mah", "Marshallese" },+	{ "mai", "Maithili" },+	{ "maj", "Jalapa De Díaz Mazatec" },+	{ "mak", "Makasar" },+	{ "mal", "Malayalam" },+	{ "mam", "Mam" },+	{ "man", "Mandingo" },+	{ "maq", "Chiquihuitlán Mazatec" },+	{ "mar", "Marathi" },+	{ "mas", "Masai" },+	{ "mat", "San Francisco Matlatzinca" },+	{ "mau", "Huautla Mazatec" },+	{ "mav", "Sateré-Mawé" },+	{ "maw", "Mampruli" },+	{ "max", "North Moluccan Malay" },+	{ "maz", "Central Mazahua" },+	{ "mba", "Higaonon" },+	{ "mbb", "Western Bukidnon Manobo" },+	{ "mbc", "Macushi" },+	{ "mbd", "Dibabawon Manobo" },+	{ "mbe", "Molale" },+	{ "mbf", "Baba Malay" },+	{ "mbh", "Mangseng" },+	{ "mbi", "Ilianen Manobo" },+	{ "mbj", "Nadëb" },+	{ "mbk", "Malol" },+	{ "mbl", "Maxakalí" },+	{ "mbm", "Ombamba" },+	{ "mbn", "Macaguán" },+	{ "mbo", "Mbo (Cameroon)" },+	{ "mbp", "Malayo" },+	{ "mbq", "Maisin" },+	{ "mbr", "Nukak Makú" },+	{ "mbs", "Sarangani Manobo" },+	{ "mbt", "Matigsalug Manobo" },+	{ "mbu", "Mbula-Bwazza" },+	{ "mbv", "Mbulungish" },+	{ "mbw", "Maring" },+	{ "mbx", "Mari (East Sepik Province)" },+	{ "mby", "Memoni" },+	{ "mbz", "Amoltepec Mixtec" },+	{ "mca", "Maca" },+	{ "mcb", "Machiguenga" },+	{ "mcc", "Bitur" },+	{ "mcd", "Sharanahua" },+	{ "mce", "Itundujia Mixtec" },+	{ "mcf", "Matsés" },+	{ "mcg", "Mapoyo" },+	{ "mch", "Maquiritari" },+	{ "mci", "Mese" },+	{ "mcj", "Mvanip" },+	{ "mck", "Mbunda" },+	{ "mcl", "Macaguaje" },+	{ "mcm", "Malaccan Creole Portuguese" },+	{ "mcn", "Masana" },+	{ "mco", "Coatlán Mixe" },+	{ "mcp", "Makaa" },+	{ "mcq", "Ese" },+	{ "mcr", "Menya" },+	{ "mcs", "Mambai" },+	{ "mct", "Mengisa" },+	{ "mcu", "Cameroon Mambila" },+	{ "mcv", "Minanibai" },+	{ "mcw", "Mawa (Chad)" },+	{ "mcx", "Mpiemo" },+	{ "mcy", "South Watut" },+	{ "mcz", "Mawan" },+	{ "mda", "Mada (Nigeria)" },+	{ "mdb", "Morigi" },+	{ "mdc", "Male (Papua New Guinea)" },+	{ "mdd", "Mbum" },+	{ "mde", "Maba (Chad)" },+	{ "mdf", "Moksha" },+	{ "mdg", "Massalat" },+	{ "mdh", "Maguindanaon" },+	{ "mdi", "Mamvu" },+	{ "mdj", "Mangbetu" },+	{ "mdk", "Mangbutu" },+	{ "mdl", "Maltese Sign Language" },+	{ "mdm", "Mayogo" },+	{ "mdn", "Mbati" },+	{ "mdp", "Mbala" },+	{ "mdq", "Mbole" },+	{ "mdr", "Mandar" },+	{ "mds", "Maria (Papua New Guinea)" },+	{ "mdt", "Mbere" },+	{ "mdu", "Mboko" },+	{ "mdv", "Santa Lucía Monteverde Mixtec" },+	{ "mdw", "Mbosi" },+	{ "mdx", "Dizin" },+	{ "mdy", "Male (Ethiopia)" },+	{ "mdz", "Suruí Do Pará" },+	{ "mea", "Menka" },+	{ "meb", "Ikobi" },+	{ "mec", "Mara" },+	{ "med", "Melpa" },+	{ "mee", "Mengen" },+	{ "mef", "Megam" },+	{ "meh", "Southwestern Tlaxiaco Mixtec" },+	{ "mei", "Midob" },+	{ "mej", "Meyah" },+	{ "mek", "Mekeo" },+	{ "mel", "Central Melanau" },+	{ "mem", "Mangala" },+	{ "men", "Mende (Sierra Leone)" },+	{ "meo", "Kedah Malay" },+	{ "mep", "Miriwung" },+	{ "meq", "Merey" },+	{ "mer", "Meru" },+	{ "mes", "Masmaje" },+	{ "met", "Mato" },+	{ "meu", "Motu" },+	{ "mev", "Mano" },+	{ "mew", "Maaka" },+	{ "mey", "Hassaniyya" },+	{ "mez", "Menominee" },+	{ "mfa", "Pattani Malay" },+	{ "mfb", "Bangka" },+	{ "mfc", "Mba" },+	{ "mfd", "Mendankwe-Nkwen" },+	{ "mfe", "Morisyen" },+	{ "mff", "Naki" },+	{ "mfg", "Mogofin" },+	{ "mfh", "Matal" },+	{ "mfi", "Wandala" },+	{ "mfj", "Mefele" },+	{ "mfk", "North Mofu" },+	{ "mfl", "Putai" },+	{ "mfm", "Marghi South" },+	{ "mfn", "Cross River Mbembe" },+	{ "mfo", "Mbe" },+	{ "mfp", "Makassar Malay" },+	{ "mfq", "Moba" },+	{ "mfr", "Marithiel" },+	{ "mfs", "Mexican Sign Language" },+	{ "mft", "Mokerang" },+	{ "mfu", "Mbwela" },+	{ "mfv", "Mandjak" },+	{ "mfw", "Mulaha" },+	{ "mfx", "Melo" },+	{ "mfy", "Mayo" },+	{ "mfz", "Mabaan" },+	{ "mga", "Middle Irish (900-1200)" },+	{ "mgb", "Mararit" },+	{ "mgc", "Morokodo" },+	{ "mgd", "Moru" },+	{ "mge", "Mango" },+	{ "mgf", "Maklew" },+	{ "mgg", "Mpumpong" },+	{ "mgh", "Makhuwa-Meetto" },+	{ "mgi", "Lijili" },+	{ "mgj", "Abureni" },+	{ "mgk", "Mawes" },+	{ "mgl", "Maleu-Kilenge" },+	{ "mgm", "Mambae" },+	{ "mgn", "Mbangi" },+	{ "mgo", "Meta'" },+	{ "mgp", "Eastern Magar" },+	{ "mgq", "Malila" },+	{ "mgr", "Mambwe-Lungu" },+	{ "mgs", "Manda (Tanzania)" },+	{ "mgt", "Mongol" },+	{ "mgu", "Mailu" },+	{ "mgv", "Matengo" },+	{ "mgw", "Matumbi" },+	{ "mgy", "Mbunga" },+	{ "mgz", "Mbugwe" },+	{ "mha", "Manda (India)" },+	{ "mhb", "Mahongwe" },+	{ "mhc", "Mocho" },+	{ "mhd", "Mbugu" },+	{ "mhe", "Besisi" },+	{ "mhf", "Mamaa" },+	{ "mhg", "Margu" },+	{ "mhh", "Maskoy Pidgin" },+	{ "mhi", "Ma'di" },+	{ "mhj", "Mogholi" },+	{ "mhk", "Mungaka" },+	{ "mhl", "Mauwake" },+	{ "mhm", "Makhuwa-Moniga" },+	{ "mhn", "Mócheno" },+	{ "mho", "Mashi (Zambia)" },+	{ "mhp", "Balinese Malay" },+	{ "mhq", "Mandan" },+	{ "mhr", "Eastern Mari" },+	{ "mhs", "Buru (Indonesia)" },+	{ "mht", "Mandahuaca" },+	{ "mhu", "Digaro-Mishmi" },+	{ "mhw", "Mbukushu" },+	{ "mhx", "Maru" },+	{ "mhy", "Ma'anyan" },+	{ "mhz", "Mor (Mor Islands)" },+	{ "mia", "Miami" },+	{ "mib", "Atatláhuca Mixtec" },+	{ "mic", "Mi'kmaq" },+	{ "mid", "Mandaic" },+	{ "mie", "Ocotepec Mixtec" },+	{ "mif", "Mofu-Gudur" },+	{ "mig", "San Miguel El Grande Mixtec" },+	{ "mih", "Chayuco Mixtec" },+	{ "mii", "Chigmecatitlán Mixtec" },+	{ "mij", "Abar" },+	{ "mik", "Mikasuki" },+	{ "mil", "Peñoles Mixtec" },+	{ "mim", "Alacatlatzala Mixtec" },+	{ "min", "Minangkabau" },+	{ "mio", "Pinotepa Nacional Mixtec" },+	{ "mip", "Apasco-Apoala Mixtec" },+	{ "miq", "Mískito" },+	{ "mir", "Isthmus Mixe" },+	{ "mis", "Uncoded languages" },+	{ "mit", "Southern Puebla Mixtec" },+	{ "miu", "Cacaloxtepec Mixtec" },+	{ "miw", "Akoye" },+	{ "mix", "Mixtepec Mixtec" },+	{ "miy", "Ayutla Mixtec" },+	{ "miz", "Coatzospan Mixtec" },+	{ "mjc", "San Juan Colorado Mixtec" },+	{ "mjd", "Northwest Maidu" },+	{ "mje", "Muskum" },+	{ "mjg", "Tu" },+	{ "mjh", "Mwera (Nyasa)" },+	{ "mji", "Kim Mun" },+	{ "mjj", "Mawak" },+	{ "mjk", "Matukar" },+	{ "mjl", "Mandeali" },+	{ "mjm", "Medebur" },+	{ "mjn", "Ma (Papua New Guinea)" },+	{ "mjo", "Malankuravan" },+	{ "mjp", "Malapandaram" },+	{ "mjq", "Malaryan" },+	{ "mjr", "Malavedan" },+	{ "mjs", "Miship" },+	{ "mjt", "Sauria Paharia" },+	{ "mju", "Manna-Dora" },+	{ "mjv", "Mannan" },+	{ "mjw", "Karbi" },+	{ "mjx", "Mahali" },+	{ "mjy", "Mahican" },+	{ "mjz", "Majhi" },+	{ "mka", "Mbre" },+	{ "mkb", "Mal Paharia" },+	{ "mkc", "Siliput" },+	{ "mkd", "Macedonian" },+	{ "mke", "Mawchi" },+	{ "mkf", "Miya" },+	{ "mkg", "Mak (China)" },+	{ "mki", "Dhatki" },+	{ "mkj", "Mokilese" },+	{ "mkk", "Byep" },+	{ "mkl", "Mokole" },+	{ "mkm", "Moklen" },+	{ "mkn", "Kupang Malay" },+	{ "mko", "Mingang Doso" },+	{ "mkp", "Moikodi" },+	{ "mkq", "Bay Miwok" },+	{ "mkr", "Malas" },+	{ "mks", "Silacayoapan Mixtec" },+	{ "mkt", "Vamale" },+	{ "mku", "Konyanka Maninka" },+	{ "mkv", "Mafea" },+	{ "mkw", "Kituba (Congo)" },+	{ "mkx", "Kinamiging Manobo" },+	{ "mky", "East Makian" },+	{ "mkz", "Makasae" },+	{ "mla", "Malo" },+	{ "mlb", "Mbule" },+	{ "mlc", "Cao Lan" },+	{ "mle", "Manambu" },+	{ "mlf", "Mal" },+	{ "mlg", "Malagasy" },+	{ "mlh", "Mape" },+	{ "mli", "Malimpung" },+	{ "mlj", "Miltu" },+	{ "mlk", "Ilwana" },+	{ "mll", "Malua Bay" },+	{ "mlm", "Mulam" },+	{ "mln", "Malango" },+	{ "mlo", "Mlomp" },+	{ "mlp", "Bargam" },+	{ "mlq", "Western Maninkakan" },+	{ "mlr", "Vame" },+	{ "mls", "Masalit" },+	{ "mlt", "Maltese" },+	{ "mlu", "To'abaita" },+	{ "mlv", "Motlav" },+	{ "mlw", "Moloko" },+	{ "mlx", "Malfaxal" },+	{ "mlz", "Malaynon" },+	{ "mma", "Mama" },+	{ "mmb", "Momina" },+	{ "mmc", "Michoacán Mazahua" },+	{ "mmd", "Maonan" },+	{ "mme", "Mae" },+	{ "mmf", "Mundat" },+	{ "mmg", "North Ambrym" },+	{ "mmh", "Mehináku" },+	{ "mmi", "Musar" },+	{ "mmj", "Majhwar" },+	{ "mmk", "Mukha-Dora" },+	{ "mml", "Man Met" },+	{ "mmm", "Maii" },+	{ "mmn", "Mamanwa" },+	{ "mmo", "Mangga Buang" },+	{ "mmp", "Siawi" },+	{ "mmq", "Musak" },+	{ "mmr", "Western Xiangxi Miao" },+	{ "mmt", "Malalamai" },+	{ "mmu", "Mmaala" },+	{ "mmv", "Miriti" },+	{ "mmw", "Emae" },+	{ "mmx", "Madak" },+	{ "mmy", "Migaama" },+	{ "mmz", "Mabaale" },+	{ "mna", "Mbula" },+	{ "mnb", "Muna" },+	{ "mnc", "Manchu" },+	{ "mnd", "Mondé" },+	{ "mne", "Naba" },+	{ "mnf", "Mundani" },+	{ "mng", "Eastern Mnong" },+	{ "mnh", "Mono (Democratic Republic of Congo)" },+	{ "mni", "Manipuri" },+	{ "mnj", "Munji" },+	{ "mnk", "Mandinka" },+	{ "mnl", "Tiale" },+	{ "mnm", "Mapena" },+	{ "mnn", "Southern Mnong" },+	{ "mnp", "Min Bei Chinese" },+	{ "mnq", "Minriq" },+	{ "mnr", "Mono (USA)" },+	{ "mns", "Mansi" },+	{ "mnu", "Mer" },+	{ "mnv", "Rennell-Bellona" },+	{ "mnw", "Mon" },+	{ "mnx", "Manikion" },+	{ "mny", "Manyawa" },+	{ "mnz", "Moni" },+	{ "moa", "Mwan" },+	{ "moc", "Mocoví" },+	{ "mod", "Mobilian" },+	{ "moe", "Montagnais" },+	{ "mog", "Mongondow" },+	{ "moh", "Mohawk" },+	{ "moi", "Mboi" },+	{ "moj", "Monzombo" },+	{ "mok", "Morori" },+	{ "mom", "Mangue" },+	{ "mon", "Mongolian" },+	{ "moo", "Monom" },+	{ "mop", "Mopán Maya" },+	{ "moq", "Mor (Bomberai Peninsula)" },+	{ "mor", "Moro" },+	{ "mos", "Mossi" },+	{ "mot", "Barí" },+	{ "mou", "Mogum" },+	{ "mov", "Mohave" },+	{ "mow", "Moi (Congo)" },+	{ "mox", "Molima" },+	{ "moy", "Shekkacho" },+	{ "moz", "Mukulu" },+	{ "mpa", "Mpoto" },+	{ "mpb", "Mullukmulluk" },+	{ "mpc", "Mangarayi" },+	{ "mpd", "Machinere" },+	{ "mpe", "Majang" },+	{ "mpg", "Marba" },+	{ "mph", "Maung" },+	{ "mpi", "Mpade" },+	{ "mpj", "Martu Wangka" },+	{ "mpk", "Mbara (Chad)" },+	{ "mpl", "Middle Watut" },+	{ "mpm", "Yosondúa Mixtec" },+	{ "mpn", "Mindiri" },+	{ "mpo", "Miu" },+	{ "mpp", "Migabac" },+	{ "mpq", "Matís" },+	{ "mpr", "Vangunu" },+	{ "mps", "Dadibi" },+	{ "mpt", "Mian" },+	{ "mpu", "Makuráp" },+	{ "mpv", "Mungkip" },+	{ "mpw", "Mapidian" },+	{ "mpx", "Misima-Panaeati" },+	{ "mpy", "Mapia" },+	{ "mpz", "Mpi" },+	{ "mqa", "Maba (Indonesia)" },+	{ "mqb", "Mbuko" },+	{ "mqc", "Mangole" },+	{ "mqe", "Matepi" },+	{ "mqf", "Momuna" },+	{ "mqg", "Kota Bangun Kutai Malay" },+	{ "mqh", "Tlazoyaltepec Mixtec" },+	{ "mqi", "Mariri" },+	{ "mqj", "Mamasa" },+	{ "mqk", "Rajah Kabunsuwan Manobo" },+	{ "mql", "Mbelime" },+	{ "mqm", "South Marquesan" },+	{ "mqn", "Moronene" },+	{ "mqo", "Modole" },+	{ "mqp", "Manipa" },+	{ "mqq", "Minokok" },+	{ "mqr", "Mander" },+	{ "mqs", "West Makian" },+	{ "mqt", "Mok" },+	{ "mqu", "Mandari" },+	{ "mqv", "Mosimo" },+	{ "mqw", "Murupi" },+	{ "mqx", "Mamuju" },+	{ "mqy", "Manggarai" },+	{ "mqz", "Pano" },+	{ "mra", "Mlabri" },+	{ "mrb", "Marino" },+	{ "mrc", "Maricopa" },+	{ "mrd", "Western Magar" },+	{ "mre", "Martha's Vineyard Sign Language" },+	{ "mrf", "Elseng" },+	{ "mrg", "Mising" },+	{ "mrh", "Mara Chin" },+	{ "mri", "Maori" },+	{ "mrj", "Western Mari" },+	{ "mrk", "Hmwaveke" },+	{ "mrl", "Mortlockese" },+	{ "mrm", "Merlav" },+	{ "mrn", "Cheke Holo" },+	{ "mro", "Mru" },+	{ "mrp", "Morouas" },+	{ "mrq", "North Marquesan" },+	{ "mrr", "Maria (India)" },+	{ "mrs", "Maragus" },+	{ "mrt", "Marghi Central" },+	{ "mru", "Mono (Cameroon)" },+	{ "mrv", "Mangareva" },+	{ "mrw", "Maranao" },+	{ "mrx", "Maremgi" },+	{ "mry", "Mandaya" },+	{ "mrz", "Marind" },+	{ "msa", "Malay (macrolanguage)" },+	{ "msb", "Masbatenyo" },+	{ "msc", "Sankaran Maninka" },+	{ "msd", "Yucatec Maya Sign Language" },+	{ "mse", "Musey" },+	{ "msf", "Mekwei" },+	{ "msg", "Moraid" },+	{ "msh", "Masikoro Malagasy" },+	{ "msi", "Sabah Malay" },+	{ "msj", "Ma (Democratic Republic of Congo)" },+	{ "msk", "Mansaka" },+	{ "msl", "Molof" },+	{ "msm", "Agusan Manobo" },+	{ "msn", "Vurës" },+	{ "mso", "Mombum" },+	{ "msp", "Maritsauá" },+	{ "msq", "Caac" },+	{ "msr", "Mongolian Sign Language" },+	{ "mss", "West Masela" },+	{ "msu", "Musom" },+	{ "msv", "Maslam" },+	{ "msw", "Mansoanka" },+	{ "msx", "Moresada" },+	{ "msy", "Aruamu" },+	{ "msz", "Momare" },+	{ "mta", "Cotabato Manobo" },+	{ "mtb", "Anyin Morofo" },+	{ "mtc", "Munit" },+	{ "mtd", "Mualang" },+	{ "mte", "Mono (Solomon Islands)" },+	{ "mtf", "Murik (Papua New Guinea)" },+	{ "mtg", "Una" },+	{ "mth", "Munggui" },+	{ "mti", "Maiwa (Papua New Guinea)" },+	{ "mtj", "Moskona" },+	{ "mtk", "Mbe'" },+	{ "mtl", "Montol" },+	{ "mtm", "Mator" },+	{ "mtn", "Matagalpa" },+	{ "mto", "Totontepec Mixe" },+	{ "mtp", "Wichí Lhamtés Nocten" },+	{ "mtq", "Muong" },+	{ "mtr", "Mewari" },+	{ "mts", "Yora" },+	{ "mtt", "Mota" },+	{ "mtu", "Tututepec Mixtec" },+	{ "mtv", "Asaro'o" },+	{ "mtw", "Southern Binukidnon" },+	{ "mtx", "Tidaá Mixtec" },+	{ "mty", "Nabi" },+	{ "mua", "Mundang" },+	{ "mub", "Mubi" },+	{ "muc", "Ajumbu" },+	{ "mud", "Mednyj Aleut" },+	{ "mue", "Media Lengua" },+	{ "mug", "Musgu" },+	{ "muh", "Mündü" },+	{ "mui", "Musi" },+	{ "muj", "Mabire" },+	{ "muk", "Mugom" },+	{ "mul", "Multiple languages" },+	{ "mum", "Maiwala" },+	{ "muo", "Nyong" },+	{ "mup", "Malvi" },+	{ "muq", "Eastern Xiangxi Miao" },+	{ "mur", "Murle" },+	{ "mus", "Creek" },+	{ "mut", "Western Muria" },+	{ "muu", "Yaaku" },+	{ "muv", "Muthuvan" },+	{ "mux", "Bo-Ung" },+	{ "muy", "Muyang" },+	{ "muz", "Mursi" },+	{ "mva", "Manam" },+	{ "mvb", "Mattole" },+	{ "mvd", "Mamboru" },+	{ "mve", "Marwari (Pakistan)" },+	{ "mvf", "Peripheral Mongolian" },+	{ "mvg", "Yucuañe Mixtec" },+	{ "mvh", "Mulgi" },+	{ "mvi", "Miyako" },+	{ "mvk", "Mekmek" },+	{ "mvl", "Mbara (Australia)" },+	{ "mvm", "Muya" },+	{ "mvn", "Minaveha" },+	{ "mvo", "Marovo" },+	{ "mvp", "Duri" },+	{ "mvq", "Moere" },+	{ "mvr", "Marau" },+	{ "mvs", "Massep" },+	{ "mvt", "Mpotovoro" },+	{ "mvu", "Marfa" },+	{ "mvv", "Tagal Murut" },+	{ "mvw", "Machinga" },+	{ "mvx", "Meoswar" },+	{ "mvy", "Indus Kohistani" },+	{ "mvz", "Mesqan" },+	{ "mwa", "Mwatebu" },+	{ "mwb", "Juwal" },+	{ "mwc", "Are" },+	{ "mwe", "Mwera (Chimwera)" },+	{ "mwf", "Murrinh-Patha" },+	{ "mwg", "Aiklep" },+	{ "mwh", "Mouk-Aria" },+	{ "mwi", "Labo" },+	{ "mwj", "Maligo" },+	{ "mwk", "Kita Maninkakan" },+	{ "mwl", "Mirandese" },+	{ "mwm", "Sar" },+	{ "mwn", "Nyamwanga" },+	{ "mwo", "Central Maewo" },+	{ "mwp", "Kala Lagaw Ya" },+	{ "mwq", "Mün Chin" },+	{ "mwr", "Marwari" },+	{ "mws", "Mwimbi-Muthambi" },+	{ "mwt", "Moken" },+	{ "mwu", "Mittu" },+	{ "mwv", "Mentawai" },+	{ "mww", "Hmong Daw" },+	{ "mwx", "Mediak" },+	{ "mwy", "Mosiro" },+	{ "mwz", "Moingi" },+	{ "mxa", "Northwest Oaxaca Mixtec" },+	{ "mxb", "Tezoatlán Mixtec" },+	{ "mxc", "Manyika" },+	{ "mxd", "Modang" },+	{ "mxe", "Mele-Fila" },+	{ "mxf", "Malgbe" },+	{ "mxg", "Mbangala" },+	{ "mxh", "Mvuba" },+	{ "mxi", "Mozarabic" },+	{ "mxj", "Miju-Mishmi" },+	{ "mxk", "Monumbo" },+	{ "mxl", "Maxi Gbe" },+	{ "mxm", "Meramera" },+	{ "mxn", "Moi (Indonesia)" },+	{ "mxo", "Mbowe" },+	{ "mxp", "Tlahuitoltepec Mixe" },+	{ "mxq", "Juquila Mixe" },+	{ "mxr", "Murik (Malaysia)" },+	{ "mxs", "Huitepec Mixtec" },+	{ "mxt", "Jamiltepec Mixtec" },+	{ "mxu", "Mada (Cameroon)" },+	{ "mxv", "Metlatónoc Mixtec" },+	{ "mxw", "Namo" },+	{ "mxx", "Mahou" },+	{ "mxy", "Southeastern Nochixtlán Mixtec" },+	{ "mxz", "Central Masela" },+	{ "mya", "Burmese" },+	{ "myb", "Mbay" },+	{ "myc", "Mayeka" },+	{ "myd", "Maramba" },+	{ "mye", "Myene" },+	{ "myf", "Bambassi" },+	{ "myg", "Manta" },+	{ "myh", "Makah" },+	{ "myi", "Mina (India)" },+	{ "myj", "Mangayat" },+	{ "myk", "Mamara Senoufo" },+	{ "myl", "Moma" },+	{ "mym", "Me'en" },+	{ "myo", "Anfillo" },+	{ "myp", "Pirahã" },+	{ "myr", "Muniche" },+	{ "mys", "Mesmes" },+	{ "myu", "Mundurukú" },+	{ "myv", "Erzya" },+	{ "myw", "Muyuw" },+	{ "myx", "Masaaba" },+	{ "myy", "Macuna" },+	{ "myz", "Classical Mandaic" },+	{ "mza", "Santa María Zacatepec Mixtec" },+	{ "mzb", "Tumzabt" },+	{ "mzc", "Madagascar Sign Language" },+	{ "mzd", "Malimba" },+	{ "mze", "Morawa" },+	{ "mzg", "Monastic Sign Language" },+	{ "mzh", "Wichí Lhamtés Güisnay" },+	{ "mzi", "Ixcatlán Mazatec" },+	{ "mzj", "Manya" },+	{ "mzk", "Nigeria Mambila" },+	{ "mzl", "Mazatlán Mixe" },+	{ "mzm", "Mumuye" },+	{ "mzn", "Mazanderani" },+	{ "mzo", "Matipuhy" },+	{ "mzp", "Movima" },+	{ "mzq", "Mori Atas" },+	{ "mzr", "Marúbo" },+	{ "mzs", "Macanese" },+	{ "mzt", "Mintil" },+	{ "mzu", "Inapang" },+	{ "mzv", "Manza" },+	{ "mzw", "Deg" },+	{ "mzx", "Mawayana" },+	{ "mzy", "Mozambican Sign Language" },+	{ "mzz", "Maiadomu" },+	{ "naa", "Namla" },+	{ "nab", "Southern Nambikuára" },+	{ "nac", "Narak" },+	{ "nad", "Nijadali" },+	{ "nae", "Naka'ela" },+	{ "naf", "Nabak" },+	{ "nag", "Naga Pidgin" },+	{ "naj", "Nalu" },+	{ "nak", "Nakanai" },+	{ "nal", "Nalik" },+	{ "nam", "Ngan'gityemerri" },+	{ "nan", "Min Nan Chinese" },+	{ "nao", "Naaba" },+	{ "nap", "Neapolitan" },+	{ "naq", "Nama (Namibia)" },+	{ "nar", "Iguta" },+	{ "nas", "Naasioi" },+	{ "nat", "Hungworo" },+	{ "nau", "Nauru" },+	{ "nav", "Navajo" },+	{ "naw", "Nawuri" },+	{ "nax", "Nakwi" },+	{ "nay", "Narrinyeri" },+	{ "naz", "Coatepec Nahuatl" },+	{ "nba", "Nyemba" },+	{ "nbb", "Ndoe" },+	{ "nbc", "Chang Naga" },+	{ "nbd", "Ngbinda" },+	{ "nbe", "Konyak Naga" },+	{ "nbg", "Nagarchal" },+	{ "nbh", "Ngamo" },+	{ "nbi", "Mao Naga" },+	{ "nbj", "Ngarinman" },+	{ "nbk", "Nake" },+	{ "nbl", "South Ndebele" },+	{ "nbm", "Ngbaka Ma'bo" },+	{ "nbn", "Kuri" },+	{ "nbo", "Nkukoli" },+	{ "nbp", "Nnam" },+	{ "nbq", "Nggem" },+	{ "nbr", "Numana-Nunku-Gbantu-Numbu" },+	{ "nbs", "Namibian Sign Language" },+	{ "nbt", "Na" },+	{ "nbu", "Rongmei Naga" },+	{ "nbv", "Ngamambo" },+	{ "nbw", "Southern Ngbandi" },+	{ "nby", "Ningera" },+	{ "nca", "Iyo" },+	{ "ncb", "Central Nicobarese" },+	{ "ncc", "Ponam" },+	{ "ncd", "Nachering" },+	{ "nce", "Yale" },+	{ "ncf", "Notsi" },+	{ "ncg", "Nisga'a" },+	{ "nch", "Central Huasteca Nahuatl" },+	{ "nci", "Classical Nahuatl" },+	{ "ncj", "Northern Puebla Nahuatl" },+	{ "nck", "Nakara" },+	{ "ncl", "Michoacán Nahuatl" },+	{ "ncm", "Nambo" },+	{ "ncn", "Nauna" },+	{ "nco", "Sibe" },+	{ "ncp", "Ndaktup" },+	{ "ncr", "Ncane" },+	{ "ncs", "Nicaraguan Sign Language" },+	{ "nct", "Chothe Naga" },+	{ "ncu", "Chumburung" },+	{ "ncx", "Central Puebla Nahuatl" },+	{ "ncz", "Natchez" },+	{ "nda", "Ndasa" },+	{ "ndb", "Kenswei Nsei" },+	{ "ndc", "Ndau" },+	{ "ndd", "Nde-Nsele-Nta" },+	{ "nde", "North Ndebele" },+	{ "ndf", "Nadruvian" },+	{ "ndg", "Ndengereko" },+	{ "ndh", "Ndali" },+	{ "ndi", "Samba Leko" },+	{ "ndj", "Ndamba" },+	{ "ndk", "Ndaka" },+	{ "ndl", "Ndolo" },+	{ "ndm", "Ndam" },+	{ "ndn", "Ngundi" },+	{ "ndo", "Ndonga" },+	{ "ndp", "Ndo" },+	{ "ndq", "Ndombe" },+	{ "ndr", "Ndoola" },+	{ "nds", "Low German" },+	{ "ndt", "Ndunga" },+	{ "ndu", "Dugun" },+	{ "ndv", "Ndut" },+	{ "ndw", "Ndobo" },+	{ "ndx", "Nduga" },+	{ "ndy", "Lutos" },+	{ "ndz", "Ndogo" },+	{ "nea", "Eastern Ngad'a" },+	{ "neb", "Toura (Côte d'Ivoire)" },+	{ "nec", "Nedebang" },+	{ "ned", "Nde-Gbite" },+	{ "nee", "Nêlêmwa-Nixumwak" },+	{ "nef", "Nefamese" },+	{ "neg", "Negidal" },+	{ "neh", "Nyenkha" },+	{ "nei", "Neo-Hittite" },+	{ "nej", "Neko" },+	{ "nek", "Neku" },+	{ "nem", "Nemi" },+	{ "nen", "Nengone" },+	{ "neo", "Ná-Meo" },+	{ "nep", "Nepali (macrolanguage)" },+	{ "neq", "North Central Mixe" },+	{ "ner", "Yahadian" },+	{ "nes", "Bhoti Kinnauri" },+	{ "net", "Nete" },+	{ "neu", "Neo" },+	{ "nev", "Nyaheun" },+	{ "new", "Newari" },+	{ "nex", "Neme" },+	{ "ney", "Neyo" },+	{ "nez", "Nez Perce" },+	{ "nfa", "Dhao" },+	{ "nfd", "Ahwai" },+	{ "nfl", "Ayiwo" },+	{ "nfr", "Nafaanra" },+	{ "nfu", "Mfumte" },+	{ "nga", "Ngbaka" },+	{ "ngb", "Northern Ngbandi" },+	{ "ngc", "Ngombe (Democratic Republic of Congo)" },+	{ "ngd", "Ngando (Central African Republic)" },+	{ "nge", "Ngemba" },+	{ "ngg", "Ngbaka Manza" },+	{ "ngh", "Nu" },+	{ "ngi", "Ngizim" },+	{ "ngj", "Ngie" },+	{ "ngk", "Dalabon" },+	{ "ngl", "Lomwe" },+	{ "ngm", "Ngatik Men's Creole" },+	{ "ngn", "Ngwo" },+	{ "ngo", "Ngoni" },+	{ "ngp", "Ngulu" },+	{ "ngq", "Ngurimi" },+	{ "ngr", "Engdewu" },+	{ "ngs", "Gvoko" },+	{ "ngt", "Ngeq" },+	{ "ngu", "Guerrero Nahuatl" },+	{ "ngv", "Nagumi" },+	{ "ngw", "Ngwaba" },+	{ "ngx", "Nggwahyi" },+	{ "ngy", "Tibea" },+	{ "ngz", "Ngungwel" },+	{ "nha", "Nhanda" },+	{ "nhb", "Beng" },+	{ "nhc", "Tabasco Nahuatl" },+	{ "nhd", "Chiripá" },+	{ "nhe", "Eastern Huasteca Nahuatl" },+	{ "nhf", "Nhuwala" },+	{ "nhg", "Tetelcingo Nahuatl" },+	{ "nhh", "Nahari" },+	{ "nhi", "Zacatlán-Ahuacatlán-Tepetzintla Nahuatl" },+	{ "nhk", "Isthmus-Cosoleacaque Nahuatl" },+	{ "nhm", "Morelos Nahuatl" },+	{ "nhn", "Central Nahuatl" },+	{ "nho", "Takuu" },+	{ "nhp", "Isthmus-Pajapan Nahuatl" },+	{ "nhq", "Huaxcaleca Nahuatl" },+	{ "nhr", "Naro" },+	{ "nht", "Ometepec Nahuatl" },+	{ "nhu", "Noone" },+	{ "nhv", "Temascaltepec Nahuatl" },+	{ "nhw", "Western Huasteca Nahuatl" },+	{ "nhx", "Isthmus-Mecayapan Nahuatl" },+	{ "nhy", "Northern Oaxaca Nahuatl" },+	{ "nhz", "Santa María La Alta Nahuatl" },+	{ "nia", "Nias" },+	{ "nib", "Nakame" },+	{ "nid", "Ngandi" },+	{ "nie", "Niellim" },+	{ "nif", "Nek" },+	{ "nig", "Ngalakan" },+	{ "nih", "Nyiha (Tanzania)" },+	{ "nii", "Nii" },+	{ "nij", "Ngaju" },+	{ "nik", "Southern Nicobarese" },+	{ "nil", "Nila" },+	{ "nim", "Nilamba" },+	{ "nin", "Ninzo" },+	{ "nio", "Nganasan" },+	{ "niq", "Nandi" },+	{ "nir", "Nimboran" },+	{ "nis", "Nimi" },+	{ "nit", "Southeastern Kolami" },+	{ "niu", "Niuean" },+	{ "niv", "Gilyak" },+	{ "niw", "Nimo" },+	{ "nix", "Hema" },+	{ "niy", "Ngiti" },+	{ "niz", "Ningil" },+	{ "nja", "Nzanyi" },+	{ "njb", "Nocte Naga" },+	{ "njd", "Ndonde Hamba" },+	{ "njh", "Lotha Naga" },+	{ "nji", "Gudanji" },+	{ "njj", "Njen" },+	{ "njl", "Njalgulgule" },+	{ "njm", "Angami Naga" },+	{ "njn", "Liangmai Naga" },+	{ "njo", "Ao Naga" },+	{ "njr", "Njerep" },+	{ "njs", "Nisa" },+	{ "njt", "Ndyuka-Trio Pidgin" },+	{ "nju", "Ngadjunmaya" },+	{ "njx", "Kunyi" },+	{ "njy", "Njyem" },+	{ "njz", "Nyishi" },+	{ "nka", "Nkoya" },+	{ "nkb", "Khoibu Naga" },+	{ "nkc", "Nkongho" },+	{ "nkd", "Koireng" },+	{ "nke", "Duke" },+	{ "nkf", "Inpui Naga" },+	{ "nkg", "Nekgini" },+	{ "nkh", "Khezha Naga" },+	{ "nki", "Thangal Naga" },+	{ "nkj", "Nakai" },+	{ "nkk", "Nokuku" },+	{ "nkm", "Namat" },+	{ "nkn", "Nkangala" },+	{ "nko", "Nkonya" },+	{ "nkp", "Niuatoputapu" },+	{ "nkq", "Nkami" },+	{ "nkr", "Nukuoro" },+	{ "nks", "North Asmat" },+	{ "nkt", "Nyika (Tanzania)" },+	{ "nku", "Bouna Kulango" },+	{ "nkv", "Nyika (Malawi and Zambia)" },+	{ "nkw", "Nkutu" },+	{ "nkx", "Nkoroo" },+	{ "nkz", "Nkari" },+	{ "nla", "Ngombale" },+	{ "nlc", "Nalca" },+	{ "nld", "Dutch" },+	{ "nle", "East Nyala" },+	{ "nlg", "Gela" },+	{ "nli", "Grangali" },+	{ "nlj", "Nyali" },+	{ "nlk", "Ninia Yali" },+	{ "nll", "Nihali" },+	{ "nlo", "Ngul" },+	{ "nlq", "Lao Naga" },+	{ "nlu", "Nchumbulu" },+	{ "nlv", "Orizaba Nahuatl" },+	{ "nlw", "Walangama" },+	{ "nlx", "Nahali" },+	{ "nly", "Nyamal" },+	{ "nlz", "Nalögo" },+	{ "nma", "Maram Naga" },+	{ "nmb", "Big Nambas" },+	{ "nmc", "Ngam" },+	{ "nmd", "Ndumu" },+	{ "nme", "Mzieme Naga" },+	{ "nmf", "Tangkhul Naga (India)" },+	{ "nmg", "Kwasio" },+	{ "nmh", "Monsang Naga" },+	{ "nmi", "Nyam" },+	{ "nmj", "Ngombe (Central African Republic)" },+	{ "nmk", "Namakura" },+	{ "nml", "Ndemli" },+	{ "nmm", "Manangba" },+	{ "nmn", "!Xóõ" },+	{ "nmo", "Moyon Naga" },+	{ "nmp", "Nimanbur" },+	{ "nmq", "Nambya" },+	{ "nmr", "Nimbari" },+	{ "nms", "Letemboi" },+	{ "nmt", "Namonuito" },+	{ "nmu", "Northeast Maidu" },+	{ "nmv", "Ngamini" },+	{ "nmw", "Nimoa" },+	{ "nmx", "Nama (Papua New Guinea)" },+	{ "nmy", "Namuyi" },+	{ "nmz", "Nawdm" },+	{ "nna", "Nyangumarta" },+	{ "nnb", "Nande" },+	{ "nnc", "Nancere" },+	{ "nnd", "West Ambae" },+	{ "nne", "Ngandyera" },+	{ "nnf", "Ngaing" },+	{ "nng", "Maring Naga" },+	{ "nnh", "Ngiemboon" },+	{ "nni", "North Nuaulu" },+	{ "nnj", "Nyangatom" },+	{ "nnk", "Nankina" },+	{ "nnl", "Northern Rengma Naga" },+	{ "nnm", "Namia" },+	{ "nnn", "Ngete" },+	{ "nno", "Norwegian Nynorsk" },+	{ "nnp", "Wancho Naga" },+	{ "nnq", "Ngindo" },+	{ "nnr", "Narungga" },+	{ "nns", "Ningye" },+	{ "nnt", "Nanticoke" },+	{ "nnu", "Dwang" },+	{ "nnv", "Nugunu (Australia)" },+	{ "nnw", "Southern Nuni" },+	{ "nnx", "Ngong" },+	{ "nny", "Nyangga" },+	{ "nnz", "Nda'nda'" },+	{ "noa", "Woun Meu" },+	{ "nob", "Norwegian Bokmål" },+	{ "noc", "Nuk" },+	{ "nod", "Northern Thai" },+	{ "noe", "Nimadi" },+	{ "nof", "Nomane" },+	{ "nog", "Nogai" },+	{ "noh", "Nomu" },+	{ "noi", "Noiri" },+	{ "noj", "Nonuya" },+	{ "nok", "Nooksack" },+	{ "nol", "Nomlaki" },+	{ "nom", "Nocamán" },+	{ "non", "Old Norse" },+	{ "nop", "Numanggang" },+	{ "noq", "Ngongo" },+	{ "nor", "Norwegian" },+	{ "nos", "Eastern Nisu" },+	{ "not", "Nomatsiguenga" },+	{ "nou", "Ewage-Notu" },+	{ "nov", "Novial" },+	{ "now", "Nyambo" },+	{ "noy", "Noy" },+	{ "noz", "Nayi" },+	{ "npa", "Nar Phu" },+	{ "npb", "Nupbikha" },+	{ "npg", "Ponyo-Gongwang Naga" },+	{ "nph", "Phom Naga" },+	{ "npi", "Nepali (individual language)" },+	{ "npl", "Southeastern Puebla Nahuatl" },+	{ "npn", "Mondropolon" },+	{ "npo", "Pochuri Naga" },+	{ "nps", "Nipsan" },+	{ "npu", "Puimei Naga" },+	{ "npy", "Napu" },+	{ "nqg", "Southern Nago" },+	{ "nqk", "Kura Ede Nago" },+	{ "nqm", "Ndom" },+	{ "nqn", "Nen" },+	{ "nqo", "N'Ko" },+	{ "nqq", "Kyan-Karyaw Naga" },+	{ "nqy", "Akyaung Ari Naga" },+	{ "nra", "Ngom" },+	{ "nrb", "Nara" },+	{ "nrc", "Noric" },+	{ "nre", "Southern Rengma Naga" },+	{ "nrg", "Narango" },+	{ "nri", "Chokri Naga" },+	{ "nrk", "Ngarla" },+	{ "nrl", "Ngarluma" },+	{ "nrm", "Narom" },+	{ "nrn", "Norn" },+	{ "nrp", "North Picene" },+	{ "nrr", "Norra" },+	{ "nrt", "Northern Kalapuya" },+	{ "nru", "Narua" },+	{ "nrx", "Ngurmbur" },+	{ "nrz", "Lala" },+	{ "nsa", "Sangtam Naga" },+	{ "nsc", "Nshi" },+	{ "nsd", "Southern Nisu" },+	{ "nse", "Nsenga" },+	{ "nsf", "Northwestern Nisu" },+	{ "nsg", "Ngasa" },+	{ "nsh", "Ngoshie" },+	{ "nsi", "Nigerian Sign Language" },+	{ "nsk", "Naskapi" },+	{ "nsl", "Norwegian Sign Language" },+	{ "nsm", "Sumi Naga" },+	{ "nsn", "Nehan" },+	{ "nso", "Pedi" },+	{ "nsp", "Nepalese Sign Language" },+	{ "nsq", "Northern Sierra Miwok" },+	{ "nsr", "Maritime Sign Language" },+	{ "nss", "Nali" },+	{ "nst", "Tase Naga" },+	{ "nsu", "Sierra Negra Nahuatl" },+	{ "nsv", "Southwestern Nisu" },+	{ "nsw", "Navut" },+	{ "nsx", "Nsongo" },+	{ "nsy", "Nasal" },+	{ "nsz", "Nisenan" },+	{ "nte", "Nathembo" },+	{ "ntg", "Ngantangarra" },+	{ "nti", "Natioro" },+	{ "ntj", "Ngaanyatjarra" },+	{ "ntk", "Ikoma-Nata-Isenye" },+	{ "ntm", "Nateni" },+	{ "nto", "Ntomba" },+	{ "ntp", "Northern Tepehuan" },+	{ "ntr", "Delo" },+	{ "nts", "Natagaimas" },+	{ "ntu", "Natügu" },+	{ "ntw", "Nottoway" },+	{ "ntx", "Tangkhul Naga (Myanmar)" },+	{ "nty", "Mantsi" },+	{ "ntz", "Natanzi" },+	{ "nua", "Yuanga" },+	{ "nuc", "Nukuini" },+	{ "nud", "Ngala" },+	{ "nue", "Ngundu" },+	{ "nuf", "Nusu" },+	{ "nug", "Nungali" },+	{ "nuh", "Ndunda" },+	{ "nui", "Ngumbi" },+	{ "nuj", "Nyole" },+	{ "nuk", "Nuu-chah-nulth" },+	{ "nul", "Nusa Laut" },+	{ "num", "Niuafo'ou" },+	{ "nun", "Anong" },+	{ "nuo", "Nguôn" },+	{ "nup", "Nupe-Nupe-Tako" },+	{ "nuq", "Nukumanu" },+	{ "nur", "Nukuria" },+	{ "nus", "Nuer" },+	{ "nut", "Nung (Viet Nam)" },+	{ "nuu", "Ngbundu" },+	{ "nuv", "Northern Nuni" },+	{ "nuw", "Nguluwan" },+	{ "nux", "Mehek" },+	{ "nuy", "Nunggubuyu" },+	{ "nuz", "Tlamacazapa Nahuatl" },+	{ "nvh", "Nasarian" },+	{ "nvm", "Namiae" },+	{ "nvo", "Nyokon" },+	{ "nwa", "Nawathinehena" },+	{ "nwb", "Nyabwa" },+	{ "nwc", "Classical Newari" },+	{ "nwe", "Ngwe" },+	{ "nwg", "Ngayawung" },+	{ "nwi", "Southwest Tanna" },+	{ "nwm", "Nyamusa-Molo" },+	{ "nwo", "Nauo" },+	{ "nwr", "Nawaru" },+	{ "nwx", "Middle Newar" },+	{ "nwy", "Nottoway-Meherrin" },+	{ "nxa", "Nauete" },+	{ "nxd", "Ngando (Democratic Republic of Congo)" },+	{ "nxe", "Nage" },+	{ "nxg", "Ngad'a" },+	{ "nxi", "Nindi" },+	{ "nxk", "Koki Naga" },+	{ "nxl", "South Nuaulu" },+	{ "nxm", "Numidian" },+	{ "nxn", "Ngawun" },+	{ "nxq", "Naxi" },+	{ "nxr", "Ninggerum" },+	{ "nxu", "Narau" },+	{ "nxx", "Nafri" },+	{ "nya", "Nyanja" },+	{ "nyb", "Nyangbo" },+	{ "nyc", "Nyanga-li" },+	{ "nyd", "Nyore" },+	{ "nye", "Nyengo" },+	{ "nyf", "Giryama" },+	{ "nyg", "Nyindu" },+	{ "nyh", "Nyigina" },+	{ "nyi", "Ama (Sudan)" },+	{ "nyj", "Nyanga" },+	{ "nyk", "Nyaneka" },+	{ "nyl", "Nyeu" },+	{ "nym", "Nyamwezi" },+	{ "nyn", "Nyankole" },+	{ "nyo", "Nyoro" },+	{ "nyp", "Nyang'i" },+	{ "nyq", "Nayini" },+	{ "nyr", "Nyiha (Malawi)" },+	{ "nys", "Nyunga" },+	{ "nyt", "Nyawaygi" },+	{ "nyu", "Nyungwe" },+	{ "nyv", "Nyulnyul" },+	{ "nyw", "Nyaw" },+	{ "nyx", "Nganyaywana" },+	{ "nyy", "Nyakyusa-Ngonde" },+	{ "nza", "Tigon Mbembe" },+	{ "nzb", "Njebi" },+	{ "nzi", "Nzima" },+	{ "nzk", "Nzakara" },+	{ "nzm", "Zeme Naga" },+	{ "nzs", "New Zealand Sign Language" },+	{ "nzu", "Teke-Nzikou" },+	{ "nzy", "Nzakambay" },+	{ "nzz", "Nanga Dama Dogon" },+	{ "oaa", "Orok" },+	{ "oac", "Oroch" },+	{ "oar", "Old Aramaic (up to 700 BCE)" },+	{ "oav", "Old Avar" },+	{ "obi", "Obispeño" },+	{ "obk", "Southern Bontok" },+	{ "obl", "Oblo" },+	{ "obm", "Moabite" },+	{ "obo", "Obo Manobo" },+	{ "obr", "Old Burmese" },+	{ "obt", "Old Breton" },+	{ "obu", "Obulom" },+	{ "oca", "Ocaina" },+	{ "och", "Old Chinese" },+	{ "oci", "Occitan (post 1500)" },+	{ "oco", "Old Cornish" },+	{ "ocu", "Atzingo Matlatzinca" },+	{ "oda", "Odut" },+	{ "odk", "Od" },+	{ "odt", "Old Dutch" },+	{ "odu", "Odual" },+	{ "ofo", "Ofo" },+	{ "ofs", "Old Frisian" },+	{ "ofu", "Efutop" },+	{ "ogb", "Ogbia" },+	{ "ogc", "Ogbah" },+	{ "oge", "Old Georgian" },+	{ "ogg", "Ogbogolo" },+	{ "ogo", "Khana" },+	{ "ogu", "Ogbronuagum" },+	{ "oht", "Old Hittite" },+	{ "ohu", "Old Hungarian" },+	{ "oia", "Oirata" },+	{ "oin", "Inebu One" },+	{ "ojb", "Northwestern Ojibwa" },+	{ "ojc", "Central Ojibwa" },+	{ "ojg", "Eastern Ojibwa" },+	{ "oji", "Ojibwa" },+	{ "ojp", "Old Japanese" },+	{ "ojs", "Severn Ojibwa" },+	{ "ojv", "Ontong Java" },+	{ "ojw", "Western Ojibwa" },+	{ "oka", "Okanagan" },+	{ "okb", "Okobo" },+	{ "okd", "Okodia" },+	{ "oke", "Okpe (Southwestern Edo)" },+	{ "okg", "Koko Babangk" },+	{ "okh", "Koresh-e Rostam" },+	{ "oki", "Okiek" },+	{ "okj", "Oko-Juwoi" },+	{ "okk", "Kwamtim One" },+	{ "okl", "Old Kentish Sign Language" },+	{ "okm", "Middle Korean (10th-16th cent.)" },+	{ "okn", "Oki-No-Erabu" },+	{ "oko", "Old Korean (3rd-9th cent.)" },+	{ "okr", "Kirike" },+	{ "oks", "Oko-Eni-Osayen" },+	{ "oku", "Oku" },+	{ "okv", "Orokaiva" },+	{ "okx", "Okpe (Northwestern Edo)" },+	{ "ola", "Walungge" },+	{ "old", "Mochi" },+	{ "ole", "Olekha" },+	{ "olk", "Olkol" },+	{ "olm", "Oloma" },+	{ "olo", "Livvi" },+	{ "olr", "Olrat" },+	{ "oma", "Omaha-Ponca" },+	{ "omb", "East Ambae" },+	{ "omc", "Mochica" },+	{ "ome", "Omejes" },+	{ "omg", "Omagua" },+	{ "omi", "Omi" },+	{ "omk", "Omok" },+	{ "oml", "Ombo" },+	{ "omn", "Minoan" },+	{ "omo", "Utarmbung" },+	{ "omp", "Old Manipuri" },+	{ "omr", "Old Marathi" },+	{ "omt", "Omotik" },+	{ "omu", "Omurano" },+	{ "omw", "South Tairora" },+	{ "omx", "Old Mon" },+	{ "ona", "Ona" },+	{ "onb", "Lingao" },+	{ "one", "Oneida" },+	{ "ong", "Olo" },+	{ "oni", "Onin" },+	{ "onj", "Onjob" },+	{ "onk", "Kabore One" },+	{ "onn", "Onobasulu" },+	{ "ono", "Onondaga" },+	{ "onp", "Sartang" },+	{ "onr", "Northern One" },+	{ "ons", "Ono" },+	{ "ont", "Ontenu" },+	{ "onu", "Unua" },+	{ "onw", "Old Nubian" },+	{ "onx", "Onin Based Pidgin" },+	{ "ood", "Tohono O'odham" },+	{ "oog", "Ong" },+	{ "oon", "Önge" },+	{ "oor", "Oorlams" },+	{ "oos", "Old Ossetic" },+	{ "opa", "Okpamheri" },+	{ "opk", "Kopkaka" },+	{ "opm", "Oksapmin" },+	{ "opo", "Opao" },+	{ "opt", "Opata" },+	{ "opy", "Ofayé" },+	{ "ora", "Oroha" },+	{ "orc", "Orma" },+	{ "ore", "Orejón" },+	{ "org", "Oring" },+	{ "orh", "Oroqen" },+	{ "ori", "Oriya (macrolanguage)" },+	{ "orm", "Oromo" },+	{ "orn", "Orang Kanaq" },+	{ "oro", "Orokolo" },+	{ "orr", "Oruma" },+	{ "ors", "Orang Seletar" },+	{ "ort", "Adivasi Oriya" },+	{ "oru", "Ormuri" },+	{ "orv", "Old Russian" },+	{ "orw", "Oro Win" },+	{ "orx", "Oro" },+	{ "ory", "Oriya (individual language)" },+	{ "orz", "Ormu" },+	{ "osa", "Osage" },+	{ "osc", "Oscan" },+	{ "osi", "Osing" },+	{ "oso", "Ososo" },+	{ "osp", "Old Spanish" },+	{ "oss", "Ossetian" },+	{ "ost", "Osatu" },+	{ "osu", "Southern One" },+	{ "osx", "Old Saxon" },+	{ "ota", "Ottoman Turkish (1500-1928)" },+	{ "otb", "Old Tibetan" },+	{ "otd", "Ot Danum" },+	{ "ote", "Mezquital Otomi" },+	{ "oti", "Oti" },+	{ "otk", "Old Turkish" },+	{ "otl", "Tilapa Otomi" },+	{ "otm", "Eastern Highland Otomi" },+	{ "otn", "Tenango Otomi" },+	{ "otq", "Querétaro Otomi" },+	{ "otr", "Otoro" },+	{ "ots", "Estado de México Otomi" },+	{ "ott", "Temoaya Otomi" },+	{ "otu", "Otuke" },+	{ "otw", "Ottawa" },+	{ "otx", "Texcatepec Otomi" },+	{ "oty", "Old Tamil" },+	{ "otz", "Ixtenco Otomi" },+	{ "oua", "Tagargrent" },+	{ "oub", "Glio-Oubi" },+	{ "oue", "Oune" },+	{ "oui", "Old Uighur" },+	{ "oum", "Ouma" },+	{ "oun", "!O!ung" },+	{ "owi", "Owiniga" },+	{ "owl", "Old Welsh" },+	{ "oyb", "Oy" },+	{ "oyd", "Oyda" },+	{ "oym", "Wayampi" },+	{ "oyy", "Oya'oya" },+	{ "ozm", "Koonzime" },+	{ "pab", "Parecís" },+	{ "pac", "Pacoh" },+	{ "pad", "Paumarí" },+	{ "pae", "Pagibete" },+	{ "paf", "Paranawát" },+	{ "pag", "Pangasinan" },+	{ "pah", "Tenharim" },+	{ "pai", "Pe" },+	{ "pak", "Parakanã" },+	{ "pal", "Pahlavi" },+	{ "pam", "Pampanga" },+	{ "pan", "Panjabi" },+	{ "pao", "Northern Paiute" },+	{ "pap", "Papiamento" },+	{ "paq", "Parya" },+	{ "par", "Panamint" },+	{ "pas", "Papasena" },+	{ "pat", "Papitalai" },+	{ "pau", "Palauan" },+	{ "pav", "Pakaásnovos" },+	{ "paw", "Pawnee" },+	{ "pax", "Pankararé" },+	{ "pay", "Pech" },+	{ "paz", "Pankararú" },+	{ "pbb", "Páez" },+	{ "pbc", "Patamona" },+	{ "pbe", "Mezontla Popoloca" },+	{ "pbf", "Coyotepec Popoloca" },+	{ "pbg", "Paraujano" },+	{ "pbh", "E'ñapa Woromaipu" },+	{ "pbi", "Parkwa" },+	{ "pbl", "Mak (Nigeria)" },+	{ "pbn", "Kpasam" },+	{ "pbo", "Papel" },+	{ "pbp", "Badyara" },+	{ "pbr", "Pangwa" },+	{ "pbs", "Central Pame" },+	{ "pbt", "Southern Pashto" },+	{ "pbu", "Northern Pashto" },+	{ "pbv", "Pnar" },+	{ "pby", "Pyu" },+	{ "pca", "Santa Inés Ahuatempan Popoloca" },+	{ "pcb", "Pear" },+	{ "pcc", "Bouyei" },+	{ "pcd", "Picard" },+	{ "pce", "Ruching Palaung" },+	{ "pcf", "Paliyan" },+	{ "pcg", "Paniya" },+	{ "pch", "Pardhan" },+	{ "pci", "Duruwa" },+	{ "pcj", "Parenga" },+	{ "pck", "Paite Chin" },+	{ "pcl", "Pardhi" },+	{ "pcm", "Nigerian Pidgin" },+	{ "pcn", "Piti" },+	{ "pcp", "Pacahuara" },+	{ "pcw", "Pyapun" },+	{ "pda", "Anam" },+	{ "pdc", "Pennsylvania German" },+	{ "pdi", "Pa Di" },+	{ "pdn", "Podena" },+	{ "pdo", "Padoe" },+	{ "pdt", "Plautdietsch" },+	{ "pdu", "Kayan" },+	{ "pea", "Peranakan Indonesian" },+	{ "peb", "Eastern Pomo" },+	{ "ped", "Mala (Papua New Guinea)" },+	{ "pee", "Taje" },+	{ "pef", "Northeastern Pomo" },+	{ "peg", "Pengo" },+	{ "peh", "Bonan" },+	{ "pei", "Chichimeca-Jonaz" },+	{ "pej", "Northern Pomo" },+	{ "pek", "Penchal" },+	{ "pel", "Pekal" },+	{ "pem", "Phende" },+	{ "peo", "Old Persian (ca. 600-400 B.C.)" },+	{ "pep", "Kunja" },+	{ "peq", "Southern Pomo" },+	{ "pes", "Iranian Persian" },+	{ "pev", "Pémono" },+	{ "pex", "Petats" },+	{ "pey", "Petjo" },+	{ "pez", "Eastern Penan" },+	{ "pfa", "Pááfang" },+	{ "pfe", "Peere" },+	{ "pfl", "Pfaelzisch" },+	{ "pga", "Sudanese Creole Arabic" },+	{ "pgg", "Pangwali" },+	{ "pgi", "Pagi" },+	{ "pgk", "Rerep" },+	{ "pgl", "Primitive Irish" },+	{ "pgn", "Paelignian" },+	{ "pgs", "Pangseng" },+	{ "pgu", "Pagu" },+	{ "pha", "Pa-Hng" },+	{ "phd", "Phudagi" },+	{ "phg", "Phuong" },+	{ "phh", "Phukha" },+	{ "phk", "Phake" },+	{ "phl", "Phalura" },+	{ "phm", "Phimbi" },+	{ "phn", "Phoenician" },+	{ "pho", "Phunoi" },+	{ "phq", "Phana'" },+	{ "phr", "Pahari-Potwari" },+	{ "pht", "Phu Thai" },+	{ "phu", "Phuan" },+	{ "phv", "Pahlavani" },+	{ "phw", "Phangduwali" },+	{ "pia", "Pima Bajo" },+	{ "pib", "Yine" },+	{ "pic", "Pinji" },+	{ "pid", "Piaroa" },+	{ "pie", "Piro" },+	{ "pif", "Pingelapese" },+	{ "pig", "Pisabo" },+	{ "pih", "Pitcairn-Norfolk" },+	{ "pii", "Pini" },+	{ "pij", "Pijao" },+	{ "pil", "Yom" },+	{ "pim", "Powhatan" },+	{ "pin", "Piame" },+	{ "pio", "Piapoco" },+	{ "pip", "Pero" },+	{ "pir", "Piratapuyo" },+	{ "pis", "Pijin" },+	{ "pit", "Pitta Pitta" },+	{ "piu", "Pintupi-Luritja" },+	{ "piv", "Pileni" },+	{ "piw", "Pimbwe" },+	{ "pix", "Piu" },+	{ "piy", "Piya-Kwonci" },+	{ "piz", "Pije" },+	{ "pjt", "Pitjantjatjara" },+	{ "pka", "Ardhamāgadhī Prākrit" },+	{ "pkb", "Pokomo" },+	{ "pkc", "Paekche" },+	{ "pkg", "Pak-Tong" },+	{ "pkh", "Pankhu" },+	{ "pkn", "Pakanha" },+	{ "pko", "Pökoot" },+	{ "pkp", "Pukapuka" },+	{ "pkr", "Attapady Kurumba" },+	{ "pks", "Pakistan Sign Language" },+	{ "pkt", "Maleng" },+	{ "pku", "Paku" },+	{ "pla", "Miani" },+	{ "plb", "Polonombauk" },+	{ "plc", "Central Palawano" },+	{ "pld", "Polari" },+	{ "ple", "Palu'e" },+	{ "plg", "Pilagá" },+	{ "plh", "Paulohi" },+	{ "pli", "Pali" },+	{ "plj", "Polci" },+	{ "plk", "Kohistani Shina" },+	{ "pll", "Shwe Palaung" },+	{ "pln", "Palenquero" },+	{ "plo", "Oluta Popoluca" },+	{ "plp", "Palpa" },+	{ "plq", "Palaic" },+	{ "plr", "Palaka Senoufo" },+	{ "pls", "San Marcos Tlalcoyalco Popoloca" },+	{ "plt", "Plateau Malagasy" },+	{ "plu", "Palikúr" },+	{ "plv", "Southwest Palawano" },+	{ "plw", "Brooke's Point Palawano" },+	{ "ply", "Bolyu" },+	{ "plz", "Paluan" },+	{ "pma", "Paama" },+	{ "pmb", "Pambia" },+	{ "pmc", "Palumata" },+	{ "pmd", "Pallanganmiddang" },+	{ "pme", "Pwaamei" },+	{ "pmf", "Pamona" },+	{ "pmh", "Māhārāṣṭri Prākrit" },+	{ "pmi", "Northern Pumi" },+	{ "pmj", "Southern Pumi" },+	{ "pmk", "Pamlico" },+	{ "pml", "Lingua Franca" },+	{ "pmm", "Pomo" },+	{ "pmn", "Pam" },+	{ "pmo", "Pom" },+	{ "pmq", "Northern Pame" },+	{ "pmr", "Paynamar" },+	{ "pms", "Piemontese" },+	{ "pmt", "Tuamotuan" },+	{ "pmu", "Mirpur Panjabi" },+	{ "pmw", "Plains Miwok" },+	{ "pmx", "Poumei Naga" },+	{ "pmy", "Papuan Malay" },+	{ "pmz", "Southern Pame" },+	{ "pna", "Punan Bah-Biau" },+	{ "pnb", "Western Panjabi" },+	{ "pnc", "Pannei" },+	{ "pne", "Western Penan" },+	{ "png", "Pongu" },+	{ "pnh", "Penrhyn" },+	{ "pni", "Aoheng" },+	{ "pnj", "Pinjarup" },+	{ "pnk", "Paunaka" },+	{ "pnl", "Paleni" },+	{ "pnm", "Punan Batu 1" },+	{ "pnn", "Pinai-Hagahai" },+	{ "pno", "Panobo" },+	{ "pnp", "Pancana" },+	{ "pnq", "Pana (Burkina Faso)" },+	{ "pnr", "Panim" },+	{ "pns", "Ponosakan" },+	{ "pnt", "Pontic" },+	{ "pnu", "Jiongnai Bunu" },+	{ "pnv", "Pinigura" },+	{ "pnw", "Panytyima" },+	{ "pnx", "Phong-Kniang" },+	{ "pny", "Pinyin" },+	{ "pnz", "Pana (Central African Republic)" },+	{ "poc", "Poqomam" },+	{ "pod", "Ponares" },+	{ "poe", "San Juan Atzingo Popoloca" },+	{ "pof", "Poke" },+	{ "pog", "Potiguára" },+	{ "poh", "Poqomchi'" },+	{ "poi", "Highland Popoluca" },+	{ "pok", "Pokangá" },+	{ "pol", "Polish" },+	{ "pom", "Southeastern Pomo" },+	{ "pon", "Pohnpeian" },+	{ "poo", "Central Pomo" },+	{ "pop", "Pwapwâ" },+	{ "poq", "Texistepec Popoluca" },+	{ "por", "Portuguese" },+	{ "pos", "Sayula Popoluca" },+	{ "pot", "Potawatomi" },+	{ "pov", "Upper Guinea Crioulo" },+	{ "pow", "San Felipe Otlaltepec Popoloca" },+	{ "pox", "Polabian" },+	{ "poy", "Pogolo" },+	{ "ppa", "Pao" },+	{ "ppe", "Papi" },+	{ "ppi", "Paipai" },+	{ "ppk", "Uma" },+	{ "ppl", "Pipil" },+	{ "ppm", "Papuma" },+	{ "ppn", "Papapana" },+	{ "ppo", "Folopa" },+	{ "ppp", "Pelende" },+	{ "ppq", "Pei" },+	{ "pps", "San Luís Temalacayuca Popoloca" },+	{ "ppt", "Pare" },+	{ "ppu", "Papora" },+	{ "pqa", "Pa'a" },+	{ "pqm", "Malecite-Passamaquoddy" },+	{ "prb", "Lua'" },+	{ "prc", "Parachi" },+	{ "prd", "Parsi-Dari" },+	{ "pre", "Principense" },+	{ "prf", "Paranan" },+	{ "prg", "Prussian" },+	{ "prh", "Porohanon" },+	{ "pri", "Paicî" },+	{ "prk", "Parauk" },+	{ "prl", "Peruvian Sign Language" },+	{ "prm", "Kibiri" },+	{ "prn", "Prasuni" },+	{ "pro", "Old Provençal (to 1500)" },+	{ "prp", "Parsi" },+	{ "prq", "Ashéninka Perené" },+	{ "prr", "Puri" },+	{ "prs", "Dari" },+	{ "prt", "Phai" },+	{ "pru", "Puragi" },+	{ "prw", "Parawen" },+	{ "prx", "Purik" },+	{ "pry", "Pray 3" },+	{ "prz", "Providencia Sign Language" },+	{ "psa", "Asue Awyu" },+	{ "psc", "Persian Sign Language" },+	{ "psd", "Plains Indian Sign Language" },+	{ "pse", "Central Malay" },+	{ "psg", "Penang Sign Language" },+	{ "psh", "Southwest Pashayi" },+	{ "psi", "Southeast Pashayi" },+	{ "psl", "Puerto Rican Sign Language" },+	{ "psm", "Pauserna" },+	{ "psn", "Panasuan" },+	{ "pso", "Polish Sign Language" },+	{ "psp", "Philippine Sign Language" },+	{ "psq", "Pasi" },+	{ "psr", "Portuguese Sign Language" },+	{ "pss", "Kaulong" },+	{ "pst", "Central Pashto" },+	{ "psu", "Sauraseni Prākrit" },+	{ "psw", "Port Sandwich" },+	{ "psy", "Piscataway" },+	{ "pta", "Pai Tavytera" },+	{ "pth", "Pataxó Hã-Ha-Hãe" },+	{ "pti", "Pintiini" },+	{ "ptn", "Patani" },+	{ "pto", "Zo'é" },+	{ "ptp", "Patep" },+	{ "ptr", "Piamatsina" },+	{ "ptt", "Enrekang" },+	{ "ptu", "Bambam" },+	{ "ptv", "Port Vato" },+	{ "ptw", "Pentlatch" },+	{ "pty", "Pathiya" },+	{ "pua", "Western Highland Purepecha" },+	{ "pub", "Purum" },+	{ "puc", "Punan Merap" },+	{ "pud", "Punan Aput" },+	{ "pue", "Puelche" },+	{ "puf", "Punan Merah" },+	{ "pug", "Phuie" },+	{ "pui", "Puinave" },+	{ "puj", "Punan Tubu" },+	{ "puk", "Pu Ko" },+	{ "pum", "Puma" },+	{ "puo", "Puoc" },+	{ "pup", "Pulabu" },+	{ "puq", "Puquina" },+	{ "pur", "Puruborá" },+	{ "pus", "Pushto" },+	{ "put", "Putoh" },+	{ "puu", "Punu" },+	{ "puw", "Puluwatese" },+	{ "pux", "Puare" },+	{ "puy", "Purisimeño" },+	{ "puz", "Purum Naga" },+	{ "pwa", "Pawaia" },+	{ "pwb", "Panawa" },+	{ "pwg", "Gapapaiwa" },+	{ "pwi", "Patwin" },+	{ "pwm", "Molbog" },+	{ "pwn", "Paiwan" },+	{ "pwo", "Pwo Western Karen" },+	{ "pwr", "Powari" },+	{ "pww", "Pwo Northern Karen" },+	{ "pxm", "Quetzaltepec Mixe" },+	{ "pye", "Pye Krumen" },+	{ "pym", "Fyam" },+	{ "pyn", "Poyanáwa" },+	{ "pys", "Paraguayan Sign Language" },+	{ "pyu", "Puyuma" },+	{ "pyx", "Pyu (Myanmar)" },+	{ "pyy", "Pyen" },+	{ "pzn", "Para Naga" },+	{ "qaa", "Reserved for local use" },+	{ "qab", "Reserved for local use" },+	{ "qac", "Reserved for local use" },+	{ "qad", "Reserved for local use" },+	{ "qae", "Reserved for local use" },+	{ "qaf", "Reserved for local use" },+	{ "qag", "Reserved for local use" },+	{ "qah", "Reserved for local use" },+	{ "qai", "Reserved for local use" },+	{ "qaj", "Reserved for local use" },+	{ "qak", "Reserved for local use" },+	{ "qal", "Reserved for local use" },+	{ "qam", "Reserved for local use" },+	{ "qan", "Reserved for local use" },+	{ "qao", "Reserved for local use" },+	{ "qap", "Reserved for local use" },+	{ "qaq", "Reserved for local use" },+	{ "qar", "Reserved for local use" },+	{ "qas", "Reserved for local use" },+	{ "qat", "Reserved for local use" },+	{ "qau", "Reserved for local use" },+	{ "qav", "Reserved for local use" },+	{ "qaw", "Reserved for local use" },+	{ "qax", "Reserved for local use" },+	{ "qay", "Reserved for local use" },+	{ "qaz", "Reserved for local use" },+	{ "qba", "Reserved for local use" },+	{ "qbb", "Reserved for local use" },+	{ "qbc", "Reserved for local use" },+	{ "qbd", "Reserved for local use" },+	{ "qbe", "Reserved for local use" },+	{ "qbf", "Reserved for local use" },+	{ "qbg", "Reserved for local use" },+	{ "qbh", "Reserved for local use" },+	{ "qbi", "Reserved for local use" },+	{ "qbj", "Reserved for local use" },+	{ "qbk", "Reserved for local use" },+	{ "qbl", "Reserved for local use" },+	{ "qbm", "Reserved for local use" },+	{ "qbn", "Reserved for local use" },+	{ "qbo", "Reserved for local use" },+	{ "qbp", "Reserved for local use" },+	{ "qbq", "Reserved for local use" },+	{ "qbr", "Reserved for local use" },+	{ "qbs", "Reserved for local use" },+	{ "qbt", "Reserved for local use" },+	{ "qbu", "Reserved for local use" },+	{ "qbv", "Reserved for local use" },+	{ "qbw", "Reserved for local use" },+	{ "qbx", "Reserved for local use" },+	{ "qby", "Reserved for local use" },+	{ "qbz", "Reserved for local use" },+	{ "qca", "Reserved for local use" },+	{ "qcb", "Reserved for local use" },+	{ "qcc", "Reserved for local use" },+	{ "qcd", "Reserved for local use" },+	{ "qce", "Reserved for local use" },+	{ "qcf", "Reserved for local use" },+	{ "qcg", "Reserved for local use" },+	{ "qch", "Reserved for local use" },+	{ "qci", "Reserved for local use" },+	{ "qcj", "Reserved for local use" },+	{ "qck", "Reserved for local use" },+	{ "qcl", "Reserved for local use" },+	{ "qcm", "Reserved for local use" },+	{ "qcn", "Reserved for local use" },+	{ "qco", "Reserved for local use" },+	{ "qcp", "Reserved for local use" },+	{ "qcq", "Reserved for local use" },+	{ "qcr", "Reserved for local use" },+	{ "qcs", "Reserved for local use" },+	{ "qct", "Reserved for local use" },+	{ "qcu", "Reserved for local use" },+	{ "qcv", "Reserved for local use" },+	{ "qcw", "Reserved for local use" },+	{ "qcx", "Reserved for local use" },+	{ "qcy", "Reserved for local use" },+	{ "qcz", "Reserved for local use" },+	{ "qda", "Reserved for local use" },+	{ "qdb", "Reserved for local use" },+	{ "qdc", "Reserved for local use" },+	{ "qdd", "Reserved for local use" },+	{ "qde", "Reserved for local use" },+	{ "qdf", "Reserved for local use" },+	{ "qdg", "Reserved for local use" },+	{ "qdh", "Reserved for local use" },+	{ "qdi", "Reserved for local use" },+	{ "qdj", "Reserved for local use" },+	{ "qdk", "Reserved for local use" },+	{ "qdl", "Reserved for local use" },+	{ "qdm", "Reserved for local use" },+	{ "qdn", "Reserved for local use" },+	{ "qdo", "Reserved for local use" },+	{ "qdp", "Reserved for local use" },+	{ "qdq", "Reserved for local use" },+	{ "qdr", "Reserved for local use" },+	{ "qds", "Reserved for local use" },+	{ "qdt", "Reserved for local use" },+	{ "qdu", "Reserved for local use" },+	{ "qdv", "Reserved for local use" },+	{ "qdw", "Reserved for local use" },+	{ "qdx", "Reserved for local use" },+	{ "qdy", "Reserved for local use" },+	{ "qdz", "Reserved for local use" },+	{ "qea", "Reserved for local use" },+	{ "qeb", "Reserved for local use" },+	{ "qec", "Reserved for local use" },+	{ "qed", "Reserved for local use" },+	{ "qee", "Reserved for local use" },+	{ "qef", "Reserved for local use" },+	{ "qeg", "Reserved for local use" },+	{ "qeh", "Reserved for local use" },+	{ "qei", "Reserved for local use" },+	{ "qej", "Reserved for local use" },+	{ "qek", "Reserved for local use" },+	{ "qel", "Reserved for local use" },+	{ "qem", "Reserved for local use" },+	{ "qen", "Reserved for local use" },+	{ "qeo", "Reserved for local use" },+	{ "qep", "Reserved for local use" },+	{ "qeq", "Reserved for local use" },+	{ "qer", "Reserved for local use" },+	{ "qes", "Reserved for local use" },+	{ "qet", "Reserved for local use" },+	{ "qeu", "Reserved for local use" },+	{ "qev", "Reserved for local use" },+	{ "qew", "Reserved for local use" },+	{ "qex", "Reserved for local use" },+	{ "qey", "Reserved for local use" },+	{ "qez", "Reserved for local use" },+	{ "qfa", "Reserved for local use" },+	{ "qfb", "Reserved for local use" },+	{ "qfc", "Reserved for local use" },+	{ "qfd", "Reserved for local use" },+	{ "qfe", "Reserved for local use" },+	{ "qff", "Reserved for local use" },+	{ "qfg", "Reserved for local use" },+	{ "qfh", "Reserved for local use" },+	{ "qfi", "Reserved for local use" },+	{ "qfj", "Reserved for local use" },+	{ "qfk", "Reserved for local use" },+	{ "qfl", "Reserved for local use" },+	{ "qfm", "Reserved for local use" },+	{ "qfn", "Reserved for local use" },+	{ "qfo", "Reserved for local use" },+	{ "qfp", "Reserved for local use" },+	{ "qfq", "Reserved for local use" },+	{ "qfr", "Reserved for local use" },+	{ "qfs", "Reserved for local use" },+	{ "qft", "Reserved for local use" },+	{ "qfu", "Reserved for local use" },+	{ "qfv", "Reserved for local use" },+	{ "qfw", "Reserved for local use" },+	{ "qfx", "Reserved for local use" },+	{ "qfy", "Reserved for local use" },+	{ "qfz", "Reserved for local use" },+	{ "qga", "Reserved for local use" },+	{ "qgb", "Reserved for local use" },+	{ "qgc", "Reserved for local use" },+	{ "qgd", "Reserved for local use" },+	{ "qge", "Reserved for local use" },+	{ "qgf", "Reserved for local use" },+	{ "qgg", "Reserved for local use" },+	{ "qgh", "Reserved for local use" },+	{ "qgi", "Reserved for local use" },+	{ "qgj", "Reserved for local use" },+	{ "qgk", "Reserved for local use" },+	{ "qgl", "Reserved for local use" },+	{ "qgm", "Reserved for local use" },+	{ "qgn", "Reserved for local use" },+	{ "qgo", "Reserved for local use" },+	{ "qgp", "Reserved for local use" },+	{ "qgq", "Reserved for local use" },+	{ "qgr", "Reserved for local use" },+	{ "qgs", "Reserved for local use" },+	{ "qgt", "Reserved for local use" },+	{ "qgu", "Reserved for local use" },+	{ "qgv", "Reserved for local use" },+	{ "qgw", "Reserved for local use" },+	{ "qgx", "Reserved for local use" },+	{ "qgy", "Reserved for local use" },+	{ "qgz", "Reserved for local use" },+	{ "qha", "Reserved for local use" },+	{ "qhb", "Reserved for local use" },+	{ "qhc", "Reserved for local use" },+	{ "qhd", "Reserved for local use" },+	{ "qhe", "Reserved for local use" },+	{ "qhf", "Reserved for local use" },+	{ "qhg", "Reserved for local use" },+	{ "qhh", "Reserved for local use" },+	{ "qhi", "Reserved for local use" },+	{ "qhj", "Reserved for local use" },+	{ "qhk", "Reserved for local use" },+	{ "qhl", "Reserved for local use" },+	{ "qhm", "Reserved for local use" },+	{ "qhn", "Reserved for local use" },+	{ "qho", "Reserved for local use" },+	{ "qhp", "Reserved for local use" },+	{ "qhq", "Reserved for local use" },+	{ "qhr", "Reserved for local use" },+	{ "qhs", "Reserved for local use" },+	{ "qht", "Reserved for local use" },+	{ "qhu", "Reserved for local use" },+	{ "qhv", "Reserved for local use" },+	{ "qhw", "Reserved for local use" },+	{ "qhx", "Reserved for local use" },+	{ "qhy", "Reserved for local use" },+	{ "qhz", "Reserved for local use" },+	{ "qia", "Reserved for local use" },+	{ "qib", "Reserved for local use" },+	{ "qic", "Reserved for local use" },+	{ "qid", "Reserved for local use" },+	{ "qie", "Reserved for local use" },+	{ "qif", "Reserved for local use" },+	{ "qig", "Reserved for local use" },+	{ "qih", "Reserved for local use" },+	{ "qii", "Reserved for local use" },+	{ "qij", "Reserved for local use" },+	{ "qik", "Reserved for local use" },+	{ "qil", "Reserved for local use" },+	{ "qim", "Reserved for local use" },+	{ "qin", "Reserved for local use" },+	{ "qio", "Reserved for local use" },+	{ "qip", "Reserved for local use" },+	{ "qiq", "Reserved for local use" },+	{ "qir", "Reserved for local use" },+	{ "qis", "Reserved for local use" },+	{ "qit", "Reserved for local use" },+	{ "qiu", "Reserved for local use" },+	{ "qiv", "Reserved for local use" },+	{ "qiw", "Reserved for local use" },+	{ "qix", "Reserved for local use" },+	{ "qiy", "Reserved for local use" },+	{ "qiz", "Reserved for local use" },+	{ "qja", "Reserved for local use" },+	{ "qjb", "Reserved for local use" },+	{ "qjc", "Reserved for local use" },+	{ "qjd", "Reserved for local use" },+	{ "qje", "Reserved for local use" },+	{ "qjf", "Reserved for local use" },+	{ "qjg", "Reserved for local use" },+	{ "qjh", "Reserved for local use" },+	{ "qji", "Reserved for local use" },+	{ "qjj", "Reserved for local use" },+	{ "qjk", "Reserved for local use" },+	{ "qjl", "Reserved for local use" },+	{ "qjm", "Reserved for local use" },+	{ "qjn", "Reserved for local use" },+	{ "qjo", "Reserved for local use" },+	{ "qjp", "Reserved for local use" },+	{ "qjq", "Reserved for local use" },+	{ "qjr", "Reserved for local use" },+	{ "qjs", "Reserved for local use" },+	{ "qjt", "Reserved for local use" },+	{ "qju", "Reserved for local use" },+	{ "qjv", "Reserved for local use" },+	{ "qjw", "Reserved for local use" },+	{ "qjx", "Reserved for local use" },+	{ "qjy", "Reserved for local use" },+	{ "qjz", "Reserved for local use" },+	{ "qka", "Reserved for local use" },+	{ "qkb", "Reserved for local use" },+	{ "qkc", "Reserved for local use" },+	{ "qkd", "Reserved for local use" },+	{ "qke", "Reserved for local use" },+	{ "qkf", "Reserved for local use" },+	{ "qkg", "Reserved for local use" },+	{ "qkh", "Reserved for local use" },+	{ "qki", "Reserved for local use" },+	{ "qkj", "Reserved for local use" },+	{ "qkk", "Reserved for local use" },+	{ "qkl", "Reserved for local use" },+	{ "qkm", "Reserved for local use" },+	{ "qkn", "Reserved for local use" },+	{ "qko", "Reserved for local use" },+	{ "qkp", "Reserved for local use" },+	{ "qkq", "Reserved for local use" },+	{ "qkr", "Reserved for local use" },+	{ "qks", "Reserved for local use" },+	{ "qkt", "Reserved for local use" },+	{ "qku", "Reserved for local use" },+	{ "qkv", "Reserved for local use" },+	{ "qkw", "Reserved for local use" },+	{ "qkx", "Reserved for local use" },+	{ "qky", "Reserved for local use" },+	{ "qkz", "Reserved for local use" },+	{ "qla", "Reserved for local use" },+	{ "qlb", "Reserved for local use" },+	{ "qlc", "Reserved for local use" },+	{ "qld", "Reserved for local use" },+	{ "qle", "Reserved for local use" },+	{ "qlf", "Reserved for local use" },+	{ "qlg", "Reserved for local use" },+	{ "qlh", "Reserved for local use" },+	{ "qli", "Reserved for local use" },+	{ "qlj", "Reserved for local use" },+	{ "qlk", "Reserved for local use" },+	{ "qll", "Reserved for local use" },+	{ "qlm", "Reserved for local use" },+	{ "qln", "Reserved for local use" },+	{ "qlo", "Reserved for local use" },+	{ "qlp", "Reserved for local use" },+	{ "qlq", "Reserved for local use" },+	{ "qlr", "Reserved for local use" },+	{ "qls", "Reserved for local use" },+	{ "qlt", "Reserved for local use" },+	{ "qlu", "Reserved for local use" },+	{ "qlv", "Reserved for local use" },+	{ "qlw", "Reserved for local use" },+	{ "qlx", "Reserved for local use" },+	{ "qly", "Reserved for local use" },+	{ "qlz", "Reserved for local use" },+	{ "qma", "Reserved for local use" },+	{ "qmb", "Reserved for local use" },+	{ "qmc", "Reserved for local use" },+	{ "qmd", "Reserved for local use" },+	{ "qme", "Reserved for local use" },+	{ "qmf", "Reserved for local use" },+	{ "qmg", "Reserved for local use" },+	{ "qmh", "Reserved for local use" },+	{ "qmi", "Reserved for local use" },+	{ "qmj", "Reserved for local use" },+	{ "qmk", "Reserved for local use" },+	{ "qml", "Reserved for local use" },+	{ "qmm", "Reserved for local use" },+	{ "qmn", "Reserved for local use" },+	{ "qmo", "Reserved for local use" },+	{ "qmp", "Reserved for local use" },+	{ "qmq", "Reserved for local use" },+	{ "qmr", "Reserved for local use" },+	{ "qms", "Reserved for local use" },+	{ "qmt", "Reserved for local use" },+	{ "qmu", "Reserved for local use" },+	{ "qmv", "Reserved for local use" },+	{ "qmw", "Reserved for local use" },+	{ "qmx", "Reserved for local use" },+	{ "qmy", "Reserved for local use" },+	{ "qmz", "Reserved for local use" },+	{ "qna", "Reserved for local use" },+	{ "qnb", "Reserved for local use" },+	{ "qnc", "Reserved for local use" },+	{ "qnd", "Reserved for local use" },+	{ "qne", "Reserved for local use" },+	{ "qnf", "Reserved for local use" },+	{ "qng", "Reserved for local use" },+	{ "qnh", "Reserved for local use" },+	{ "qni", "Reserved for local use" },+	{ "qnj", "Reserved for local use" },+	{ "qnk", "Reserved for local use" },+	{ "qnl", "Reserved for local use" },+	{ "qnm", "Reserved for local use" },+	{ "qnn", "Reserved for local use" },+	{ "qno", "Reserved for local use" },+	{ "qnp", "Reserved for local use" },+	{ "qnq", "Reserved for local use" },+	{ "qnr", "Reserved for local use" },+	{ "qns", "Reserved for local use" },+	{ "qnt", "Reserved for local use" },+	{ "qnu", "Reserved for local use" },+	{ "qnv", "Reserved for local use" },+	{ "qnw", "Reserved for local use" },+	{ "qnx", "Reserved for local use" },+	{ "qny", "Reserved for local use" },+	{ "qnz", "Reserved for local use" },+	{ "qoa", "Reserved for local use" },+	{ "qob", "Reserved for local use" },+	{ "qoc", "Reserved for local use" },+	{ "qod", "Reserved for local use" },+	{ "qoe", "Reserved for local use" },+	{ "qof", "Reserved for local use" },+	{ "qog", "Reserved for local use" },+	{ "qoh", "Reserved for local use" },+	{ "qoi", "Reserved for local use" },+	{ "qoj", "Reserved for local use" },+	{ "qok", "Reserved for local use" },+	{ "qol", "Reserved for local use" },+	{ "qom", "Reserved for local use" },+	{ "qon", "Reserved for local use" },+	{ "qoo", "Reserved for local use" },+	{ "qop", "Reserved for local use" },+	{ "qoq", "Reserved for local use" },+	{ "qor", "Reserved for local use" },+	{ "qos", "Reserved for local use" },+	{ "qot", "Reserved for local use" },+	{ "qou", "Reserved for local use" },+	{ "qov", "Reserved for local use" },+	{ "qow", "Reserved for local use" },+	{ "qox", "Reserved for local use" },+	{ "qoy", "Reserved for local use" },+	{ "qoz", "Reserved for local use" },+	{ "qpa", "Reserved for local use" },+	{ "qpb", "Reserved for local use" },+	{ "qpc", "Reserved for local use" },+	{ "qpd", "Reserved for local use" },+	{ "qpe", "Reserved for local use" },+	{ "qpf", "Reserved for local use" },+	{ "qpg", "Reserved for local use" },+	{ "qph", "Reserved for local use" },+	{ "qpi", "Reserved for local use" },+	{ "qpj", "Reserved for local use" },+	{ "qpk", "Reserved for local use" },+	{ "qpl", "Reserved for local use" },+	{ "qpm", "Reserved for local use" },+	{ "qpn", "Reserved for local use" },+	{ "qpo", "Reserved for local use" },+	{ "qpp", "Reserved for local use" },+	{ "qpq", "Reserved for local use" },+	{ "qpr", "Reserved for local use" },+	{ "qps", "Reserved for local use" },+	{ "qpt", "Reserved for local use" },+	{ "qpu", "Reserved for local use" },+	{ "qpv", "Reserved for local use" },+	{ "qpw", "Reserved for local use" },+	{ "qpx", "Reserved for local use" },+	{ "qpy", "Reserved for local use" },+	{ "qpz", "Reserved for local use" },+	{ "qqa", "Reserved for local use" },+	{ "qqb", "Reserved for local use" },+	{ "qqc", "Reserved for local use" },+	{ "qqd", "Reserved for local use" },+	{ "qqe", "Reserved for local use" },+	{ "qqf", "Reserved for local use" },+	{ "qqg", "Reserved for local use" },+	{ "qqh", "Reserved for local use" },+	{ "qqi", "Reserved for local use" },+	{ "qqj", "Reserved for local use" },+	{ "qqk", "Reserved for local use" },+	{ "qql", "Reserved for local use" },+	{ "qqm", "Reserved for local use" },+	{ "qqn", "Reserved for local use" },+	{ "qqo", "Reserved for local use" },+	{ "qqp", "Reserved for local use" },+	{ "qqq", "Reserved for local use" },+	{ "qqr", "Reserved for local use" },+	{ "qqs", "Reserved for local use" },+	{ "qqt", "Reserved for local use" },+	{ "qqu", "Reserved for local use" },+	{ "qqv", "Reserved for local use" },+	{ "qqw", "Reserved for local use" },+	{ "qqx", "Reserved for local use" },+	{ "qqy", "Reserved for local use" },+	{ "qqz", "Reserved for local use" },+	{ "qra", "Reserved for local use" },+	{ "qrb", "Reserved for local use" },+	{ "qrc", "Reserved for local use" },+	{ "qrd", "Reserved for local use" },+	{ "qre", "Reserved for local use" },+	{ "qrf", "Reserved for local use" },+	{ "qrg", "Reserved for local use" },+	{ "qrh", "Reserved for local use" },+	{ "qri", "Reserved for local use" },+	{ "qrj", "Reserved for local use" },+	{ "qrk", "Reserved for local use" },+	{ "qrl", "Reserved for local use" },+	{ "qrm", "Reserved for local use" },+	{ "qrn", "Reserved for local use" },+	{ "qro", "Reserved for local use" },+	{ "qrp", "Reserved for local use" },+	{ "qrq", "Reserved for local use" },+	{ "qrr", "Reserved for local use" },+	{ "qrs", "Reserved for local use" },+	{ "qrt", "Reserved for local use" },+	{ "qru", "Reserved for local use" },+	{ "qrv", "Reserved for local use" },+	{ "qrw", "Reserved for local use" },+	{ "qrx", "Reserved for local use" },+	{ "qry", "Reserved for local use" },+	{ "qrz", "Reserved for local use" },+	{ "qsa", "Reserved for local use" },+	{ "qsb", "Reserved for local use" },+	{ "qsc", "Reserved for local use" },+	{ "qsd", "Reserved for local use" },+	{ "qse", "Reserved for local use" },+	{ "qsf", "Reserved for local use" },+	{ "qsg", "Reserved for local use" },+	{ "qsh", "Reserved for local use" },+	{ "qsi", "Reserved for local use" },+	{ "qsj", "Reserved for local use" },+	{ "qsk", "Reserved for local use" },+	{ "qsl", "Reserved for local use" },+	{ "qsm", "Reserved for local use" },+	{ "qsn", "Reserved for local use" },+	{ "qso", "Reserved for local use" },+	{ "qsp", "Reserved for local use" },+	{ "qsq", "Reserved for local use" },+	{ "qsr", "Reserved for local use" },+	{ "qss", "Reserved for local use" },+	{ "qst", "Reserved for local use" },+	{ "qsu", "Reserved for local use" },+	{ "qsv", "Reserved for local use" },+	{ "qsw", "Reserved for local use" },+	{ "qsx", "Reserved for local use" },+	{ "qsy", "Reserved for local use" },+	{ "qsz", "Reserved for local use" },+	{ "qta", "Reserved for local use" },+	{ "qtb", "Reserved for local use" },+	{ "qtc", "Reserved for local use" },+	{ "qtd", "Reserved for local use" },+	{ "qte", "Reserved for local use" },+	{ "qtf", "Reserved for local use" },+	{ "qtg", "Reserved for local use" },+	{ "qth", "Reserved for local use" },+	{ "qti", "Reserved for local use" },+	{ "qtj", "Reserved for local use" },+	{ "qtk", "Reserved for local use" },+	{ "qtl", "Reserved for local use" },+	{ "qtm", "Reserved for local use" },+	{ "qtn", "Reserved for local use" },+	{ "qto", "Reserved for local use" },+	{ "qtp", "Reserved for local use" },+	{ "qtq", "Reserved for local use" },+	{ "qtr", "Reserved for local use" },+	{ "qts", "Reserved for local use" },+	{ "qtt", "Reserved for local use" },+	{ "qtu", "Reserved for local use" },+	{ "qtv", "Reserved for local use" },+	{ "qtw", "Reserved for local use" },+	{ "qtx", "Reserved for local use" },+	{ "qty", "Reserved for local use" },+	{ "qtz", "Reserved for local use" },+	{ "qua", "Quapaw" },+	{ "qub", "Huallaga Huánuco Quechua" },+	{ "quc", "K'iche'" },+	{ "qud", "Calderón Highland Quichua" },+	{ "que", "Quechua" },+	{ "quf", "Lambayeque Quechua" },+	{ "qug", "Chimborazo Highland Quichua" },+	{ "quh", "South Bolivian Quechua" },+	{ "qui", "Quileute" },+	{ "quk", "Chachapoyas Quechua" },+	{ "qul", "North Bolivian Quechua" },+	{ "qum", "Sipacapense" },+	{ "qun", "Quinault" },+	{ "qup", "Southern Pastaza Quechua" },+	{ "quq", "Quinqui" },+	{ "qur", "Yanahuanca Pasco Quechua" },+	{ "qus", "Santiago del Estero Quichua" },+	{ "quv", "Sacapulteco" },+	{ "quw", "Tena Lowland Quichua" },+	{ "qux", "Yauyos Quechua" },+	{ "quy", "Ayacucho Quechua" },+	{ "quz", "Cusco Quechua" },+	{ "qva", "Ambo-Pasco Quechua" },+	{ "qvc", "Cajamarca Quechua" },+	{ "qve", "Eastern Apurímac Quechua" },+	{ "qvh", "Huamalíes-Dos de Mayo Huánuco Quechua" },+	{ "qvi", "Imbabura Highland Quichua" },+	{ "qvj", "Loja Highland Quichua" },+	{ "qvl", "Cajatambo North Lima Quechua" },+	{ "qvm", "Margos-Yarowilca-Lauricocha Quechua" },+	{ "qvn", "North Junín Quechua" },+	{ "qvo", "Napo Lowland Quechua" },+	{ "qvp", "Pacaraos Quechua" },+	{ "qvs", "San Martín Quechua" },+	{ "qvw", "Huaylla Wanca Quechua" },+	{ "qvy", "Queyu" },+	{ "qvz", "Northern Pastaza Quichua" },+	{ "qwa", "Corongo Ancash Quechua" },+	{ "qwc", "Classical Quechua" },+	{ "qwh", "Huaylas Ancash Quechua" },+	{ "qwm", "Kuman (Russia)" },+	{ "qws", "Sihuas Ancash Quechua" },+	{ "qwt", "Kwalhioqua-Tlatskanai" },+	{ "qxa", "Chiquián Ancash Quechua" },+	{ "qxc", "Chincha Quechua" },+	{ "qxh", "Panao Huánuco Quechua" },+	{ "qxl", "Salasaca Highland Quichua" },+	{ "qxn", "Northern Conchucos Ancash Quechua" },+	{ "qxo", "Southern Conchucos Ancash Quechua" },+	{ "qxp", "Puno Quechua" },+	{ "qxq", "Qashqa'i" },+	{ "qxr", "Cañar Highland Quichua" },+	{ "qxs", "Southern Qiang" },+	{ "qxt", "Santa Ana de Tusi Pasco Quechua" },+	{ "qxu", "Arequipa-La Unión Quechua" },+	{ "qxw", "Jauja Wanca Quechua" },+	{ "qya", "Quenya" },+	{ "qyp", "Quiripi" },+	{ "raa", "Dungmali" },+	{ "rab", "Camling" },+	{ "rac", "Rasawa" },+	{ "rad", "Rade" },+	{ "raf", "Western Meohang" },+	{ "rag", "Logooli" },+	{ "rah", "Rabha" },+	{ "rai", "Ramoaaina" },+	{ "raj", "Rajasthani" },+	{ "rak", "Tulu-Bohuai" },+	{ "ral", "Ralte" },+	{ "ram", "Canela" },+	{ "ran", "Riantana" },+	{ "rao", "Rao" },+	{ "rap", "Rapanui" },+	{ "raq", "Saam" },+	{ "rar", "Rarotongan" },+	{ "ras", "Tegali" },+	{ "rat", "Razajerdi" },+	{ "rau", "Raute" },+	{ "rav", "Sampang" },+	{ "raw", "Rawang" },+	{ "rax", "Rang" },+	{ "ray", "Rapa" },+	{ "raz", "Rahambuu" },+	{ "rbb", "Rumai Palaung" },+	{ "rbk", "Northern Bontok" },+	{ "rbl", "Miraya Bikol" },+	{ "rbp", "Barababaraba" },+	{ "rcf", "Réunion Creole French" },+	{ "rdb", "Rudbari" },+	{ "rea", "Rerau" },+	{ "reb", "Rembong" },+	{ "ree", "Rejang Kayan" },+	{ "reg", "Kara (Tanzania)" },+	{ "rei", "Reli" },+	{ "rej", "Rejang" },+	{ "rel", "Rendille" },+	{ "rem", "Remo" },+	{ "ren", "Rengao" },+	{ "rer", "Rer Bare" },+	{ "res", "Reshe" },+	{ "ret", "Retta" },+	{ "rey", "Reyesano" },+	{ "rga", "Roria" },+	{ "rge", "Romano-Greek" },+	{ "rgk", "Rangkas" },+	{ "rgn", "Romagnol" },+	{ "rgr", "Resígaro" },+	{ "rgs", "Southern Roglai" },+	{ "rgu", "Ringgou" },+	{ "rhg", "Rohingya" },+	{ "rhp", "Yahang" },+	{ "ria", "Riang (India)" },+	{ "rie", "Rien" },+	{ "rif", "Tarifit" },+	{ "ril", "Riang (Myanmar)" },+	{ "rim", "Nyaturu" },+	{ "rin", "Nungu" },+	{ "rir", "Ribun" },+	{ "rit", "Ritarungo" },+	{ "riu", "Riung" },+	{ "rjg", "Rajong" },+	{ "rji", "Raji" },+	{ "rjs", "Rajbanshi" },+	{ "rka", "Kraol" },+	{ "rkb", "Rikbaktsa" },+	{ "rkh", "Rakahanga-Manihiki" },+	{ "rki", "Rakhine" },+	{ "rkm", "Marka" },+	{ "rkt", "Rangpuri" },+	{ "rkw", "Arakwal" },+	{ "rma", "Rama" },+	{ "rmb", "Rembarunga" },+	{ "rmc", "Carpathian Romani" },+	{ "rmd", "Traveller Danish" },+	{ "rme", "Angloromani" },+	{ "rmf", "Kalo Finnish Romani" },+	{ "rmg", "Traveller Norwegian" },+	{ "rmh", "Murkim" },+	{ "rmi", "Lomavren" },+	{ "rmk", "Romkun" },+	{ "rml", "Baltic Romani" },+	{ "rmm", "Roma" },+	{ "rmn", "Balkan Romani" },+	{ "rmo", "Sinte Romani" },+	{ "rmp", "Rempi" },+	{ "rmq", "Caló" },+	{ "rms", "Romanian Sign Language" },+	{ "rmt", "Domari" },+	{ "rmu", "Tavringer Romani" },+	{ "rmv", "Romanova" },+	{ "rmw", "Welsh Romani" },+	{ "rmx", "Romam" },+	{ "rmy", "Vlax Romani" },+	{ "rmz", "Marma" },+	{ "rna", "Runa" },+	{ "rnd", "Ruund" },+	{ "rng", "Ronga" },+	{ "rnl", "Ranglong" },+	{ "rnn", "Roon" },+	{ "rnp", "Rongpo" },+	{ "rnr", "Nari Nari" },+	{ "rnw", "Rungwa" },+	{ "rob", "Tae'" },+	{ "roc", "Cacgia Roglai" },+	{ "rod", "Rogo" },+	{ "roe", "Ronji" },+	{ "rof", "Rombo" },+	{ "rog", "Northern Roglai" },+	{ "roh", "Romansh" },+	{ "rol", "Romblomanon" },+	{ "rom", "Romany" },+	{ "ron", "Romanian" },+	{ "roo", "Rotokas" },+	{ "rop", "Kriol" },+	{ "ror", "Rongga" },+	{ "rou", "Runga" },+	{ "row", "Dela-Oenale" },+	{ "rpn", "Repanbitip" },+	{ "rpt", "Rapting" },+	{ "rri", "Ririo" },+	{ "rro", "Waima" },+	{ "rrt", "Arritinngithigh" },+	{ "rsb", "Romano-Serbian" },+	{ "rsi", "Rennellese Sign Language" },+	{ "rsl", "Russian Sign Language" },+	{ "rtc", "Rungtu Chin" },+	{ "rth", "Ratahan" },+	{ "rtm", "Rotuman" },+	{ "rtw", "Rathawi" },+	{ "rub", "Gungu" },+	{ "ruc", "Ruuli" },+	{ "rue", "Rusyn" },+	{ "ruf", "Luguru" },+	{ "rug", "Roviana" },+	{ "ruh", "Ruga" },+	{ "rui", "Rufiji" },+	{ "ruk", "Che" },+	{ "run", "Rundi" },+	{ "ruo", "Istro Romanian" },+	{ "rup", "Macedo-Romanian" },+	{ "ruq", "Megleno Romanian" },+	{ "rus", "Russian" },+	{ "rut", "Rutul" },+	{ "ruu", "Lanas Lobu" },+	{ "ruy", "Mala (Nigeria)" },+	{ "ruz", "Ruma" },+	{ "rwa", "Rawo" },+	{ "rwk", "Rwa" },+	{ "rwm", "Amba (Uganda)" },+	{ "rwo", "Rawa" },+	{ "rwr", "Marwari (India)" },+	{ "rxd", "Ngardi" },+	{ "rxw", "Karuwali" },+	{ "ryn", "Northern Amami-Oshima" },+	{ "rys", "Yaeyama" },+	{ "ryu", "Central Okinawan" },+	{ "saa", "Saba" },+	{ "sab", "Buglere" },+	{ "sac", "Meskwaki" },+	{ "sad", "Sandawe" },+	{ "sae", "Sabanê" },+	{ "saf", "Safaliba" },+	{ "sag", "Sango" },+	{ "sah", "Yakut" },+	{ "saj", "Sahu" },+	{ "sak", "Sake" },+	{ "sam", "Samaritan Aramaic" },+	{ "san", "Sanskrit" },+	{ "sao", "Sause" },+	{ "sap", "Sanapaná" },+	{ "saq", "Samburu" },+	{ "sar", "Saraveca" },+	{ "sas", "Sasak" },+	{ "sat", "Santali" },+	{ "sau", "Saleman" },+	{ "sav", "Saafi-Saafi" },+	{ "saw", "Sawi" },+	{ "sax", "Sa" },+	{ "say", "Saya" },+	{ "saz", "Saurashtra" },+	{ "sba", "Ngambay" },+	{ "sbb", "Simbo" },+	{ "sbc", "Kele (Papua New Guinea)" },+	{ "sbd", "Southern Samo" },+	{ "sbe", "Saliba" },+	{ "sbf", "Shabo" },+	{ "sbg", "Seget" },+	{ "sbh", "Sori-Harengan" },+	{ "sbi", "Seti" },+	{ "sbj", "Surbakhal" },+	{ "sbk", "Safwa" },+	{ "sbl", "Botolan Sambal" },+	{ "sbm", "Sagala" },+	{ "sbn", "Sindhi Bhil" },+	{ "sbo", "Sabüm" },+	{ "sbp", "Sangu (Tanzania)" },+	{ "sbq", "Sileibi" },+	{ "sbr", "Sembakung Murut" },+	{ "sbs", "Subiya" },+	{ "sbt", "Kimki" },+	{ "sbu", "Stod Bhoti" },+	{ "sbv", "Sabine" },+	{ "sbw", "Simba" },+	{ "sbx", "Seberuang" },+	{ "sby", "Soli" },+	{ "sbz", "Sara Kaba" },+	{ "scb", "Chut" },+	{ "sce", "Dongxiang" },+	{ "scf", "San Miguel Creole French" },+	{ "scg", "Sanggau" },+	{ "sch", "Sakachep" },+	{ "sci", "Sri Lankan Creole Malay" },+	{ "sck", "Sadri" },+	{ "scl", "Shina" },+	{ "scn", "Sicilian" },+	{ "sco", "Scots" },+	{ "scp", "Helambu Sherpa" },+	{ "scq", "Sa'och" },+	{ "scs", "North Slavey" },+	{ "scu", "Shumcho" },+	{ "scv", "Sheni" },+	{ "scw", "Sha" },+	{ "scx", "Sicel" },+	{ "sda", "Toraja-Sa'dan" },+	{ "sdb", "Shabak" },+	{ "sdc", "Sassarese Sardinian" },+	{ "sde", "Surubu" },+	{ "sdf", "Sarli" },+	{ "sdg", "Savi" },+	{ "sdh", "Southern Kurdish" },+	{ "sdj", "Suundi" },+	{ "sdk", "Sos Kundi" },+	{ "sdl", "Saudi Arabian Sign Language" },+	{ "sdm", "Semandang" },+	{ "sdn", "Gallurese Sardinian" },+	{ "sdo", "Bukar-Sadung Bidayuh" },+	{ "sdp", "Sherdukpen" },+	{ "sdr", "Oraon Sadri" },+	{ "sds", "Sened" },+	{ "sdt", "Shuadit" },+	{ "sdu", "Sarudu" },+	{ "sdx", "Sibu Melanau" },+	{ "sdz", "Sallands" },+	{ "sea", "Semai" },+	{ "seb", "Shempire Senoufo" },+	{ "sec", "Sechelt" },+	{ "sed", "Sedang" },+	{ "see", "Seneca" },+	{ "sef", "Cebaara Senoufo" },+	{ "seg", "Segeju" },+	{ "seh", "Sena" },+	{ "sei", "Seri" },+	{ "sej", "Sene" },+	{ "sek", "Sekani" },+	{ "sel", "Selkup" },+	{ "sen", "Nanerigé Sénoufo" },+	{ "seo", "Suarmin" },+	{ "sep", "Sìcìté Sénoufo" },+	{ "seq", "Senara Sénoufo" },+	{ "ser", "Serrano" },+	{ "ses", "Koyraboro Senni Songhai" },+	{ "set", "Sentani" },+	{ "seu", "Serui-Laut" },+	{ "sev", "Nyarafolo Senoufo" },+	{ "sew", "Sewa Bay" },+	{ "sey", "Secoya" },+	{ "sez", "Senthang Chin" },+	{ "sfb", "Langue des signes de Belgique Francophone" },+	{ "sfe", "Eastern Subanen" },+	{ "sfm", "Small Flowery Miao" },+	{ "sfs", "South African Sign Language" },+	{ "sfw", "Sehwi" },+	{ "sga", "Old Irish (to 900)" },+	{ "sgb", "Mag-antsi Ayta" },+	{ "sgc", "Kipsigis" },+	{ "sgd", "Surigaonon" },+	{ "sge", "Segai" },+	{ "sgg", "Swiss-German Sign Language" },+	{ "sgh", "Shughni" },+	{ "sgi", "Suga" },+	{ "sgj", "Surgujia" },+	{ "sgk", "Sangkong" },+	{ "sgm", "Singa" },+	{ "sgo", "Songa" },+	{ "sgp", "Singpho" },+	{ "sgr", "Sangisari" },+	{ "sgs", "Samogitian" },+	{ "sgt", "Brokpake" },+	{ "sgu", "Salas" },+	{ "sgw", "Sebat Bet Gurage" },+	{ "sgx", "Sierra Leone Sign Language" },+	{ "sgy", "Sanglechi" },+	{ "sgz", "Sursurunga" },+	{ "sha", "Shall-Zwall" },+	{ "shb", "Ninam" },+	{ "shc", "Sonde" },+	{ "shd", "Kundal Shahi" },+	{ "she", "Sheko" },+	{ "shg", "Shua" },+	{ "shh", "Shoshoni" },+	{ "shi", "Tachelhit" },+	{ "shj", "Shatt" },+	{ "shk", "Shilluk" },+	{ "shl", "Shendu" },+	{ "shm", "Shahrudi" },+	{ "shn", "Shan" },+	{ "sho", "Shanga" },+	{ "shp", "Shipibo-Conibo" },+	{ "shq", "Sala" },+	{ "shr", "Shi" },+	{ "shs", "Shuswap" },+	{ "sht", "Shasta" },+	{ "shu", "Chadian Arabic" },+	{ "shv", "Shehri" },+	{ "shw", "Shwai" },+	{ "shx", "She" },+	{ "shy", "Tachawit" },+	{ "shz", "Syenara Senoufo" },+	{ "sia", "Akkala Sami" },+	{ "sib", "Sebop" },+	{ "sid", "Sidamo" },+	{ "sie", "Simaa" },+	{ "sif", "Siamou" },+	{ "sig", "Paasaal" },+	{ "sih", "Zire" },+	{ "sii", "Shom Peng" },+	{ "sij", "Numbami" },+	{ "sik", "Sikiana" },+	{ "sil", "Tumulung Sisaala" },+	{ "sim", "Mende (Papua New Guinea)" },+	{ "sin", "Sinhala" },+	{ "sip", "Sikkimese" },+	{ "siq", "Sonia" },+	{ "sir", "Siri" },+	{ "sis", "Siuslaw" },+	{ "siu", "Sinagen" },+	{ "siv", "Sumariup" },+	{ "siw", "Siwai" },+	{ "six", "Sumau" },+	{ "siy", "Sivandi" },+	{ "siz", "Siwi" },+	{ "sja", "Epena" },+	{ "sjb", "Sajau Basap" },+	{ "sjd", "Kildin Sami" },+	{ "sje", "Pite Sami" },+	{ "sjg", "Assangori" },+	{ "sjk", "Kemi Sami" },+	{ "sjl", "Sajalong" },+	{ "sjm", "Mapun" },+	{ "sjn", "Sindarin" },+	{ "sjo", "Xibe" },+	{ "sjp", "Surjapuri" },+	{ "sjr", "Siar-Lak" },+	{ "sjs", "Senhaja De Srair" },+	{ "sjt", "Ter Sami" },+	{ "sju", "Ume Sami" },+	{ "sjw", "Shawnee" },+	{ "ska", "Skagit" },+	{ "skb", "Saek" },+	{ "skc", "Ma Manda" },+	{ "skd", "Southern Sierra Miwok" },+	{ "ske", "Seke (Vanuatu)" },+	{ "skf", "Sakirabiá" },+	{ "skg", "Sakalava Malagasy" },+	{ "skh", "Sikule" },+	{ "ski", "Sika" },+	{ "skj", "Seke (Nepal)" },+	{ "skk", "Sok" },+	{ "skm", "Kutong" },+	{ "skn", "Kolibugan Subanon" },+	{ "sko", "Seko Tengah" },+	{ "skp", "Sekapan" },+	{ "skq", "Sininkere" },+	{ "skr", "Seraiki" },+	{ "sks", "Maia" },+	{ "skt", "Sakata" },+	{ "sku", "Sakao" },+	{ "skv", "Skou" },+	{ "skw", "Skepi Creole Dutch" },+	{ "skx", "Seko Padang" },+	{ "sky", "Sikaiana" },+	{ "skz", "Sekar" },+	{ "slc", "Sáliba" },+	{ "sld", "Sissala" },+	{ "sle", "Sholaga" },+	{ "slf", "Swiss-Italian Sign Language" },+	{ "slg", "Selungai Murut" },+	{ "slh", "Southern Puget Sound Salish" },+	{ "sli", "Lower Silesian" },+	{ "slj", "Salumá" },+	{ "slk", "Slovak" },+	{ "sll", "Salt-Yui" },+	{ "slm", "Pangutaran Sama" },+	{ "sln", "Salinan" },+	{ "slp", "Lamaholot" },+	{ "slq", "Salchuq" },+	{ "slr", "Salar" },+	{ "sls", "Singapore Sign Language" },+	{ "slt", "Sila" },+	{ "slu", "Selaru" },+	{ "slv", "Slovenian" },+	{ "slw", "Sialum" },+	{ "slx", "Salampasu" },+	{ "sly", "Selayar" },+	{ "slz", "Ma'ya" },+	{ "sma", "Southern Sami" },+	{ "smb", "Simbari" },+	{ "smc", "Som" },+	{ "smd", "Sama" },+	{ "sme", "Northern Sami" },+	{ "smf", "Auwe" },+	{ "smg", "Simbali" },+	{ "smh", "Samei" },+	{ "smj", "Lule Sami" },+	{ "smk", "Bolinao" },+	{ "sml", "Central Sama" },+	{ "smm", "Musasa" },+	{ "smn", "Inari Sami" },+	{ "smo", "Samoan" },+	{ "smp", "Samaritan" },+	{ "smq", "Samo" },+	{ "smr", "Simeulue" },+	{ "sms", "Skolt Sami" },+	{ "smt", "Simte" },+	{ "smu", "Somray" },+	{ "smv", "Samvedi" },+	{ "smw", "Sumbawa" },+	{ "smx", "Samba" },+	{ "smy", "Semnani" },+	{ "smz", "Simeku" },+	{ "sna", "Shona" },+	{ "snb", "Sebuyau" },+	{ "snc", "Sinaugoro" },+	{ "snd", "Sindhi" },+	{ "sne", "Bau Bidayuh" },+	{ "snf", "Noon" },+	{ "sng", "Sanga (Democratic Republic of Congo)" },+	{ "snh", "Shinabo" },+	{ "sni", "Sensi" },+	{ "snj", "Riverain Sango" },+	{ "snk", "Soninke" },+	{ "snl", "Sangil" },+	{ "snm", "Southern Ma'di" },+	{ "snn", "Siona" },+	{ "sno", "Snohomish" },+	{ "snp", "Siane" },+	{ "snq", "Sangu (Gabon)" },+	{ "snr", "Sihan" },+	{ "sns", "South West Bay" },+	{ "snu", "Senggi" },+	{ "snv", "Sa'ban" },+	{ "snw", "Selee" },+	{ "snx", "Sam" },+	{ "sny", "Saniyo-Hiyewe" },+	{ "snz", "Sinsauru" },+	{ "soa", "Thai Song" },+	{ "sob", "Sobei" },+	{ "soc", "So (Democratic Republic of Congo)" },+	{ "sod", "Songoora" },+	{ "soe", "Songomeno" },+	{ "sog", "Sogdian" },+	{ "soh", "Aka" },+	{ "soi", "Sonha" },+	{ "soj", "Soi" },+	{ "sok", "Sokoro" },+	{ "sol", "Solos" },+	{ "som", "Somali" },+	{ "soo", "Songo" },+	{ "sop", "Songe" },+	{ "soq", "Kanasi" },+	{ "sor", "Somrai" },+	{ "sos", "Seeku" },+	{ "sot", "Southern Sotho" },+	{ "sou", "Southern Thai" },+	{ "sov", "Sonsorol" },+	{ "sow", "Sowanda" },+	{ "sox", "Swo" },+	{ "soy", "Miyobe" },+	{ "soz", "Temi" },+	{ "spa", "Spanish" },+	{ "spb", "Sepa (Indonesia)" },+	{ "spc", "Sapé" },+	{ "spd", "Saep" },+	{ "spe", "Sepa (Papua New Guinea)" },+	{ "spg", "Sian" },+	{ "spi", "Saponi" },+	{ "spk", "Sengo" },+	{ "spl", "Selepet" },+	{ "spm", "Akukem" },+	{ "spo", "Spokane" },+	{ "spp", "Supyire Senoufo" },+	{ "spq", "Loreto-Ucayali Spanish" },+	{ "spr", "Saparua" },+	{ "sps", "Saposa" },+	{ "spt", "Spiti Bhoti" },+	{ "spu", "Sapuan" },+	{ "spv", "Sambalpuri" },+	{ "spx", "South Picene" },+	{ "spy", "Sabaot" },+	{ "sqa", "Shama-Sambuga" },+	{ "sqh", "Shau" },+	{ "sqi", "Albanian" },+	{ "sqk", "Albanian Sign Language" },+	{ "sqm", "Suma" },+	{ "sqn", "Susquehannock" },+	{ "sqo", "Sorkhei" },+	{ "sqq", "Sou" },+	{ "sqr", "Siculo Arabic" },+	{ "sqs", "Sri Lankan Sign Language" },+	{ "sqt", "Soqotri" },+	{ "squ", "Squamish" },+	{ "sra", "Saruga" },+	{ "srb", "Sora" },+	{ "src", "Logudorese Sardinian" },+	{ "srd", "Sardinian" },+	{ "sre", "Sara" },+	{ "srf", "Nafi" },+	{ "srg", "Sulod" },+	{ "srh", "Sarikoli" },+	{ "sri", "Siriano" },+	{ "srk", "Serudung Murut" },+	{ "srl", "Isirawa" },+	{ "srm", "Saramaccan" },+	{ "srn", "Sranan Tongo" },+	{ "sro", "Campidanese Sardinian" },+	{ "srp", "Serbian" },+	{ "srq", "Sirionó" },+	{ "srr", "Serer" },+	{ "srs", "Sarsi" },+	{ "srt", "Sauri" },+	{ "sru", "Suruí" },+	{ "srv", "Southern Sorsoganon" },+	{ "srw", "Serua" },+	{ "srx", "Sirmauri" },+	{ "sry", "Sera" },+	{ "srz", "Shahmirzadi" },+	{ "ssb", "Southern Sama" },+	{ "ssc", "Suba-Simbiti" },+	{ "ssd", "Siroi" },+	{ "sse", "Balangingi" },+	{ "ssf", "Thao" },+	{ "ssg", "Seimat" },+	{ "ssh", "Shihhi Arabic" },+	{ "ssi", "Sansi" },+	{ "ssj", "Sausi" },+	{ "ssk", "Sunam" },+	{ "ssl", "Western Sisaala" },+	{ "ssm", "Semnam" },+	{ "ssn", "Waata" },+	{ "sso", "Sissano" },+	{ "ssp", "Spanish Sign Language" },+	{ "ssq", "So'a" },+	{ "ssr", "Swiss-French Sign Language" },+	{ "sss", "Sô" },+	{ "sst", "Sinasina" },+	{ "ssu", "Susuami" },+	{ "ssv", "Shark Bay" },+	{ "ssw", "Swati" },+	{ "ssx", "Samberigi" },+	{ "ssy", "Saho" },+	{ "ssz", "Sengseng" },+	{ "sta", "Settla" },+	{ "stb", "Northern Subanen" },+	{ "std", "Sentinel" },+	{ "ste", "Liana-Seti" },+	{ "stf", "Seta" },+	{ "stg", "Trieng" },+	{ "sth", "Shelta" },+	{ "sti", "Bulo Stieng" },+	{ "stj", "Matya Samo" },+	{ "stk", "Arammba" },+	{ "stl", "Stellingwerfs" },+	{ "stm", "Setaman" },+	{ "stn", "Owa" },+	{ "sto", "Stoney" },+	{ "stp", "Southeastern Tepehuan" },+	{ "stq", "Saterfriesisch" },+	{ "str", "Straits Salish" },+	{ "sts", "Shumashti" },+	{ "stt", "Budeh Stieng" },+	{ "stu", "Samtao" },+	{ "stv", "Silt'e" },+	{ "stw", "Satawalese" },+	{ "sty", "Siberian Tatar" },+	{ "sua", "Sulka" },+	{ "sub", "Suku" },+	{ "suc", "Western Subanon" },+	{ "sue", "Suena" },+	{ "sug", "Suganga" },+	{ "sui", "Suki" },+	{ "suj", "Shubi" },+	{ "suk", "Sukuma" },+	{ "sun", "Sundanese" },+	{ "suq", "Suri" },+	{ "sur", "Mwaghavul" },+	{ "sus", "Susu" },+	{ "sut", "Subtiaba" },+	{ "suv", "Puroik" },+	{ "suw", "Sumbwa" },+	{ "sux", "Sumerian" },+	{ "suy", "Suyá" },+	{ "suz", "Sunwar" },+	{ "sva", "Svan" },+	{ "svb", "Ulau-Suain" },+	{ "svc", "Vincentian Creole English" },+	{ "sve", "Serili" },+	{ "svk", "Slovakian Sign Language" },+	{ "svm", "Slavomolisano" },+	{ "svr", "Savara" },+	{ "svs", "Savosavo" },+	{ "svx", "Skalvian" },+	{ "swa", "Swahili (macrolanguage)" },+	{ "swb", "Maore Comorian" },+	{ "swc", "Congo Swahili" },+	{ "swe", "Swedish" },+	{ "swf", "Sere" },+	{ "swg", "Swabian" },+	{ "swh", "Swahili (individual language)" },+	{ "swi", "Sui" },+	{ "swj", "Sira" },+	{ "swk", "Malawi Sena" },+	{ "swl", "Swedish Sign Language" },+	{ "swm", "Samosa" },+	{ "swn", "Sawknah" },+	{ "swo", "Shanenawa" },+	{ "swp", "Suau" },+	{ "swq", "Sharwa" },+	{ "swr", "Saweru" },+	{ "sws", "Seluwasan" },+	{ "swt", "Sawila" },+	{ "swu", "Suwawa" },+	{ "swv", "Shekhawati" },+	{ "sww", "Sowa" },+	{ "swx", "Suruahá" },+	{ "swy", "Sarua" },+	{ "sxb", "Suba" },+	{ "sxc", "Sicanian" },+	{ "sxe", "Sighu" },+	{ "sxg", "Shixing" },+	{ "sxk", "Southern Kalapuya" },+	{ "sxl", "Selian" },+	{ "sxm", "Samre" },+	{ "sxn", "Sangir" },+	{ "sxo", "Sorothaptic" },+	{ "sxr", "Saaroa" },+	{ "sxs", "Sasaru" },+	{ "sxu", "Upper Saxon" },+	{ "sxw", "Saxwe Gbe" },+	{ "sya", "Siang" },+	{ "syb", "Central Subanen" },+	{ "syc", "Classical Syriac" },+	{ "syi", "Seki" },+	{ "syk", "Sukur" },+	{ "syl", "Sylheti" },+	{ "sym", "Maya Samo" },+	{ "syn", "Senaya" },+	{ "syo", "Suoy" },+	{ "syr", "Syriac" },+	{ "sys", "Sinyar" },+	{ "syw", "Kagate" },+	{ "syy", "Al-Sayyid Bedouin Sign Language" },+	{ "sza", "Semelai" },+	{ "szb", "Ngalum" },+	{ "szc", "Semaq Beri" },+	{ "szd", "Seru" },+	{ "sze", "Seze" },+	{ "szg", "Sengele" },+	{ "szl", "Silesian" },+	{ "szn", "Sula" },+	{ "szp", "Suabo" },+	{ "szv", "Isu (Fako Division)" },+	{ "szw", "Sawai" },+	{ "taa", "Lower Tanana" },+	{ "tab", "Tabassaran" },+	{ "tac", "Lowland Tarahumara" },+	{ "tad", "Tause" },+	{ "tae", "Tariana" },+	{ "taf", "Tapirapé" },+	{ "tag", "Tagoi" },+	{ "tah", "Tahitian" },+	{ "taj", "Eastern Tamang" },+	{ "tak", "Tala" },+	{ "tal", "Tal" },+	{ "tam", "Tamil" },+	{ "tan", "Tangale" },+	{ "tao", "Yami" },+	{ "tap", "Taabwa" },+	{ "taq", "Tamasheq" },+	{ "tar", "Central Tarahumara" },+	{ "tas", "Tay Boi" },+	{ "tat", "Tatar" },+	{ "tau", "Upper Tanana" },+	{ "tav", "Tatuyo" },+	{ "taw", "Tai" },+	{ "tax", "Tamki" },+	{ "tay", "Atayal" },+	{ "taz", "Tocho" },+	{ "tba", "Aikanã" },+	{ "tbb", "Tapeba" },+	{ "tbc", "Takia" },+	{ "tbd", "Kaki Ae" },+	{ "tbe", "Tanimbili" },+	{ "tbf", "Mandara" },+	{ "tbg", "North Tairora" },+	{ "tbh", "Thurawal" },+	{ "tbi", "Gaam" },+	{ "tbj", "Tiang" },+	{ "tbk", "Calamian Tagbanwa" },+	{ "tbl", "Tboli" },+	{ "tbm", "Tagbu" },+	{ "tbn", "Barro Negro Tunebo" },+	{ "tbo", "Tawala" },+	{ "tbp", "Taworta" },+	{ "tbr", "Tumtum" },+	{ "tbs", "Tanguat" },+	{ "tbt", "Tembo (Kitembo)" },+	{ "tbu", "Tubar" },+	{ "tbv", "Tobo" },+	{ "tbw", "Tagbanwa" },+	{ "tbx", "Kapin" },+	{ "tby", "Tabaru" },+	{ "tbz", "Ditammari" },+	{ "tca", "Ticuna" },+	{ "tcb", "Tanacross" },+	{ "tcc", "Datooga" },+	{ "tcd", "Tafi" },+	{ "tce", "Southern Tutchone" },+	{ "tcf", "Malinaltepec Me'phaa" },+	{ "tcg", "Tamagario" },+	{ "tch", "Turks And Caicos Creole English" },+	{ "tci", "Wára" },+	{ "tck", "Tchitchege" },+	{ "tcl", "Taman (Myanmar)" },+	{ "tcm", "Tanahmerah" },+	{ "tcn", "Tichurong" },+	{ "tco", "Taungyo" },+	{ "tcp", "Tawr Chin" },+	{ "tcq", "Kaiy" },+	{ "tcs", "Torres Strait Creole" },+	{ "tct", "T'en" },+	{ "tcu", "Southeastern Tarahumara" },+	{ "tcw", "Tecpatlán Totonac" },+	{ "tcx", "Toda" },+	{ "tcy", "Tulu" },+	{ "tcz", "Thado Chin" },+	{ "tda", "Tagdal" },+	{ "tdb", "Panchpargania" },+	{ "tdc", "Emberá-Tadó" },+	{ "tdd", "Tai Nüa" },+	{ "tde", "Tiranige Diga Dogon" },+	{ "tdf", "Talieng" },+	{ "tdg", "Western Tamang" },+	{ "tdh", "Thulung" },+	{ "tdi", "Tomadino" },+	{ "tdj", "Tajio" },+	{ "tdk", "Tambas" },+	{ "tdl", "Sur" },+	{ "tdn", "Tondano" },+	{ "tdo", "Teme" },+	{ "tdq", "Tita" },+	{ "tdr", "Todrah" },+	{ "tds", "Doutai" },+	{ "tdt", "Tetun Dili" },+	{ "tdu", "Tempasuk Dusun" },+	{ "tdv", "Toro" },+	{ "tdx", "Tandroy-Mahafaly Malagasy" },+	{ "tdy", "Tadyawan" },+	{ "tea", "Temiar" },+	{ "teb", "Tetete" },+	{ "tec", "Terik" },+	{ "ted", "Tepo Krumen" },+	{ "tee", "Huehuetla Tepehua" },+	{ "tef", "Teressa" },+	{ "teg", "Teke-Tege" },+	{ "teh", "Tehuelche" },+	{ "tei", "Torricelli" },+	{ "tek", "Ibali Teke" },+	{ "tel", "Telugu" },+	{ "tem", "Timne" },+	{ "ten", "Tama (Colombia)" },+	{ "teo", "Teso" },+	{ "tep", "Tepecano" },+	{ "teq", "Temein" },+	{ "ter", "Tereno" },+	{ "tes", "Tengger" },+	{ "tet", "Tetum" },+	{ "teu", "Soo" },+	{ "tev", "Teor" },+	{ "tew", "Tewa (USA)" },+	{ "tex", "Tennet" },+	{ "tey", "Tulishi" },+	{ "tfi", "Tofin Gbe" },+	{ "tfn", "Tanaina" },+	{ "tfo", "Tefaro" },+	{ "tfr", "Teribe" },+	{ "tft", "Ternate" },+	{ "tga", "Sagalla" },+	{ "tgb", "Tobilung" },+	{ "tgc", "Tigak" },+	{ "tgd", "Ciwogai" },+	{ "tge", "Eastern Gorkha Tamang" },+	{ "tgf", "Chalikha" },+	{ "tgh", "Tobagonian Creole English" },+	{ "tgi", "Lawunuia" },+	{ "tgj", "Tagin" },+	{ "tgk", "Tajik" },+	{ "tgl", "Tagalog" },+	{ "tgn", "Tandaganon" },+	{ "tgo", "Sudest" },+	{ "tgp", "Tangoa" },+	{ "tgq", "Tring" },+	{ "tgr", "Tareng" },+	{ "tgs", "Nume" },+	{ "tgt", "Central Tagbanwa" },+	{ "tgu", "Tanggu" },+	{ "tgv", "Tingui-Boto" },+	{ "tgw", "Tagwana Senoufo" },+	{ "tgx", "Tagish" },+	{ "tgy", "Togoyo" },+	{ "tgz", "Tagalaka" },+	{ "tha", "Thai" },+	{ "thc", "Tai Hang Tong" },+	{ "thd", "Thayore" },+	{ "the", "Chitwania Tharu" },+	{ "thf", "Thangmi" },+	{ "thh", "Northern Tarahumara" },+	{ "thi", "Tai Long" },+	{ "thk", "Tharaka" },+	{ "thl", "Dangaura Tharu" },+	{ "thm", "Aheu" },+	{ "thn", "Thachanadan" },+	{ "thp", "Thompson" },+	{ "thq", "Kochila Tharu" },+	{ "thr", "Rana Tharu" },+	{ "ths", "Thakali" },+	{ "tht", "Tahltan" },+	{ "thu", "Thuri" },+	{ "thv", "Tahaggart Tamahaq" },+	{ "thw", "Thudam" },+	{ "thx", "The" },+	{ "thy", "Tha" },+	{ "thz", "Tayart Tamajeq" },+	{ "tia", "Tidikelt Tamazight" },+	{ "tic", "Tira" },+	{ "tid", "Tidong" },+	{ "tif", "Tifal" },+	{ "tig", "Tigre" },+	{ "tih", "Timugon Murut" },+	{ "tii", "Tiene" },+	{ "tij", "Tilung" },+	{ "tik", "Tikar" },+	{ "til", "Tillamook" },+	{ "tim", "Timbe" },+	{ "tin", "Tindi" },+	{ "tio", "Teop" },+	{ "tip", "Trimuris" },+	{ "tiq", "Tiéfo" },+	{ "tir", "Tigrinya" },+	{ "tis", "Masadiit Itneg" },+	{ "tit", "Tinigua" },+	{ "tiu", "Adasen" },+	{ "tiv", "Tiv" },+	{ "tiw", "Tiwi" },+	{ "tix", "Southern Tiwa" },+	{ "tiy", "Tiruray" },+	{ "tiz", "Tai Hongjin" },+	{ "tja", "Tajuasohn" },+	{ "tjg", "Tunjung" },+	{ "tji", "Northern Tujia" },+	{ "tjl", "Tai Laing" },+	{ "tjm", "Timucua" },+	{ "tjn", "Tonjon" },+	{ "tjo", "Temacine Tamazight" },+	{ "tjs", "Southern Tujia" },+	{ "tju", "Tjurruru" },+	{ "tjw", "Djabwurrung" },+	{ "tka", "Truká" },+	{ "tkb", "Buksa" },+	{ "tkd", "Tukudede" },+	{ "tke", "Takwane" },+	{ "tkf", "Tukumanféd" },+	{ "tkg", "Tesaka Malagasy" },+	{ "tkl", "Tokelau" },+	{ "tkm", "Takelma" },+	{ "tkn", "Toku-No-Shima" },+	{ "tkp", "Tikopia" },+	{ "tkq", "Tee" },+	{ "tkr", "Tsakhur" },+	{ "tks", "Takestani" },+	{ "tkt", "Kathoriya Tharu" },+	{ "tku", "Upper Necaxa Totonac" },+	{ "tkw", "Teanu" },+	{ "tkx", "Tangko" },+	{ "tkz", "Takua" },+	{ "tla", "Southwestern Tepehuan" },+	{ "tlb", "Tobelo" },+	{ "tlc", "Yecuatla Totonac" },+	{ "tld", "Talaud" },+	{ "tlf", "Telefol" },+	{ "tlg", "Tofanma" },+	{ "tlh", "Klingon" },+	{ "tli", "Tlingit" },+	{ "tlj", "Talinga-Bwisi" },+	{ "tlk", "Taloki" },+	{ "tll", "Tetela" },+	{ "tlm", "Tolomako" },+	{ "tln", "Talondo'" },+	{ "tlo", "Talodi" },+	{ "tlp", "Filomena Mata-Coahuitlán Totonac" },+	{ "tlq", "Tai Loi" },+	{ "tlr", "Talise" },+	{ "tls", "Tambotalo" },+	{ "tlt", "Teluti" },+	{ "tlu", "Tulehu" },+	{ "tlv", "Taliabu" },+	{ "tlx", "Khehek" },+	{ "tly", "Talysh" },+	{ "tma", "Tama (Chad)" },+	{ "tmb", "Katbol" },+	{ "tmc", "Tumak" },+	{ "tmd", "Haruai" },+	{ "tme", "Tremembé" },+	{ "tmf", "Toba-Maskoy" },+	{ "tmg", "Ternateño" },+	{ "tmh", "Tamashek" },+	{ "tmi", "Tutuba" },+	{ "tmj", "Samarokena" },+	{ "tmk", "Northwestern Tamang" },+	{ "tml", "Tamnim Citak" },+	{ "tmm", "Tai Thanh" },+	{ "tmn", "Taman (Indonesia)" },+	{ "tmo", "Temoq" },+	{ "tmp", "Tai Mène" },+	{ "tmq", "Tumleo" },+	{ "tmr", "Jewish Babylonian Aramaic (ca. 200-1200 CE)" },+	{ "tms", "Tima" },+	{ "tmt", "Tasmate" },+	{ "tmu", "Iau" },+	{ "tmv", "Tembo (Motembo)" },+	{ "tmw", "Temuan" },+	{ "tmy", "Tami" },+	{ "tmz", "Tamanaku" },+	{ "tna", "Tacana" },+	{ "tnb", "Western Tunebo" },+	{ "tnc", "Tanimuca-Retuarã" },+	{ "tnd", "Angosturas Tunebo" },+	{ "tne", "Tinoc Kallahan" },+	{ "tng", "Tobanga" },+	{ "tnh", "Maiani" },+	{ "tni", "Tandia" },+	{ "tnk", "Kwamera" },+	{ "tnl", "Lenakel" },+	{ "tnm", "Tabla" },+	{ "tnn", "North Tanna" },+	{ "tno", "Toromono" },+	{ "tnp", "Whitesands" },+	{ "tnq", "Taino" },+	{ "tnr", "Ménik" },+	{ "tns", "Tenis" },+	{ "tnt", "Tontemboan" },+	{ "tnu", "Tay Khang" },+	{ "tnv", "Tangchangya" },+	{ "tnw", "Tonsawang" },+	{ "tnx", "Tanema" },+	{ "tny", "Tongwe" },+	{ "tnz", "Tonga (Thailand)" },+	{ "tob", "Toba" },+	{ "toc", "Coyutla Totonac" },+	{ "tod", "Toma" },+	{ "toe", "Tomedes" },+	{ "tof", "Gizrra" },+	{ "tog", "Tonga (Nyasa)" },+	{ "toh", "Gitonga" },+	{ "toi", "Tonga (Zambia)" },+	{ "toj", "Tojolabal" },+	{ "tol", "Tolowa" },+	{ "tom", "Tombulu" },+	{ "ton", "Tonga (Tonga Islands)" },+	{ "too", "Xicotepec De Juárez Totonac" },+	{ "top", "Papantla Totonac" },+	{ "toq", "Toposa" },+	{ "tor", "Togbo-Vara Banda" },+	{ "tos", "Highland Totonac" },+	{ "tou", "Tho" },+	{ "tov", "Upper Taromi" },+	{ "tow", "Jemez" },+	{ "tox", "Tobian" },+	{ "toy", "Topoiyo" },+	{ "toz", "To" },+	{ "tpa", "Taupota" },+	{ "tpc", "Azoyú Me'phaa" },+	{ "tpe", "Tippera" },+	{ "tpf", "Tarpia" },+	{ "tpg", "Kula" },+	{ "tpi", "Tok Pisin" },+	{ "tpj", "Tapieté" },+	{ "tpk", "Tupinikin" },+	{ "tpl", "Tlacoapa Me'phaa" },+	{ "tpm", "Tampulma" },+	{ "tpn", "Tupinambá" },+	{ "tpo", "Tai Pao" },+	{ "tpp", "Pisaflores Tepehua" },+	{ "tpq", "Tukpa" },+	{ "tpr", "Tuparí" },+	{ "tpt", "Tlachichilco Tepehua" },+	{ "tpu", "Tampuan" },+	{ "tpv", "Tanapag" },+	{ "tpw", "Tupí" },+	{ "tpx", "Acatepec Me'phaa" },+	{ "tpy", "Trumai" },+	{ "tpz", "Tinputz" },+	{ "tqb", "Tembé" },+	{ "tql", "Lehali" },+	{ "tqm", "Turumsa" },+	{ "tqn", "Tenino" },+	{ "tqo", "Toaripi" },+	{ "tqp", "Tomoip" },+	{ "tqq", "Tunni" },+	{ "tqr", "Torona" },+	{ "tqt", "Western Totonac" },+	{ "tqu", "Touo" },+	{ "tqw", "Tonkawa" },+	{ "tra", "Tirahi" },+	{ "trb", "Terebu" },+	{ "trc", "Copala Triqui" },+	{ "trd", "Turi" },+	{ "tre", "East Tarangan" },+	{ "trf", "Trinidadian Creole English" },+	{ "trg", "Lishán Didán" },+	{ "trh", "Turaka" },+	{ "tri", "Trió" },+	{ "trj", "Toram" },+	{ "trl", "Traveller Scottish" },+	{ "trm", "Tregami" },+	{ "trn", "Trinitario" },+	{ "tro", "Tarao Naga" },+	{ "trp", "Kok Borok" },+	{ "trq", "San Martín Itunyoso Triqui" },+	{ "trr", "Taushiro" },+	{ "trs", "Chicahuaxtla Triqui" },+	{ "trt", "Tunggare" },+	{ "tru", "Turoyo" },+	{ "trv", "Taroko" },+	{ "trw", "Torwali" },+	{ "trx", "Tringgus-Sembaan Bidayuh" },+	{ "try", "Turung" },+	{ "trz", "Torá" },+	{ "tsa", "Tsaangi" },+	{ "tsb", "Tsamai" },+	{ "tsc", "Tswa" },+	{ "tsd", "Tsakonian" },+	{ "tse", "Tunisian Sign Language" },+	{ "tsf", "Southwestern Tamang" },+	{ "tsg", "Tausug" },+	{ "tsh", "Tsuvan" },+	{ "tsi", "Tsimshian" },+	{ "tsj", "Tshangla" },+	{ "tsk", "Tseku" },+	{ "tsl", "Ts'ün-Lao" },+	{ "tsm", "Turkish Sign Language" },+	{ "tsn", "Tswana" },+	{ "tso", "Tsonga" },+	{ "tsp", "Northern Toussian" },+	{ "tsq", "Thai Sign Language" },+	{ "tsr", "Akei" },+	{ "tss", "Taiwan Sign Language" },+	{ "tst", "Tondi Songway Kiini" },+	{ "tsu", "Tsou" },+	{ "tsv", "Tsogo" },+	{ "tsw", "Tsishingini" },+	{ "tsx", "Mubami" },+	{ "tsy", "Tebul Sign Language" },+	{ "tsz", "Purepecha" },+	{ "tta", "Tutelo" },+	{ "ttb", "Gaa" },+	{ "ttc", "Tektiteko" },+	{ "ttd", "Tauade" },+	{ "tte", "Bwanabwana" },+	{ "ttf", "Tuotomb" },+	{ "ttg", "Tutong" },+	{ "tth", "Upper Ta'oih" },+	{ "tti", "Tobati" },+	{ "ttj", "Tooro" },+	{ "ttk", "Totoro" },+	{ "ttl", "Totela" },+	{ "ttm", "Northern Tutchone" },+	{ "ttn", "Towei" },+	{ "tto", "Lower Ta'oih" },+	{ "ttp", "Tombelala" },+	{ "ttq", "Tawallammat Tamajaq" },+	{ "ttr", "Tera" },+	{ "tts", "Northeastern Thai" },+	{ "ttt", "Muslim Tat" },+	{ "ttu", "Torau" },+	{ "ttv", "Titan" },+	{ "ttw", "Long Wat" },+	{ "tty", "Sikaritai" },+	{ "ttz", "Tsum" },+	{ "tua", "Wiarumus" },+	{ "tub", "Tübatulabal" },+	{ "tuc", "Mutu" },+	{ "tud", "Tuxá" },+	{ "tue", "Tuyuca" },+	{ "tuf", "Central Tunebo" },+	{ "tug", "Tunia" },+	{ "tuh", "Taulil" },+	{ "tui", "Tupuri" },+	{ "tuj", "Tugutil" },+	{ "tuk", "Turkmen" },+	{ "tul", "Tula" },+	{ "tum", "Tumbuka" },+	{ "tun", "Tunica" },+	{ "tuo", "Tucano" },+	{ "tuq", "Tedaga" },+	{ "tur", "Turkish" },+	{ "tus", "Tuscarora" },+	{ "tuu", "Tututni" },+	{ "tuv", "Turkana" },+	{ "tux", "Tuxináwa" },+	{ "tuy", "Tugen" },+	{ "tuz", "Turka" },+	{ "tva", "Vaghua" },+	{ "tvd", "Tsuvadi" },+	{ "tve", "Te'un" },+	{ "tvk", "Southeast Ambrym" },+	{ "tvl", "Tuvalu" },+	{ "tvm", "Tela-Masbuar" },+	{ "tvn", "Tavoyan" },+	{ "tvo", "Tidore" },+	{ "tvs", "Taveta" },+	{ "tvt", "Tutsa Naga" },+	{ "tvu", "Tunen" },+	{ "tvw", "Sedoa" },+	{ "tvy", "Timor Pidgin" },+	{ "twa", "Twana" },+	{ "twb", "Western Tawbuid" },+	{ "twc", "Teshenawa" },+	{ "twd", "Twents" },+	{ "twe", "Tewa (Indonesia)" },+	{ "twf", "Northern Tiwa" },+	{ "twg", "Tereweng" },+	{ "twh", "Tai Dón" },+	{ "twi", "Twi" },+	{ "twl", "Tawara" },+	{ "twm", "Tawang Monpa" },+	{ "twn", "Twendi" },+	{ "two", "Tswapong" },+	{ "twp", "Ere" },+	{ "twq", "Tasawaq" },+	{ "twr", "Southwestern Tarahumara" },+	{ "twt", "Turiwára" },+	{ "twu", "Termanu" },+	{ "tww", "Tuwari" },+	{ "twx", "Tewe" },+	{ "twy", "Tawoyan" },+	{ "txa", "Tombonuo" },+	{ "txb", "Tokharian B" },+	{ "txc", "Tsetsaut" },+	{ "txe", "Totoli" },+	{ "txg", "Tangut" },+	{ "txh", "Thracian" },+	{ "txi", "Ikpeng" },+	{ "txm", "Tomini" },+	{ "txn", "West Tarangan" },+	{ "txo", "Toto" },+	{ "txq", "Tii" },+	{ "txr", "Tartessian" },+	{ "txs", "Tonsea" },+	{ "txt", "Citak" },+	{ "txu", "Kayapó" },+	{ "txx", "Tatana" },+	{ "txy", "Tanosy Malagasy" },+	{ "tya", "Tauya" },+	{ "tye", "Kyanga" },+	{ "tyh", "O'du" },+	{ "tyi", "Teke-Tsaayi" },+	{ "tyj", "Tai Do" },+	{ "tyl", "Thu Lao" },+	{ "tyn", "Kombai" },+	{ "typ", "Thaypan" },+	{ "tyr", "Tai Daeng" },+	{ "tys", "Tày Sa Pa" },+	{ "tyt", "Tày Tac" },+	{ "tyu", "Kua" },+	{ "tyv", "Tuvinian" },+	{ "tyx", "Teke-Tyee" },+	{ "tyz", "Tày" },+	{ "tza", "Tanzanian Sign Language" },+	{ "tzh", "Tzeltal" },+	{ "tzj", "Tz'utujil" },+	{ "tzl", "Talossan" },+	{ "tzm", "Central Atlas Tamazight" },+	{ "tzn", "Tugun" },+	{ "tzo", "Tzotzil" },+	{ "tzx", "Tabriak" },+	{ "uam", "Uamué" },+	{ "uan", "Kuan" },+	{ "uar", "Tairuma" },+	{ "uba", "Ubang" },+	{ "ubi", "Ubi" },+	{ "ubl", "Buhi'non Bikol" },+	{ "ubr", "Ubir" },+	{ "ubu", "Umbu-Ungu" },+	{ "uby", "Ubykh" },+	{ "uda", "Uda" },+	{ "ude", "Udihe" },+	{ "udg", "Muduga" },+	{ "udi", "Udi" },+	{ "udj", "Ujir" },+	{ "udl", "Wuzlam" },+	{ "udm", "Udmurt" },+	{ "udu", "Uduk" },+	{ "ues", "Kioko" },+	{ "ufi", "Ufim" },+	{ "uga", "Ugaritic" },+	{ "ugb", "Kuku-Ugbanh" },+	{ "uge", "Ughele" },+	{ "ugn", "Ugandan Sign Language" },+	{ "ugo", "Ugong" },+	{ "ugy", "Uruguayan Sign Language" },+	{ "uha", "Uhami" },+	{ "uhn", "Damal" },+	{ "uig", "Uighur" },+	{ "uis", "Uisai" },+	{ "uiv", "Iyive" },+	{ "uji", "Tanjijili" },+	{ "uka", "Kaburi" },+	{ "ukg", "Ukuriguma" },+	{ "ukh", "Ukhwejo" },+	{ "ukl", "Ukrainian Sign Language" },+	{ "ukp", "Ukpe-Bayobiri" },+	{ "ukq", "Ukwa" },+	{ "ukr", "Ukrainian" },+	{ "uks", "Urubú-Kaapor Sign Language" },+	{ "uku", "Ukue" },+	{ "ukw", "Ukwuani-Aboh-Ndoni" },+	{ "uky", "Kuuk-Yak" },+	{ "ula", "Fungwa" },+	{ "ulb", "Ulukwumi" },+	{ "ulc", "Ulch" },+	{ "ule", "Lule" },+	{ "ulf", "Usku" },+	{ "uli", "Ulithian" },+	{ "ulk", "Meriam" },+	{ "ull", "Ullatan" },+	{ "ulm", "Ulumanda'" },+	{ "uln", "Unserdeutsch" },+	{ "ulu", "Uma' Lung" },+	{ "ulw", "Ulwa" },+	{ "uma", "Umatilla" },+	{ "umb", "Umbundu" },+	{ "umc", "Marrucinian" },+	{ "umd", "Umbindhamu" },+	{ "umg", "Umbuygamu" },+	{ "umi", "Ukit" },+	{ "umm", "Umon" },+	{ "umn", "Makyan Naga" },+	{ "umo", "Umotína" },+	{ "ump", "Umpila" },+	{ "umr", "Umbugarla" },+	{ "ums", "Pendau" },+	{ "umu", "Munsee" },+	{ "una", "North Watut" },+	{ "und", "Undetermined" },+	{ "une", "Uneme" },+	{ "ung", "Ngarinyin" },+	{ "unk", "Enawené-Nawé" },+	{ "unm", "Unami" },+	{ "unn", "Kurnai" },+	{ "unr", "Mundari" },+	{ "unu", "Unubahe" },+	{ "unx", "Munda" },+	{ "unz", "Unde Kaili" },+	{ "uok", "Uokha" },+	{ "upi", "Umeda" },+	{ "upv", "Uripiv-Wala-Rano-Atchin" },+	{ "ura", "Urarina" },+	{ "urb", "Urubú-Kaapor" },+	{ "urc", "Urningangg" },+	{ "urd", "Urdu" },+	{ "ure", "Uru" },+	{ "urf", "Uradhi" },+	{ "urg", "Urigina" },+	{ "urh", "Urhobo" },+	{ "uri", "Urim" },+	{ "urk", "Urak Lawoi'" },+	{ "url", "Urali" },+	{ "urm", "Urapmin" },+	{ "urn", "Uruangnirin" },+	{ "uro", "Ura (Papua New Guinea)" },+	{ "urp", "Uru-Pa-In" },+	{ "urr", "Lehalurup" },+	{ "urt", "Urat" },+	{ "uru", "Urumi" },+	{ "urv", "Uruava" },+	{ "urw", "Sop" },+	{ "urx", "Urimo" },+	{ "ury", "Orya" },+	{ "urz", "Uru-Eu-Wau-Wau" },+	{ "usa", "Usarufa" },+	{ "ush", "Ushojo" },+	{ "usi", "Usui" },+	{ "usk", "Usaghade" },+	{ "usp", "Uspanteco" },+	{ "usu", "Uya" },+	{ "uta", "Otank" },+	{ "ute", "Ute-Southern Paiute" },+	{ "utp", "Amba (Solomon Islands)" },+	{ "utr", "Etulo" },+	{ "utu", "Utu" },+	{ "uum", "Urum" },+	{ "uun", "Kulon-Pazeh" },+	{ "uur", "Ura (Vanuatu)" },+	{ "uuu", "U" },+	{ "uve", "West Uvean" },+	{ "uvh", "Uri" },+	{ "uvl", "Lote" },+	{ "uwa", "Kuku-Uwanh" },+	{ "uya", "Doko-Uyanga" },+	{ "uzb", "Uzbek" },+	{ "uzn", "Northern Uzbek" },+	{ "uzs", "Southern Uzbek" },+	{ "vaa", "Vaagri Booli" },+	{ "vae", "Vale" },+	{ "vaf", "Vafsi" },+	{ "vag", "Vagla" },+	{ "vah", "Varhadi-Nagpuri" },+	{ "vai", "Vai" },+	{ "vaj", "Vasekela Bushman" },+	{ "val", "Vehes" },+	{ "vam", "Vanimo" },+	{ "van", "Valman" },+	{ "vao", "Vao" },+	{ "vap", "Vaiphei" },+	{ "var", "Huarijio" },+	{ "vas", "Vasavi" },+	{ "vau", "Vanuma" },+	{ "vav", "Varli" },+	{ "vay", "Wayu" },+	{ "vbb", "Southeast Babar" },+	{ "vbk", "Southwestern Bontok" },+	{ "vec", "Venetian" },+	{ "ved", "Veddah" },+	{ "vel", "Veluws" },+	{ "vem", "Vemgo-Mabas" },+	{ "ven", "Venda" },+	{ "veo", "Ventureño" },+	{ "vep", "Veps" },+	{ "ver", "Mom Jango" },+	{ "vgr", "Vaghri" },+	{ "vgt", "Vlaamse Gebarentaal" },+	{ "vic", "Virgin Islands Creole English" },+	{ "vid", "Vidunda" },+	{ "vie", "Vietnamese" },+	{ "vif", "Vili" },+	{ "vig", "Viemo" },+	{ "vil", "Vilela" },+	{ "vin", "Vinza" },+	{ "vis", "Vishavan" },+	{ "vit", "Viti" },+	{ "viv", "Iduna" },+	{ "vka", "Kariyarra" },+	{ "vki", "Ija-Zuba" },+	{ "vkj", "Kujarge" },+	{ "vkk", "Kaur" },+	{ "vkl", "Kulisusu" },+	{ "vkm", "Kamakan" },+	{ "vko", "Kodeoha" },+	{ "vkp", "Korlai Creole Portuguese" },+	{ "vkt", "Tenggarong Kutai Malay" },+	{ "vku", "Kurrama" },+	{ "vlp", "Valpei" },+	{ "vls", "Vlaams" },+	{ "vma", "Martuyhunira" },+	{ "vmb", "Barbaram" },+	{ "vmc", "Juxtlahuaca Mixtec" },+	{ "vmd", "Mudu Koraga" },+	{ "vme", "East Masela" },+	{ "vmf", "Mainfränkisch" },+	{ "vmg", "Lungalunga" },+	{ "vmh", "Maraghei" },+	{ "vmi", "Miwa" },+	{ "vmj", "Ixtayutla Mixtec" },+	{ "vmk", "Makhuwa-Shirima" },+	{ "vml", "Malgana" },+	{ "vmm", "Mitlatongo Mixtec" },+	{ "vmp", "Soyaltepec Mazatec" },+	{ "vmq", "Soyaltepec Mixtec" },+	{ "vmr", "Marenje" },+	{ "vms", "Moksela" },+	{ "vmu", "Muluridyi" },+	{ "vmv", "Valley Maidu" },+	{ "vmw", "Makhuwa" },+	{ "vmx", "Tamazola Mixtec" },+	{ "vmy", "Ayautla Mazatec" },+	{ "vmz", "Mazatlán Mazatec" },+	{ "vnk", "Vano" },+	{ "vnm", "Vinmavis" },+	{ "vnp", "Vunapu" },+	{ "vol", "Volapük" },+	{ "vor", "Voro" },+	{ "vot", "Votic" },+	{ "vra", "Vera'a" },+	{ "vro", "Võro" },+	{ "vrs", "Varisi" },+	{ "vrt", "Burmbar" },+	{ "vsi", "Moldova Sign Language" },+	{ "vsl", "Venezuelan Sign Language" },+	{ "vsv", "Valencian Sign Language" },+	{ "vto", "Vitou" },+	{ "vum", "Vumbu" },+	{ "vun", "Vunjo" },+	{ "vut", "Vute" },+	{ "vwa", "Awa (China)" },+	{ "waa", "Walla Walla" },+	{ "wab", "Wab" },+	{ "wac", "Wasco-Wishram" },+	{ "wad", "Wandamen" },+	{ "wae", "Walser" },+	{ "waf", "Wakoná" },+	{ "wag", "Wa'ema" },+	{ "wah", "Watubela" },+	{ "wai", "Wares" },+	{ "waj", "Waffa" },+	{ "wal", "Wolaytta" },+	{ "wam", "Wampanoag" },+	{ "wan", "Wan" },+	{ "wao", "Wappo" },+	{ "wap", "Wapishana" },+	{ "waq", "Wageman" },+	{ "war", "Waray (Philippines)" },+	{ "was", "Washo" },+	{ "wat", "Kaninuwa" },+	{ "wau", "Waurá" },+	{ "wav", "Waka" },+	{ "waw", "Waiwai" },+	{ "wax", "Watam" },+	{ "way", "Wayana" },+	{ "waz", "Wampur" },+	{ "wba", "Warao" },+	{ "wbb", "Wabo" },+	{ "wbe", "Waritai" },+	{ "wbf", "Wara" },+	{ "wbh", "Wanda" },+	{ "wbi", "Vwanji" },+	{ "wbj", "Alagwa" },+	{ "wbk", "Waigali" },+	{ "wbl", "Wakhi" },+	{ "wbm", "Wa" },+	{ "wbp", "Warlpiri" },+	{ "wbq", "Waddar" },+	{ "wbr", "Wagdi" },+	{ "wbt", "Wanman" },+	{ "wbv", "Wajarri" },+	{ "wbw", "Woi" },+	{ "wca", "Yanomámi" },+	{ "wci", "Waci Gbe" },+	{ "wdd", "Wandji" },+	{ "wdg", "Wadaginam" },+	{ "wdj", "Wadjiginy" },+	{ "wdk", "Wadikali" },+	{ "wdu", "Wadjigu" },+	{ "wdy", "Wadjabangayi" },+	{ "wea", "Wewaw" },+	{ "wec", "Wè Western" },+	{ "wed", "Wedau" },+	{ "weg", "Wergaia" },+	{ "weh", "Weh" },+	{ "wei", "Kiunum" },+	{ "wem", "Weme Gbe" },+	{ "weo", "Wemale" },+	{ "wep", "Westphalien" },+	{ "wer", "Weri" },+	{ "wes", "Cameroon Pidgin" },+	{ "wet", "Perai" },+	{ "weu", "Rawngtu Chin" },+	{ "wew", "Wejewa" },+	{ "wfg", "Yafi" },+	{ "wga", "Wagaya" },+	{ "wgb", "Wagawaga" },+	{ "wgg", "Wangganguru" },+	{ "wgi", "Wahgi" },+	{ "wgo", "Waigeo" },+	{ "wgu", "Wirangu" },+	{ "wgy", "Warrgamay" },+	{ "wha", "Manusela" },+	{ "whg", "North Wahgi" },+	{ "whk", "Wahau Kenyah" },+	{ "whu", "Wahau Kayan" },+	{ "wib", "Southern Toussian" },+	{ "wic", "Wichita" },+	{ "wie", "Wik-Epa" },+	{ "wif", "Wik-Keyangan" },+	{ "wig", "Wik-Ngathana" },+	{ "wih", "Wik-Me'anha" },+	{ "wii", "Minidien" },+	{ "wij", "Wik-Iiyanh" },+	{ "wik", "Wikalkan" },+	{ "wil", "Wilawila" },+	{ "wim", "Wik-Mungkan" },+	{ "win", "Ho-Chunk" },+	{ "wir", "Wiraféd" },+	{ "wiu", "Wiru" },+	{ "wiv", "Vitu" },+	{ "wiy", "Wiyot" },+	{ "wja", "Waja" },+	{ "wji", "Warji" },+	{ "wka", "Kw'adza" },+	{ "wkb", "Kumbaran" },+	{ "wkd", "Wakde" },+	{ "wkl", "Kalanadi" },+	{ "wku", "Kunduvadi" },+	{ "wkw", "Wakawaka" },+	{ "wky", "Wangkayutyuru" },+	{ "wla", "Walio" },+	{ "wlc", "Mwali Comorian" },+	{ "wle", "Wolane" },+	{ "wlg", "Kunbarlang" },+	{ "wli", "Waioli" },+	{ "wlk", "Wailaki" },+	{ "wll", "Wali (Sudan)" },+	{ "wlm", "Middle Welsh" },+	{ "wln", "Walloon" },+	{ "wlo", "Wolio" },+	{ "wlr", "Wailapa" },+	{ "wls", "Wallisian" },+	{ "wlu", "Wuliwuli" },+	{ "wlv", "Wichí Lhamtés Vejoz" },+	{ "wlw", "Walak" },+	{ "wlx", "Wali (Ghana)" },+	{ "wly", "Waling" },+	{ "wma", "Mawa (Nigeria)" },+	{ "wmb", "Wambaya" },+	{ "wmc", "Wamas" },+	{ "wmd", "Mamaindé" },+	{ "wme", "Wambule" },+	{ "wmh", "Waima'a" },+	{ "wmi", "Wamin" },+	{ "wmm", "Maiwa (Indonesia)" },+	{ "wmn", "Waamwang" },+	{ "wmo", "Wom (Papua New Guinea)" },+	{ "wms", "Wambon" },+	{ "wmt", "Walmajarri" },+	{ "wmw", "Mwani" },+	{ "wmx", "Womo" },+	{ "wnb", "Wanambre" },+	{ "wnc", "Wantoat" },+	{ "wnd", "Wandarang" },+	{ "wne", "Waneci" },+	{ "wng", "Wanggom" },+	{ "wni", "Ndzwani Comorian" },+	{ "wnk", "Wanukaka" },+	{ "wnm", "Wanggamala" },+	{ "wnn", "Wunumara" },+	{ "wno", "Wano" },+	{ "wnp", "Wanap" },+	{ "wnu", "Usan" },+	{ "wnw", "Wintu" },+	{ "wny", "Wanyi" },+	{ "woa", "Tyaraity" },+	{ "wob", "Wè Northern" },+	{ "woc", "Wogeo" },+	{ "wod", "Wolani" },+	{ "woe", "Woleaian" },+	{ "wof", "Gambian Wolof" },+	{ "wog", "Wogamusin" },+	{ "woi", "Kamang" },+	{ "wok", "Longto" },+	{ "wol", "Wolof" },+	{ "wom", "Wom (Nigeria)" },+	{ "won", "Wongo" },+	{ "woo", "Manombai" },+	{ "wor", "Woria" },+	{ "wos", "Hanga Hundi" },+	{ "wow", "Wawonii" },+	{ "woy", "Weyto" },+	{ "wpc", "Maco" },+	{ "wra", "Warapu" },+	{ "wrb", "Warluwara" },+	{ "wrd", "Warduji" },+	{ "wrg", "Warungu" },+	{ "wrh", "Wiradhuri" },+	{ "wri", "Wariyangga" },+	{ "wrk", "Garrwa" },+	{ "wrl", "Warlmanpa" },+	{ "wrm", "Warumungu" },+	{ "wrn", "Warnang" },+	{ "wro", "Worrorra" },+	{ "wrp", "Waropen" },+	{ "wrr", "Wardaman" },+	{ "wrs", "Waris" },+	{ "wru", "Waru" },+	{ "wrv", "Waruna" },+	{ "wrw", "Gugu Warra" },+	{ "wrx", "Wae Rana" },+	{ "wry", "Merwari" },+	{ "wrz", "Waray (Australia)" },+	{ "wsa", "Warembori" },+	{ "wsi", "Wusi" },+	{ "wsk", "Waskia" },+	{ "wsr", "Owenia" },+	{ "wss", "Wasa" },+	{ "wsu", "Wasu" },+	{ "wsv", "Wotapuri-Katarqalai" },+	{ "wtf", "Watiwa" },+	{ "wth", "Wathawurrung" },+	{ "wti", "Berta" },+	{ "wtk", "Watakataui" },+	{ "wtm", "Mewati" },+	{ "wtw", "Wotu" },+	{ "wua", "Wikngenchera" },+	{ "wub", "Wunambal" },+	{ "wud", "Wudu" },+	{ "wuh", "Wutunhua" },+	{ "wul", "Silimo" },+	{ "wum", "Wumbvu" },+	{ "wun", "Bungu" },+	{ "wur", "Wurrugu" },+	{ "wut", "Wutung" },+	{ "wuu", "Wu Chinese" },+	{ "wuv", "Wuvulu-Aua" },+	{ "wux", "Wulna" },+	{ "wuy", "Wauyai" },+	{ "wwa", "Waama" },+	{ "wwb", "Wakabunga" },+	{ "wwo", "Wetamut" },+	{ "wwr", "Warrwa" },+	{ "www", "Wawa" },+	{ "wxa", "Waxianghua" },+	{ "wxw", "Wardandi" },+	{ "wya", "Wyandot" },+	{ "wyb", "Wangaaybuwan-Ngiyambaa" },+	{ "wyi", "Woiwurrung" },+	{ "wym", "Wymysorys" },+	{ "wyr", "Wayoró" },+	{ "wyy", "Western Fijian" },+	{ "xaa", "Andalusian Arabic" },+	{ "xab", "Sambe" },+	{ "xac", "Kachari" },+	{ "xad", "Adai" },+	{ "xae", "Aequian" },+	{ "xag", "Aghwan" },+	{ "xai", "Kaimbé" },+	{ "xal", "Kalmyk" },+	{ "xam", "Xam" },+	{ "xan", "Xamtanga" },+	{ "xao", "Khao" },+	{ "xap", "Apalachee" },+	{ "xaq", "Aquitanian" },+	{ "xar", "Karami" },+	{ "xas", "Kamas" },+	{ "xat", "Katawixi" },+	{ "xau", "Kauwera" },+	{ "xav", "Xavánte" },+	{ "xaw", "Kawaiisu" },+	{ "xay", "Kayan Mahakam" },+	{ "xba", "Kamba (Brazil)" },+	{ "xbb", "Lower Burdekin" },+	{ "xbc", "Bactrian" },+	{ "xbd", "Bindal" },+	{ "xbe", "Bigambal" },+	{ "xbg", "Bunganditj" },+	{ "xbi", "Kombio" },+	{ "xbj", "Birrpayi" },+	{ "xbm", "Middle Breton" },+	{ "xbn", "Kenaboi" },+	{ "xbo", "Bolgarian" },+	{ "xbp", "Bibbulman" },+	{ "xbr", "Kambera" },+	{ "xbw", "Kambiwá" },+	{ "xbx", "Kabixí" },+	{ "xby", "Batyala" },+	{ "xcb", "Cumbric" },+	{ "xcc", "Camunic" },+	{ "xce", "Celtiberian" },+	{ "xcg", "Cisalpine Gaulish" },+	{ "xch", "Chemakum" },+	{ "xcl", "Classical Armenian" },+	{ "xcm", "Comecrudo" },+	{ "xcn", "Cotoname" },+	{ "xco", "Chorasmian" },+	{ "xcr", "Carian" },+	{ "xct", "Classical Tibetan" },+	{ "xcu", "Curonian" },+	{ "xcv", "Chuvantsy" },+	{ "xcw", "Coahuilteco" },+	{ "xcy", "Cayuse" },+	{ "xda", "Darkinyung" },+	{ "xdc", "Dacian" },+	{ "xdk", "Dharuk" },+	{ "xdm", "Edomite" },+	{ "xdy", "Malayic Dayak" },+	{ "xeb", "Eblan" },+	{ "xed", "Hdi" },+	{ "xeg", "Xegwi" },+	{ "xel", "Kelo" },+	{ "xem", "Kembayan" },+	{ "xep", "Epi-Olmec" },+	{ "xer", "Xerénte" },+	{ "xes", "Kesawai" },+	{ "xet", "Xetá" },+	{ "xeu", "Keoru-Ahia" },+	{ "xfa", "Faliscan" },+	{ "xga", "Galatian" },+	{ "xgb", "Gbin" },+	{ "xgd", "Gudang" },+	{ "xgf", "Gabrielino-Fernandeño" },+	{ "xgg", "Goreng" },+	{ "xgi", "Garingbal" },+	{ "xgl", "Galindan" },+	{ "xgm", "Guwinmal" },+	{ "xgr", "Garza" },+	{ "xgu", "Unggumi" },+	{ "xgw", "Guwa" },+	{ "xha", "Harami" },+	{ "xhc", "Hunnic" },+	{ "xhd", "Hadrami" },+	{ "xhe", "Khetrani" },+	{ "xho", "Xhosa" },+	{ "xhr", "Hernican" },+	{ "xht", "Hattic" },+	{ "xhu", "Hurrian" },+	{ "xhv", "Khua" },+	{ "xib", "Iberian" },+	{ "xii", "Xiri" },+	{ "xil", "Illyrian" },+	{ "xin", "Xinca" },+	{ "xip", "Xipináwa" },+	{ "xir", "Xiriâna" },+	{ "xiv", "Indus Valley Language" },+	{ "xiy", "Xipaya" },+	{ "xjb", "Minjungbal" },+	{ "xjt", "Jaitmatang" },+	{ "xka", "Kalkoti" },+	{ "xkb", "Northern Nago" },+	{ "xkc", "Kho'ini" },+	{ "xkd", "Mendalam Kayan" },+	{ "xke", "Kereho" },+	{ "xkf", "Khengkha" },+	{ "xkg", "Kagoro" },+	{ "xkh", "Karahawyana" },+	{ "xki", "Kenyan Sign Language" },+	{ "xkj", "Kajali" },+	{ "xkk", "Kaco'" },+	{ "xkl", "Mainstream Kenyah" },+	{ "xkn", "Kayan River Kayan" },+	{ "xko", "Kiorr" },+	{ "xkp", "Kabatei" },+	{ "xkq", "Koroni" },+	{ "xkr", "Xakriabá" },+	{ "xks", "Kumbewaha" },+	{ "xkt", "Kantosi" },+	{ "xku", "Kaamba" },+	{ "xkv", "Kgalagadi" },+	{ "xkw", "Kembra" },+	{ "xkx", "Karore" },+	{ "xky", "Uma' Lasan" },+	{ "xkz", "Kurtokha" },+	{ "xla", "Kamula" },+	{ "xlb", "Loup B" },+	{ "xlc", "Lycian" },+	{ "xld", "Lydian" },+	{ "xle", "Lemnian" },+	{ "xlg", "Ligurian (Ancient)" },+	{ "xli", "Liburnian" },+	{ "xln", "Alanic" },+	{ "xlo", "Loup A" },+	{ "xlp", "Lepontic" },+	{ "xls", "Lusitanian" },+	{ "xlu", "Cuneiform Luwian" },+	{ "xly", "Elymian" },+	{ "xma", "Mushungulu" },+	{ "xmb", "Mbonga" },+	{ "xmc", "Makhuwa-Marrevone" },+	{ "xmd", "Mbudum" },+	{ "xme", "Median" },+	{ "xmf", "Mingrelian" },+	{ "xmg", "Mengaka" },+	{ "xmh", "Kuku-Muminh" },+	{ "xmj", "Majera" },+	{ "xmk", "Ancient Macedonian" },+	{ "xml", "Malaysian Sign Language" },+	{ "xmm", "Manado Malay" },+	{ "xmn", "Manichaean Middle Persian" },+	{ "xmo", "Morerebi" },+	{ "xmp", "Kuku-Mu'inh" },+	{ "xmq", "Kuku-Mangk" },+	{ "xmr", "Meroitic" },+	{ "xms", "Moroccan Sign Language" },+	{ "xmt", "Matbat" },+	{ "xmu", "Kamu" },+	{ "xmv", "Antankarana Malagasy" },+	{ "xmw", "Tsimihety Malagasy" },+	{ "xmx", "Maden" },+	{ "xmy", "Mayaguduna" },+	{ "xmz", "Mori Bawah" },+	{ "xna", "Ancient North Arabian" },+	{ "xnb", "Kanakanabu" },+	{ "xng", "Middle Mongolian" },+	{ "xnh", "Kuanhua" },+	{ "xni", "Ngarigu" },+	{ "xnk", "Nganakarti" },+	{ "xnn", "Northern Kankanay" },+	{ "xno", "Anglo-Norman" },+	{ "xnr", "Kangri" },+	{ "xns", "Kanashi" },+	{ "xnt", "Narragansett" },+	{ "xnu", "Nukunul" },+	{ "xny", "Nyiyaparli" },+	{ "xnz", "Kenzi" },+	{ "xoc", "O'chi'chi'" },+	{ "xod", "Kokoda" },+	{ "xog", "Soga" },+	{ "xoi", "Kominimung" },+	{ "xok", "Xokleng" },+	{ "xom", "Komo (Sudan)" },+	{ "xon", "Konkomba" },+	{ "xoo", "Xukurú" },+	{ "xop", "Kopar" },+	{ "xor", "Korubo" },+	{ "xow", "Kowaki" },+	{ "xpa", "Pirriya" },+	{ "xpc", "Pecheneg" },+	{ "xpe", "Liberia Kpelle" },+	{ "xpg", "Phrygian" },+	{ "xpi", "Pictish" },+	{ "xpj", "Mpalitjanh" },+	{ "xpk", "Kulina Pano" },+	{ "xpm", "Pumpokol" },+	{ "xpn", "Kapinawá" },+	{ "xpo", "Pochutec" },+	{ "xpp", "Puyo-Paekche" },+	{ "xpq", "Mohegan-Pequot" },+	{ "xpr", "Parthian" },+	{ "xps", "Pisidian" },+	{ "xpt", "Punthamara" },+	{ "xpu", "Punic" },+	{ "xpy", "Puyo" },+	{ "xqa", "Karakhanid" },+	{ "xqt", "Qatabanian" },+	{ "xra", "Krahô" },+	{ "xrb", "Eastern Karaboro" },+	{ "xrd", "Gundungurra" },+	{ "xre", "Kreye" },+	{ "xrg", "Minang" },+	{ "xri", "Krikati-Timbira" },+	{ "xrm", "Armazic" },+	{ "xrn", "Arin" },+	{ "xrq", "Karranga" },+	{ "xrr", "Raetic" },+	{ "xrt", "Aranama-Tamique" },+	{ "xru", "Marriammu" },+	{ "xrw", "Karawa" },+	{ "xsa", "Sabaean" },+	{ "xsb", "Sambal" },+	{ "xsc", "Scythian" },+	{ "xsd", "Sidetic" },+	{ "xse", "Sempan" },+	{ "xsh", "Shamang" },+	{ "xsi", "Sio" },+	{ "xsj", "Subi" },+	{ "xsl", "South Slavey" },+	{ "xsm", "Kasem" },+	{ "xsn", "Sanga (Nigeria)" },+	{ "xso", "Solano" },+	{ "xsp", "Silopi" },+	{ "xsq", "Makhuwa-Saka" },+	{ "xsr", "Sherpa" },+	{ "xss", "Assan" },+	{ "xsu", "Sanumá" },+	{ "xsv", "Sudovian" },+	{ "xsy", "Saisiyat" },+	{ "xta", "Alcozauca Mixtec" },+	{ "xtb", "Chazumba Mixtec" },+	{ "xtc", "Katcha-Kadugli-Miri" },+	{ "xtd", "Diuxi-Tilantongo Mixtec" },+	{ "xte", "Ketengban" },+	{ "xtg", "Transalpine Gaulish" },+	{ "xth", "Yitha Yitha" },+	{ "xti", "Sinicahua Mixtec" },+	{ "xtj", "San Juan Teita Mixtec" },+	{ "xtl", "Tijaltepec Mixtec" },+	{ "xtm", "Magdalena Peñasco Mixtec" },+	{ "xtn", "Northern Tlaxiaco Mixtec" },+	{ "xto", "Tokharian A" },+	{ "xtp", "San Miguel Piedras Mixtec" },+	{ "xtq", "Tumshuqese" },+	{ "xtr", "Early Tripuri" },+	{ "xts", "Sindihui Mixtec" },+	{ "xtt", "Tacahua Mixtec" },+	{ "xtu", "Cuyamecalco Mixtec" },+	{ "xtv", "Thawa" },+	{ "xtw", "Tawandê" },+	{ "xty", "Yoloxochitl Mixtec" },+	{ "xtz", "Tasmanian" },+	{ "xua", "Alu Kurumba" },+	{ "xub", "Betta Kurumba" },+	{ "xud", "Umiida" },+	{ "xug", "Kunigami" },+	{ "xuj", "Jennu Kurumba" },+	{ "xul", "Ngunawal" },+	{ "xum", "Umbrian" },+	{ "xun", "Unggaranggu" },+	{ "xuo", "Kuo" },+	{ "xup", "Upper Umpqua" },+	{ "xur", "Urartian" },+	{ "xut", "Kuthant" },+	{ "xuu", "Kxoe" },+	{ "xve", "Venetic" },+	{ "xvi", "Kamviri" },+	{ "xvn", "Vandalic" },+	{ "xvo", "Volscian" },+	{ "xvs", "Vestinian" },+	{ "xwa", "Kwaza" },+	{ "xwc", "Woccon" },+	{ "xwd", "Wadi Wadi" },+	{ "xwe", "Xwela Gbe" },+	{ "xwg", "Kwegu" },+	{ "xwj", "Wajuk" },+	{ "xwk", "Wangkumara" },+	{ "xwl", "Western Xwla Gbe" },+	{ "xwo", "Written Oirat" },+	{ "xwr", "Kwerba Mamberamo" },+	{ "xwt", "Wotjobaluk" },+	{ "xww", "Wemba Wemba" },+	{ "xxb", "Boro (Ghana)" },+	{ "xxk", "Ke'o" },+	{ "xxm", "Minkin" },+	{ "xxr", "Koropó" },+	{ "xxt", "Tambora" },+	{ "xya", "Yaygir" },+	{ "xyb", "Yandjibara" },+	{ "xyj", "Mayi-Yapi" },+	{ "xyk", "Mayi-Kulan" },+	{ "xyl", "Yalakalore" },+	{ "xyt", "Mayi-Thakurti" },+	{ "xyy", "Yorta Yorta" },+	{ "xzh", "Zhang-Zhung" },+	{ "xzm", "Zemgalian" },+	{ "xzp", "Ancient Zapotec" },+	{ "yaa", "Yaminahua" },+	{ "yab", "Yuhup" },+	{ "yac", "Pass Valley Yali" },+	{ "yad", "Yagua" },+	{ "yae", "Pumé" },+	{ "yaf", "Yaka (Democratic Republic of Congo)" },+	{ "yag", "Yámana" },+	{ "yah", "Yazgulyam" },+	{ "yai", "Yagnobi" },+	{ "yaj", "Banda-Yangere" },+	{ "yak", "Yakama" },+	{ "yal", "Yalunka" },+	{ "yam", "Yamba" },+	{ "yan", "Mayangna" },+	{ "yao", "Yao" },+	{ "yap", "Yapese" },+	{ "yaq", "Yaqui" },+	{ "yar", "Yabarana" },+	{ "yas", "Nugunu (Cameroon)" },+	{ "yat", "Yambeta" },+	{ "yau", "Yuwana" },+	{ "yav", "Yangben" },+	{ "yaw", "Yawalapití" },+	{ "yax", "Yauma" },+	{ "yay", "Agwagwune" },+	{ "yaz", "Lokaa" },+	{ "yba", "Yala" },+	{ "ybb", "Yemba" },+	{ "ybe", "West Yugur" },+	{ "ybh", "Yakha" },+	{ "ybi", "Yamphu" },+	{ "ybj", "Hasha" },+	{ "ybk", "Bokha" },+	{ "ybl", "Yukuben" },+	{ "ybm", "Yaben" },+	{ "ybn", "Yabaâna" },+	{ "ybo", "Yabong" },+	{ "ybx", "Yawiyo" },+	{ "yby", "Yaweyuha" },+	{ "ych", "Chesu" },+	{ "ycl", "Lolopo" },+	{ "ycn", "Yucuna" },+	{ "ycp", "Chepya" },+	{ "yda", "Yanda" },+	{ "ydd", "Eastern Yiddish" },+	{ "yde", "Yangum Dey" },+	{ "ydg", "Yidgha" },+	{ "ydk", "Yoidik" },+	{ "yds", "Yiddish Sign Language" },+	{ "yea", "Ravula" },+	{ "yec", "Yeniche" },+	{ "yee", "Yimas" },+	{ "yei", "Yeni" },+	{ "yej", "Yevanic" },+	{ "yel", "Yela" },+	{ "yer", "Tarok" },+	{ "yes", "Nyankpa" },+	{ "yet", "Yetfa" },+	{ "yeu", "Yerukula" },+	{ "yev", "Yapunda" },+	{ "yey", "Yeyi" },+	{ "yga", "Malyangapa" },+	{ "ygi", "Yiningayi" },+	{ "ygl", "Yangum Gel" },+	{ "ygm", "Yagomi" },+	{ "ygp", "Gepo" },+	{ "ygr", "Yagaria" },+	{ "ygu", "Yugul" },+	{ "ygw", "Yagwoia" },+	{ "yha", "Baha Buyang" },+	{ "yhd", "Judeo-Iraqi Arabic" },+	{ "yhl", "Hlepho Phowa" },+	{ "yia", "Yinggarda" },+	{ "yid", "Yiddish" },+	{ "yif", "Ache" },+	{ "yig", "Wusa Nasu" },+	{ "yih", "Western Yiddish" },+	{ "yii", "Yidiny" },+	{ "yij", "Yindjibarndi" },+	{ "yik", "Dongshanba Lalo" },+	{ "yil", "Yindjilandji" },+	{ "yim", "Yimchungru Naga" },+	{ "yin", "Yinchia" },+	{ "yip", "Pholo" },+	{ "yiq", "Miqie" },+	{ "yir", "North Awyu" },+	{ "yis", "Yis" },+	{ "yit", "Eastern Lalu" },+	{ "yiu", "Awu" },+	{ "yiv", "Northern Nisu" },+	{ "yix", "Axi Yi" },+	{ "yiz", "Azhe" },+	{ "yka", "Yakan" },+	{ "ykg", "Northern Yukaghir" },+	{ "yki", "Yoke" },+	{ "ykk", "Yakaikeke" },+	{ "ykl", "Khlula" },+	{ "ykm", "Kap" },+	{ "ykn", "Kua-nsi" },+	{ "yko", "Yasa" },+	{ "ykr", "Yekora" },+	{ "ykt", "Kathu" },+	{ "yku", "Kuamasi" },+	{ "yky", "Yakoma" },+	{ "yla", "Yaul" },+	{ "ylb", "Yaleba" },+	{ "yle", "Yele" },+	{ "ylg", "Yelogu" },+	{ "yli", "Angguruk Yali" },+	{ "yll", "Yil" },+	{ "ylm", "Limi" },+	{ "yln", "Langnian Buyang" },+	{ "ylo", "Naluo Yi" },+	{ "ylr", "Yalarnnga" },+	{ "ylu", "Aribwaung" },+	{ "yly", "Nyâlayu" },+	{ "ymb", "Yambes" },+	{ "ymc", "Southern Muji" },+	{ "ymd", "Muda" },+	{ "yme", "Yameo" },+	{ "ymg", "Yamongeri" },+	{ "ymh", "Mili" },+	{ "ymi", "Moji" },+	{ "ymk", "Makwe" },+	{ "yml", "Iamalele" },+	{ "ymm", "Maay" },+	{ "ymn", "Yamna" },+	{ "ymo", "Yangum Mon" },+	{ "ymp", "Yamap" },+	{ "ymq", "Qila Muji" },+	{ "ymr", "Malasar" },+	{ "yms", "Mysian" },+	{ "ymt", "Mator-Taygi-Karagas" },+	{ "ymx", "Northern Muji" },+	{ "ymz", "Muzi" },+	{ "yna", "Aluo" },+	{ "ynd", "Yandruwandha" },+	{ "yne", "Lang'e" },+	{ "yng", "Yango" },+	{ "ynh", "Yangho" },+	{ "ynk", "Naukan Yupik" },+	{ "ynl", "Yangulam" },+	{ "ynn", "Yana" },+	{ "yno", "Yong" },+	{ "ynq", "Yendang" },+	{ "yns", "Yansi" },+	{ "ynu", "Yahuna" },+	{ "yob", "Yoba" },+	{ "yog", "Yogad" },+	{ "yoi", "Yonaguni" },+	{ "yok", "Yokuts" },+	{ "yol", "Yola" },+	{ "yom", "Yombe" },+	{ "yon", "Yongkom" },+	{ "yor", "Yoruba" },+	{ "yot", "Yotti" },+	{ "yox", "Yoron" },+	{ "yoy", "Yoy" },+	{ "ypa", "Phala" },+	{ "ypb", "Labo Phowa" },+	{ "ypg", "Phola" },+	{ "yph", "Phupha" },+	{ "ypm", "Phuma" },+	{ "ypn", "Ani Phowa" },+	{ "ypo", "Alo Phola" },+	{ "ypp", "Phupa" },+	{ "ypz", "Phuza" },+	{ "yra", "Yerakai" },+	{ "yrb", "Yareba" },+	{ "yre", "Yaouré" },+	{ "yri", "Yarí" },+	{ "yrk", "Nenets" },+	{ "yrl", "Nhengatu" },+	{ "yrm", "Yirrk-Mel" },+	{ "yrn", "Yerong" },+	{ "yrs", "Yarsun" },+	{ "yrw", "Yarawata" },+	{ "yry", "Yarluyandi" },+	{ "ysc", "Yassic" },+	{ "ysd", "Samatao" },+	{ "ysg", "Sonaga" },+	{ "ysl", "Yugoslavian Sign Language" },+	{ "ysn", "Sani" },+	{ "yso", "Nisi (China)" },+	{ "ysp", "Southern Lolopo" },+	{ "ysr", "Sirenik Yupik" },+	{ "yss", "Yessan-Mayo" },+	{ "ysy", "Sanie" },+	{ "yta", "Talu" },+	{ "ytl", "Tanglang" },+	{ "ytp", "Thopho" },+	{ "ytw", "Yout Wam" },+	{ "yty", "Yatay" },+	{ "yua", "Yucateco" },+	{ "yub", "Yugambal" },+	{ "yuc", "Yuchi" },+	{ "yud", "Judeo-Tripolitanian Arabic" },+	{ "yue", "Yue Chinese" },+	{ "yuf", "Havasupai-Walapai-Yavapai" },+	{ "yug", "Yug" },+	{ "yui", "Yurutí" },+	{ "yuj", "Karkar-Yuri" },+	{ "yuk", "Yuki" },+	{ "yul", "Yulu" },+	{ "yum", "Quechan" },+	{ "yun", "Bena (Nigeria)" },+	{ "yup", "Yukpa" },+	{ "yuq", "Yuqui" },+	{ "yur", "Yurok" },+	{ "yut", "Yopno" },+	{ "yuu", "Yugh" },+	{ "yuw", "Yau (Morobe Province)" },+	{ "yux", "Southern Yukaghir" },+	{ "yuy", "East Yugur" },+	{ "yuz", "Yuracare" },+	{ "yva", "Yawa" },+	{ "yvt", "Yavitero" },+	{ "ywa", "Kalou" },+	{ "ywg", "Yinhawangka" },+	{ "ywl", "Western Lalu" },+	{ "ywn", "Yawanawa" },+	{ "ywq", "Wuding-Luquan Yi" },+	{ "ywr", "Yawuru" },+	{ "ywt", "Xishanba Lalo" },+	{ "ywu", "Wumeng Nasu" },+	{ "yww", "Yawarawarga" },+	{ "yxa", "Mayawali" },+	{ "yxg", "Yagara" },+	{ "yxl", "Yardliyawarra" },+	{ "yxm", "Yinwum" },+	{ "yxu", "Yuyu" },+	{ "yxy", "Yabula Yabula" },+	{ "yyr", "Yir Yoront" },+	{ "yyu", "Yau (Sandaun Province)" },+	{ "yyz", "Ayizi" },+	{ "yzg", "E'ma Buyang" },+	{ "yzk", "Zokhuo" },+	{ "zaa", "Sierra de Juárez Zapotec" },+	{ "zab", "San Juan Guelavía Zapotec" },+	{ "zac", "Ocotlán Zapotec" },+	{ "zad", "Cajonos Zapotec" },+	{ "zae", "Yareni Zapotec" },+	{ "zaf", "Ayoquesco Zapotec" },+	{ "zag", "Zaghawa" },+	{ "zah", "Zangwal" },+	{ "zai", "Isthmus Zapotec" },+	{ "zaj", "Zaramo" },+	{ "zak", "Zanaki" },+	{ "zal", "Zauzou" },+	{ "zam", "Miahuatlán Zapotec" },+	{ "zao", "Ozolotepec Zapotec" },+	{ "zap", "Zapotec" },+	{ "zaq", "Aloápam Zapotec" },+	{ "zar", "Rincón Zapotec" },+	{ "zas", "Santo Domingo Albarradas Zapotec" },+	{ "zat", "Tabaa Zapotec" },+	{ "zau", "Zangskari" },+	{ "zav", "Yatzachi Zapotec" },+	{ "zaw", "Mitla Zapotec" },+	{ "zax", "Xadani Zapotec" },+	{ "zay", "Zayse-Zergulla" },+	{ "zaz", "Zari" },+	{ "zbc", "Central Berawan" },+	{ "zbe", "East Berawan" },+	{ "zbl", "Blissymbols" },+	{ "zbt", "Batui" },+	{ "zbw", "West Berawan" },+	{ "zca", "Coatecas Altas Zapotec" },+	{ "zch", "Central Hongshuihe Zhuang" },+	{ "zdj", "Ngazidja Comorian" },+	{ "zea", "Zeeuws" },+	{ "zeg", "Zenag" },+	{ "zeh", "Eastern Hongshuihe Zhuang" },+	{ "zen", "Zenaga" },+	{ "zga", "Kinga" },+	{ "zgb", "Guibei Zhuang" },+	{ "zgh", "Standard Moroccan Tamazight" },+	{ "zgm", "Minz Zhuang" },+	{ "zgn", "Guibian Zhuang" },+	{ "zgr", "Magori" },+	{ "zha", "Zhuang" },+	{ "zhb", "Zhaba" },+	{ "zhd", "Dai Zhuang" },+	{ "zhi", "Zhire" },+	{ "zhn", "Nong Zhuang" },+	{ "zho", "Chinese" },+	{ "zhw", "Zhoa" },+	{ "zia", "Zia" },+	{ "zib", "Zimbabwe Sign Language" },+	{ "zik", "Zimakani" },+	{ "zil", "Zialo" },+	{ "zim", "Mesme" },+	{ "zin", "Zinza" },+	{ "zir", "Ziriya" },+	{ "ziw", "Zigula" },+	{ "ziz", "Zizilivakan" },+	{ "zka", "Kaimbulawa" },+	{ "zkb", "Koibal" },+	{ "zkd", "Kadu" },+	{ "zkg", "Koguryo" },+	{ "zkh", "Khorezmian" },+	{ "zkk", "Karankawa" },+	{ "zkn", "Kanan" },+	{ "zko", "Kott" },+	{ "zkp", "São Paulo Kaingáng" },+	{ "zkr", "Zakhring" },+	{ "zkt", "Kitan" },+	{ "zku", "Kaurna" },+	{ "zkv", "Krevinian" },+	{ "zkz", "Khazar" },+	{ "zlj", "Liujiang Zhuang" },+	{ "zlm", "Malay (individual language)" },+	{ "zln", "Lianshan Zhuang" },+	{ "zlq", "Liuqian Zhuang" },+	{ "zma", "Manda (Australia)" },+	{ "zmb", "Zimba" },+	{ "zmc", "Margany" },+	{ "zmd", "Maridan" },+	{ "zme", "Mangerr" },+	{ "zmf", "Mfinu" },+	{ "zmg", "Marti Ke" },+	{ "zmh", "Makolkol" },+	{ "zmi", "Negeri Sembilan Malay" },+	{ "zmj", "Maridjabin" },+	{ "zmk", "Mandandanyi" },+	{ "zml", "Madngele" },+	{ "zmm", "Marimanindji" },+	{ "zmn", "Mbangwe" },+	{ "zmo", "Molo" },+	{ "zmp", "Mpuono" },+	{ "zmq", "Mituku" },+	{ "zmr", "Maranunggu" },+	{ "zms", "Mbesa" },+	{ "zmt", "Maringarr" },+	{ "zmu", "Muruwari" },+	{ "zmv", "Mbariman-Gudhinma" },+	{ "zmw", "Mbo (Democratic Republic of Congo)" },+	{ "zmx", "Bomitaba" },+	{ "zmy", "Mariyedi" },+	{ "zmz", "Mbandja" },+	{ "zna", "Zan Gula" },+	{ "zne", "Zande (individual language)" },+	{ "zng", "Mang" },+	{ "znk", "Manangkari" },+	{ "zns", "Mangas" },+	{ "zoc", "Copainalá Zoque" },+	{ "zoh", "Chimalapa Zoque" },+	{ "zom", "Zou" },+	{ "zoo", "Asunción Mixtepec Zapotec" },+	{ "zoq", "Tabasco Zoque" },+	{ "zor", "Rayón Zoque" },+	{ "zos", "Francisco León Zoque" },+	{ "zpa", "Lachiguiri Zapotec" },+	{ "zpb", "Yautepec Zapotec" },+	{ "zpc", "Choapan Zapotec" },+	{ "zpd", "Southeastern Ixtlán Zapotec" },+	{ "zpe", "Petapa Zapotec" },+	{ "zpf", "San Pedro Quiatoni Zapotec" },+	{ "zpg", "Guevea De Humboldt Zapotec" },+	{ "zph", "Totomachapan Zapotec" },+	{ "zpi", "Santa María Quiegolani Zapotec" },+	{ "zpj", "Quiavicuzas Zapotec" },+	{ "zpk", "Tlacolulita Zapotec" },+	{ "zpl", "Lachixío Zapotec" },+	{ "zpm", "Mixtepec Zapotec" },+	{ "zpn", "Santa Inés Yatzechi Zapotec" },+	{ "zpo", "Amatlán Zapotec" },+	{ "zpp", "El Alto Zapotec" },+	{ "zpq", "Zoogocho Zapotec" },+	{ "zpr", "Santiago Xanica Zapotec" },+	{ "zps", "Coatlán Zapotec" },+	{ "zpt", "San Vicente Coatlán Zapotec" },+	{ "zpu", "Yalálag Zapotec" },+	{ "zpv", "Chichicapan Zapotec" },+	{ "zpw", "Zaniza Zapotec" },+	{ "zpx", "San Baltazar Loxicha Zapotec" },+	{ "zpy", "Mazaltepec Zapotec" },+	{ "zpz", "Texmelucan Zapotec" },+	{ "zqe", "Qiubei Zhuang" },+	{ "zra", "Kara (Korea)" },+	{ "zrg", "Mirgan" },+	{ "zrn", "Zerenkel" },+	{ "zro", "Záparo" },+	{ "zrp", "Zarphatic" },+	{ "zrs", "Mairasi" },+	{ "zsa", "Sarasira" },+	{ "zsk", "Kaskean" },+	{ "zsl", "Zambian Sign Language" },+	{ "zsm", "Standard Malay" },+	{ "zsr", "Southern Rincon Zapotec" },+	{ "zsu", "Sukurum" },+	{ "zte", "Elotepec Zapotec" },+	{ "ztg", "Xanaguía Zapotec" },+	{ "ztl", "Lapaguía-Guivini Zapotec" },+	{ "ztm", "San Agustín Mixtepec Zapotec" },+	{ "ztn", "Santa Catarina Albarradas Zapotec" },+	{ "ztp", "Loxicha Zapotec" },+	{ "ztq", "Quioquitani-Quierí Zapotec" },+	{ "zts", "Tilquiapan Zapotec" },+	{ "ztt", "Tejalapan Zapotec" },+	{ "ztu", "Güilá Zapotec" },+	{ "ztx", "Zaachila Zapotec" },+	{ "zty", "Yatee Zapotec" },+	{ "zua", "Zeem" },+	{ "zuh", "Tokano" },+	{ "zul", "Zulu" },+	{ "zum", "Kumzari" },+	{ "zun", "Zuni" },+	{ "zuy", "Zumaya" },+	{ "zwa", "Zay" },+	{ "zxx", "No linguistic content" },+	{ "zyb", "Yongbei Zhuang" },+	{ "zyg", "Yang Zhuang" },+	{ "zyj", "Youjiang Zhuang" },+	{ "zyn", "Yongnan Zhuang" },+	{ "zyp", "Zyphe Chin" },+	{ "zza", "Zaza" },+	{ "zzj", "Zuojiang Zhuang" },+};+static int niso639_3= sizeof( iso639_3 ) / sizeof( iso639_3[0] );++char *+iso639_3_from_code( const char *code )+{+	int i;+	for ( i=0; i<niso639_3; ++i ) {+		if ( !strcasecmp( iso639_3[i].code, code ) )+			return iso639_3[i].language;+	}+	return NULL;+}
+ bibutils/iso639_3.h view
@@ -0,0 +1,9 @@+/*+ * iso639_3.h+ */+#ifndef ISO639_3_H+#define iSO639_3_H++extern char * iso639_3_from_code( const char *code );++#endif
bibutils/latex.c view
@@ -63,14 +63,14 @@    { 230, "{\\ae}",  "\\ae",    ""      }, /* Latin Small ae */                                             /* Latin Capital C */-   { 199, "{\\c{C}}","\\c{C}",  ""      }, /*               with cedilla */+   { 199, "{\\c{C}}","\\c{C}",  "\\c c" }, /*               with cedilla */    { 262, "{\\'{C}}","\\'{C}",  "\\'C"  }, /*               with acute */    { 264, "{\\^{C}}","\\^{C}",  "\\^C"  }, /*               with circumflex */    { 266, "{\\.{C}}","\\.{C}",  "\\.C"  }, /*               with dot above */    { 268, "{\\v{C}}","\\v{C}",  "\\v C" }, /*               with caron (hacek) */                                             /* Latin Small c */-   { 231, "{\\c{c}}","\\c{c}",  ""      }, /*               with cedilla*/+   { 231, "{\\c{c}}","\\c{c}",  "\\c C" }, /*               with cedilla*/    { 263, "{\\'{c}}","\\'{c}",  "\\'c"  }, /*               with acute */    { 265, "{\\^{c}}","\\^{c}",  "\\^c"  }, /*               with circumflex */    { 267, "{\\.{c}}","\\.{c}",  "\\.c"  }, /*               with dot above */@@ -512,6 +512,8 @@ 	if ( value=='{' || value=='\\' || value=='~' ||  	     value=='$' || value=='\'' || value=='`' ||  	     value=='-' || value=='^' ) {+		if ( *p=='\\' && ( *p=='{' || *p=='}' ) ) {+		} else { 		for ( i=0; i<nlatex_chars; ++i ) { 			q[0] = latex_chars[i].bib1; 			l[0] = strlen( q[0] );@@ -526,6 +528,7 @@ 					return latex_chars[i].unicode; 				} 			}+		} 		} 	} 	*unicode = 0;
bibutils/list.c view
@@ -1,9 +1,9 @@ /*  * list.c  *- * version: 2013-04-02+ * version: 2014-11-15  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *@@ -18,7 +18,7 @@ 	a->str = NULL; 	a->max = 0; 	a->n = 0;-	a->sorted = 0;+	a->sorted = 1; }  void@@ -66,27 +66,71 @@ 	return 1; } -/*- * return pointer to newstr 'n', list_getstr() is deprecated- */+static int+list_comp( const void *v1, const void *v2 )+{+	newstr *s1 = ( newstr *) v1;+	newstr *s2 = ( newstr *) v2;+	if ( !s1->len && !s2->len ) return 0;+	else if ( !s1->len ) return -1;+	else if ( !s2->len ) return 1;+	else return strcmp( s1->data, s2->data );+}++static int+list_comp_step( list *a, int n1, int n2 )+{+	return list_comp( (const void*) &(a->str[n1]), (const void*) &(a->str[n2]) );+}++static newstr *+list_set_cleanup( list *a, int n )+{+	if ( newstr_memerr( &(a->str[n]) ) ) return NULL;+	if ( a->sorted ) {+		if ( n>0 && list_comp_step( a, n-1, n )>0 )+			a->sorted = 0;+	}+	if ( a->sorted ) {+		if ( n<a->n-1 && list_comp_step( a, n, n+1 )>0 )+			a->sorted = 0;+	}+	return &(a->str[n]);+}+ newstr *-list_get( list *a, int n )+list_set( list *a, int n, newstr *s ) { 	if ( !list_valid_num( a, n ) ) return NULL;-	else return &(a->str[n]);+	newstr_newstrcpy( &(a->str[n]), s );+	return list_set_cleanup( a, n ); }+ newstr *-list_getstr( list *a, int n )+list_setc( list *a, int n, const char *s ) { 	if ( !list_valid_num( a, n ) ) return NULL;+	newstr_strcpy( &(a->str[n]), s );+	return list_set_cleanup( a, n );+}++/*+ * return pointer to newstr 'n'+ */+newstr *+list_get( list *a, int n )+{+	if ( !list_valid_num( a, n ) ) return NULL; 	else return &(a->str[n]); }  /*- * return pointer to C string 'n', list_getstr_char() is deprecated+ * return pointer to C string 'n'  *- * Ensure that a pointer is returned even if the newstr doesn't- * point to data. Thus we can convert loops like:+ * So long as the index is a valid number ensure+ * that a pointer is returned even if the newstr doesn't+ * point to data. Only return NULL if the index+ * is invalid. Thus we can convert loops like:  *  * for ( i=0; i<a->n; ++i ) {  *      p = list_getc( a, i );@@ -113,23 +157,18 @@ 	if ( p ) return p; 	else return empty; }-char *-list_getstr_char( list *a, int n )-{-	return list_getc( a, n );-}  static int list_alloc( list *a ) { 	int i, alloc = 20; 	a->str = ( newstr* ) malloc( sizeof( newstr ) * alloc );-	if ( !(a->str) ) return 0;+	if ( !(a->str) ) return LIST_ERR; 	a->max = alloc; 	a->n = 0; 	for ( i=0; i<alloc; ++i ) 		newstr_init( &(a->str[i]) );-	return 1;+	return LIST_OK; }  static int@@ -138,94 +177,122 @@ 	newstr *more; 	int i, alloc = a->max * 2; 	more = ( newstr* ) realloc( a->str, sizeof( newstr ) * alloc );-	if ( !more ) return 0;+	if ( !more ) return LIST_ERR; 	a->str = more; 	for ( i=a->max; i<alloc; ++i ) 		newstr_init( &(a->str[i]) ); 	a->max = alloc;-	return 1;+	return LIST_OK; } + static int list_ensure_space( list *a ) {-	int ok = 1;-	if ( a->max==0 ) ok = list_alloc( a );-	else if ( a->n >= a->max ) ok = list_realloc( a );-	return ok;+	int status = LIST_OK;+	if ( a->max==0 )+		status = list_alloc( a );+	else if ( a->n >= a->max )+		status = list_realloc( a );+	return status; }  newstr *-list_addvp( list *a, void *vp, unsigned char mode )+list_addvp( list *a, unsigned char mode, void *vp ) { 	newstr *s = NULL;-	int ok;-	ok = list_ensure_space( a );-	if ( ok ) {+	int status;+	status = list_ensure_space( a );+	if ( status==LIST_OK ) { 		s = &( a->str[a->n] ); 		if ( mode==LIST_CHR )-			newstr_strcpy( s, (char*) vp );+			newstr_strcpy( s, (const char*) vp ); 		else if ( mode==LIST_STR ) 			newstr_newstrcpy( s, (newstr*) vp ); 		else 			return NULL;-		a->sorted = 0;+		if ( newstr_memerr( s ) ) return NULL; 		a->n++;+		if ( a->sorted && a->n > 1 ) {+			if ( list_comp_step( a, a->n-2, a->n-1 ) > 0 )+				a->sorted = 0;+		} 	} 	return s; } newstr *-list_add( list *a, char *s )+list_addc( list *a, const char *s ) {-	return list_addvp( a, (void*)s, LIST_CHR );+	return list_addvp( a, LIST_CHR, (void*)s ); } newstr *-list_addstr( list *a, newstr *s )+list_add( list *a, newstr *s ) {-	return list_addvp( a, (void*)s, LIST_STR );+	return list_addvp( a, LIST_STR, (void*)s ); }  newstr *-list_addvp_unique( list *a, void *vp, unsigned char mode )+list_addvp_unique( list *a, unsigned char mode, void *vp ) { 	newstr *s; 	int n; 	if ( mode==LIST_CHR )-		n = list_find( a, (char*) vp );+		n = list_find( a, (const char*) vp ); 	else if ( mode==LIST_STR ) 		n = list_find( a, ( (newstr*) vp )->data ); 	else 		return NULL; 	if ( n!=-1 ) 		s = &( a->str[n] );-	else-		s = list_addvp( a, vp, mode );+	else {+		s = list_addvp( a, mode, vp );+	} 	return s; } newstr *-list_add_unique( list *a, char *s )+list_addc_unique( list *a, const char *s ) {-	return list_addvp_unique( a, (void*) s, LIST_CHR );+	return list_addvp_unique( a, LIST_CHR, (void*)s ); } newstr *-list_addstr_unique( list *a, newstr *s )+list_add_unique( list *a, newstr *s ) {-	return list_addvp_unique( a, (void*) s, LIST_STR );+	return list_addvp_unique( a, LIST_STR, (void*)s ); }  int-list_adds( list *a, ... )+list_addvp_all( list *a, unsigned char mode, ... ) {-	int ret = 1;+	int ret = LIST_OK; 	va_list ap; 	newstr *s;-	char *v;+	void *v;+	va_start( ap, mode );+	do {+		if ( mode==LIST_CHR ) v = va_arg( ap, char * );+		else v = va_arg( ap, newstr * );+		if ( v ) {+			s = list_addvp( a, mode, v );+			if ( s==NULL ) { ret = LIST_ERR; goto out; }+		}+	} while ( v );+out:+	va_end( ap );+	return ret;+}++int+list_add_all( list *a, ... )+{+	int ret = LIST_OK;+	va_list ap;+	newstr *s, *v; 	va_start( ap, a ); 	do {-		v = va_arg( ap, char * );+		v = va_arg( ap, newstr * ); 		if ( v ) {-			s = list_addvp( a, (void*) v, LIST_CHR );-			if ( s==NULL ) { ret = 0; goto out; }+			s = list_addvp( a, LIST_STR, (void*)v );+			if ( s==NULL ) { ret = LIST_ERR; goto out; } 		} 	} while ( v ); out:@@ -233,43 +300,67 @@ 	return ret; } -void+int+list_addc_all( list *a, ... )+{+	int ret = LIST_OK;+	va_list ap;+	newstr *s;+	const char *v;+	va_start( ap, a );+	do {+		v = va_arg( ap, const char * );+		if ( v ) {+			s = list_addvp( a, LIST_CHR, (void*)v );+			if ( s==NULL ) { ret = LIST_ERR; goto out; }+		}+	} while ( v );+out:+	va_end( ap );+	return ret;+}++int list_append( list *a, list *toadd ) {+	newstr *s; 	int i; 	for ( i=0; i<toadd->n; ++i ) {-		list_addstr( a, &(toadd->str[i]) );+		s = list_add( a, &(toadd->str[i]) );+		if ( !s ) return LIST_ERR; 	}+	return LIST_OK; } -void+int list_append_unique( list *a, list *toadd ) {+	newstr *s; 	int i; 	for ( i=0; i<toadd->n; ++i ) {-		list_addstr_unique( a, &(toadd->str[i]) );+		s = list_add_unique( a, &(toadd->str[i]) );+		if ( !s ) return LIST_ERR; 	}+	return LIST_OK; } -void+int list_remove( list *a, int n ) { 	int i;-	if ( !list_valid_num( a, n ) ) return;-	for ( i=n+1; i<a->n; ++i )+	if ( !list_valid_num( a, n ) ) return -1;+	for ( i=n+1; i<a->n; ++i ) { 		newstr_newstrcpy( &(a->str[i-1]), &(a->str[i]) );+		if ( newstr_memerr( &(a->str[i-1]) ) ) return LIST_ERR;+	} 	a->n--;+	return LIST_OK; } -static int-list_comp( const void *v1, const void *v2 )+void+list_swap( list *a, int n1, int n2 ) {-	newstr *s1 = ( newstr *) v1;-	newstr *s2 = ( newstr *) v2;-	if ( !s1->len && !s2->len ) return 0;-	else if ( !s1->len ) return -1;-	else if ( !s2->len ) return 1;-	else return strcmp( s1->data, s2->data );+	newstr_swapstrings( &(a->str[n1]), &(a->str[n2]) ); }  void@@ -280,11 +371,10 @@ }  static int-list_find_sorted( list *a, char *searchstr )+list_find_sorted( list *a, const char *searchstr ) { 	int min, max, mid, comp; 	newstr s, *cs;-	if ( a->n==0 ) return -1; 	newstr_init( &s ); 	newstr_strcpy( &s, searchstr ); 	min = 0;@@ -293,7 +383,10 @@ 		mid = ( min + max ) / 2; 		cs = list_get( a, mid ); 		comp = list_comp( (void*)cs, (void*) (&s) );-		if ( comp==0 ) return mid;+		if ( comp==0 ) {+			newstr_free( &s );+			return mid;+		} 		else if ( comp > 0 ) max = mid - 1; 		else if ( comp < 0 ) min = mid + 1; 	}@@ -302,7 +395,7 @@ }  static int-list_find_simple( list *a, char *searchstr, int nocase )+list_find_simple( list *a, const char *searchstr, int nocase ) { 	int i; 	if ( nocase ) {@@ -311,15 +404,16 @@ 				return i; 	} else { 		for ( i=0; i<a->n; ++i )-			if ( !strcmp(a->str[i].data,searchstr) ) +			if ( !strcmp(a->str[i].data,searchstr) ) 				return i; 	} 	return -1; }  int-list_find( list *a, char *searchstr )+list_find( list *a, const char *searchstr ) {+	if ( a->n==0 ) return -1; 	if ( a->sorted ) 		return list_find_sorted( a, searchstr ); 	else@@ -327,86 +421,90 @@ }  int-list_findnocase( list *a, char *searchstr )+list_findnocase( list *a, const char *searchstr ) { 	return list_find_simple( a, searchstr, 1 ); } -/* Return the index of searched-for string.- * If cannot find string, add to list and then- * return the index- */ int-list_find_or_add( list *a, char *searchstr )-{-	int n = list_find( a, searchstr );-	if ( n==-1 ) {-		list_add( a, searchstr );-		n = a->n - 1;-	}-	return n;-}--void-list_fillfp( list *a, FILE *fp )+list_fillfp( list *a, FILE *fp, unsigned char skip_blank_lines ) {+	int bufpos = 0, ret = LIST_OK;+	char buf[512]=""; 	newstr line;-	char *p, buf[512]="";-	int  bufpos = 0; -	list_init( a );+	list_empty( a ); 	newstr_init( &line ); 	while ( newstr_fget( fp, buf, sizeof(buf), &bufpos, &line ) ) {-		p = &(line.data[0]);-		if ( *p=='\0' ) continue;-		if ( !list_add( a, line.data ) ) return;+		if ( skip_blank_lines && line.len==0 ) continue;+		if ( !list_add( a, &line ) ) { ret = LIST_ERR; goto out; } 	}+out: 	newstr_free( &line );+	return ret; }  int-list_fill( list *a, char *filename )+list_fill( list *a, const char *filename, unsigned char skip_blank_lines ) {-	FILE *fp = fopen( filename, "r" );-	if ( !fp ) return 0;-	list_fillfp( a, fp );+	FILE *fp;+	int ret;++	fp = fopen( filename, "r" );+	if ( !fp ) return LIST_ERR_CANNOTOPEN;++	ret = list_fillfp( a, fp, skip_blank_lines );+ 	fclose( fp );-	return 1;++	return ret; } -void+int list_copy( list *to, list *from ) { 	int i;+ 	list_free( to );++	if ( from->n==0 ) return LIST_OK;+ 	to->str = ( newstr * ) malloc( sizeof( newstr ) * from->n );-	if ( !to->str ) return;-	to->n = to->max = from->n;-	for ( i=0; i<from->n; ++i ) {+	if ( !to->str ) {+		to->n = to->max = 0;+		return LIST_ERR;+	}++	to->max = from->n;+	to->sorted = from->sorted;++	for ( i=0; i<from->n; i++ ) 		newstr_init( &(to->str[i]) );-		newstr_strcpy( &(to->str[i]), from->str[i].data );++	for ( i=0; i<from->n; i++ ) {+		newstr_newstrcpy( &(to->str[i]), &(from->str[i]) );+		if ( newstr_memerr( &(to->str[i]) ) ) return LIST_ERR;+		to->n += 1; 	}+	return LIST_OK; }  list *-list_dup( list *aold )+list_dup( list *from ) {-	list *anew;-	int i;-	anew = ( list* ) malloc( sizeof( list ) );-	if ( !anew ) goto err0;-	anew->str = ( newstr* ) malloc( sizeof( newstr ) * aold->n );-	if ( !anew->str ) goto err1;-	anew->n = anew->max = aold->n;-	for ( i=0; i<aold->n; ++i ) {-		newstr_init( &(anew->str[i]) );-		newstr_strcpy( &(anew->str[i]), aold->str[i].data );+	list *to;+	int ok;++	to = list_new();+	if ( to ) {+		ok = list_copy( to, from );+		if ( !ok ) {+			list_delete( to );+			to = NULL;+		} 	}-	return anew;-err1:-	free( anew );-err0:-	return NULL;++	return to; }  int@@ -431,44 +529,38 @@ 	} } -void-list_tokenize( list *tokens, newstr *in, char delim, int merge_delim )+int+list_tokenizec( list *tokens, char *p, const char *delim, int merge_delim ) {-	newstr s;-	char *p;+	int ret = LIST_OK;+	newstr s, *t;+	char *q; 	list_empty( tokens );-	p = in->data; 	newstr_init( &s ); 	while ( p && *p ) {-		while ( *p && *p!=delim ) newstr_addchar( &s, *p++ );-		if ( s.len ) list_add( tokens, s.data );-		else if ( !merge_delim ) list_add( tokens, "" );-		newstr_empty( &s );-		if ( *p==delim ) p++;+		q = p;+		while ( *q && !strchr( delim, *q ) ) q++;+		newstr_segcpy( &s, p, q );+		if ( newstr_memerr( &s ) ) { ret = LIST_ERR; goto out; }+		if ( s.len ) {+			t = list_addvp( tokens, LIST_STR, (void*) &s );+			if ( !t ) { ret = LIST_ERR; goto out; }+		} else if ( !merge_delim ) {+			t = list_addvp( tokens, LIST_CHR, (void*) "" );+			if ( !t ) { ret = LIST_ERR; goto out; }+		}+		p = q;+		if ( *p ) p++; 	}+out: 	newstr_free( &s );+	return ret; } -void-list_newstrtok( list *t, newstr *s, char *sep )+int+list_tokenize( list *tokens, newstr *in, const char *delim, int merge_delim ) {-	newstr tmp;-	char *p;-	list_empty( t );-	if ( !s->len ) return;-	newstr_init( &tmp );-	p = s->data;-	while ( *p ) {-		if ( strchr( sep, *p ) ) {-			if ( tmp.len ) {-				list_add( t, tmp.data );-				newstr_empty( &tmp );-			}-		} else newstr_addchar( &tmp, *p );-		p++;-	}-	if ( tmp.len ) list_add( t, tmp.data );-	newstr_free( &tmp );+	return list_tokenizec( tokens, in->data, delim, merge_delim ); }  void
bibutils/list.h view
@@ -1,9 +1,9 @@ /*  * list.h  *- * version: 2013-04-02+ * version: 2014-11-15  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *@@ -18,13 +18,17 @@ #include <string.h> #include "newstr.h" +#define LIST_ERR (0)+#define LIST_ERR_CANNOTOPEN (-1)+#define LIST_OK  (1)+ #define LIST_CHR (0) #define LIST_STR (1)  typedef struct list { 	int n, max;-	int sorted; 	newstr *str;+	unsigned char sorted; } list;  @@ -41,40 +45,43 @@ extern void    list_delete( list * );  extern list*   list_dup( list *a );-extern void    list_copy( list *to, list *from );+extern int     list_copy( list *to, list *from ); -extern newstr * list_add( list *a, char *value );-extern newstr * list_addstr( list *a, newstr *value );-extern newstr * list_addvp( list *a, void *vp, unsigned char mode );+extern newstr * list_addvp( list *a, unsigned char mode, void *vp );+extern newstr * list_addc( list *a, const char *value );+extern newstr * list_add( list *a, newstr *value ); -extern int      list_adds( list *a, ... );+extern int      list_addvp_all( list *a, unsigned char mode, ... );+extern int      list_addc_all( list *a, ... );+extern int      list_add_all( list *a, ... ); -extern newstr * list_add_unique( list *a, char *value );-extern newstr * list_addstr_unique( list *a, newstr *value );-extern newstr * list_addvp_unique( list *a, void *vp, unsigned char mode );+extern newstr * list_addvp_unique( list *a, unsigned char mode, void *vp );+extern newstr * list_addc_unique( list *a, const char *value );+extern newstr * list_add_unique( list *a, newstr *value ); -extern void    list_append( list *a, list *toadd );-extern void    list_append_unique( list *a, list *toadd );+extern int     list_append( list *a, list *toadd );+extern int     list_append_unique( list *a, list *toadd ); -extern void    list_remove( list *a, int n );+extern int     list_remove( list *a, int n );  extern newstr* list_get( list *a, int n );-extern newstr* list_getstr( list *a, int n ); extern char*   list_getc( list *a, int n );-extern char*   list_getstr_char( list *a, int n ); +extern newstr* list_set( list *a, int n, newstr *s );+extern newstr* list_setc( list *a, int n, const char *s );+ extern void    list_sort( list *a ); -extern int     list_find( list *a, char *searchstr );-extern int     list_findnocase( list *a, char *searchstr );-extern int     list_find_or_add( list *a, char *searchstr );+extern void    list_swap( list *a, int n1, int n2 );++extern int     list_find( list *a, const char *searchstr );+extern int     list_findnocase( list *a, const char *searchstr ); extern int     list_match_entry( list *a, int n, char *s ); extern void    list_trimend( list *a, int n ); -extern int     list_fill( list *a, char *filename );-extern void    list_fillfp( list *a, FILE *fp );-extern void    list_tokenize( list *tokens, newstr *in, char delim, int merge_delim );-extern void    list_newstrtok( list *t, newstr *s, char *sep );-+extern int     list_fill( list *a, const char *filename, unsigned char skip_blank_lines );+extern int     list_fillfp( list *a, FILE *fp, unsigned char skip_blank_lines );+extern int     list_tokenize( list *tokens, newstr *in, const char *delim, int merge_delim );+extern int     list_tokenizec( list *tokens, char *p, const char *delim, int merge_delim );  #endif
bibutils/marc.c view
@@ -1,7 +1,7 @@ /*  * marc.c  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *@@ -22,8 +22,10 @@ 		"bibliography", 		"biography", 		"book",+		"calendar", 		"catalog",  		"chart",+		"comic or graphic novel", 		"comic strip", 		"conference publication", 		"database",@@ -49,9 +51,12 @@ 		"handbook", 		"history", 		"humor, satire",+		"hymnal", 		"index", 		"instruction", 		"interview",+		"issue",+		"journal", 		"kit", 		"language instruction", 		"law report or digest",@@ -86,6 +91,7 @@ 		"slide", 		"sound", 		"speech",+		"standard or specification", 		"statistics", 		"survey of literature", 		"technical drawing",@@ -95,7 +101,8 @@ 		"transparency", 		"treaty", 		"videorecording",-		"web site" +		"web site",+		"yearbook", 	}; 	int nmarc = sizeof( marc ) / sizeof( char* ); 	int i;@@ -110,11 +117,14 @@ { 	char *marc[] = {  		"cartographic",+		"kit", 		"mixed material", 		"moving image", 		"notated music", 		"software, multimedia", 		"sound recording",+		"sound recording - musical",+		"sound recording - nonmusical", 		"still image", 		"text", 		"three dimensional object"
bibutils/medin.c view
@@ -1,7 +1,7 @@ /*  * medin.c  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *@@ -18,6 +18,9 @@ #include "iso639_2.h" #include "bibutils.h" +/*****************************************************+ PUBLIC: void medin_initparams()+*****************************************************/ void medin_initparams( param *p, const char *progname ) {@@ -48,6 +51,10 @@ 	else p->progname = strdup( progname ); } +/*****************************************************+ PUBLIC: int medin_readf()+*****************************************************/+ /*  * The only difference between MEDLINE and PUBMED in format is  * that the entire library is wrapped in <MedlineCitationSet>@@ -108,25 +115,9 @@ 	return haveref; } -static inline int-xml_hasdata( xml *node )-{-	if ( node && node->value && node->value->data ) return 1;-	return 0;-}--static inline char *-xml_data( xml *node )-{-	return node->value->data;-}--static inline int-xml_tagwithdata( xml *node, char *tag )-{-	if ( !xml_hasdata( node ) ) return 0;-	return xml_tagexact( node, tag );-}+/*****************************************************+ PUBLIC: int medin_processf()+*****************************************************/  typedef struct xml_convert { 	char *in;       /* The input tag */@@ -136,75 +127,79 @@ } xml_convert;  static int-medin_doconvert( xml *node, fields *info, xml_convert *c, int nc )+medin_doconvert( xml *node, fields *info, xml_convert *c, int nc, int *found ) {-	int i, found = 0;+	int i, fstatus; 	char *d;-	if ( !xml_hasdata( node ) ) return 0;+	*found = 0;+	if ( !xml_hasdata( node ) ) return BIBL_OK; 	d = xml_data( node );-	for ( i=0; i<nc && found==0; ++i ) {+	for ( i=0; i<nc && *found==0; ++i ) { 		if ( c[i].a==NULL ) { 			if ( xml_tagexact( node, c[i].in ) ) {-				found = 1;-				fields_add( info, c[i].out, d, c[i].level );+				*found = 1;+				fstatus = fields_add( info, c[i].out, d, c[i].level );+				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 			} 		} else { 			if ( xml_tag_attrib( node, c[i].in, c[i].a, c[i].aval)){-				found = 1;-				fields_add( info, c[i].out, d, c[i].level );+				*found = 1;+				fstatus = fields_add( info, c[i].out, d, c[i].level );+				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 			} 		} 	 	}-	return found;+	return BIBL_OK; }  /* <ArticleTitle>Mechanism and.....</ArticleTitle>  */-static void+static int medin_articletitle( xml *node, fields *info ) {-	if ( xml_hasdata( node ) )-		fields_add( info, "TITLE", xml_data( node ), 0 );+	int fstatus, status = BIBL_OK;+	if ( xml_hasdata( node ) ) {+		fstatus = fields_add( info, "TITLE", xml_data( node ), 0 );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+	}+	return status; }  /*            <MedlineDate>2003 Jan-Feb</MedlineDate> */-static void-medin_medlinedate( fields *info, char *string, int level )+static int+medin_medlinedate( fields *info, char *p, int level ) {+	int fstatus; 	newstr tmp;-	char *p, *q;  	newstr_init( &tmp ); -	/* extract year */-	p = string;-	q = skip_notws( string );-	newstr_segcpy( &tmp, p, q );-	fields_add( info, "PARTYEAR", tmp.data, level );-	q = skip_ws( q );+	p = newstr_cpytodelim( &tmp, skip_ws( p ), " \t\n\r", 0 );+	if ( newstr_memerr( &tmp ) ) return BIBL_ERR_MEMERR;+	if ( tmp.len > 0 ) {+		fstatus = fields_add( info, "PARTYEAR", tmp.data, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	} -	/* extract month */-	if ( q ) {-		p = q;-		newstr_empty( &tmp );-		q = skip_notws( q );-		newstr_segcpy( &tmp, p, q );+	p = newstr_cpytodelim( &tmp, skip_ws( p ), " \t\n\r", 0 );+	if ( newstr_memerr( &tmp ) ) return BIBL_ERR_MEMERR;+	if ( tmp.len > 0 ) { 		newstr_findreplace( &tmp, "-", "/" );-		fields_add( info, "PARTMONTH", tmp.data, level );-		q = skip_ws( q );+		fstatus = fields_add( info, "PARTMONTH", tmp.data, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	} -	/* extract day */-	if ( q ) {-		p = q;-		newstr_empty( &tmp );-		q = skip_notws( q );-		newstr_segcpy( &tmp, p, q );-		fields_add( info, "PARTDAY", tmp.data, level );+	p = newstr_cpytodelim( &tmp, skip_ws( p ), " \t\n\r", 0 );+	if ( newstr_memerr( &tmp ) ) return BIBL_ERR_MEMERR;+	if ( tmp.len > 0 ) {+		fstatus = fields_add( info, "PARTDAY", tmp.data, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}  	newstr_free( &tmp );++	return BIBL_OK; }  /* <Langauge>eng</Language>@@ -213,13 +208,16 @@ medin_language( xml *node, fields *info, int level ) { 	char *code, *language;-	int ok;+	int fstatus; 	code = xml_data( node );-	if ( !code ) return 1;+	if ( !code ) return BIBL_OK; 	language = iso639_2_from_code( code );-	if ( language ) ok = fields_add( info, "LANGUAGE", language, level );-	else ok = fields_add( info, "LANGUAGE", code, level );-	return ok;+	if ( language )+		fstatus = fields_add( info, "LANGUAGE", language, level );+	else+		fstatus = fields_add( info, "LANGUAGE", code, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR; }  /* <Journal>@@ -250,7 +248,7 @@  *    <ISOAbbreviation>Alcohol Alcohol.</ISOAbbreviation>  * </Journal>  */-static void+static int medin_journal1( xml *node, fields *info ) { 	xml_convert c[] = {@@ -263,60 +261,87 @@ 		{ "Month",           NULL, NULL, "PARTMONTH",  1 }, 		{ "Day",             NULL, NULL, "PARTDAY",    1 }, 	};-	int nc = sizeof( c ) / sizeof( c[0] );;-	if ( xml_hasdata( node ) && !medin_doconvert( node, info, c, nc ) ) {-		if ( xml_tagexact( node, "MedlineDate" ) )-			medin_medlinedate( info, xml_data( node ), 1 );-		if ( xml_tagexact( node, "Language" ) )-			medin_language( node, info, 1 );+	int nc = sizeof( c ) / sizeof( c[0] ), status, found;+	if ( xml_hasdata( node ) ) {+		status = medin_doconvert( node, info, c, nc, &found );+		if ( status!=BIBL_OK ) return status;+		if ( !found ) {+			if ( xml_tagexact( node, "MedlineDate" ) ) {+				status = medin_medlinedate( info, xml_data( node ), 1 );+				if ( status!=BIBL_OK ) return status;+			}+			if ( xml_tagexact( node, "Language" ) ) {+				status = medin_language( node, info, 1 );+				if ( status!=BIBL_OK ) return status;+			}+		} 	}-	if ( node->down ) medin_journal1( node->down, info );-	if ( node->next ) medin_journal1( node->next, info );+	if ( node->down ) {+		status = medin_journal1( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = medin_journal1( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; }  /* <Pagination>  *    <MedlinePgn>12111-6</MedlinePgn>  * </Pagination>  */-static void+static int medin_pagination( xml *node, fields *info ) {+	int i, fstatus, status; 	newstr sp, ep;-	char *p;-	int i;+	char *p, *pp; 	if ( xml_tagexact( node, "MedlinePgn" ) && node->value ) { 		newstrs_init( &sp, &ep, NULL );-		p = xml_data( node );-		while ( *p && *p!='-' )-			newstr_addchar( &sp, *p++ );-		if ( *p=='-' ) p++;-		while ( *p )-			newstr_addchar( &ep, *p++ );-		if ( sp.len ) fields_add( info, "PAGESTART", sp.data, 1 );+		p = newstr_cpytodelim( &sp, xml_data( node ), "-", 1 );+		if ( newstr_memerr( &sp ) ) return BIBL_ERR_MEMERR;+		if ( sp.len ) {+			fstatus = fields_add( info, "PAGESTART", sp.data, 1 );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		}+		p = newstr_cpytodelim( &ep, p, "", 0 );+		if ( newstr_memerr( &ep ) ) return BIBL_ERR_MEMERR; 		if ( ep.len ) { 			if ( sp.len > ep.len ) { 				for ( i=sp.len-ep.len; i<sp.len; ++i ) 					sp.data[i] = ep.data[i-sp.len+ep.len];-				fields_add( info, "PAGEEND", sp.data, 1 );-			} else-				fields_add( info, "PAGEEND", ep.data, 1 );+				pp = sp.data;+			} else  pp = ep.data;+			fstatus = fields_add( info, "PAGEEND", pp, 1 );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 		} 		newstrs_free( &sp, &ep, NULL ); 	}-	if ( node->down ) medin_pagination( node->down, info );-	if ( node->next ) medin_pagination( node->next, info );+	if ( node->down ) {+		status = medin_pagination( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) {+		status = medin_pagination( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; }  /* <Abstract>  *    <AbstractText>ljwejrelr</AbstractText>  * </Abstract>  */-static void+static int medin_abstract( xml *node, fields *info ) {-	if ( xml_tagwithdata( node, "AbstractText" ) )-		fields_add( info, "ABSTRACT", xml_data( node ), 0 );-	else if ( node->next ) medin_abstract( node->next, info );+	int fstatus;+	if ( xml_tagwithdata( node, "AbstractText" ) ) {+		fstatus = fields_add( info, "ABSTRACT", xml_data( node ), 0 );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	} else if ( node->next ) return medin_abstract( node->next, info );+	return BIBL_OK; }  /* <AuthorList CompleteYN="Y">@@ -331,7 +356,7 @@  *    </Author>  * </AuthorList>  */-static void+static int medin_author( xml *node, newstr *name ) { 	char *p;@@ -357,37 +382,45 @@ 		} 	} 	if ( node->next ) medin_author( node->next, name );+	return BIBL_OK; } -static void+static int medin_corpauthor( xml *node, newstr *name ) { 	if ( xml_tagexact( node, "CollectiveName" ) ) { 		newstr_strcpy( name, xml_data( node ) ); 	} else if ( node->next ) medin_corpauthor( node->next, name );+	return BIBL_OK; } -static void+static int medin_authorlist( xml *node, fields *info ) {+	int fstatus, status; 	newstr name;+	char *tag; 	newstr_init( &name ); 	node = node->down; 	while ( node ) { 		if ( xml_tagexact( node, "Author" ) && node->down ) {-			medin_author( node->down, &name );+			status = medin_author( node->down, &name );+			tag = "AUTHOR";+			if ( !name.len ) {+				status = medin_corpauthor( node->down, &name );+				tag = "AUTHOR:CORP";+			}+			if ( newstr_memerr( &name ) || status!=BIBL_OK ) return BIBL_ERR_MEMERR; 			if ( name.len ) {-				fields_add(info,"AUTHOR",name.data,0);-			} else {-				medin_corpauthor( node->down, &name );-				if ( name.len )-					fields_add(info,"AUTHOR:CORP",name.data,0);+				fstatus = fields_add(info,tag,name.data,0);+				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 			} 			newstr_empty( &name ); 		} 		node = node->next; 	} 	newstr_free( &name );+	return BIBL_OK; }  /* <PublicationTypeList>@@ -402,13 +435,20 @@  * </MedlineJournalInfo>  */ -static void+static int medin_journal2( xml *node, fields *info ) {-	if ( xml_tagwithdata( node, "MedlineTA" ) && fields_find( info, "TITLE", 1 )==-1 )-		fields_add( info, "TITLE", xml_data( node ), 1 );-	if ( node->down ) medin_journal2( node->down, info );-	if ( node->next ) medin_journal2( node->next, info );+	int fstatus, status = BIBL_OK;+	if ( xml_tagwithdata( node, "MedlineTA" ) && fields_find( info, "TITLE", 1 )==-1 ) {+		fstatus = fields_add( info, "TITLE", xml_data( node ), 1 );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	if ( node->down ) {+		status = medin_journal2( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) status = medin_journal2( node->next, info );+	return status; }  /*@@ -421,20 +461,28 @@ </MeshHeading> </MeshHeadingList> */-static void+static int medin_meshheading( xml *node, fields *info ) {-	if ( xml_tagwithdata( node, "DescriptorName" ) )-		fields_add( info, "KEYWORD", xml_data( node ), 0 );-	if ( node->next ) medin_meshheading( node->next, info );+	int fstatus, status = BIBL_OK;+	if ( xml_tagwithdata( node, "DescriptorName" ) ) {+		fstatus = fields_add( info, "KEYWORD", xml_data( node ), 0 );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	if ( node->next ) status = medin_meshheading( node->next, info );+	return status; } -static void+static int medin_meshheadinglist( xml *node, fields *info ) {-	if ( xml_tagexact( node, "MeshHeading" ) && node->down )-		medin_meshheading( node->down, info );-	if ( node->next ) medin_meshheadinglist( node->next, info );+	int status = BIBL_OK;+	if ( xml_tagexact( node, "MeshHeading" ) && node->down ) {+		status = medin_meshheading( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) status = medin_meshheadinglist( node->next, info );+	return status; }  /* <PubmedData>@@ -449,8 +497,7 @@  *  * I think "pii" is "Publisher Item Identifier"  */--static void+static int medin_pubmeddata( xml *node, fields *info ) { 	xml_convert c[] = {@@ -459,88 +506,127 @@ 		{ "ArticleId", "IdType", "medline", "MEDLINE", 0 }, 		{ "ArticleId", "IdType", "pii",     "PII",     0 }, 	};-	int nc = sizeof( c ) / sizeof( c[0] );-	medin_doconvert( node, info, c, nc );-	if ( node->next ) medin_pubmeddata( node->next, info );-	if ( node->down ) medin_pubmeddata( node->down, info );+	int nc = sizeof( c ) / sizeof( c[0] ), found, status;+	status = medin_doconvert( node, info, c, nc, &found );+	if ( status!=BIBL_OK ) return status;+	if ( node->next ) {+		status = medin_pubmeddata( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->down ) {+		medin_pubmeddata( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	return BIBL_OK; } -static void+static int medin_article( xml *node, fields *info ) {-	if ( xml_tagexact( node, "Journal" ) ) -		medin_journal1( node, info );+	int fstatus, status = BIBL_OK;+	if ( xml_tagexact( node, "Journal" ) )+		status = medin_journal1( node, info ); 	else if ( xml_tagexact( node, "ArticleTitle" ) )-		medin_articletitle( node, info );+		status = medin_articletitle( node, info ); 	else if ( xml_tagexact( node, "Pagination" ) && node->down )-		medin_pagination( node->down, info );+		status = medin_pagination( node->down, info ); 	else if ( xml_tagexact( node, "Abstract" ) && node->down )-		medin_abstract( node->down, info );+		status = medin_abstract( node->down, info ); 	else if ( xml_tagexact( node, "AuthorList" ) )-		medin_authorlist( node, info );+		status = medin_authorlist( node, info ); 	else if ( xml_tagexact( node, "Language" ) )-		medin_language( node, info, 0 );-	else if ( xml_tagexact( node, "Affiliation" ) )-		fields_add( info, "ADDRESS", xml_data( node ), 0 );-	if ( node->next ) medin_article( node->next, info );+		status = medin_language( node, info, 0 );+	else if ( xml_tagexact( node, "Affiliation" ) ) {+		fstatus = fields_add( info, "ADDRESS", xml_data( node ), 0 );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+	}+	if ( status!=BIBL_OK ) return status;+	if ( node->next ) status = medin_article( node->next, info );+	return BIBL_OK; } -static void+static int medin_medlinecitation( xml *node, fields *info ) {-	if ( xml_tagexact( node, "PMID" ) && node->value->data )-		fields_add( info, "PMID", node->value->data, 0 );+	int fstatus, status = BIBL_OK;+	if ( xml_tagexact( node, "PMID" ) && node->value->data ) {+		fstatus = fields_add( info, "PMID", node->value->data, 0 );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	} 	if ( node->down ) {-		if ( xml_tagexact( node, "Article" ) )-			medin_article( node->down, info );-		else if ( xml_tagexact( node, "MedlineJournalInfo" ) )-			medin_journal2( node->down, info );-		else if ( xml_tagexact( node, "MeshHeadingList" ) )-			medin_meshheadinglist( node->down, info );+		if ( xml_tagexact( node, "Article" ) ) {+			status = medin_article( node->down, info );+		} else if ( xml_tagexact( node, "MedlineJournalInfo" ) ) {+			status = medin_journal2( node->down, info );+		} else if ( xml_tagexact( node, "MeshHeadingList" ) )+			status = medin_meshheadinglist( node->down, info );+		if ( status!=BIBL_OK ) return status; 	}-	if ( node->next ) medin_medlinecitation( node->next, info );+	if ( node->next ) status = medin_medlinecitation( node->next, info );+	return status; } -static void+static int medin_pubmedarticle( xml *node, fields *info ) {+	int status = BIBL_OK; 	if ( node->down ) { 		if ( xml_tagexact( node, "MedlineCitation" ) )-			medin_medlinecitation( node->down, info );+			status = medin_medlinecitation( node->down, info ); 		else if ( xml_tagexact( node, "PubmedData" ) )-			medin_pubmeddata( node->down, info );+			status = medin_pubmeddata( node->down, info );+		if ( status!=BIBL_OK ) return status; 	}-	if ( node->next ) medin_pubmedarticle( node->next, info );+	if ( node->next ) status = medin_pubmedarticle( node->next, info );+	return status; } -static void+static int medin_assembleref( xml *node, fields *info ) {+	int status = BIBL_OK; 	if ( node->down ) { 		if ( xml_tagexact( node, "PubmedArticle" ) )-			medin_pubmedarticle( node->down, info );+			status = medin_pubmedarticle( node->down, info ); 		else if ( xml_tagexact( node, "MedlineCitation" ) )-			medin_medlinecitation( node->down, info );-		else medin_assembleref( node->down, info );+			status = medin_medlinecitation( node->down, info );+		else+			status = medin_assembleref( node->down, info ); 	}+	if ( status!=BIBL_OK ) return status; -	if ( node->next ) medin_assembleref( node->next, info );+	if ( node->next ) {+		status = medin_assembleref( node->next, info );+		if ( status!=BIBL_OK ) return status;+	}+ 	/* assume everything is a journal article */ 	if ( fields_num( info ) ) {-		fields_add( info, "RESOURCE", "text", 0 );-		fields_add( info, "ISSUANCE", "continuing", 1 );-		fields_add( info, "GENRE", "periodical", 1 );-		fields_add( info, "GENRE", "academic journal", 1 );+		status = fields_add( info, "RESOURCE", "text", 0 );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		status = fields_add( info, "ISSUANCE", "continuing", 1 );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		status = fields_add( info, "GENRE", "periodical", 1 );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		status = fields_add( info, "GENRE", "academic journal", 1 );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		status = BIBL_OK; 	}++	return status; }  int medin_processf( fields *medin, char *data, char *filename, long nref ) {+	int status; 	xml top;+ 	xml_init( &top ); 	xml_tree( data, &top );-	medin_assembleref( &top, medin );+	status = medin_assembleref( &top, medin ); 	xml_free( &top );-	return 1;++	if ( status==BIBL_OK ) return 1;+	return 0; }
bibutils/medin.h view
@@ -1,7 +1,7 @@ /*  * medin.h  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *
bibutils/modsin.c view
@@ -1,7 +1,7 @@ /*  * modsin.c  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *@@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h>+#include "is_ws.h" #include "newstr.h" #include "newstr_conv.h" #include "xml.h"@@ -19,9 +20,15 @@ #include "reftypes.h" #include "modstypes.h" #include "marc.h"+#include "iso639_1.h"+#include "iso639_2.h"+#include "iso639_3.h" #include "bibutils.h" #include "modsin.h" +/*****************************************************+ PUBLIC: void modsin_initparams()+*****************************************************/ void modsin_initparams( param *p, const char *progname ) {@@ -55,113 +62,162 @@ 	else p->progname = strdup( progname ); } +/*****************************************************+ PUBLIC: int modsin_processf()+*****************************************************/+ static char modsns[]="mods"; -static void+static int modsin_detailr( xml *node, newstr *value ) {+	int status = BIBL_OK; 	if ( node->value && node->value->len ) { 		if ( value->len ) newstr_addchar( value, ' ' ); 		newstr_newstrcat( value, node->value );+		if ( newstr_memerr( value ) ) return BIBL_ERR_MEMERR; 	}-	if ( node->down ) modsin_detailr( node->down, value );-	if ( node->next ) modsin_detailr( node->next, value );+	if ( node->down ) {+		status = modsin_detailr( node->down, value );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next )+		status = modsin_detailr( node->next, value );+	return status; } -static void+static int modsin_detail( xml *node, fields *info, int level ) { 	newstr type, value, *tp;+	int fstatus, status = BIBL_OK; 	if ( node->down ) { 		newstrs_init( &type, &value, NULL ); 		tp = xml_getattrib( node, "type" ); 		if ( tp ) { 			newstr_newstrcpy( &type, tp ); 			newstr_toupper( &type );+			if ( newstr_memerr( &type ) ) goto out; 		}-		modsin_detailr( node->down, &value );+		status = modsin_detailr( node->down, &value );+		if ( status!=BIBL_OK ) goto out; 		if ( type.data && !strcasecmp( type.data, "PAGE" ) ) {-			fields_add( info, "PAGESTART", value.data, level );-		} else fields_add( info, type.data, value.data, level );+			fstatus = fields_add( info, "PAGESTART", value.data, level );+		} else {+			fstatus = fields_add( info, type.data, value.data, level );+		}+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+out: 		newstrs_free( &type, &value, NULL ); 	}+	return status; } -static void+static int modsin_date( xml *node, fields *info, int level, int part ) {-/*	char *month[12] = { "January", "February", "March", "April",-		"May", "June", "July", "August", "September", "October",-		"November", "December" };*/+	int fstatus, status = BIBL_OK;+	char *tag, *p = NULL; 	newstr s;-	char *p = NULL;-/*	int m;*/ 	if ( node->value ) p = node->value->data; 	if ( p ) { 		newstr_init( &s );-		while ( *p && *p!='-' ) newstr_addchar( &s, *p++ );-		if ( !part ) fields_add( info, "YEAR", s.data, level );-		else fields_add( info, "PARTYEAR", s.data, level );-		if ( *p=='-' ) p++;-		newstr_empty( &s );-		while ( *p && *p!='-' ) newstr_addchar( &s, *p++ );-/*		m = atoi( s.data );*/-/*		if ( m > 0 && m < 13 )  {-			if ( !part ) fields_add( info, "MONTH", month[m-1], level );-			else fields_add( info, "PARTMONTH", month[m-1], level );-		} else {*/-			if ( !part ) fields_add( info, "MONTH", s.data, level );-			else fields_add( info, "PARTMONTH", s.data, level );-/*		}*/-		if ( *p=='-' ) p++;-		newstr_empty( &s );-		while ( *p ) newstr_addchar( &s, *p++ );-		if ( !part ) fields_add( info, "DAY", s.data, level );-		else fields_add( info, "PARTDAY", s.data, level );++		p = newstr_cpytodelim( &s, skip_ws( p ), "-", 1 );+		if ( newstr_memerr( &s ) ) { status = BIBL_ERR_MEMERR; goto out; }+		if ( s.len ) {+			tag = ( part ) ? "PARTYEAR" : "YEAR";+			fstatus =  fields_add( info, tag, s.data, level );+			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+		}++		p = newstr_cpytodelim( &s, skip_ws( p ), "-", 1 );+		if ( newstr_memerr( &s ) ) { status = BIBL_ERR_MEMERR; goto out; }+		if ( s.len ) {+			tag = ( part ) ? "PARTMONTH" : "MONTH";+			fstatus =  fields_add( info, tag, s.data, level );+			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+		}++		p = newstr_cpytodelim( &s, skip_ws( p ), "", 0 );+		if ( newstr_memerr( &s ) ) { status = BIBL_ERR_MEMERR; goto out; }+		if ( s.len ) {+			tag = ( part ) ? "PARTDAY" : "DAY";+			fstatus =  fields_add( info, tag, s.data, level );+			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+		}+out: 		newstr_free( &s ); 	}+	return status; } -static void+static int modsin_pager( xml *node, newstr *sp, newstr *ep, newstr *tp, newstr *lp ) {+	int status = BIBL_OK; 	if ( xml_tagexact( node, "start" ) ) { 		newstr_newstrcpy( sp, node->value );+		if ( newstr_memerr( sp ) ) return BIBL_ERR_MEMERR; 	} else if ( xml_tagexact( node, "end" ) ) { 		newstr_newstrcpy( ep, node->value );+		if ( newstr_memerr( ep ) ) return BIBL_ERR_MEMERR; 	} else if ( xml_tagexact( node, "total" ) ) { 		newstr_newstrcpy( tp, node->value );+		if ( newstr_memerr( tp ) ) return BIBL_ERR_MEMERR; 	} else if ( xml_tagexact( node, "list" ) ) { 		newstr_newstrcpy( lp, node->value );+		if ( newstr_memerr( lp ) ) return BIBL_ERR_MEMERR; 	}-	if ( node->down ) modsin_pager( node->down, sp, ep, tp, lp );-	if ( node->next ) modsin_pager( node->next, sp, ep, tp, lp );+	if ( node->down ) {+		status = modsin_pager( node->down, sp, ep, tp, lp );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next )+		status = modsin_pager( node->next, sp, ep, tp, lp );+	return status; } -static void+static int modsin_page( xml *node, fields *info, int level ) {+	int fstatus, status = BIBL_OK; 	newstr sp, ep, tp, lp;-	if ( node->down ) {-		newstrs_init( &sp, &ep, &tp, &lp, NULL );-		modsin_pager( node->down, &sp, &ep, &tp, &lp );-		if ( sp.len || ep.len ) {-			if ( sp.len )-				fields_add( info, "PAGESTART", sp.data, level );-			if ( ep.len )-				fields_add( info, "PAGEEND", ep.data, level );-		} else if ( lp.len ) {-			fields_add( info, "PAGESTART", lp.data, level );+	xml *dnode = node->down;++	if ( !dnode ) return BIBL_OK;++	newstrs_init( &sp, &ep, &tp, &lp, NULL );++	status = modsin_pager( dnode, &sp, &ep, &tp, &lp );+	if ( status!=BIBL_OK ) goto out;++	if ( sp.len || ep.len ) {+		if ( sp.len ) {+			fstatus = fields_add( info, "PAGESTART", sp.data, level );+			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; } 		}-		if ( tp.len )-			fields_add( info, "TOTALPAGES", tp.data, level );-		newstrs_free( &sp, &ep, &tp, &lp, NULL );+		if ( ep.len ) {+			fstatus = fields_add( info, "PAGEEND", ep.data, level );+			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+		}+	} else if ( lp.len ) {+		fstatus = fields_add( info, "PAGESTART", lp.data, level );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; } 	}+	if ( tp.len ) {+		fstatus = fields_add( info, "TOTALPAGES", tp.data, level );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+	}+out:+	newstrs_free( &sp, &ep, &tp, &lp, NULL );+	return BIBL_OK; } -static void+static int modsin_titler( xml *node, newstr *title, newstr *subtitle ) {+	int status = BIBL_OK; 	if ( xml_tagexact( node, "title" ) ) { 		if ( title->len ) { 			newstr_strcat( title, " : " );@@ -169,34 +225,54 @@ 		} else { 			newstr_newstrcat( title, node->value ); 		}-	} else if ( xml_tagexact( node, "subTitle" ) )+		if ( newstr_memerr( title ) ) return BIBL_ERR_MEMERR;+	} else if ( xml_tagexact( node, "subTitle" ) ) { 		newstr_newstrcat( subtitle, node->value );-	if ( node->down ) modsin_titler( node->down, title, subtitle );-	if ( node->next ) modsin_titler( node->next, title, subtitle );+		if ( newstr_memerr( subtitle ) ) return BIBL_ERR_MEMERR;+	}+	if ( node->down ) {+		status = modsin_titler( node->down, title, subtitle );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next )+		status = modsin_titler( node->next, title, subtitle );+	return status; } -static void+static int modsin_title( xml *node, fields *info, int level ) {+	char *titletag[2][2] = {+		{ "TITLE",    "SHORTTITLE" },+		{ "SUBTITLE", "SHORTSUBTITLE" },+	};+	int fstatus, status = BIBL_OK; 	newstr title, subtitle;-	int abbr = xml_tag_attrib( node, "titleInfo", "type", "abbreviated" );-	if ( node->down ) {-		newstrs_init( &title, &subtitle, NULL );-		modsin_titler( node->down, &title, &subtitle );-		if ( title.len ) {-			if ( abbr )-				fields_add( info, "SHORTTITLE", title.data, level );-			else-				fields_add( info, "TITLE", title.data, level );-		}-		if ( subtitle.len ) {-			if ( abbr )-				fields_add( info, "SHORTSUBTITLE", subtitle.data, level );-			else-				fields_add( info, "SUBTITLE", subtitle.data, level );-		}-		newstrs_free( &title, &subtitle, NULL );+	xml *dnode = node->down;+	int abbr;++	dnode = node->down;+	if ( !dnode ) return status;++	newstrs_init( &title, &subtitle, NULL );+	abbr = xml_tag_attrib( node, "titleInfo", "type", "abbreviated" );++	status = modsin_titler( dnode, &title, &subtitle );+	if ( status!=BIBL_OK ) goto out;++	if ( title.len ) {+		fstatus = fields_add( info, titletag[0][abbr], title.data, level );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; } 	}++	if ( subtitle.len ) {+		fstatus = fields_add( info, titletag[1][abbr], subtitle.data, level );+		if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }+	}++out:+	newstrs_free( &title, &subtitle, NULL );+	return status; }  /* modsin_marcrole_convert()@@ -207,7 +283,7 @@  * Take input strings with roles separated by '|' characters, e.g.  * "author" or "author|creator" or "edt" or "editor|edt".  */-static void+static int modsin_marcrole_convert( newstr *s, char *suffix, newstr *out ) { 	convert roles[] = {@@ -228,7 +304,7 @@ 		{ "pth",                 "ASSIGNEE" } 	}; 	int nroles = sizeof( roles ) / sizeof( roles[0] );-	int i, nmismatch, n = -1;+	int i, nmismatch, n = -1, status = BIBL_OK; 	char *p, *q;  	if ( s->len == 0 ) {@@ -259,25 +335,36 @@ 	} else { 		newstr_strcpy( out, s->data ); 	}+	if ( newstr_memerr( out ) ) status = BIBL_ERR_MEMERR;+	return status; } -static void+static int modsin_asis_corp_r( xml *node, newstr *name, newstr *role ) {-	if ( xml_tagexact( node, "namePart" ) )+	int status = BIBL_OK;+	if ( xml_tagexact( node, "namePart" ) ) { 		newstr_newstrcpy( name, node->value );-	else if ( xml_tagexact( node, "roleTerm" ) ) {+		if ( newstr_memerr( name ) ) return BIBL_ERR_MEMERR;+	} else if ( xml_tagexact( node, "roleTerm" ) ) { 		if ( role->len ) newstr_addchar( role, '|' ); 		newstr_newstrcat( role, node->value );+		if ( newstr_memerr( role ) ) return BIBL_ERR_MEMERR; 	}-	if ( node->down ) modsin_asis_corp_r( node->down, name, role );-	if ( node->next ) modsin_asis_corp_r( node->next, name, role );+	if ( node->down ) {+		status = modsin_asis_corp_r( node->down, name, role );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next )+		status = modsin_asis_corp_r( node->next, name, role );+	return status; } -static void+static int modsin_personr( xml *node, newstr *name, newstr *suffix, newstr *roles ) { 	newstr outname;+	int status = BIBL_OK; 	newstr_init( &outname ); 	if ( xml_tagexact( node, "namePart" ) ) { 		if ( xml_tag_attrib( node, "namePart", "type", "family" ) ) {@@ -297,150 +384,242 @@ 		if ( roles->len ) newstr_addchar( roles, '|' ); 		newstr_newstrcat( roles, node->value ); 	}-	if ( node->down ) modsin_personr( node->down, name, suffix, roles );-	if ( node->next ) modsin_personr( node->next, name, suffix, roles );+	if ( node->down ) {+		status = modsin_personr( node->down, name, suffix, roles );+		if ( status!=BIBL_OK ) goto out;+	}+	if ( node->next ) status = modsin_personr( node->next, name, suffix, roles );+out: 	newstr_free( &outname );+	return status; } -static void+static int modsin_asis_corp( xml *node, fields *info, int level, char *suffix ) {+	int fstatus, status = BIBL_OK; 	newstr name, roles, role_out; 	xml *dnode = node->down; 	if ( dnode ) { 		newstrs_init( &name, &roles, &role_out, NULL );-		modsin_asis_corp_r( dnode, &name, &roles );-		modsin_marcrole_convert( &roles, suffix, &role_out );-		fields_add( info, role_out.data, name.data, level );+		status = modsin_asis_corp_r( dnode, &name, &roles );+		if ( status!=BIBL_OK ) goto out;+		status = modsin_marcrole_convert( &roles, suffix, &role_out );+		if ( status!=BIBL_OK ) goto out;+		fstatus = fields_add( info, role_out.data, name.data, level );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+out: 		newstrs_free( &name, &roles, &role_out, NULL ); 	}+	return status; } -static void+static int modsin_person( xml *node, fields *info, int level ) {-	newstr name, suffix, roles, role, role_out;+	newstr name, suffix, roles, role_out;+	int fstatus, status = BIBL_OK; 	xml *dnode = node->down; 	if ( dnode ) {-		newstrs_init( &name, &suffix, &role, &roles, &role_out, NULL );-		modsin_personr( dnode, &name, &suffix, &roles );-		modsin_marcrole_convert( &roles, NULL, &role_out );+		newstrs_init( &name, &suffix, &roles, &role_out, NULL );++		status = modsin_personr( dnode, &name, &suffix, &roles );+		if ( status!=BIBL_OK ) goto out; 		if ( suffix.len ) { 			newstr_strcat( &name, "||" ); 			newstr_newstrcat( &name, &suffix );+			if ( newstr_memerr( &name ) ) { status=BIBL_ERR_MEMERR; goto out; } 		}-		fields_add( info, role_out.data, name.data, level );-		newstrs_free( &name, &suffix, &role, &roles, NULL );++		status = modsin_marcrole_convert( &roles, NULL, &role_out );+		if ( status!=BIBL_OK ) goto out;++		fstatus = fields_add( info, role_out.data, name.data, level );+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+out:+		newstrs_free( &name, &suffix, &roles, &role_out, NULL ); 	}+	return status; } -static void-modsin_placeterm( xml *node, fields *info, int level, int school )+static int+modsin_placeterm_text( xml *node, fields *info, int level, int school ) {-	char address_tag[] = "ADDRESS",-	     addresscode_tag[] = "CODEDADDRESS",-	     school_tag[] = "SCHOOL",-	     *newtag;-	newstr *type, s;+	char address_tag[] = "ADDRESS";+	char school_tag[]  = "SCHOOL";+	char *tag;+	int fstatus; -	newtag = ( school ) ? school_tag : address_tag;+	tag = ( school ) ? school_tag : address_tag; +	fstatus = fields_add( info, tag, xml_data( node ), level );+	if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;++	return BIBL_OK;+}++static int+modsin_placeterm_code( xml *node, fields *info, int level )+{+	int fstatus, status = BIBL_OK;+	newstr s, *auth;++	newstr_init( &s );++	auth = xml_getattrib( node, "authority" );+	if ( auth && auth->len ) {+		newstr_newstrcpy( &s, auth );+		newstr_addchar( &s, '|' );+	}+	newstr_newstrcat( &s, node->value );++	if ( newstr_memerr( &s ) ) {+		status = BIBL_ERR_MEMERR;+		goto out;+	}++	fstatus = fields_add( info, "CODEDADDRESS", s.data, level );+	if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;+out:+	newstr_free( &s );+	return status;+}++static int+modsin_placeterm( xml *node, fields *info, int level, int school )+{+	int status = BIBL_OK;+	newstr *type;+ 	type = xml_getattrib( node, "type" ); 	if ( type && type->len ) {-		if ( !strcmp( type->data, "text" ) ) {-			fields_add( info, newtag, node->value->data, level );-		} else if ( !strcmp( type->data, "code" ) ) {-			newstr_init( &s );-			type = xml_getattrib( node, "authority" );-			if ( type && type->len ) newstr_newstrcpy(&s, type);-			newstr_addchar( &s, '|' );-			newstr_newstrcat( &s, node->value );-			fields_add( info, addresscode_tag, s.data, level );-			newstr_free( &s );-		}+		if ( !strcmp( type->data, "text" ) )+			status = modsin_placeterm_text( node, info, level, school );+		else if ( !strcmp( type->data, "code" ) )+			status = modsin_placeterm_code( node, info, level ); 	}++	return status; } -static void+static int modsin_placer( xml *node, fields *info, int level, int school ) {+	int status = BIBL_OK; 	if ( xml_tag_attrib( node, "place", "type", "school" ) ) { 		school = 1; 	} else if ( xml_tagexact( node, "placeTerm" ) ) {-		modsin_placeterm( node, info, level, school );+		status = modsin_placeterm( node, info, level, school ); 	}-	if ( node->down ) modsin_placer( node->down, info, level, school );-	if ( node->next ) modsin_placer( node->next, info, level, school );+	if ( node->down ) {+		status = modsin_placer( node->down, info, level, school );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) status = modsin_placer( node->next, info, level, school );+	return status; } -static void+static int modsin_origininfor( xml *node, fields *info, int level, newstr *pub, newstr *add, newstr *addc, newstr *ed, newstr *iss ) {+	int status = BIBL_OK; 	if ( xml_tagexact( node, "dateIssued" ) )-		modsin_date( node, info, level, 0 );-	else if ( xml_tagexact( node, "publisher" ) )+		status = modsin_date( node, info, level, 0 );+	else if ( xml_tagexact( node, "publisher" ) && xml_hasdata( node ) ) { 		newstr_newstrcat( pub, node->value );-	else if ( xml_tagexact( node, "edition" ) )+		if ( newstr_memerr( pub ) ) return BIBL_ERR_MEMERR;+	} else if ( xml_tagexact( node, "edition" ) && xml_hasdata( node ) ) { 		newstr_newstrcat( ed, node->value );-	else if ( xml_tagexact( node, "issuance" ) )+		if( newstr_memerr( ed ) ) return BIBL_ERR_MEMERR;+	} else if ( xml_tagexact( node, "issuance" ) && xml_hasdata( node ) ) { 		newstr_newstrcat( iss, node->value );-	else if ( xml_tagexact( node, "place" ) )-		modsin_placer( node, info, level, 0 );-	if ( node->down )-		modsin_origininfor( node->down, info, level, pub, add, -				addc, ed, iss );-	if ( node->next ) modsin_origininfor( node->next, info, level, pub, add, addc, ed, iss );+		if ( newstr_memerr( iss ) ) return BIBL_ERR_MEMERR;+	} else if ( xml_tagexact( node, "place" ) && xml_hasdata( node ) )+		status = modsin_placer( node, info, level, 0 );+	if ( status!=BIBL_OK ) return status;+	if ( node->down ) {+		status = modsin_origininfor( node->down, info, level, pub, add, addc, ed, iss );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next )+		status = modsin_origininfor( node->next, info, level, pub, add, addc, ed, iss );+	return status; } -static void+static int modsin_origininfo( xml *node, fields *info, int level ) { 	newstr publisher, address, addcode, edition, issuance;+	int fstatus, status = BIBL_OK; 	if ( node->down ) { 		newstrs_init( &publisher, &address, &addcode, &edition, &issuance, NULL );-		modsin_origininfor( node->down, info, level, &publisher, +		status = modsin_origininfor( node->down, info, level, &publisher,  				&address, &addcode, &edition, &issuance );-		if ( publisher.len )-			fields_add( info, "PUBLISHER", publisher.data, level );-		if ( address.len )-			fields_add( info, "ADDRESS", address.data, level );-		if ( addcode.len )-			fields_add( info, "CODEDADDRESS", addcode.data, level );-		if ( edition.len )-			fields_add( info, "EDITION", edition.data, level );-		if ( issuance.len ) -			fields_add( info, "ISSUANCE", issuance.data, level );+		if ( status!=BIBL_OK ) goto out;+		if ( publisher.len ) {+			fstatus = fields_add( info, "PUBLISHER", publisher.data, level );+			if ( fstatus!=FIELDS_OK ) { status=BIBL_ERR_MEMERR; goto out; }+		}+		if ( address.len ) {+			fstatus = fields_add( info, "ADDRESS", address.data, level );+			if ( fstatus!=FIELDS_OK ) { status=BIBL_ERR_MEMERR; goto out; }+		}+		if ( addcode.len ) {+			fstatus = fields_add( info, "CODEDADDRESS", addcode.data, level );+			if ( fstatus!=FIELDS_OK ) { status=BIBL_ERR_MEMERR; goto out; }+		}+		if ( edition.len ) {+			fstatus = fields_add( info, "EDITION", edition.data, level );+			if ( fstatus!=FIELDS_OK ) { status=BIBL_ERR_MEMERR; goto out; }+		}+		if ( issuance.len ) {+			fstatus = fields_add( info, "ISSUANCE", issuance.data, level );+			if ( fstatus!=FIELDS_OK ) { status=BIBL_ERR_MEMERR; goto out; }+		}+out: 		newstrs_free( &publisher, &address, &addcode, &edition, &issuance, NULL ); 	}+	return status; } -static void+static int modsin_subjectr( xml *node, fields *info, int level ) {+	int fstatus, status = BIBL_OK; 	if ( xml_tagexact( node, "topic" ) || xml_tagexact( node, "geographic" )) {-		fields_add( info, "KEYWORD", node->value->data, level );+		fstatus = fields_add( info, "KEYWORD", node->value->data, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}-	if ( node->down ) modsin_subjectr( node->down, info, level );-	if ( node->next ) modsin_subjectr( node->next, info, level );+	if ( node->down ) {+		status = modsin_subjectr( node->down, info, level );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) status = modsin_subjectr( node->next, info, level );+	return status; } -static void+static int modsin_subject( xml *node, fields *info, int level ) {-	if ( node->down ) modsin_subjectr( node->down, info, level );+	int status = BIBL_OK;+	if ( node->down ) status = modsin_subjectr( node->down, info, level );+	return status; } -static void+static int modsin_id1( xml *node, fields *info, int level ) {+	int fstatus; 	newstr *ns; 	ns = xml_getattrib( node, "ID" );-	if ( ns ) {-		fields_add( info, "REFNUM", ns->data, level );+	if ( ns && ns->len ) {+		fstatus = fields_add( info, "REFNUM", ns->data, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}+	return BIBL_OK; } -static void+static int modsin_genre( xml *node, fields *info, int level ) { 	char *added[] = { "manuscript", "academic journal", "magazine",@@ -451,181 +630,234 @@ 		"press release", "television broadcast", "electronic" 	}; 	int nadded = sizeof( added ) /sizeof( char *);-	int j, ismarc = 0, isadded = 0;-	if ( node->value && node->value->len ) {-		if ( marc_findgenre( node->value->data )!=-1 ) ismarc = 1;-		for ( j=0; j<nadded && ismarc==0 && isadded==0; ++j ) {-			if ( !strcasecmp( node->value->data, added[j] ) )-				isadded = 1;-		}-		if ( ismarc || isadded ) -			fields_add( info, "GENRE", node->value->data, level );-		else-			fields_add( info, "NGENRE", node->value->data, level );+	int i, ismarc = 0, isadded = 0, fstatus;+	char *d;++	if ( !xml_hasdata( node ) ) return BIBL_OK;+	d = xml_data( node );+	if ( marc_findgenre( d )!=-1 ) ismarc = 1;+	if ( !ismarc ) {+		for ( i=0; i<nadded && ismarc==0 && isadded==0; ++i )+			if ( !strcasecmp( d, added[i] ) ) isadded = 1; 	}-} -static void-modsin_resource( xml *node, fields *info, int level )-{-	if ( node->value && node->value->len )-		fields_add( info, "RESOURCE", node->value->data, level );+	if ( ismarc || isadded ) +		fstatus = fields_add( info, "GENRE", d, level );+	else+		fstatus = fields_add( info, "NGENRE", d, level );+	if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;++	return BIBL_OK; } -static void+/* in MODS version 3.5+ * <languageTerm type="text">....</languageTerm>+ * <languageTerm type="code" authority="xxx">...</languageTerm>+ * xxx = rfc3066+ * xxx = iso639-2b+ * xxx = iso639-3+ * xxx = rfc4646+ * xxx = rfc5646+ */+static int modsin_languager( xml *node, fields *info, int level ) {-	if ( xml_tag_attrib( node, "languageTerm", "type", "text" ) ) {-		if ( node->value && node->value->len )-			fields_add( info, "LANGUAGE", node->value->data, level );+	int fstatus, status = BIBL_OK;+	char *d = NULL;+	if ( xml_tagexact( node, "languageTerm" ) ) {+		if ( xml_hasdata( node ) ) {+			if ( xml_hasattrib( node, "type", "code" ) ) {+				if ( xml_hasattrib( node, "authority", "iso639-1" ) )+					d = iso639_1_from_code( xml_data( node ) );+				else if ( xml_hasattrib( node, "authority", "iso639-2b" ) )+					d = iso639_2_from_code( xml_data( node ) );+				else if ( xml_hasattrib( node, "authority", "iso639-3" ))+					d = iso639_3_from_code( xml_data( node ) );+			}+			if ( !d ) d  = xml_data( node );+			fstatus = fields_add( info, "LANGUAGE", d, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		} 	}-	if ( node->next ) modsin_languager( node->next, info, level );+	if ( node->next ) status = modsin_languager( node->next, info, level );+	return status; } -static void+static int modsin_language( xml *node, fields *info, int level ) {+	int fstatus, status = BIBL_OK; 	/* Old versions of MODS had <language>English</language> */-	if ( node->value && node->value->len )-		fields_add( info, "LANGUAGE", node->value->data, level );+	if ( xml_hasdata( node ) ) {+		fstatus = fields_add( info, "LANGUAGE", xml_data( node ), level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}  	/* New versions of MODS have <language><languageTerm>English</languageTerm></language> */-	if ( node->down ) modsin_languager( node->down, info, level );-}--static void-modsin_toc( xml *node, fields *info, int level )-{-	if ( node->value && node->value->len )-		fields_add( info, "CONTENTS", node->value->data, level );-}--static void-modsin_note( xml *node, fields *info, int level )-{-	if ( node->value && node->value->len )-		fields_add( info, "NOTES", node->value->data, level );-}--static void-modsin_annote( xml *node, fields *info, int level )-{-	if ( node->value && node->value->len )-		fields_add( info, "ANNOTE", node->value->data, level );+	if ( node->down ) status = modsin_languager( node->down, info, level );+	return status; } -static void-modsin_abstract( xml *node, fields *info, int level )+static int+modsin_simple( xml *node, fields *info, char *tag, int level ) {-	if ( node->value && node->value->len )-		fields_add( info, "ABSTRACT", node->value->data, level );+	int fstatus;+	if ( xml_hasdata( node ) ) {+		fstatus = fields_add( info, tag, xml_data( node ), level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	}+	return BIBL_OK; } -static void+static int modsin_locationr( xml *node, fields *info, int level ) {-	char url[]="URL", school[]="SCHOOL", loc[]="LOCATION";-	char fileattach[]="FILEATTACH", *tag=NULL;--	if ( xml_tag_attrib( node, "url", "access", "raw object" ) ) {-		tag = fileattach;-	} else if ( xml_tagexact( node, "url" ) ) {-		tag = url;-	}+	int fstatus, status = BIBL_OK;+	char *tag=NULL; -	if ( xml_tag_attrib( node, "physicalLocation", "type", "school" ) ) {-		tag = school;+	if ( xml_tagexact( node, "url" ) ) {+		if ( xml_hasattrib( node, "access", "raw object" ) )+			tag = "FILEATTACH";+		else+			tag = "URL"; 	} else if ( xml_tagexact( node, "physicalLocation" ) ) {-		tag = loc;+		if ( xml_hasattrib( node, "type", "school" ) )+			tag = "SCHOOL";+		else+			tag = "LOCATION"; 	} -	if ( tag ) fields_add( info, tag, node->value->data, level );+	if ( tag ) {+		fstatus = fields_add( info, tag, node->value->data, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+	} -	if ( node->down ) modsin_locationr( node->down, info, level );-	if ( node->next ) modsin_locationr( node->next, info, level );+	if ( node->down ) {+		status = modsin_locationr( node->down, info, level );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) status = modsin_locationr( node->next, info, level );+	return status; } -static void+static int modsin_location( xml *node, fields *info, int level ) {-	if ( node->down ) modsin_locationr( node->down, info, level );+	int status = BIBL_OK;+	if ( node->down ) status = modsin_locationr( node->down, info, level );+	return status; } -static void+static int modsin_descriptionr( xml *node, newstr *s ) {+	int status = BIBL_OK; 	if ( xml_tagexact( node, "extent" ) || 	     xml_tagexact( node, "note" ) ) { 		newstr_newstrcpy( s, node->value );+		if ( newstr_memerr( s ) ) return BIBL_ERR_MEMERR; 	}-	if ( node->down ) modsin_descriptionr( node->down, s );-	if ( node->next ) modsin_descriptionr( node->next, s );+	if ( node->down ) {+		status = modsin_descriptionr( node->down, s );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) status = modsin_descriptionr( node->next, s );+	return status; } -static void+static int modsin_description( xml *node, fields *info, int level ) {+	int fstatus, status = BIBL_OK; 	newstr s; 	newstr_init( &s );-	if ( node->down ) modsin_descriptionr( node->down, &s );-	else {-		if ( node->value && node->value->data );-		newstr_newstrcpy( &s, node->value );+	if ( node->down ) {+		status = modsin_descriptionr( node->down, &s );+		if ( status!=BIBL_OK ) goto out;+	} else {+		if ( node->value && node->value->len > 0 )+			newstr_newstrcpy( &s, node->value );+		if ( newstr_memerr( &s ) ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		} 	}-	if ( s.len ) fields_add( info, "DESCRIPTION", s.data, level );+	if ( s.len ) {+		fstatus = fields_add( info, "DESCRIPTION", s.data, level );+		if ( fstatus!=FIELDS_OK ) {+			status = BIBL_ERR_MEMERR;+			goto out;+		}+	}+out: 	newstr_free( &s );+	return BIBL_OK; } -static void+static int modsin_partr( xml *node, fields *info, int level ) {+	int status = BIBL_OK; 	if ( xml_tagexact( node, "detail" ) )-		modsin_detail( node, info, level );+		status = modsin_detail( node, info, level ); 	else if ( xml_tag_attrib( node, "extent", "unit", "page" ) )-		modsin_page( node, info, level );+		status = modsin_page( node, info, level ); 	else if ( xml_tag_attrib( node, "extent", "unit", "pages" ) )-		modsin_page( node, info, level );+		status = modsin_page( node, info, level ); 	else if ( xml_tagexact( node, "date" ) )-		modsin_date( node, info, level, 1 );-	if ( node->next ) modsin_partr( node->next, info, level );+		status = modsin_date( node, info, level, 1 );+	if ( status!=BIBL_OK ) return status;+	if ( node->next ) status = modsin_partr( node->next, info, level );+	return status; } -static void+static int modsin_part( xml *node, fields *info, int level ) {-	if ( node->down ) modsin_partr( node->down, info, level );+	if ( node->down ) return modsin_partr( node->down, info, level );+	return BIBL_OK; }  /* <classification authority="lcc">Q3 .A65</classification> */-static void+static int modsin_classification( xml *node, fields *info, int level ) {-	if ( node->value && node->value->len ) {-		if (xml_tag_attrib(node, "classification", "authority", "lcc")){-			fields_add( info, "LCC", node->value->data, level );-		} else-		 fields_add( info, "CLASSIFICATION", node->value->data, level );+	int fstatus, status = BIBL_OK;+	char *tag, *d;+	if ( xml_hasdata( node ) ) {+		d = xml_data( node );+		if ( xml_tag_attrib( node, "classification", "authority", "lcc" ) )+			tag = "LCC";+		else+			tag = "CLASSIFICATION";+		fstatus = fields_add( info, tag, d, level );+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}-	if ( node->down ) modsin_classification( node->down, info, level );+	if ( node->down ) status = modsin_classification( node->down, info, level );+	return status; } -static void+static int modsin_recordinfo( xml *node, fields *info, int level ) {+	int fstatus; 	xml *curr;+	char *d;  	/* extract recordIdentifier */ 	curr = node; 	while ( curr ) {-		if ( xml_tagexact( curr, "recordIdentifier" ) ) {-			fields_add( info, "REFNUM", curr->value->data, level );+		if ( xml_tagexact( curr, "recordIdentifier" ) && xml_hasdata( curr ) ) {+			d = xml_data( curr );+			fstatus = fields_add( info, "REFNUM", d, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 		} 		curr = curr->next; 	}-+	return BIBL_OK; } -static void+static int modsin_identifier( xml *node, fields *info, int level ) { 	convert ids[] = {@@ -645,87 +877,118 @@ 		{ "accessnum",     "ACCESSNUM"    }, 		{ "jstor",         "JSTOR"        }, 	};-	int i , n = sizeof( ids ) / sizeof( ids[0] );-	if ( !node->value || !node->value->data ) return;+	int i, fstatus, n = sizeof( ids ) / sizeof( ids[0] );+	if ( !node->value || node->value->len==0 ) return BIBL_OK; 	for ( i=0; i<n; ++i ) {-		if ( xml_tag_attrib( node, "identifier", "type", ids[i].mods ) )-			fields_add( info, ids[i].internal, node->value->data, level );+		if ( xml_tag_attrib( node, "identifier", "type", ids[i].mods ) ) {+			fstatus = fields_add( info, ids[i].internal, node->value->data, level );+			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;+		} 	}+	return BIBL_OK; } -static void+static int modsin_mods( xml *node, fields *info, int level ) {-	if ( xml_tagexact( node, "titleInfo" ) )-		modsin_title( node, info, level );-	else if ( xml_tag_attrib( node, "name", "type", "personal" ) )-		modsin_person( node, info, level );-	else if ( xml_tag_attrib( node, "name", "type", "corporate" ) )-		modsin_asis_corp( node, info, level, ":CORP" );-	else if ( xml_tagexact( node, "name" ) )-		modsin_asis_corp( node, info, level, ":ASIS" );-	else if ( xml_tagexact( node, "recordInfo" ) && node->down )-		modsin_recordinfo( node->down, info, level );-	else if  ( xml_tagexact( node, "part" ) )-		modsin_part( node, info, level );-	else if ( xml_tagexact( node, "identifier" ) )-		modsin_identifier( node, info, level );-	else if ( xml_tagexact( node, "originInfo" ) )-		modsin_origininfo( node, info, level );-	else if ( xml_tagexact( node, "typeOfResource" ) )-		modsin_resource( node, info, level );-	else if ( xml_tagexact( node, "language" ) )-		modsin_language( node, info, level );-	else if ( xml_tagexact( node, "tableOfContents" ) )-		modsin_toc( node, info, level );-	else if ( xml_tagexact( node, "genre" ) )-		modsin_genre( node, info, level );-	else if ( xml_tagexact( node, "date" ) )-		modsin_date( node, info, level, 0 );-	else if ( xml_tagexact( node, "note" ) )-		modsin_note( node, info, level );-	else if ( xml_tagexact( node, "bibtex-annote" ) )-		modsin_annote( node, info, level );-	else if ( xml_tagexact( node, "abstract" ) )-		modsin_abstract( node, info, level );-	else if ( xml_tagexact( node, "subject" ) )-		modsin_subject( node, info, level );-	else if ( xml_tagexact( node, "classification" ) )-		modsin_classification( node, info, level );-	else if ( xml_tagexact( node, "location" ) )-		modsin_location( node, info, level );-	else if ( xml_tagexact( node, "physicalDescription" ) )-		modsin_description( node, info, level );-	else if ( xml_tag_attrib( node, "relatedItem", "type", "host" ) ||-		  xml_tag_attrib( node, "relatedItem", "type", "series" ) ) {-		if ( node->down ) modsin_mods( node->down, info, level+1 );+	convert simple[] = {+		{ "note",            "NOTES" },+		{ "abstract",        "ABSTRACT" },+		{ "bibtex-annote",   "ANNOTE" },+		{ "typeOfResource",  "RESOURCE" },+		{ "tableOfContents", "CONTENTS" },+	};+	int nsimple = sizeof( simple ) / sizeof( simple[0] );+	int i, found = 0, status = BIBL_OK;++	for ( i=0; i<nsimple && found==0; i++ ) {+		if ( xml_tagexact( node, simple[i].mods ) ) {+			status = modsin_simple( node, info, simple[i].internal, level );+			if ( status!=BIBL_OK ) return status;+			found = 1;+		} 	} -	if ( node->next ) modsin_mods( node->next, info, level );+	if ( !found ) {+		if ( xml_tagexact( node, "titleInfo" ) )+			modsin_title( node, info, level );+		else if ( xml_tag_attrib( node, "name", "type", "personal" ) )+			status = modsin_person( node, info, level );+		else if ( xml_tag_attrib( node, "name", "type", "corporate" ) )+			status = modsin_asis_corp( node, info, level, ":CORP" );+		else if ( xml_tagexact( node, "name" ) )+			status = modsin_asis_corp( node, info, level, ":ASIS" );+		else if ( xml_tagexact( node, "recordInfo" ) && node->down )+			status = modsin_recordinfo( node->down, info, level );+		else if  ( xml_tagexact( node, "part" ) )+			modsin_part( node, info, level );+		else if ( xml_tagexact( node, "identifier" ) )+			status = modsin_identifier( node, info, level );+		else if ( xml_tagexact( node, "originInfo" ) )+			status = modsin_origininfo( node, info, level );+		else if ( xml_tagexact( node, "language" ) )+			status = modsin_language( node, info, level );+		else if ( xml_tagexact( node, "genre" ) )+			status = modsin_genre( node, info, level );+		else if ( xml_tagexact( node, "date" ) )+			status = modsin_date( node, info, level, 0 );+		else if ( xml_tagexact( node, "subject" ) )+			status = modsin_subject( node, info, level );+		else if ( xml_tagexact( node, "classification" ) )+			status = modsin_classification( node, info, level );+		else if ( xml_tagexact( node, "location" ) )+			status = modsin_location( node, info, level );+		else if ( xml_tagexact( node, "physicalDescription" ) )+			status = modsin_description( node, info, level );+		else if ( xml_tag_attrib( node, "relatedItem", "type", "host" ) ||+			  xml_tag_attrib( node, "relatedItem", "type", "series" ) ) {+			if ( node->down ) status = modsin_mods( node->down, info, level+1 );+		}+		if ( status!=BIBL_OK ) return status;+	} +	if ( node->next ) status = modsin_mods( node->next, info, level );++	return status; } -static void+static int modsin_assembleref( xml *node, fields *info ) {+	int status = BIBL_OK; 	if ( xml_tagexact( node, "mods" ) ) {-		modsin_id1( node, info, 0 );-		if ( node->down ) modsin_mods( node->down, info, 0 );-	} else if ( node->down ) modsin_assembleref( node->down, info );-	if ( node->next ) modsin_assembleref( node->next, info );+		status = modsin_id1( node, info, 0 );+		if ( status!=BIBL_OK ) return status;+		if ( node->down ) {+			status = modsin_mods( node->down, info, 0 );+			if ( status!=BIBL_OK ) return status;+		}+	} else if ( node->down ) {+		status = modsin_assembleref( node->down, info );+		if ( status!=BIBL_OK ) return status;+	}+	if ( node->next ) status = modsin_assembleref( node->next, info );+	return status; }  int modsin_processf( fields *modsin, char *data, char *filename, long nref ) {+	int status; 	xml top;+ 	xml_init( &top ); 	xml_tree( data, &top );-	modsin_assembleref( &top, modsin );+	status = modsin_assembleref( &top, modsin ); 	xml_free( &top );-	return 1;++	if ( status==BIBL_OK ) return 1;+	else return 0; } +/*****************************************************+ PUBLIC: int modsin_readf()+*****************************************************/  static char * modsin_startptr( char *p )
bibutils/modsin.h view
@@ -1,7 +1,7 @@ /*  * modsin.h  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *
bibutils/modsout.c view
@@ -1,7 +1,7 @@ /*  * modsout.c  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Source code released under the GPL version 2  *@@ -30,7 +30,7 @@ 	p->latexout         = 0; 	p->utf8out          = 1; 	p->utf8bom          = 1;-	p->xmlout           = 1;+	p->xmlout           = BIBL_XMLOUT_TRUE; 	p->nosplittitle     = 0; 	p->verbose          = 0; 	p->addcount         = 0;@@ -386,6 +386,7 @@ 		{ "issuance",	  "ISSUANCE",	0 }, 		{ "publisher",	  "PUBLISHER",	0 }, 		{ "place",	  "ADDRESS",	1 },+		{ "place",	  "AUTHORADDRESS",	0 }, 		{ "edition",	  "EDITION",	0 }, 		{ "dateCaptured", "URLDATE",    0 } 	};@@ -571,9 +572,10 @@ static int output_partpages( fields *f, FILE *outptr, int level, int wrote_header ) {-	convert parts[3] = {+	convert parts[4] = { 		{ "",  "PAGESTART",                -1 }, 		{ "",  "PAGEEND",                  -1 },+		{ "",  "PAGES",                    -1 }, 		{ "",  "TOTALPAGES",               -1 } 	}; 	int nparts = sizeof(parts)/sizeof(parts[0]);@@ -591,13 +593,16 @@ 			mods_output_detail( f, outptr, parts[1].code, 				"page", level ); 		if ( parts[2].code!=-1 )+			mods_output_detail( f, outptr, parts[2].code,+				"page", level );+		if ( parts[3].code!=-1 ) 			mods_output_extents( f, outptr, -1, -1,-					parts[2].code, "page", level ); +					parts[3].code, "page", level ); 	} 	/* If both PAGESTART and PAGEEND are defined */ 	else { 		mods_output_extents( f, outptr, parts[0].code, -			parts[1].code, parts[2].code, "page", level ); +			parts[1].code, parts[3].code, "page", level ); 	}  	return 1;@@ -763,6 +768,7 @@ { 	convert sn_types[] = { 		{ "isbn",      "ISBN",      0 },+		{ "isbn",      "ISBN13",    0 }, 		{ "lccn",      "LCCN",      0 }, 		{ "issn",      "ISSN",      0 }, 		{ "citekey",   "REFNUM",    0 },
bibutils/modsout.h view
@@ -1,7 +1,7 @@ /*  * modsout.h  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Source code released under the GPL version 2  *
bibutils/name.c view
@@ -3,7 +3,7 @@  *  * mangle names w/ and w/o commas  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *@@ -363,13 +363,14 @@ int name_addmultielement( fields *info, char *tag, list *tokens, int begin, int end, int level ) {+	int status, ok = 1; 	newstr name;-	int ok;  	newstr_init( &name );  	name_construct_multi( &name, tokens, begin, end );-	ok = fields_add( info, tag, name.data, level );+	status = fields_add( info, tag, name.data, level );+	if ( status!=FIELDS_OK ) ok = 0;  	newstr_free( &name ); @@ -386,13 +387,14 @@ int name_addsingleelement( fields *info, char *tag, char *name, int level, int corp ) {+	int status, ok = 1; 	newstr outtag;-	int ok; 	newstr_init( &outtag ); 	newstr_strcpy( &outtag, tag ); 	if ( !corp ) newstr_strcat( &outtag, ":ASIS" ); 	else newstr_strcat( &outtag, ":CORP" );-	ok = fields_add( info, outtag.data, name, level );+	status = fields_add( info, outtag.data, name, level );+	if ( status!=FIELDS_OK ) ok = 0; 	newstr_free( &outtag ); 	return ok; }@@ -428,7 +430,7 @@ 	}  	newstr_findreplace( inname, ",", ", " );-	list_tokenize( &tokens, inname, ' ', 1 );+	list_tokenize( &tokens, inname, " ", 1 );  	if ( tokens.n==1 ) { 		newstr_newstrcpy( outname, inname );@@ -486,7 +488,7 @@ int name_add( fields *info, char *tag, char *q, int level, list *asis, list *corps ) {-	int ok, nametype, ret = 1;+	int ok, status, nametype, ret = 1; 	newstr inname, outname; 	list tokens; @@ -500,10 +502,12 @@ 		q = name_copy( &inname, q );  		nametype = name_parse( &outname, &inname, asis, corps );-		if ( !nametype ) return 0;+		if ( !nametype ) { ret = 0; goto out; } -		if ( nametype==1 )-			ok = fields_add( info, tag, outname.data, level );+		if ( nametype==1 ) {+			status = fields_add( info, tag, outname.data, level );+			ok = ( status==FIELDS_OK ) ? 1 : 0;+		} 		else if ( nametype==2 ) 			ok = name_addsingleelement( info, tag, outname.data, level, 0 ); 		else@@ -515,7 +519,7 @@  out: 	newstrs_free( &inname, &outname, NULL );-	newstr_free( &outname );+	list_free( &tokens );  	return ret; }
bibutils/name.h view
@@ -3,7 +3,7 @@  *  * mangle names w/ and w/o commas  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *
bibutils/newstr.c view
@@ -1,9 +1,9 @@ /*  * newstr.c  *- * Version: 04/21/13+ * Version: 04/27/14  *- * Copyright (c) Chris Putnam 1999-2013+ * Copyright (c) Chris Putnam 1999-2014  *  * Source code released under the GPL version 2  *@@ -20,10 +20,17 @@ #include "newstr.h" #include "is_ws.h" +/* Do not use asserts in NEWSTR_NOASSERT defined */+#ifdef NEWSTR_NOASSERT+#define NDEBUG+#endif #include <assert.h>  #define newstr_initlen (64) ++/* Clear memory in resize/free if NEWSTR_PARANOIA defined */+ #ifndef NEWSTR_PARANOIA  static void @@ -43,11 +50,8 @@ 	s->dim = size; } -/* define as no-op */-static inline void-newstr_nullify( newstr *s )-{-}+/* define as a no-op */+#define newstr_nullify( s )  #else @@ -91,7 +95,7 @@ }  void-newstr_initstr( newstr *s, char *initstr )+newstr_initstr( newstr *s, const char *initstr ) { 	assert( s ); 	assert( initstr );@@ -113,15 +117,27 @@ 	va_end( ap ); } +/*+ * This is currently a stub. Later it will+ * report whether or not a newstr function+ * could not be performed due to a memory+ * error.+ */+int+newstr_memerr( newstr *s )+{+	return 0;+}+ void newstr_mergestrs( newstr *s, ... ) { 	va_list ap;-	char *cp;+	const char *cp; 	newstr_empty( s ); 	va_start( ap, s ); 	do {-		cp = va_arg( ap, char * );+		cp = va_arg( ap, const char * ); 		if ( cp ) newstr_strcat( s, cp ); 	} while ( cp ); 	va_end( ap );@@ -180,6 +196,14 @@ }  void+newstr_delete( newstr *s )+{+	assert( s );+	newstr_free( s );+	free( s );+}++void newstr_empty( newstr *s ) { 	assert( s );@@ -208,10 +232,11 @@ newstr_addchar( newstr *s, char newchar ) { 	assert( s );+	if ( newchar=='\0' ) return; /* appending '\0' is a null operation */ 	if ( !s->data || s->dim==0 )  		newstr_initalloc( s, newstr_initlen ); 	if ( s->len + 2 > s->dim ) -		newstr_realloc( s, s->len+2 );+		newstr_realloc( s, s->len*2 ); 	s->data[s->len++] = newchar; 	s->data[s->len] = '\0'; }@@ -224,8 +249,8 @@  * Since we can progress more than one byte at p, return the  * properly updated pointer p.  */-char *-newstr_addutf8( newstr *s, char *p )+const char *+newstr_addutf8( newstr *s, const char *p ) { 	if ( ! ((*p) & 128 ) ) { 		newstr_addchar( s, *p );@@ -247,11 +272,12 @@ }  void-newstr_prepend( newstr *s, char *addstr )+newstr_prepend( newstr *s, const char *addstr ) { 	unsigned long lenaddstr, i; 	assert( s && addstr ); 	lenaddstr = strlen( addstr );+	if ( lenaddstr==0 ) return; 	if ( !s->data || !s->dim ) 		newstr_initalloc( s, lenaddstr+1 ); 	else {@@ -276,7 +302,7 @@ }  static inline void -newstr_strcat_internal( newstr *s, char *addstr, unsigned long n )+newstr_strcat_internal( newstr *s, const char *addstr, unsigned long n ) { 	newstr_strcat_ensurespace( s, n ); 	strncat( &(s->data[s->len]), addstr, n );@@ -293,7 +319,7 @@ }  void-newstr_strcat( newstr *s, char *addstr )+newstr_strcat( newstr *s, const char *addstr ) { 	unsigned long n; 	assert( s && addstr );@@ -304,41 +330,78 @@ void newstr_segcat( newstr *s, char *startat, char *endat ) {-	size_t seglength;-	char *p, *q;+	unsigned long n;+	char *p;  	assert( s && startat && endat ); 	assert( (size_t) startat < (size_t) endat ); -	seglength=(size_t) endat - (size_t) startat;-	if ( !s->data || !s->dim )-		newstr_initalloc( s, seglength+1 );-	else {-		if ( s->len + seglength + 1 > s->dim )-			newstr_realloc( s, s->len + seglength+1 );-	}-	q = &(s->data[s->len]);+	if ( startat==endat ) return;++	n = 0; 	p = startat;-	while ( *p && p!=endat ) *q++ = *p++;-	*q = '\0';-	s->len += seglength;+	while ( p!=endat ) {+		n++;+		p++;+	}++	newstr_strcat_internal( s, startat, n ); } +void+newstr_indxcat( newstr *s, char *p, unsigned long start, unsigned long stop )+{+	unsigned long i;+	assert( s && p );+	assert( start <= stop );+	for ( i=start; i<stop; ++i )+		newstr_addchar( s, p[i] );+}++/* newstr_cpytodelim()+ *     term      = string of characters to be used as terminators+ *     finalstep = set to non-zero to position return value past the+ *                 terminating character+ */+char *+newstr_cpytodelim( newstr *s, char *p, const char *delim, unsigned char finalstep )+{+	newstr_empty( s );+	return newstr_cattodelim( s, p, delim, finalstep );+}++/* newstr_cpytodelim()+ *     term      = string of characters to be used as terminators+ *     finalstep = set to non-zero to position return value past the+ *                 terminating character+ */+char *+newstr_cattodelim( newstr *s, char *p, const char *delim, unsigned char finalstep )+{+	while ( p && *p && !strchr( delim, *p ) ) {+		newstr_addchar( s, *p );+		p++;+	}+	if ( *p && finalstep ) p++;+	return p;+}+ static inline void newstr_strcpy_ensurespace( newstr *s, unsigned long n ) { 	unsigned long m = n + 1; 	if ( !s->data || !s->dim ) 		newstr_initalloc( s, m );-	else if ( n+1 > s->dim ) +	else if ( m > s->dim ) 		newstr_realloc( s, m ); }  static inline void-newstr_strcpy_internal( newstr *s, char *p, unsigned long n )+newstr_strcpy_internal( newstr *s, const char *p, unsigned long n ) { 	newstr_strcpy_ensurespace( s, n );-	strcpy( s->data, p );+	strncpy( s->data, p, n );+	s->data[n] = '\0'; 	s->len = n; } @@ -352,7 +415,7 @@ }  void -newstr_strcpy( newstr *s, char *addstr )+newstr_strcpy( newstr *s, const char *addstr ) { 	unsigned long n; 	assert( s && addstr );@@ -360,65 +423,63 @@ 	newstr_strcpy_internal( s, addstr, n ); } -newstr *-newstr_strdup( char *s1 )+/* newstr_segcpy( s, start, end );+ *+ * copies [start,end) into s+ */+void+newstr_segcpy( newstr *s, char *startat, char *endat ) {-	newstr *s2 = newstr_new();-	if ( s2 )-		newstr_strcpy( s2, s1 );-	return s2;+	unsigned long n;+	char *p;++	assert( s && startat && endat );+	assert( ((size_t) startat) <= ((size_t) endat) );++	if ( startat==endat ) {+		newstr_empty( s );+		return;+	}++	n = 0;+	p = startat;+	while ( p!=endat ) {+		p++;+		n++;+	}++	newstr_strcpy_internal( s, startat, n ); }  /*  * newstr_indxcpy( s, in, start, stop );  *- * copies in[start] to in[stop] (includes stop) into s+ * copies in[start,stop) (excludes stop) into s  */ void-newstr_indxcpy( newstr *s, char *p, int start, int stop )+newstr_indxcpy( newstr *s, char *p, unsigned long start, unsigned long stop ) {-	int i;-	assert( s );-	assert( p );+	unsigned long i;+	assert( s && p ); 	assert( start <= stop );+	if ( start == stop ) {+		newstr_empty( s );+		return;+	} 	newstr_strcpy_ensurespace( s, stop-start+1 );-	for ( i=start; i<=stop; ++i )+	for ( i=start; i<stop; ++i ) 		s->data[i-start] = p[i];-	s->data[i] = '\0';-	s->len = stop-start+1;-}--void-newstr_indxcat( newstr *s, char *p, int start, int stop )-{-	int i;-	assert( s );-	assert( p );-	assert( start <= stop );-	for ( i=start; i<=stop; ++i )-		newstr_addchar( s, p[i] );+	s->len = stop-start;+	s->data[s->len] = '\0'; } -/* newstr_segcpy( s, start, end );- *- * copies [start,end) into s- */-void-newstr_segcpy( newstr *s, char *startat, char *endat )+newstr *+newstr_strdup( const char *s1 ) {-	size_t n;-	char *p, *q;--	assert( s && startat && endat );-	assert( ((size_t) startat) <= ((size_t) endat) );--	n = (size_t) endat - (size_t) startat;-	newstr_strcpy_ensurespace( s, n );-	q = s->data;-	p = startat;-	while ( *p && p!=endat ) *q++ = *p++;-	*q = '\0';-	s->len = n;+	newstr *s2 = newstr_new();+	if ( s2 )+		newstr_strcpy( s2, s1 );+	return s2; }  void@@ -446,7 +507,7 @@  */  int-newstr_findreplace( newstr *s, char *find, char *replace )+newstr_findreplace( newstr *s, const char *find, const char *replace ) { 	long diff; 	size_t findstart, searchstart;@@ -503,6 +564,7 @@ { 	int  bufpos = *pbufpos, done = 0; 	char *ok;+	assert( fp && outs ); 	newstr_empty( outs ); 	while ( !done ) { 		while ( buf[bufpos] && buf[bufpos]!='\r' && buf[bufpos]!='\n' )@@ -573,29 +635,26 @@ void newstr_trimstartingws( newstr *s ) {-	unsigned char still_ws;-	unsigned long n, m;+	char *p, *q;+	int n;  	assert( s );  	if ( s->len==0 || !is_ws( s->data[0] ) ) return; -	m = n = 0;-	still_ws = 1;-	while ( m <= s->len ) {-		if ( still_ws && !is_ws( s->data[ m ] ) ) {-			still_ws = 0;-		}-		if ( !still_ws ) {-			s->data[ n ] = s->data[ m ];-			n++;-		}-		m++;+	n = 0;+	p = s->data;+	while ( is_ws( *p ) ) p++;++	q = s->data;+	while ( *p ) {+		*q++ = *p++;+		n++; 	}+	*q = '\0';  	s->len = n; }-	  void newstr_trimendingws( newstr *s )@@ -610,6 +669,7 @@ int newstr_match_first( newstr *s, char ch ) {+	assert( s ); 	if ( !s->len ) return 0; 	if ( s->data[0] == ch ) return 1; 	return 0;@@ -618,37 +678,81 @@ int newstr_match_end( newstr *s, char ch ) {+	assert( s ); 	if ( !s->len ) return 0; 	if ( s->data[ s->len - 1 ] == ch ) return 1; 	return 0; }  void-newstr_trimbegin( newstr *s, int n )+newstr_trimbegin( newstr *s, unsigned long n ) {-	int i;+	char *p, *q;+ 	assert( s );-	if ( s->len - n < 1 ) newstr_empty( s );-	for ( i=1; i<=s->len; ++i ) /* pick up '\0' with '<=' */-		s->data[i-1] = s->data[i];-	s->len -= n;++	if ( n==0 ) return;+	if ( s->len==0 ) return;+	if ( n >= s->len ) {+		newstr_empty( s );+		return;+	}++	p = s->data;+	while ( n-- > 0 ) p++;++	n = 0;+	q = s->data;+	while ( *p ) {+		*q++ = *p++;+		n++;+	}+	*q = '\0';++	s->len = n; }  void-newstr_trimend( newstr *s, int n )+newstr_trimend( newstr *s, unsigned long n ) { 	assert( s );-	if ( s->len - n < 1 ) newstr_empty( s );-	else {-		s->len -= n;-		s->data[ s->len ] = '\0';++	if ( n==0 ) return;+	if ( n >= s->len ) {+		newstr_empty( s );+		return; 	}++	s->len -= n;+	s->data[ s->len ] = '\0'; } +void+newstr_pad( newstr *s, unsigned long len, char ch )+{+	unsigned long i;+	assert( s );+	for ( i=s->len; i<len; i++ )+		newstr_addchar( s, ch );+}++void+newstr_copyposlen( newstr *s, newstr *in, unsigned long pos, unsigned long len )+{+	unsigned long i, max;+	assert( s );+	newstr_empty( s );+	max = pos+len;+	if ( max > in->len ) max = in->len;+	for ( i=pos; i<max; ++i )+		newstr_addchar( s, in->data[i] );+}+ static void newstr_check_case( newstr *s, int *lowercase, int *uppercase ) { 	int i;+	assert( s ); 	*lowercase = 0; 	*uppercase = 0; 	if ( s->len < 1 ) return;@@ -709,31 +813,28 @@ }  int-newstr_newstrcmp( newstr *s, newstr *t )+newstr_newstrcmp( const newstr *s, const newstr *t ) { 	assert( s ); 	assert( t ); 	if ( s->len == 0 && t->len == 0 ) return 0;+	if ( s->len == 0 ) return strcmp( "", t->data );+	if ( t->len == 0 ) return strcmp( s->data, "" ); 	return strcmp( s->data, t->data ); }  void newstr_reverse( newstr *s ) {-	newstr ns;-	unsigned long i;-+	unsigned long i, max;+	char tmp; 	assert( s );--	if ( s->len==0 ) return;-	newstr_init( &ns );-	i = s->len;-	do {-		i--;-		newstr_addchar( &ns, s->data[i] );-	} while ( i>0 );-	newstr_swapstrings( s, &ns );-	newstr_free( &ns );+	max = s->len / 2;+	for ( i=0; i<max; ++i ) {+		tmp = s->data[ i ];+		s->data[ i ] = s->data[ s->len - 1 - i ];+		s->data[ s->len - 1 - i ] = tmp;+	} }  int@@ -741,11 +842,15 @@ { 	int ch, eol = 0; 	assert( s );+	assert( fp ); 	newstr_empty( s ); 	if ( feof( fp ) ) return 0; 	while ( !feof( fp ) && !eol ) { 		ch = fgetc( fp );-		if ( ch == EOF ) eol = 1;+		if ( ch == EOF ) {+			if ( s->len ) return 1;+			else return 0;+		} 		else if ( ch == '\n' ) eol = 1; 		else if ( ch == '\r' ) { 			ch = fgetc( fp );@@ -761,14 +866,15 @@ /*  * s = "Hi!\0", s.len = 3  *- * newstr_char( s, 0 ) = 'H'  newstr_revchar( s, 0 ) = '\0'- * newstr_char( s, 1 ) = 'i'  newstr_revchar( s, 1 ) = '!'- * newstr_char( s, 2 ) = '!'  newstr_revchar( s, 2 ) = 'i'- * newstr_char( s, 3 ) = '\0' newstr_revchar( s, 3 ) = 'H'+ * newstr_char( s, 0 ) = 'H'  newstr_revchar( s, 0 ) = '!'+ * newstr_char( s, 1 ) = 'i'  newstr_revchar( s, 1 ) = 'i'+ * newstr_char( s, 2 ) = '!'  newstr_revchar( s, 2 ) = 'H'+ * newstr_char( s, 3 ) = '\0' newstr_revchar( s, 3 ) = '\0'  */ char newstr_char( newstr *s, unsigned long n ) {+	assert( s ); 	if ( s->len==0 || n >= s->len ) return '\0'; 	return s->data[ n ]; }@@ -776,6 +882,20 @@ char newstr_revchar( newstr *s, unsigned long n ) {+	assert( s ); 	if ( s->len==0 || n >= s->len ) return '\0';-	return s->data[ s->len - n ];+	return s->data[ s->len - n - 1];+}++void+newstr_makepath( newstr *path, const char *dirname, const char *filename, char sep )+{+	assert( path );+	if ( dirname ) newstr_strcpy( path, dirname );+	else newstr_empty( path );++	if ( path->len && path->data[path->len-1]!=sep )+		newstr_addchar( path, sep );++	if ( filename ) newstr_strcat( path, filename ); }
bibutils/newstr.h view
@@ -1,9 +1,9 @@ /*  * newstr.h  *- * Version: 04/21/13+ * Version: 04/27/14  *- * Copyright (c) Chris Putnam 1999-2013+ * Copyright (c) Chris Putnam 1999-2014  *  * Source code released under the GPL version 2  *@@ -20,9 +20,10 @@ }  newstr;  newstr *newstr_new         ( void ); +void    newstr_delete      ( newstr *s );  void    newstr_init        ( newstr *s );-void    newstr_initstr     ( newstr *s, char *initstr );+void    newstr_initstr     ( newstr *s, const char *initstr ); void    newstr_empty       ( newstr *s ); void    newstr_free        ( newstr *s ); @@ -31,52 +32,70 @@ void    newstrs_free       ( newstr *s, ... );  void newstr_mergestrs   ( newstr *s, ... );-newstr *newstr_strdup   ( char *buf );+newstr *newstr_strdup   ( const char *p ); void newstr_addchar     ( newstr *s, char newchar ); void newstr_reverse     ( newstr *s );-char *newstr_addutf8    ( newstr *s, char *p );-void newstr_strcat      ( newstr *s, char *addstr );+const char *newstr_addutf8    ( newstr *s, const char *p );+void newstr_strcat      ( newstr *s, const char *addstr ); void newstr_newstrcat   ( newstr *s, newstr *old ); void newstr_segcat      ( newstr *s, char *startat, char *endat );-void newstr_prepend     ( newstr *s, char *addstr );-void newstr_strcpy      ( newstr *s, char *addstr );+char *newstr_cpytodelim  ( newstr *s, char *p, const char *delim, unsigned char finalstep );+char *newstr_cattodelim  ( newstr *s, char *p, const char *delim, unsigned char finalstep );+void newstr_prepend     ( newstr *s, const char *addstr );+void newstr_strcpy      ( newstr *s, const char *addstr ); void newstr_newstrcpy   ( newstr *s, newstr *old ); void newstr_segcpy      ( newstr *s, char *startat, char *endat ); void newstr_segdel      ( newstr *s, char *startat, char *endat );-void newstr_indxcpy     ( newstr *s, char *p, int start, int stop );-void newstr_indxcat     ( newstr *s, char *p, int start, int stop );+void newstr_indxcpy     ( newstr *s, char *p, unsigned long start, unsigned long stop );+void newstr_indxcat     ( newstr *s, char *p, unsigned long start, unsigned long stop ); void newstr_fprintf     ( FILE *fp, newstr *s ); int  newstr_fget        ( FILE *fp, char *buf, int bufsize, int *pbufpos,                           newstr *outs ); char newstr_char        ( newstr *s, unsigned long n ); char newstr_revchar     ( newstr *s, unsigned long n ); int  newstr_fgetline    ( newstr *s, FILE *fp );-int  newstr_findreplace ( newstr *s, char *find, char *replace );+int  newstr_findreplace ( newstr *s, const char *find, const char *replace ); void newstr_toupper     ( newstr *s ); void newstr_tolower     ( newstr *s ); void newstr_trimstartingws( newstr *s ); void newstr_trimendingws( newstr *s ); void newstr_swapstrings ( newstr *s1, newstr *s2 );+void newstr_stripws     ( newstr *s );  int  newstr_match_first ( newstr *s, char ch ); int  newstr_match_end   ( newstr *s, char ch );-void newstr_trimbegin   ( newstr *s, int n );-void newstr_trimend     ( newstr *s, int n );+void newstr_trimbegin   ( newstr *s, unsigned long n );+void newstr_trimend     ( newstr *s, unsigned long n ); +void newstr_pad         ( newstr *s, unsigned long len, char ch );+void newstr_copyposlen  ( newstr *s, newstr *in, unsigned long pos, unsigned long len );++void newstr_makepath    ( newstr *path, const char *dirname, const char *filename, char sep );++ int  newstr_is_mixedcase( newstr *s ); int  newstr_is_lowercase( newstr *s ); int  newstr_is_uppercase( newstr *s ); -int newstr_newstrcmp    ( newstr *s, newstr *t );+int  newstr_newstrcmp    ( const newstr *s, const newstr *t ); -/* NEWSTR_PARANOIA+int  newstr_memerr( newstr *s );+++/* #define NEWSTR_PARANOIA  *  * set to clear memory before it is freed or reallocated  * note that this is slower...may be important if string  * contains sensitive information  */ -#undef NEWSTR_PARANOIA+/* #define NEWSTR_NOASSERT+ *+ * set to turn off the use of asserts (and associated call to exit)+ * in newstr functions...useful for library construction for+ * Linux distributions that don't want libraries calling exit, but+ * not useful during code development+ */  #endif 
bibutils/newstr_conv.c view
@@ -1,7 +1,7 @@ /*  * newstr_conv.c  *- * Copyright (c) Chris Putnam 1999-2013+ * Copyright (c) Chris Putnam 1999-2014  *  * Source code released under the GPL version 2  *@@ -50,13 +50,13 @@ }  static void-addutf8char( newstr *s, unsigned int ch, int xmlout, int utf8out )+addutf8char( newstr *s, unsigned int ch, int xmlout ) { 	unsigned char code[6]; 	int nc, i; 	if ( xmlout ) { 		if ( minimalxmlchars( s, ch ) ) return;-		if ( ch > 127 && xmlout > 1 )+		if ( ch > 127 && xmlout == NEWSTR_CONV_XMLOUT_ENTITIES ) 			{ addentity( s, ch ); return; } 	} 	nc = utf8_encode( ch, code );@@ -65,13 +65,13 @@ }  static void-addgb18030char( newstr *s, unsigned int ch, int xmlout, int utf8out )+addgb18030char( newstr *s, unsigned int ch, int xmlout ) { 	unsigned char code[4]; 	int nc, i; 	if ( xmlout ) { 		if ( minimalxmlchars( s, ch ) ) return;-		if ( ch > 127 && xmlout > 1 )+		if ( ch > 127 && xmlout == NEWSTR_CONV_XMLOUT_ENTITIES ) 			{ addentity( s, ch ); return; } 	} 	nc = gb18030_encode( ch, code );@@ -89,7 +89,7 @@ 	 * output the unicode. 	 */ 	if ( utf8out && !strcmp( buf, "?" ) ) {-		addutf8char( s, ch, xmlout, utf8out );+		addutf8char( s, ch, xmlout ); 	} else { 		newstr_strcat( s, buf ); 	}@@ -151,9 +151,9 @@ 	if ( latexout ) { 		addlatexchar( s, ch, xmlout, utf8out ); 	} else if ( utf8out ) {-		addutf8char( s, ch, xmlout, utf8out );+		addutf8char( s, ch, xmlout ); 	} else if ( charsetout==CHARSET_GB18030 ) {-		addgb18030char( s, ch, xmlout, utf8out );+		addgb18030char( s, ch, xmlout ); 	} else { 		c = charset_lookupuni( charsetout, ch ); 		if ( xmlout ) addxmlchar( s, c );@@ -173,9 +173,9 @@ 	unsigned int pos = 0; 	unsigned int ch; 	newstr ns;-	int ok;+	int ok = 1; -	if ( !s || s->len==0 ) return 1;+	if ( !s || s->len==0 ) return ok;  	newstr_init( &ns ); @@ -185,13 +185,13 @@ 	while ( s->data[pos] ) { 		ch = get_unicode( s, &pos, charsetin, latexin, utf8in, xmlin ); 		ok = write_unicode( &ns, ch, charsetout, latexout, utf8out, xmlout );-		if ( !ok ) return 0;+		if ( !ok ) goto out; 	}  	newstr_swapstrings( s, &ns );-+out: 	newstr_free( &ns ); -	return 1;+	return ok; } 
bibutils/newstr_conv.h view
@@ -1,13 +1,17 @@ /*  * newstring_conv.h  *- * Copyright (c) Chris Putnam 1999-2013+ * Copyright (c) Chris Putnam 1999-2014  *  * Source code released under the GPL version 2  *  */ #ifndef NEWSTR_CONV_H #define NEWSTR_CONV_H++#define NEWSTR_CONV_XMLOUT_FALSE    (0)+#define NEWSTR_CONV_XMLOUT_TRUE     (1)+#define NEWSTR_CONV_XMLOUT_ENTITIES (3)  #include "newstr.h" 
bibutils/risin.c view
@@ -1,7 +1,7 @@ /*  * risin.c  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Source code released under the GPL version 2  *@@ -20,6 +20,9 @@ #include "doi.h" #include "risin.h" +/*****************************************************+ PUBLIC: void risin_initparams()+*****************************************************/ void risin_initparams( param *p, const char *progname ) {@@ -49,6 +52,10 @@ 	else p->progname = strdup( progname ); } +/*****************************************************+ PUBLIC: int risin_readf()+*****************************************************/+ /* RIS definition of a tag is strict:     character 1 = uppercase alphabetic character     character 2 = uppercase alphabetic character or digit@@ -130,6 +137,10 @@ 	return haveref; } +/*****************************************************+ PUBLIC: int risin_processf()+*****************************************************/+ static char* process_line2( newstr *tag, newstr *data, char *p ) {@@ -161,7 +172,7 @@ risin_processf( fields *risin, char *p, char *filename, long nref ) { 	newstr tag, data;-	int n;+	int status, n;  	newstrs_init( &tag, &data, NULL ); @@ -170,7 +181,8 @@ 		p = process_line( &tag, &data, p ); 		/* no anonymous fields allowed */ 		if ( tag.len )-			fields_add( risin, tag.data, data.data, 0 );+			status = fields_add( risin, tag.data, data.data, 0 );+			if ( status!=FIELDS_OK ) return 0; 		} else { 			p = process_line2( &tag, &data, p ); 			n = fields_num( risin );@@ -188,15 +200,42 @@ 	return 1; } +/*****************************************************+ PUBLIC: int risin_typef()+*****************************************************/++int+risin_typef( fields *risin, char *filename, int nref, param *p, variants *all, int nall )+{+	char *refnum = "";+	int n, reftype, nreftype;+	n = fields_find( risin, "TY", 0 );+	nreftype = fields_find( risin, "ID", 0 );+	if ( nreftype!=-1 ) refnum = risin[n].data->data;+	if ( n!=-1 )+		reftype = get_reftype( (risin[n].data)->data, nref, p->progname,+			all, nall, refnum );+	else+		reftype = get_reftype( "", nref, p->progname, all, nall, refnum ); /*default */+	return reftype;+}++/*****************************************************+ PUBLIC: int risin_convertf()+*****************************************************/+ /* oxfordjournals hide the DOI in the NOTES N1 field */ static int risin_addnotes( fields *f, char *tag, newstr *s, int level ) {-	int doi = is_doi( s->data );+	int doi, status;+	doi = is_doi( s->data ); 	if ( doi!=-1 )-		return fields_add( f, "DOI", &(s->data[doi]), level );+		status = fields_add( f, "DOI", &(s->data[doi]), level ); 	else-		return fields_add( f, tag, s->data, level );+		status = fields_add( f, tag, s->data, level );+	if ( status==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR; }  static int@@ -221,35 +260,45 @@ static int risin_addfile( fields *f, char *tag, newstr *s, int level ) {+	int status, n; 	char *p;-	int n;  	/* if URL is file:///path/to/xyz.pdf, only store "///path/to/xyz.pdf" */ 	n = is_uri_file_scheme( s->data ); 	if ( n ) { 		/* skip past "file:" and store only actual path */ 		p = s->data + n;-		return fields_add( f, tag, p, level );+		status = fields_add( f, tag, p, level );+		if ( status==FIELDS_OK ) return BIBL_OK;+		else return BIBL_ERR_MEMERR; 	}  	/* if URL is http:, ftp:, etc. store as a URL */ 	n = is_uri_remote_scheme( s->data ); 	if ( n ) {-		return fields_add( f, "URL", s->data, level );+		status = fields_add( f, "URL", s->data, level );+		if ( status==FIELDS_OK ) return BIBL_OK;+		else return BIBL_ERR_MEMERR; 	}  	/* badly formed, RIS wants URI, but store value anyway */-	return fields_add( f, tag, s->data, level );+	status = fields_add( f, tag, s->data, level );+	if ( status==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR; }  /* scopus puts DOI in the DO or DI tag, but it needs cleaning */ static int risin_adddoi( fields *f, char *tag, newstr *s, int level ) {-	int doi = is_doi( s->data );-	if ( doi!=-1 )-		return fields_add( f, "DOI", &(s->data[doi]), level );-	else return 1;+	int status, doi;+	doi = is_doi( s->data );+	if ( doi!=-1 ) {+		status = fields_add( f, "DOI", &(s->data[doi]), level );+		if ( status==FIELDS_OK ) return BIBL_OK;+		else return BIBL_ERR_MEMERR;+	}+	else return BIBL_OK; }  static int@@ -257,60 +306,46 @@ { 	char *p = d->data; 	newstr date;-	int part = ( !strncasecmp( tag, "PART", 4 ) ), ok;+	int part, status; +	part = ( !strncasecmp( tag, "PART", 4 ) );+ 	newstr_init( &date ); 	while ( *p && *p!='/' ) newstr_addchar( &date, *p++ ); 	if ( *p=='/' ) p++; 	if ( date.len>0 ) {-		if ( part ) ok = fields_add( f, "PARTYEAR", date.data, level );-		else        ok = fields_add( f, "YEAR",     date.data, level );-		if ( !ok ) return 0;+		if ( part ) status = fields_add( f, "PARTYEAR", date.data, level );+		else        status = fields_add( f, "YEAR",     date.data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}  	newstr_empty( &date ); 	while ( *p && *p!='/' ) newstr_addchar( &date, *p++ ); 	if ( *p=='/' ) p++; 	if ( date.len>0 ) {-		if ( part ) ok = fields_add( f, "PARTMONTH", date.data, level );-		else        ok = fields_add( f, "MONTH",     date.data, level );-		if ( !ok ) return 0;+		if ( part ) status = fields_add( f, "PARTMONTH", date.data, level );+		else        status = fields_add( f, "MONTH",     date.data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}  	newstr_empty( &date ); 	while ( *p && *p!='/' ) newstr_addchar( &date, *p++ ); 	if ( *p=='/' ) p++; 	if ( date.len>0 ) {-		if ( part ) ok = fields_add( f, "PARTDAY", date.data, level );-		else        ok = fields_add( f, "DAY",     date.data, level );-		if ( !ok ) return 0;+		if ( part ) status = fields_add( f, "PARTDAY", date.data, level );+		else        status = fields_add( f, "DAY",     date.data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	}  	newstr_empty( &date ); 	while ( *p ) newstr_addchar( &date, *p++ ); 	if ( date.len>0 ) {-		if ( part ) ok = fields_add( f, "PARTDATEOTHER", date.data,level);-		else        ok = fields_add( f, "DATEOTHER", date.data, level );-		if ( !ok ) return 0;+		if ( part ) status = fields_add( f, "PARTDATEOTHER", date.data,level);+		else        status = fields_add( f, "DATEOTHER", date.data, level );+		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR; 	} 	newstr_free( &date );-	return 1;-}--int-risin_typef( fields *risin, char *filename, int nref, param *p, variants *all, int nall )-{-	char *refnum = "";-	int n, reftype, nreftype;-	n = fields_find( risin, "TY", 0 );-	nreftype = fields_find( risin, "ID", 0 );-	if ( nreftype!=-1 ) refnum = risin[n].data->data;-	if ( n!=-1 )-		reftype = get_reftype( (risin[n].data)->data, nref, p->progname,-			all, nall, refnum );-	else-		reftype = get_reftype( "", nref, p->progname, all, nall, refnum ); /*default */-	return reftype;+	return BIBL_OK; }  static void@@ -322,10 +357,18 @@ 	} } +static int+risin_simple( fields *f, char *tag, char *value, int level )+{+	int fstatus = fields_add( f, tag, value, level );+	if ( fstatus==FIELDS_OK ) return BIBL_OK;+	else return BIBL_ERR_MEMERR;+}+ int risin_convertf( fields *risin, fields *f, int reftype, param *p, variants *all, int nall ) {-	int process, level, i, n, nfields, ok;+	int process, level, i, n, nfields, ok, fstatus, status = BIBL_OK; 	char *outtag, *tag, *value; 	newstr *t, *d; @@ -345,43 +388,49 @@ 		switch ( process ) {  		case SIMPLE:-			ok = fields_add( f, outtag, d->data, level );+			status = risin_simple( f, outtag, d->data, level ); 			break;  		case PERSON: 			ok = name_add( f, outtag, d->data, level, &(p->asis), &(p->corps) );+			if ( ok ) status = BIBL_OK;+			else status = BIBL_ERR_MEMERR; 			break;  		case TITLE: 			ok = title_process( f, outtag, d->data, level, p->nosplittitle );+			if ( ok ) status = BIBL_OK;+			else status = BIBL_ERR_MEMERR; 			break;  		case SERIALNO: 			ok = addsn( f, d->data, level );+			if ( ok ) status = BIBL_OK;+			else status = BIBL_ERR_MEMERR; 			break;  		case DATE:-			ok = risin_adddate( f, outtag, d, level );+			status = risin_adddate( f, outtag, d, level ); 			break;  		case NOTES:-			ok = risin_addnotes( f, outtag, d, level );+			status = risin_addnotes( f, outtag, d, level ); 			break;  		case DOI:-			ok = risin_adddoi( f, outtag, d, level );+			status = risin_adddoi( f, outtag, d, level ); 			break;  		case LINKEDFILE:-			ok = risin_addfile( f, outtag, d, level );+			status = risin_addfile( f, outtag, d, level ); 			break;  		default:-			ok = 1;+			status = BIBL_OK; 			break;  		}-		if ( !ok ) return BIBL_ERR_MEMERR;+		if ( status!=BIBL_OK ) return status; 	}  	/* look for thesis-type hint */@@ -395,11 +444,11 @@ 			     !strcasecmp(value,"Diploma Thesis")|| 			     !strcasecmp(value,"Doctoral Thesis")|| 			     !strcasecmp(value,"Habilitation Thesis")) {-				ok = fields_add( f, "GENRE", value, 0 );-				if ( !ok ) return BIBL_ERR_MEMERR;+				fstatus = fields_add( f, "GENRE", value, 0 );+				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR; 			} 		} 	} -	return BIBL_OK;+	return status; }
bibutils/risin.h view
@@ -1,7 +1,7 @@ /*  * risin.h  *- * Copyright (c) Chris Putnam 2003-2013+ * Copyright (c) Chris Putnam 2003-2014  *  * Source code released under the GPL version 2  *
bibutils/risout.c view
@@ -28,7 +28,7 @@ 	p->latexout         = 0; 	p->utf8out          = BIBL_CHARSET_UTF8_DEFAULT; 	p->utf8bom          = BIBL_CHARSET_BOM_DEFAULT;-	p->xmlout           = 0;+	p->xmlout           = BIBL_XMLOUT_FALSE; 	p->nosplittitle     = 0; 	p->verbose          = 0; 	p->addcount         = 0;@@ -73,6 +73,41 @@ 	TYPE_UNPUBLISHED,        /* unpublished */ }; +static void+write_type( FILE *fp, int type )+{+	switch( type ) {+	case TYPE_UNKNOWN:            fprintf( fp, "TYPE_UNKNOWN" );            break;+	case TYPE_STD:                fprintf( fp, "TYPE_STD" );                break;+	case TYPE_ABSTRACT:           fprintf( fp, "TYPE_ABSTRACT" );           break;+	case TYPE_ARTICLE:            fprintf( fp, "TYPE_ARTICLE" );            break;+	case TYPE_BOOK:               fprintf( fp, "TYPE_BOOK" );               break;+	case TYPE_CASE:               fprintf( fp, "TYPE_CASE" );               break;+	case TYPE_INBOOK:             fprintf( fp, "TYPE_INBOOK" );             break;+	case TYPE_CONF:               fprintf( fp, "TYPE_CONF" );               break;+	case TYPE_ELEC:               fprintf( fp, "TYPE_ELEC" );               break;+	case TYPE_HEAR:               fprintf( fp, "TYPE_HEAR" );               break;+	case TYPE_MAGARTICLE:         fprintf( fp, "TYPE_MAGARTICLE" );         break;+	case TYPE_NEWS:               fprintf( fp, "TYPE_NEWS" );               break;+	case TYPE_MPCT:               fprintf( fp, "TYPE_MCPT" );               break;+	case TYPE_PAMP:               fprintf( fp, "TYPE_PAMP" );               break;+	case TYPE_PATENT:             fprintf( fp, "TYPE_PATENT" );             break;+	case TYPE_PCOMM:              fprintf( fp, "TYPE_PCOMM" );              break;+	case TYPE_PROGRAM:            fprintf( fp, "TYPE_PROGRAM" );            break;+	case TYPE_REPORT:             fprintf( fp, "TYPE_REPORT" );             break;+	case TYPE_STATUTE:            fprintf( fp, "TYPE_STATUTE" );            break;+	case TYPE_THESIS:             fprintf( fp, "TYPE_THESIS" );             break;+	case TYPE_MASTERSTHESIS:      fprintf( fp, "TYPE_MASTERSTHESIS" );      break;+	case TYPE_PHDTHESIS:          fprintf( fp, "TYPE_PHDTHESIS" );          break;+	case TYPE_DIPLOMATHESIS:      fprintf( fp, "TYPE_DIPLOMATHESIS" );      break;+	case TYPE_DOCTORALTHESIS:     fprintf( fp, "TYPE_DOCTORALTHESIS" );     break;+	case TYPE_HABILITATIONTHESIS: fprintf( fp, "TYPE_HABILITATIONTHESIS" ); break;+	case TYPE_MAP:                fprintf( fp, "TYPE_MAP" );                break;+	case TYPE_UNPUBLISHED:        fprintf( fp, "TYPE_UNPUBLISHED" );        break;+	default:                      fprintf( fp, "Error - type not in enum" );break;+	}+}+ typedef struct match_type { 	char *name; 	int type;@@ -82,10 +117,11 @@  * <genre></genre>  */ static int-get_type_genre( fields *f )+get_type_genre( fields *f, param *p ) { 	match_type match_genres[] = { 		{ "academic journal",          TYPE_ARTICLE },+		{ "article",                   TYPE_ARTICLE }, 		{ "journal article",           TYPE_ARTICLE }, 		{ "magazine",                  TYPE_MAGARTICLE }, 		{ "conference publication",    TYPE_CONF },@@ -109,18 +145,25 @@ 	}; 	int nmatch_genres = sizeof( match_genres ) / sizeof( match_genres[0] ); 	int type, i, j;-	char *value;+	char *tag, *value;  	type = TYPE_UNKNOWN;  	for ( i=0; i<fields_num( f ); ++i ) {-		if ( !fields_match_tag( f, i,"GENRE" ) &&-		     !fields_match_tag( f, i,"NGENRE" ) )+		if ( !fields_match_tag( f, i, "GENRE" ) &&+		     !fields_match_tag( f, i, "NGENRE" ) ) 			continue; 		value = ( char * ) fields_value( f, i, FIELDS_CHRP ); 		for ( j=0; j<nmatch_genres; ++j ) 			if ( !strcasecmp( match_genres[j].name, value ) ) 				type = match_genres[j].type;+		if ( p->verbose ) {+			tag = ( char * ) fields_tag( f, i, FIELDS_CHRP );+			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+			fprintf( stderr, "Type from tag '%s' data '%s': ", tag, value );+			write_type( stderr, type );+			fprintf( stderr, "\n" );+		} 		if ( type==TYPE_UNKNOWN ) { 			if ( !strcasecmp( value, "periodical" ) ) 				type = TYPE_ARTICLE;@@ -138,6 +181,13 @@  	} +	if ( p->verbose ) {+		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+		fprintf( stderr, "Type from genre element: " );+		write_type( stderr, type );+		fprintf( stderr, "\n" );+	}+ 	return type; } @@ -145,7 +195,7 @@  * <TypeOfResource></TypeOfResource>  */ static int-get_type_resource( fields *f )+get_type_resource( fields *f, param *p ) { 	match_type match_res[] = { 		{ "software, multimedia",      TYPE_PROGRAM },@@ -167,8 +217,21 @@ 			if ( !strcasecmp( value, match_res[j].name ) ) 				type = match_res[j].type; 		}+		if ( p->verbose ) {+			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+			fprintf( stderr, "Type from tag 'RESOURCE' data '%s': ", value );+			write_type( stderr, type );+			fprintf( stderr, "\n" );+		} 	} +	if ( p->verbose ) {+		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+		fprintf( stderr, "Type from resource element: " );+		write_type( stderr, type );+		fprintf( stderr, "\n" );+	}+ 	vplist_free( &a ); 	return type; }@@ -176,36 +239,58 @@ /* Try to determine type of reference from <issuance></issuance> and */ /* <typeOfReference></typeOfReference> */ static int-get_type_issuance( fields *f )+get_type_issuance( fields *f, param *p ) { 	int type = TYPE_UNKNOWN;-	int i, monographic = 0, text = 0, monographic_level = 0;+	int i, monographic = 0, monographic_level = 0;+//	int text = 0; 	for ( i=0; i<f->n; ++i ) { 		if ( !strcasecmp( f->tag[i].data, "issuance" ) && 		     !strcasecmp( f->data[i].data, "MONOGRAPHIC" ) ){ 			monographic = 1; 			monographic_level = f->level[i]; 		}-		if ( !strcasecmp( f->tag[i].data, "typeOfResource" ) &&-		     !strcasecmp( f->data[i].data,"text") ) {-			text = 1;-		}+//		if ( !strcasecmp( f->tag[i].data, "typeOfResource" ) &&+//		     !strcasecmp( f->data[i].data,"text") ) {+//			text = 1;+//		} 	}-	if ( monographic && text ) {+//	if ( monographic && text ) {+	if ( monographic ) { 		if ( monographic_level==0 ) type=TYPE_BOOK; 		else if ( monographic_level>0 ) type=TYPE_INBOOK; 	}++	if ( p->verbose ) {+		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+		fprintf( stderr, "Type from issuance/typeOfReference elements: " );+		write_type( stderr, type );+		fprintf( stderr, "\n" );+	}+ 	return type; }  static int-get_type( fields *f )+get_type( fields *f, param *p ) { 	int type;-	type = get_type_genre( f );-	if ( type==TYPE_UNKNOWN ) type = get_type_resource( f );-	if ( type==TYPE_UNKNOWN ) type = get_type_issuance( f );-	if ( type==TYPE_UNKNOWN ) type = TYPE_STD;+	type = get_type_genre( f, p );+	if ( type==TYPE_UNKNOWN ) type = get_type_resource( f, p );+	if ( type==TYPE_UNKNOWN ) type = get_type_issuance( f, p );+	if ( type==TYPE_UNKNOWN ) {+		if ( fields_maxlevel( f ) > 0 ) type = TYPE_INBOOK;+		else type = TYPE_STD;+	}++	if ( p->verbose ) {+		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );+		fprintf( stderr, "Final type: " );+		write_type( stderr, type );+		fprintf( stderr, "\n" );+	}++ 	return type; } @@ -525,7 +610,7 @@ risout_write( fields *f, FILE *fp, param *p, unsigned long refnum ) { 	int type;-	type = get_type( f );+	type = get_type( f, p ); 	output_type( fp, type, p );  	output_allpeople( fp, f, type );
bibutils/serialno.c view
@@ -1,7 +1,7 @@ /*  * serialno.c  *- * Copyright (c) Chris Putnam 2005-2013+ * Copyright (c) Chris Putnam 2005-2014  *  * Source code released under the GPL version 2  *@@ -12,25 +12,44 @@ int addsn( fields *info, char *buf, int level ) {-	int ndigits=0, issn=0, isbn=0;-	char *p = buf;+	int ndigits, issn=0, isbn=0, isbn10=0, isbn13=0, status;+	char *p = buf, *tag;  	if ( !strncasecmp( p, "ISSN", 4 ) ) issn=1; 	else if ( !strncasecmp( p, "ISBN", 4 ) ) isbn=1; +	if ( isbn ) {+		ndigits = 0;+		while ( *p && !(ndigits && (*p==';'||*p==':')) ) {+			if ( ( *p>='0' && *p<='9' ) || *p=='x' || *p=='X' )+				ndigits++;+			p++;+		}+		if ( ndigits==13 ) isbn13 = 1;+		else /* ( ndigits==10) */ isbn10 = 1;+	}+ 	if ( !issn && !isbn ) { 		/* a lot have semicolons between multiple ISBN's for 		   paperbacks and hardbacks with different numbers */+		ndigits = 0; 		while ( *p && !(ndigits && (*p==';'||*p==':')) ) {-			if ( ( *p>='0' && *p<='9' ) || *p=='x' || *p=='X' ) +			if ( ( *p>='0' && *p<='9' ) || *p=='x' || *p=='X' ) 				ndigits++; 			p++; 		} 		if ( ndigits==8 ) issn = 1;-		else if ( ndigits==10 || ndigits==13 ) isbn = 1;+		else if ( ndigits==10 ) isbn10 = 1;+		else if ( ndigits==13 ) isbn13 = 1; 	} 	-	if ( issn ) return fields_add( info, "ISSN", buf, level );-	else if ( isbn ) return fields_add( info, "ISBN", buf, level );-	else return fields_add( info, "SERIALNUMBER", buf, level );+	if ( issn ) tag = "ISSN";+	else if ( isbn10 ) tag = "ISBN";+	else if ( isbn13 ) tag = "ISBN13";+	else tag = "SERIALNUMBER";++	status = fields_add( info, tag, buf, level );++	if ( status==FIELDS_OK ) return 1;+	else return 0; }
bibutils/serialno.h view
@@ -1,7 +1,7 @@ /*  * serialno.h  *- * Copyright (c) Chris Putnam 2005-2013+ * Copyright (c) Chris Putnam 2005-2014  *  * Source code released under the GPL version 2  *
bibutils/title.c view
@@ -3,7 +3,7 @@  *  * process titles into title/subtitle pairs for MODS  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL version 2  *@@ -22,7 +22,7 @@ { 	newstr title, subtitle; 	char *p, *q;-	int ok;+	int status;  	newstr_init( &title ); 	newstr_init( &subtitle );@@ -45,17 +45,17 @@  	if ( strncasecmp( "SHORT", tag, 5 ) ) { 		if ( title.len>0 ) {-			ok = fields_add( info, "TITLE", title.data, level );-			if ( !ok ) return 0;+			status = fields_add( info, "TITLE", title.data, level );+			if ( status!=FIELDS_OK ) return 0; 		} 		if ( subtitle.len>0 ) {-			ok = fields_add( info, "SUBTITLE", subtitle.data, level );-			if ( !ok ) return 0;+			status = fields_add( info, "SUBTITLE", subtitle.data, level );+			if ( status!=FIELDS_OK ) return 0; 		} 	} else { 		if ( title.len>0 ) {-			ok = fields_add( info, "SHORTTITLE", title.data, level );-			if ( !ok ) return 0;+			status = fields_add( info, "SHORTTITLE", title.data, level );+			if ( status!=FIELDS_OK ) return 0; 		} 		/* no SHORT-SUBTITLE! */ 	}
bibutils/title.h view
@@ -3,7 +3,7 @@  *  * process titles into title/subtitle pairs for MODS  *- * Copyright (c) Chris Putnam 2004-2013+ * Copyright (c) Chris Putnam 2004-2014  *  * Source code released under the GPL verison 2  *
bibutils/wordin.c view
@@ -16,6 +16,10 @@ #include "xml_encoding.h" #include "wordin.h" +/*****************************************************+ PUBLIC: void wordin_initparams()+*****************************************************/+ void wordin_initparams( param *p, const char *progname ) {@@ -46,6 +50,10 @@ 	else p->progname = strdup( progname ); } +/*****************************************************+ PUBLIC: int wordin_readf()+*****************************************************/+ static char * wordin_findstartwrapper( char *buf, int *ntype ) {@@ -93,25 +101,9 @@ 	return haveref; } -static inline int-xml_hasdata( xml *node )-{-	if ( node && node->value && node->value->data ) return 1;-	return 0;-}--static inline char *-xml_data( xml *node )-{-	return node->value->data;-}--static inline int-xml_tagwithdata( xml *node, char *tag )-{-	if ( !xml_hasdata( node ) ) return 0;-	return xml_tagexact( node, tag );-}+/*****************************************************+ PUBLIC: int wordin_processf()+*****************************************************/  typedef struct xml_convert { 	char *in;       /* The input tag */@@ -120,126 +112,204 @@ 	int level; } xml_convert; -static void+/* wordin_person_last()+ *+ * From an xml list, extract the value from the first entry+ * of <b:Last>xxxx</b:Last> and copy into name+ *+ * Additional <b:Last>yyyyy</b:Last> will be ignored.+ *+ * Returns BIBL_ERR_MEMERR on memory error, BIBL_OK otherwise.+ */+static int+wordin_person_last( xml *node, newstr *name )+{+	while ( node && !xml_tagexact( node, "b:Last" ) )+		node = node->next;+	if ( node && node->value->len ) {+		newstr_strcpy( name, node->value->data );+		if ( newstr_memerr( name ) ) return BIBL_ERR_MEMERR;+	}+	return BIBL_OK;+}++/* wordin_person_first()+ *+ * From an xml list, extract the value of any+ * <b:First>xxxx</b:First> and append "|xxxx" to name.+ *+ * Returns BIBL_ERR_MEMERR on memory error, BIBL_OK otherwise+ */+static int+wordin_person_first( xml *node, newstr *name )+{+	for ( ; node; node=node->next ) {+		if ( !xml_tagexact( node, "b:First" ) ) continue;+		if ( node->value->len ) {+			if ( name->len ) newstr_addchar( name, '|' );+			newstr_strcat( name, node->value->data );+			if ( newstr_memerr( name ) ) return BIBL_ERR_MEMERR;+		}+	}+	return BIBL_OK;+}++static int wordin_person( xml *node, fields *info, char *type ) {-	xml *last, *first;+	int status, ret = BIBL_OK; 	newstr name;  	newstr_init( &name ); -	last = node;-	while ( last && !xml_tagexact( last, "b:Last" ) )-		last = last->next;-	if ( last ) newstr_strcpy( &name, last->value->data );--	first = node;-	while ( first ) {-		if ( xml_tagexact( first, "b:First" ) ) {-			if ( name.len ) newstr_addchar( &name, '|' );-			newstr_strcat( &name, first->value->data );-		}-		first = first->next;+	status = wordin_person_last( node, &name );+	if ( status!=BIBL_OK ) {+		ret = status;+		goto out; 	} -	fields_add( info, type, name.data, 0 );+	status = wordin_person_first( node, &name );+	if ( status!=BIBL_OK ) {+		ret = status;+		goto out;+	} +	status = fields_add( info, type, name.data, 0 );+	if ( status != FIELDS_OK ) ret = BIBL_ERR_MEMERR;+out: 	newstr_free( &name );+	return ret; } -static void+static int wordin_people( xml *node, fields *info, char *type ) {+	int ret = BIBL_OK; 	if ( xml_tagexact( node, "b:Author" ) && node->down ) {-		wordin_people( node->down, info, type );+		ret = wordin_people( node->down, info, type ); 	} else if ( xml_tagexact( node, "b:NameList" ) && node->down ) {-		wordin_people( node->down, info, type );+		ret = wordin_people( node->down, info, type ); 	} else if ( xml_tagexact( node, "b:Person" ) ) {-		if ( node->down ) wordin_person( node->down, info, type );-		if ( node->next ) wordin_people( node->next, info, type );+		if ( node->down ) ret = wordin_person( node->down, info, type );+		if ( ret!=BIBL_OK ) return ret;+		if ( node->next ) ret = wordin_people( node->next, info, type ); 	}+	return ret; } -static void+static int wordin_pages( xml *node, fields *info ) {+	int i, status, ret = BIBL_OK; 	newstr sp, ep; 	char *p;-	int i;+ 	newstrs_init( &sp, &ep, NULL );-/*-	newstr_init( &sp );-	newstr_init( &ep );-*/+ 	p = xml_data( node ); 	while ( *p && *p!='-' ) 		newstr_addchar( &sp, *p++ );+	if ( newstr_memerr( &sp ) ) {+		ret = BIBL_ERR_MEMERR;+		goto out;+	}+ 	if ( *p=='-' ) p++; 	while ( *p ) 		newstr_addchar( &ep, *p++ );-	if ( sp.len ) fields_add( info, "PAGESTART", sp.data, 1 );+	if ( newstr_memerr( &ep ) ) {+		ret = BIBL_ERR_MEMERR;+		goto out;+	}++	if ( sp.len ) {+		status = fields_add( info, "PAGESTART", sp.data, 1 );+		if ( status!=FIELDS_OK ) {+			ret = BIBL_ERR_MEMERR;+			goto out;+		}+	}+ 	if ( ep.len ) { 		if ( sp.len > ep.len ) { 			for ( i=sp.len-ep.len; i<sp.len; ++i ) 				sp.data[i] = ep.data[i-sp.len+ep.len];-			fields_add( info, "PAGEEND", sp.data, 1 );+			status = fields_add( info, "PAGEEND", sp.data, 1 ); 		} else-			fields_add( info, "PAGEEND", ep.data, 1 );+			status = fields_add( info, "PAGEEND", ep.data, 1 );+		if ( status!=FIELDS_OK ) {+			ret = BIBL_ERR_MEMERR;+			goto out;+		} 	}++out: 	newstrs_free( &sp, &ep, NULL );-/*-	newstr_free( &sp );-	newstr_free( &ep );-*/+	return ret; } -static void+static int wordin_reference( xml *node, fields *info ) {+	int status, ret = BIBL_OK; 	if ( xml_hasdata( node ) ) { 		if ( xml_tagexact( node, "b:Tag" ) ) {-			fields_add( info, "REFNUM", xml_data( node ), 0 );+			status = fields_add( info, "REFNUM", xml_data( node ), 0 );+			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR; 		} else if ( xml_tagexact( node, "b:SourceType" ) ) { 		} else if ( xml_tagexact( node, "b:City" ) ) {-			fields_add( info, "ADDRESS", xml_data( node ), 0 );+			status = fields_add( info, "ADDRESS", xml_data( node ), 0 );+			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR; 		} else if ( xml_tagexact( node, "b:Publisher" ) ) {-			fields_add( info, "PUBLISHER", xml_data( node ), 0 );+			status = fields_add( info, "PUBLISHER", xml_data( node ), 0 );+			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR; 		} else if ( xml_tagexact( node, "b:Title" ) ) {-			fields_add( info, "TITLE", xml_data( node ), 0 );+			status = fields_add( info, "TITLE", xml_data( node ), 0 );+			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR; 		} else if ( xml_tagexact( node, "b:JournalName" ) ) {-			fields_add( info, "TITLE", xml_data( node ), 1 );+			status = fields_add( info, "TITLE", xml_data( node ), 1 );+			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR; 		} else if ( xml_tagexact( node, "b:Volume" ) ) {-			fields_add( info, "VOLUME", xml_data( node ), 1 );+			status = fields_add( info, "VOLUME", xml_data( node ), 1 );+			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR; 		} else if ( xml_tagexact( node, "b:Comments" ) ) {-			fields_add( info, "NOTES", xml_data( node ), 0 );+			status = fields_add( info, "NOTES", xml_data( node ), 0 );+			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR; 		} else if ( xml_tagexact( node, "b:Pages" ) ) {-			wordin_pages( node, info );+			ret = wordin_pages( node, info ); 		} else if ( xml_tagexact( node, "b:Author" ) && node->down ) {-			wordin_people( node->down, info, "AUTHOR" );+			ret = wordin_people( node->down, info, "AUTHOR" ); 		} else if ( xml_tagexact( node, "b:Editor" ) && node->down ) {-			wordin_people( node->down, info, "EDITOR" );+			ret = wordin_people( node->down, info, "EDITOR" ); 		} 	}-	if ( node->next ) wordin_reference( node->next, info );+	if ( ret==BIBL_OK && node->next ) wordin_reference( node->next, info );+	return ret; } -static void+static int wordin_assembleref( xml *node, fields *info ) {+	int ret = BIBL_OK; 	if ( xml_tagexact( node, "b:Source" ) ) {-		if ( node->down ) wordin_reference( node->down, info );+		if ( node->down ) ret = wordin_reference( node->down, info ); 	} else if ( node->tag->len==0 && node->down ) {-		wordin_assembleref( node->down, info );+		ret = wordin_assembleref( node->down, info ); 	}+	return ret; }  int wordin_processf( fields *wordin, char *data, char *filename, long nref ) {+	int status, ret = 1; 	xml top;+ 	xml_init( &top ); 	xml_tree( data, &top );-	wordin_assembleref( &top, wordin );+	status = wordin_assembleref( &top, wordin ); 	xml_free( &top );-	return 1;++	if ( status==BIBL_ERR_MEMERR ) ret = 0;+	return ret; }
bibutils/wordout.c view
@@ -3,7 +3,7 @@  *   * (Word 2007 format)  *- * Copyright (c) Chris Putnam 2007-2013+ * Copyright (c) Chris Putnam 2007-2014  *  * Source code released under the GPL version 2  *@@ -26,8 +26,10 @@ 	p->latexout         = 0; 	p->utf8out          = BIBL_CHARSET_UTF8_DEFAULT; 	p->utf8bom          = BIBL_CHARSET_BOM_DEFAULT;-	if ( !p->utf8out ) p->xmlout = 3;-	else p->xmlout = 1;+	if ( !p->utf8out )+		p->xmlout   = BIBL_XMLOUT_ENTITIES;+	else+		p->xmlout   = BIBL_XMLOUT_TRUE; 	p->nosplittitle     = 0; 	p->verbose          = 0; 	p->addcount         = 0;@@ -575,6 +577,7 @@ 		{ "NUMBER",          "b:Issue",   LEVEL_ANY }, 		{ "PUBLICLAWNUMBER", "b:Volume",  LEVEL_ANY }, 		{ "SESSION",         "b:Issue",   LEVEL_ANY },+		{ "URL",             "b:Url",     LEVEL_ANY }, 	}; 	int nparts=sizeof(parts)/sizeof(convert); 	
bibutils/xml.c view
@@ -30,10 +30,10 @@ static void xmlattrib_add( xml_attrib *a, char *attrib, char *value  ) {-	if ( attrib ) list_add( &(a->attrib), attrib );-	else list_add( &(a->attrib), "" );-	if ( value ) list_add( &(a->value), value );-	else list_add( &(a->value), "" );+	if ( attrib ) list_addc( &(a->attrib), attrib );+	else list_addc( &(a->attrib), "" );+	if ( value ) list_addc( &(a->value), value );+	else list_addc( &(a->value), "" ); }  static void@@ -238,10 +238,11 @@ 					p = xml_tree( p, nnode ); 			} else if ( type==XML_CLOSE ) { 				/*check to see if it's closing for this one*/-				return p; /* assume it's right for now*/+				goto out; /* assume it's right for now */ 			} 		} 	}+out: 	newstr_free( &tag ); 	return p; }@@ -335,24 +336,33 @@ }  int-xml_tag_attrib( xml *node, char *s, char *attrib, char *value )+xml_hasattrib( xml *node, char *attrib, char *value ) { 	xml_attrib *na = node->a; 	int i; -	if ( !na || !xml_tagexact( node, s ) ) return 0;+	if ( na ) { -	for ( i=0; i<na->attrib.n; ++i ) {-		if ( !na->attrib.str[i].data || !na->value.str[i].data )-			continue;-		if ( !strcasecmp( na->attrib.str[i].data, attrib ) &&-		     !strcasecmp( na->value.str[i].data, value ) )-			return 1;+		for ( i=0; i<na->attrib.n; ++i ) {+			if ( !na->attrib.str[i].data || !na->value.str[i].data )+				continue;+			if ( !strcasecmp( na->attrib.str[i].data, attrib ) &&+			     !strcasecmp( na->value.str[i].data, value ) )+				return 1;+		}+ 	}  	return 0; } +int+xml_tag_attrib( xml *node, char *s, char *attrib, char *value )+{+	if ( !xml_tagexact( node, s ) ) return 0;+	return xml_hasattrib( node, attrib, value );+}+ newstr * xml_getattrib( xml *node, char *attrib ) {@@ -366,5 +376,25 @@ 				ns = &(na->value.str[i]); 	} 	return ns;+}++int+xml_hasdata( xml *node )+{+	if ( node && node->value && node->value->data ) return 1;+	return 0;+}++char *+xml_data( xml *node )+{+	return node->value->data;+}++int+xml_tagwithdata( xml *node, char *tag )+{+	if ( !xml_hasdata( node ) ) return 0;+	return xml_tagexact( node, tag ); } 
bibutils/xml.h view
@@ -31,8 +31,12 @@ extern char * xml_findend( char *buffer, char *tag ); extern int xml_tagexact( xml *node, char *s ); extern int xml_tag_attrib( xml *node, char *s, char *attrib, char *value );+extern int xml_hasattrib( xml *node, char *attrib, char *value ); extern void xml_free( xml *x ); extern char * xml_tree( char *p, xml *onode );+extern int xml_hasdata( xml *node );+extern char * xml_data( xml *node );+extern int xml_tagwithdata( xml *node, char *tag );  extern char *xml_pns; /* global Namespace */ 
cbits/stub.c view
@@ -9,3 +9,5 @@ {     return stdin; }++const char progname[] = "hs-bibutils";
hs-bibutils.cabal view
@@ -1,6 +1,6 @@ name:               hs-bibutils-version:            5.0-homepage:           http://gorgias.mine.nu/repos/hs-bibutils/+version:            5.5+homepage:           http://istitutocolli.org/repos/hs-bibutils/  synopsis:           Haskell bindings to bibutils, the bibliography                     conversion utilities.@@ -30,38 +30,41 @@ cabal-version:      >= 1.4 build-type:         Simple extra-source-files:-    bibutils/adsout.c bibutils/adsout.h bibutils/adsout_journals.c-    bibutils/bibcore.c bibutils/bibl.c bibutils/bibl.h-    bibutils/biblatexin.c bibutils/biblatexin.h bibutils/bibtexin.c-    bibutils/bibtexin.h bibutils/bibtexout.c bibutils/bibtexout.h-    bibutils/bibtextypes.c bibutils/bibutils.c bibutils/bibutils.h-    bibutils/bltypes.c bibutils/charsets.c bibutils/charsets.h-    bibutils/copacin.c bibutils/copacin.h bibutils/copactypes.c-    bibutils/doi.c bibutils/doi.h bibutils/ebiin.c bibutils/ebiin.h-    bibutils/endin.c bibutils/endin.h bibutils/endout.c-    bibutils/endout.h bibutils/endtypes.c bibutils/endxmlin.c-    bibutils/endxmlin.h bibutils/entities.c bibutils/entities.h-    bibutils/fields.c bibutils/fields.h bibutils/gb18030.c-    bibutils/gb18030.h bibutils/gb18030_enumeration.c bibutils/is_ws.c-    bibutils/intlis.h bibutils/intlis.c bibutils/is_ws.h-    bibutils/isiin.c bibutils/isiin.h bibutils/isiout.c-    bibutils/iso639_2.c bibutils/iso639_2.h bibutils/isiout.h-    bibutils/isitypes.c bibutils/latex.c bibutils/latex.h-    bibutils/list.c bibutils/list.h bibutils/marc.c bibutils/marc.h-    bibutils/medin.c bibutils/medin.h bibutils/modsin.c-    bibutils/modsin.h bibutils/modsout.c bibutils/modsout.h-    bibutils/modstypes.c bibutils/modstypes.h bibutils/mycvout.c-    bibutils/name.c bibutils/name.h bibutils/newstr.c-    bibutils/newstr.h bibutils/newstr_conv.c bibutils/newstr_conv.h-    bibutils/reftypes.c bibutils/reftypes.h bibutils/risin.c-    bibutils/risin.h bibutils/risout.c bibutils/risout.h-    bibutils/ristypes.c bibutils/vplist.c bibutils/vplist.h-    bibutils/serialno.c bibutils/serialno.h bibutils/strsearch.c-    bibutils/strsearch.h bibutils/title.c bibutils/title.h-    bibutils/unicode. bibutils/unicode.c bibutils/utf8.c-    bibutils/utf8.h bibutils/wordin.c bibutils/wordin.h-    bibutils/wordout.c bibutils/wordout.h bibutils/xml.c-    bibutils/xml.h bibutils/xml_encoding.c bibutils/xml_encoding.h+        bibutils/adsout.c bibutils/adsout.h bibutils/adsout_journals.c+        bibutils/bibcore.c bibutils/bibl.c bibutils/bibl.h+        bibutils/biblatexin.c bibutils/biblatexin.h+        bibutils/bibtexin.c bibutils/bibtexin.h bibutils/bibtexout.c+        bibutils/bibtexout.h bibutils/bibtextypes.c+        bibutils/bibutils.c bibutils/bibutils.h bibutils/bltypes.c+        bibutils/charsets.c bibutils/charsets.h bibutils/copacin.c+        bibutils/copacin.h bibutils/copactypes.c bibutils/doi.c+        bibutils/doi.h bibutils/ebiin.c bibutils/ebiin.h+        bibutils/endin.c bibutils/endin.h bibutils/endout.c+        bibutils/endout.h bibutils/endtypes.c bibutils/endxmlin.c+        bibutils/endxmlin.h bibutils/entities.c bibutils/entities.h+        bibutils/fields.c bibutils/fields.h bibutils/gb18030.c+        bibutils/gb18030.h bibutils/gb18030_enumeration.c+        bibutils/intlist.c bibutils/intlist.h bibutils/is_ws.c+        bibutils/is_ws.h bibutils/isiin.c bibutils/isiin.h+        bibutils/isiout.c bibutils/isiout.h bibutils/isitypes.c+        bibutils/iso639_1.c bibutils/iso639_1.h bibutils/iso639_2.c+        bibutils/iso639_2.h bibutils/iso639_3.c bibutils/iso639_3.h+        bibutils/latex.c bibutils/latex.h bibutils/list.c+        bibutils/list.h bibutils/marc.c bibutils/marc.h+        bibutils/medin.c bibutils/medin.h bibutils/modsin.c+        bibutils/modsin.h bibutils/modsout.c bibutils/modsout.h+        bibutils/modstypes.c bibutils/modstypes.h bibutils/name.c+        bibutils/name.h bibutils/newstr.c bibutils/newstr.h+        bibutils/newstr_conv.c bibutils/newstr_conv.h+        bibutils/reftypes.c bibutils/reftypes.h bibutils/risin.c+        bibutils/risin.h bibutils/risout.c bibutils/risout.h+        bibutils/ristypes.c bibutils/serialno.c bibutils/serialno.h+        bibutils/strsearch.c bibutils/strsearch.h bibutils/title.c+        bibutils/title.h bibutils/unicode.c bibutils/unicode.h+        bibutils/utf8.c bibutils/utf8.h bibutils/vplist.c+        bibutils/vplist.h bibutils/wordin.c bibutils/wordin.h+        bibutils/wordout.c bibutils/wordout.h bibutils/xml.c+        bibutils/xml.h bibutils/xml_encoding.c bibutils/xml_encoding.h  library     exposed-modules:  Text.Bibutils@@ -71,7 +74,7 @@     hs-source-dirs:   src     extensions:       ForeignFunctionInterface     include-dirs:     bibutils-    includes:         bibutils.h+    includes: bibutils.h     c-sources:         cbits/stub.c         bibutils/adsout.c bibutils/adsout_journals.c@@ -83,15 +86,16 @@         bibutils/endout.c bibutils/endtypes.c bibutils/endxmlin.c         bibutils/entities.c bibutils/fields.c bibutils/gb18030.c         bibutils/intlist.c bibutils/is_ws.c bibutils/isiin.c-        bibutils/isiout.c bibutils/isitypes.c bibutils/iso639_2.c-        bibutils/latex.c bibutils/list.c bibutils/marc.c-        bibutils/medin.c bibutils/modsin.c bibutils/modsout.c-        bibutils/modstypes.c bibutils/name.c bibutils/newstr.c-        bibutils/newstr_conv.c bibutils/reftypes.c bibutils/risin.c-        bibutils/risout.c bibutils/ristypes.c bibutils/vplist.c-        bibutils/serialno.c bibutils/strsearch.c bibutils/title.c-        bibutils/unicode.c bibutils/utf8.c bibutils/wordin.c-        bibutils/wordout.c bibutils/xml.c bibutils/xml_encoding.c+        bibutils/isiout.c bibutils/isitypes.c bibutils/iso639_1.c+        bibutils/iso639_2.c bibutils/iso639_3.c bibutils/latex.c+        bibutils/list.c bibutils/marc.c bibutils/medin.c+        bibutils/modsin.c bibutils/modsout.c bibutils/modstypes.c+        bibutils/name.c bibutils/newstr.c bibutils/newstr_conv.c+        bibutils/reftypes.c bibutils/risin.c bibutils/risout.c+        bibutils/ristypes.c bibutils/serialno.c bibutils/strsearch.c+        bibutils/title.c bibutils/unicode.c bibutils/utf8.c+        bibutils/vplist.c bibutils/wordin.c bibutils/wordout.c+        bibutils/xml.c bibutils/xml_encoding.c      if impl(ghc >= 6.10)        build-depends: base >= 4, syb