#include #include #define MAX 255 #define AND "och" #define AVAIL "Tillgänglig: " #define ED "red." #define PP "ss." #define TR "Övers." #define VOL "vol." void field(char *); void entry(void); int pf(char *, ...); char *name; struct entry { int a; /* Number of authors. */ char au[MAX][MAX]; /* author */ char ad[MAX]; /* internet address */ char bo[MAX]; /* book */ char ci[MAX]; /* city */ char da[MAX]; /* date (year) */ char ed[MAX]; /* editor */ char jo[MAX]; /* journal */ char la[MAX]; /* label */ char no[MAX]; /* TODO: issue number */ char pp[MAX]; /* pages */ char pu[MAX]; /* publisher */ char se[MAX]; /* TODO: series */ char ti[MAX]; /* title */ char tr[MAX]; /* translator */ char vo[MAX]; /* volume */ char xx[MAX]; /* extra information */ } e; %s ENTRY %% ^%.*\n field(yytext); BEGIN(ENTRY); ^[^%] entry(); ECHO; BEGIN(0); <> entry(); yyterminate(); %% void main(int argc, char *argv[0]) { name = argv[0]; e.a = 0; yylex(); } /* Save entry field. */ void field(char *t) { #define AS(a,b) if(strncmp(t, a, 2) == 0 && (t += 3)){ strcpy(b, t); return; } t++; t[strcspn(t, "\n")] = 0; AS("au",e.au[e.a++]); AS("ad",e.ad); AS("bo",e.bo); AS("ci",e.ci); AS("da",e.da); AS("ed",e.ed); AS("jo",e.jo); AS("la",e.la); AS("no",e.no); AS("pp",e.pp); AS("pu",e.pu); AS("se",e.se); AS("ti",e.ti); AS("tr",e.tr); AS("vo",e.vo); AS("xx",e.xx); fprintf(stderr, "%s: unrecognized field %%%.2s\n", name, t); exit(1); } /* Print formatted entry. */ void entry() { int i; #define EI(a, b) a ? a : b /* Print label. */ pf("% = ", e.la); /* Print authors. */ for(i = 0; i < e.a-2; i++) printf("%s, ", e.au[i]); if(i == e.a-2) printf("%s "AND" ", e.au[i++]); if(i == e.a-1) printf("%s", e.au[i]); /* Print date. */ (pf(" (%).\n", e.da) || (e.a ? pf(".\n") : 0)); /* Print title, book/journal. */ if(*e.bo || *e.jo){ pf("%.\n", e.ti); pf("\\fI%\\fP", EI(e.bo, e.jo)); pf(" ("ED" %)", e.ed); }else pf("\\fI%\\fP", e.ti); /* Print volume, pages. */ pf(", "VOL" %", e.vo); pf(", "PP" %", e.pp); pf(".\n"); /* Print translator. */ pf(TR" %.\n", e.tr); /* Print city, publisher. */ (pf("%: %.\n", e.ci, e.pu) || pf("%.\n", e.pu)); /* Print other information. */ pf("%.\n", e.xx); /* Print internet address. */ pf(AVAIL"%\n", e.ad); #define CL(a) *a = 0 e.a = 0; CL(e.ad); CL(e.bo); CL(e.ci); CL(e.da); CL(e.ed); CL(e.jo); CL(e.la); CL(e.no); CL(e.pp); CL(e.pu); CL(e.se); CL(e.ti); CL(e.tr); CL(e.vo); CL(e.xx); } /* Print formatted text if given strings are non-empty. */ int pf(char *fmt, ...) { char *buf, *p; int n; va_list ap; n = 0; for(p = fmt; *p; p++) if(*p == '%') n++; if(!(buf = malloc(strlen(fmt)+n*MAX+1))) err(1, "malloc"); va_start(ap, fmt); for(; *fmt; fmt++) switch(*fmt){ case '%': p = va_arg(ap, char *); if(!p || !*p) return 0; strcat(buf, p); break; default: strncat(buf, fmt, 1); } printf("%s", buf); va_end(ap); return 1; }