#include #include #define MAX 255 #define ED "red." #define TR "Ă–vers." void field(char *); void entry(void); int pf(char *, ...); char *name; struct entry { char au[MAX]; char al[MAX]; char bo[MAX]; char ci[MAX]; char da[MAX]; char ed[MAX]; char jo[MAX]; char no[MAX]; char pg[MAX]; char pu[MAX]; char se[MAX]; char ti[MAX]; char tr[MAX]; char vo[MAX]; } e; %s ENTRY %% ^%.*\n field(yytext); BEGIN(ENTRY); ^[^%] entry(); ECHO; BEGIN(0); <> entry(); yyterminate(); %% void main(int argc, char *argv[0]) { name = argv[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); AS("al",e.al); AS("bo",e.bo); AS("ci",e.ci); AS("da",e.da); AS("ed",e.ed); AS("jo",e.jo); AS("no",e.no); AS("pg",e.pg); AS("pu",e.pu); AS("se",e.se); AS("ti",e.ti); AS("tr",e.tr); AS("vo",e.vo); fprintf(stderr, "%s: unrecognized field %%%.2s\n", name, t); exit(1); } /* Print formatted entry. */ void entry() { #define EI(a, b) a ? a : b (pf("% (%).\n", e.au, e.da) || pf("%.\n", e.au)); if (*e.bo || *e.jo){ pf("%.\n", e.ti); pf("\\fI%\\fP", EI(e.bo, e.jo)); pf(" ("ED" %)", e.ed); pf(".\n"); }else pf("\\fI%\\fP.\n", e.ti); pf(TR" %.\n", e.tr); (pf("%: %.\n", e.ci, e.pu) || pf("%.\n", e.pu)); #define CL(a) *a = 0 CL(e.au); CL(e.al); CL(e.bo); CL(e.ci); CL(e.da); CL(e.ed); CL(e.jo); CL(e.no); CL(e.pg); CL(e.pu); CL(e.se); CL(e.ti); CL(e.tr); CL(e.vo); } /* 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; }