#include #include #include #include #include #ifdef unix /* #include */ #else #include #include #endif #define MAXMENUITEMS 256 #define KEY_ESCAPE 27 #define KEY_RETURN 13 #define MAXCOLS 80 #define MAXPOLJA 128 #define MAXFORMAT 80 #define MAXBUF 4096 struct { char item[MAXCOLS]; int row; int col; char klett; char action[MAXCOLS]; } menu[MAXMENUITEMS]; int nitems; FILE *fi, *fdtext, *fdbin, *fdmask; void tracex(char *fmt, ...) { FILE *fp; va_list argptr; if ((fp = fopen("trace", "a")) != NULL) { va_start (argptr, fmt); (void) vfprintf (fp, fmt, argptr); va_end (argptr); fclose(fp); } } void initcurses (void) { #ifdef unix WINDOW *win; win = initscr (); keypad (win, 1); #else initscr (); #endif raw (); cbreak (); noecho (); nonl (); } void endcurses (void) { clear (); refresh (); endwin (); #ifdef unix /* delscreen (); */ #endif } void activate (int iitem) { move (menu[iitem].row, menu[iitem].col); attron (A_REVERSE); addstr (menu[iitem].item); attroff (A_REVERSE); move (menu[iitem].row, menu[iitem].col); refresh (); } void deactivate (int iitem) { move (menu[iitem].row, menu[iitem].col); addstr (menu[iitem].item); move (menu[iitem].row, menu[iitem].col); refresh (); } void repaint (int iitem) { int i; for (i = 0; i < nitems; i++) { move (menu[i].row, menu[i].col); addstr (menu[i].item); } activate (iitem); } void translate (char *source, char *s1, char *s2) { char *start; int ilen1, ilen2; if ((start = strstr (source, s1)) == NULL) return; ilen1 = strlen (s1); ilen2 = strlen (s2); memmove (start + ilen2, start + ilen1, strlen (start + ilen1) + 1); memcpy (start, s2, ilen2); return; } void prikaz(FILE *fdtext, FILE *fdmask) { struct { int duljinas; char format[MAXFORMAT+1]; int duljinad; } opis[MAXPOLJA]; int npolja = 0, pocetaks, pocetakd, i; char buf[MAXBUF+1], polje[MAXBUF+1]; char zapis[MAXBUF+1]; initcurses(); clear(); rewind(fdmask); while (npolja < MAXPOLJA && fscanf (fdmask, "%d %s %d", &opis[npolja].duljinas, opis[npolja].format, &opis[npolja].duljinad) == 3) { translate (opis[npolja].format, "\\n", "\n"); npolja++; } if (fgets (buf, MAXBUF, fdtext)) { pocetaks = 0; pocetakd = 0; for (i = 0; i < npolja; i++) { strncpy (polje, &buf[pocetaks], opis[i].duljinas); polje[opis[i].duljinas] = '\0'; sscanf (polje, opis[i].format, &zapis[pocetakd]); addstr(polje); pocetaks += opis[i].duljinas; pocetakd += opis[i].duljinad; } } else addstr("Nema vishe podataka"); getch(); endcurses(); } void prepisi(FILE *fdtext, FILE *fdbin, FILE *fdmask) { struct { int duljinas; char format[MAXFORMAT+1]; int duljinad; } opis[MAXPOLJA]; int npolja = 0, pocetaks, pocetakd, i; char buf[MAXBUF+1], polje[MAXBUF+1]; char zapis[MAXBUF+1]; rewind(fdmask); rewind(fdtext); while (npolja < MAXPOLJA && fscanf (fdmask, "%d %s %d", &opis[npolja].duljinas, opis[npolja].format, &opis[npolja].duljinad) == 3) { translate (opis[npolja].format, "\\n", "\n"); npolja++; } while (fgets (buf, MAXBUF, fdtext)) { pocetaks = 0; pocetakd = 0; for (i = 0; i < npolja; i++) { strncpy (polje, &buf[pocetaks], opis[i].duljinas); polje[opis[i].duljinas] = '\0'; sscanf (polje, opis[i].format, &zapis[pocetakd]); pocetaks += opis[i].duljinas; pocetakd += opis[i].duljinad; } fwrite (zapis, pocetakd, 1, fdbin); } } void execute (int iitem) { endcurses (); if (!strcmp(menu[iitem].action, "kraj")) exit(0); else if (!strcmp(menu[iitem].action, "prvi")) { rewind(fdtext); prikaz(fdtext, fdmask); } else if (!strcmp(menu[iitem].action, "slijedeci")) prikaz(fdtext, fdmask); else if (!strcmp(menu[iitem].action, "prijepis")) prepisi(fdtext, fdbin, fdmask); else system(menu[iitem].action); initcurses (); repaint (iitem); } int main (int argc, char *argv[]) { int i, j, c; /* ime datoteke u kojoj je define menija (menu.def) */ fi = fopen (argv[1], "r"); /* ime textualne ulazne datoteke (slijedna) */ fdtext=fopen(argv[2], "r"); /* ime binarne izlazne dadoteke (binarna) */ fdbin=fopen(argv[3], "wb"); /* ime ulazne maske za list i prijepis (maska) */ fdmask=fopen(argv[4], "r"); if (!fi || !fdbin || !fdmask || !fdtext) { fprintf (stderr, "Ne mogu otvoriti dadoteku.\n"); exit (1); } nitems = 0; while (nitems < MAXMENUITEMS && fscanf (fi, "%d#%d#%c#%80[^#]%*c%80[^\n]%*c", &menu[nitems].row, &menu[nitems].col, &menu[nitems].klett, menu[nitems].item, menu[nitems].action) > 0) { /* tracex ("%d %d %c %s %s\n", menu[nitems].row, menu[nitems].col, menu[nitems].klett, menu[nitems].item, menu[nitems].action); */ nitems++; } initcurses (); i = 0; repaint (i); while (1) { c = getch (); #ifndef unix if (c == 0 ) c = 255+getch (); #endif switch (c) { case KEY_ESCAPE: endcurses (); exit (1); case KEY_DOWN: /* down */ deactivate (i); i = (i + 1) % nitems; activate (i); break; case KEY_UP: /* up */ deactivate (i); if (i == 0) i = nitems - 1; else i--; activate (i); break; case KEY_RETURN: execute (i); break; default: /* klett */ for (j = 0; j < nitems; j++) { if (toupper(menu[j].klett) == toupper(c)) { deactivate (i); i = j; activate (i); execute (i); break; } } } } }