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 void construct_url( char *prefix, newstr *id, newstr *id_url ) { if ( !strncasecmp( id->data, "http:", 5 ) ) newstr_newstrcpy( id_url, id ); else { newstr_strcpy( id_url, prefix ); if ( id->data[0]!='/' ) newstr_addchar( id_url, '/' ); newstr_newstrcat( id_url, id ); } }
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; }
/* copac names appear to always start with last name first, but don't * always seem to have a comma after the name * * editors seem to be stuck in as authors with the tag "[Editor]" in it */ static int copacin_person( fields *bibin, newstr *intag, newstr *invalue, int level, param *pm, char *outtag, fields *bibout ) { char *usetag = outtag, editor[]="EDITOR"; newstr usename, *s; list tokens; int comma = 0, i, ok; if ( list_find( &(pm->asis), invalue->data ) !=-1 || list_find( &(pm->corps), invalue->data ) !=-1 ) { ok = name_add( bibout, outtag, invalue->data, level, &(pm->asis), &(pm->corps) ); if ( ok ) return BIBL_OK; else return BIBL_ERR_MEMERR; } list_init( &tokens ); newstr_init( &usename ); list_tokenize( &tokens, invalue, " ", 1 ); for ( i=0; i<tokens.n; ++i ) { s = list_get( &tokens, i ); if ( !strcmp( s->data, "[Editor]" ) ) { usetag = editor; newstr_strcpy( s, "" ); } else if ( s->len && s->data[s->len-1]==',' ) { comma++; } } if ( comma==0 && tokens.n ) { s = list_get( &tokens, 0 ); newstr_addchar( s, ',' ); } for ( i=0; i<tokens.n; ++i ) { s = list_get( &tokens, i ); if ( s->len==0 ) continue; if ( i ) newstr_addchar( &usename, ' ' ); newstr_newstrcat( &usename, s ); } list_free( &tokens ); ok = name_add( bibout, usetag, usename.data, level, &(pm->asis), &(pm->corps) ); newstr_free( &usename ); if ( ok ) return BIBL_OK; else return 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 * * editors seem to be stuck in as authors with the tag "[Editor]" in it */ static int copacin_addname( fields *info, char *tag, newstr *name, int level, list *asis, list *corps ) { char *usetag = tag, editor[]="EDITOR"; newstr usename, *s; list tokens; int comma = 0, i, ok; if ( list_find( asis, name->data ) !=-1 || list_find( corps, name->data ) !=-1 ) { 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 ); for ( i=0; i<tokens.n; ++i ) { s = list_get( &tokens, i ); if ( !strcmp( s->data, "[Editor]" ) ) { usetag = editor; newstr_strcpy( s, "" ); } else if ( s->len && s->data[s->len-1]==',' ) { comma++; } } if ( comma==0 && tokens.n ) { s = list_get( &tokens, 0 ); newstr_addchar( s, ',' ); } for ( i=0; i<tokens.n; ++i ) { if ( i ) newstr_addchar( &usename, ' ' ); newstr_newstrcat( &usename, list_get( &tokens, i ) ); } list_free( &tokens ); ok = name_add( info, usetag, usename.data, level, asis, corps ); if ( ok ) return BIBL_OK; else return BIBL_ERR_MEMERR; }
static int test_newstrcat( newstr *s ) { int numshort = 5, numstrings = 1000, i; int failed = 0; newstr t; newstr_init( &t ); /* ...adding empty strings to an empty string shouldn't change length */ newstr_empty( s ); for ( i=0; i<numstrings; ++i ) newstr_newstrcat( s, &t ); if ( string_mismatch( s, 0, "" ) ) failed++; /* ...adding empty strings to a defined string shouldn't change string */ newstr_strcpy( s, "1" ); for ( i=0; i<numstrings; ++i ) newstr_newstrcat( s, &t ); if ( string_mismatch( s, 1, "1" ) ) failed++; /* ...build "1111" with newstr_strcat */ newstr_empty( s ); newstr_strcpy( &t, "1" ); for ( i=0; i<numshort; ++i ) newstr_newstrcat( s, &t ); if ( string_mismatch( s, numshort, "11111" ) ) failed++; /* ...build "xoxoxoxoxo" with newstr_strcat */ newstr_empty( s ); newstr_strcpy( &t, "xo" ); for ( i=0; i<numshort; ++i ) newstr_newstrcat( s, &t ); if ( string_mismatch( s, numshort*2, "xoxoxoxoxo" ) ) failed++; newstr_empty( s ); newstr_strcpy( &t, "1" ); for ( i=0; i<numstrings; ++i ) newstr_newstrcat( s, &t ); if ( inconsistent_len( s, numstrings ) ) failed++; newstr_empty( s ); newstr_strcpy( &t, "XXOO" ); for ( i=0; i<numstrings; ++i ) newstr_newstrcat( s, &t ); if ( inconsistent_len( s, numstrings*4 ) ) failed++; newstr_free( &t ); return failed; }
static void output_fileattach( FILE *fp, fields *info, int format_opts ) { newstr data; int i; newstr_init( &data ); for ( i=0; i<info->nfields; ++i ) { if ( strcasecmp( info->tag[i].data, "FILEATTACH" ) ) continue; newstr_strcpy( &data, ":" ); newstr_newstrcat( &data, &(info->data[i]) ); if ( strsearch( info->data[i].data, ".pdf" ) ) newstr_strcat( &data, ":PDF" ); else if ( strsearch( info->data[i].data, ".html" ) ) newstr_strcat( &data, ":HTML" ); else newstr_strcat( &data, ":TYPE" ); output_element( fp, "file", data.data, format_opts ); fields_setused( info, i ); newstr_empty( &data ); } newstr_free( &data ); }
/* 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; }