/* Gnome BibTeX containers.C * Copyright 1998 Alejandro Aguilar Sierra * * This program is free software; you can redistribute it and'or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. */ #include #include #include #include #include #include #include "gbib.h" using namespace std; extern ResponseType ask_about_conflict(BibEntry *old, BibEntry *nova); // with a vengeance: will skip braces on haystack int caseless_find(const char *haystack,char *needle); EntryTab BibentryTable::entryTab; BibentryTable::BibentryTable() { dbname = "none"; selected_entry = -1; conflict=Ask; } BibentryTable::~BibentryTable() { clear(); } void BibentryTable::resetUI() { conflict=Ask; } void BibentryTable::new_entry(BibEntry &bib) { int idx,idy,i; string fkey; char dletter; int oopscount; ResponseType myresponse; idx=search_key(const_cast(bib.key.c_str())); if (idx<0) entryTab.push_back(new BibEntry(bib)); else { myresponse=conflict; do_that_time_warp_thing_again: switch(myresponse) { case Ask: myresponse=ask_about_conflict(get_entry(idx),&bib); goto do_that_time_warp_thing_again; case ReplaceOldAlways: conflict=myresponse; case ReplaceOld: delete_entry(idx); entryTab.push_back(new BibEntry(bib)); break; case IgnoreNewAlways: conflict=myresponse; case IgnoreNew: // ditto break; case AutoFixAlways: conflict=myresponse; case AutoFix: dletter='a'; oopscount=0; while(1) { fkey=bib.key; for(i=0;i(fkey.c_str())); if (idy<0) { bib.key=fkey; entryTab.push_back(new BibEntry(bib)); break; } else { dletter++; if (dletter=='z') { oopscount++; dletter='a'; } } } break; } } } void BibentryTable::insert_entry(BibEntry &bib, int pos) { unsigned int ui=(unsigned int)pos; if (0 <= ui && ui < entryTab.size()) { EntryTab::iterator it = entryTab.begin(); while (ui-- > 0) it++; entryTab.insert(it, new BibEntry(bib)); } else entryTab.push_back(new BibEntry(bib)); } void BibentryTable::delete_entry(int i) { if (0 <= i && i < ((signed int)entryTab.size())) { EntryTab::iterator it = entryTab.begin(); for (int k=0; k(bib.key.c_str())); } if (0 <= idx && idx < (signed int)entryTab.size()) { (*entryTab[idx]) = bib; return false; } // This is a new entry new_entry(bib); if (selected_entry>=0) selected_entry = entryTab.size()-1; return true; } int BibentryTable::search_key(const char *s) { int found = -1; string skey = s; for (int fn=0; fn < (signed int)entryTab.size(); fn++) { BibEntry *entry = entryTab[fn]; string key = entry->getKey(); if (key == skey) { found = fn; break; } } return found; } int BibentryTable::search_string(char *s, int first) { int fn, last, found = -1; if (first >= 0) { last = entryTab.size(); } else { last = -first; first = 0; } for (fn=first; fn < last; fn++) { BibEntry *entry = entryTab[fn]; for (int i=-1; i < entry->getNoFields(); i++) { string field = (i>=0) ? entry->getField(i) : entry->getKey(); if (caseless_find(const_cast(field.c_str()),s)) { found = fn; break; } } if (found >= 0) break; } return found; } static string field_to_sort = "key"; static bool lt_fields(ApBibEntry e1, ApBibEntry e2) { const char *r1,*r2; string s1, s2; r1 = e1->getField(const_cast(field_to_sort.c_str())); r2 = e2->getField(const_cast(field_to_sort.c_str())); if ((!r1)&&(!r2)) return 0; if (!r1) return 1; if (!r2) return 0; s1=r1; s2=r2; return (s1 < s2); } static bool gt_fields(ApBibEntry e1, ApBibEntry e2) { const char *r1,*r2; string s1, s2; r1 = e1->getField(const_cast(field_to_sort.c_str())); r2 = e2->getField(const_cast(field_to_sort.c_str())); if ((!r1)&&(!r2)) return 0; if (!r1) return 1; if (!r2) return 0; s1=r1; s2=r2; return (s1 > s2); } void BibentryTable::sort(int ascending, char *s) { field_to_sort = s; ::sort(entryTab.begin(), entryTab.end(), ascending ? lt_fields : gt_fields); } // with a vengeance: will skip braces on haystack int caseless_find(const char *haystack,char *needle) { int i,j,flaws; int lh,ln; int skip_braces=1,dyn_alloc=0; char *aux,*p; char prebuf[256]; lh=strlen(haystack); ln=strlen(needle); if ((lh==0)&&(ln==0)) return 1; if (lh==0) return 0; if (strchr(needle,'{')) skip_braces=0; if (strchr(needle,'}')) skip_braces=0; if (lh>255) { aux=(char *)malloc(lh+1); dyn_alloc=1; } else aux=prebuf; if (skip_braces) { memset(aux,0,lh+1); p=aux; for(i=0;ilh) { if (dyn_alloc) free(aux); return 0; } for(i=0;i<(lh-ln+1);i++) { flaws=0; for(j=0;j= 0 && i < commands.size()) { vector_pair_strings::iterator it = commands.begin(); for (int j=0; j!=i; j++) it++; commands.erase(it); } } void BibentryTable::setCommand(int i, string s) { if (i >= 0 && i < commands.size()) { commands[i].second = s; } }