1*12256Stut #ifndef lint 2*12256Stut static char *sccsid = "@(#)addbib.c 4.1 (Berkeley) 05/06/83"; 3*12256Stut #endif 4*12256Stut 5*12256Stut #include <stdio.h> 6*12256Stut #include <ctype.h> 7*12256Stut #include <signal.h> 8*12256Stut #define MAXENT 50 9*12256Stut 10*12256Stut struct skeleton { 11*12256Stut char prompt[20]; /* prompt user for entry */ 12*12256Stut char keylet[5]; /* key letter for database */ 13*12256Stut } bibskel[MAXENT] = { 14*12256Stut " Author:", "%A", 15*12256Stut " Title:", "%T", 16*12256Stut " Journal:", "%J", 17*12256Stut " Volume:", "%V", 18*12256Stut " Pages:", "%P", 19*12256Stut "Publisher:", "%I", 20*12256Stut " City:", "%C", 21*12256Stut " Date:", "%D", 22*12256Stut " Other:", "%O", 23*12256Stut " Keywords:", "%K", }; 24*12256Stut 25*12256Stut int entries = 10; /* total number of entries in bibskel */ 26*12256Stut int abstract = 1; /* asking for abstracts is the default */ 27*12256Stut 28*12256Stut usage() /* print proper usage and exit */ 29*12256Stut { 30*12256Stut puts("Usage: addbib [-p promptfile] [-a] database"); 31*12256Stut puts("\t-p: the promptfile defines alternate fields"); 32*12256Stut puts("\t-a: don't include prompting for the abstract"); 33*12256Stut exit(1); 34*12256Stut } 35*12256Stut 36*12256Stut main(argc, argv) /* addbib: bibliography entry program */ 37*12256Stut int argc; 38*12256Stut char *argv[]; 39*12256Stut { 40*12256Stut FILE *fp, *fopen(); 41*12256Stut int i; 42*12256Stut 43*12256Stut if (argc == 1) 44*12256Stut { 45*12256Stut puts("You must specify a bibliography file (database)."); 46*12256Stut usage(); 47*12256Stut } 48*12256Stut for (i = 1; argv[i][0] == '-'; i++) 49*12256Stut { 50*12256Stut if (argv[i][1] == 'p') 51*12256Stut { 52*12256Stut if (i >= argc - 2) 53*12256Stut { 54*12256Stut puts("Not enough arguments for -p option."); 55*12256Stut usage(); 56*12256Stut } 57*12256Stut rd_skel(argv[++i]); 58*12256Stut } 59*12256Stut else if (argv[i][1] == 'a') 60*12256Stut { 61*12256Stut if (i >= argc - 1) 62*12256Stut { 63*12256Stut puts("No bibliofile specified after -a."); 64*12256Stut usage(); 65*12256Stut } 66*12256Stut abstract = 0; 67*12256Stut } 68*12256Stut else /* neither -p nor -a */ 69*12256Stut { 70*12256Stut printf("Invalid command line flag: %s\n", argv[i]); 71*12256Stut usage(); 72*12256Stut } 73*12256Stut } 74*12256Stut if (i < argc - 1) 75*12256Stut { 76*12256Stut puts("Too many arguments with no options."); 77*12256Stut usage(); 78*12256Stut } 79*12256Stut if ((fp = fopen(argv[i], "a")) == NULL) 80*12256Stut { 81*12256Stut perror(argv[i]); 82*12256Stut exit(1); 83*12256Stut } 84*12256Stut addbib(fp, argv[i]); /* loop for input */ 85*12256Stut exit(0); 86*12256Stut } 87*12256Stut 88*12256Stut addbib(fp, argv) /* add entries to a bibliographic database */ 89*12256Stut FILE *fp; 90*12256Stut char *argv; 91*12256Stut { 92*12256Stut char line[BUFSIZ]; 93*12256Stut int i = 0, firstln, repeat = 0, escape = 0; 94*12256Stut 95*12256Stut printf("Instructions? "); 96*12256Stut fgets(line, BUFSIZ, stdin); 97*12256Stut if (line[0] == 'y' || line[0] == 'Y') 98*12256Stut instruct(); 99*12256Stut while (1) 100*12256Stut { 101*12256Stut putchar('\n'); 102*12256Stut putc('\n', fp); 103*12256Stut for (i = 0; i < entries; i++) 104*12256Stut { 105*12256Stut printf("%s\t", bibskel[i].prompt); 106*12256Stut fgets(line, BUFSIZ, stdin); 107*12256Stut if (line[0] == '-' && line[1] == '\n') 108*12256Stut { 109*12256Stut i -= 2; 110*12256Stut if (i < -1) 111*12256Stut { 112*12256Stut printf("Too far back.\n"); 113*12256Stut i++; 114*12256Stut } 115*12256Stut continue; 116*12256Stut } 117*12256Stut else if (line[strlen(line)-2] == '\\') 118*12256Stut { 119*12256Stut if (line[0] != '\\') 120*12256Stut { 121*12256Stut line[strlen(line)-2] = '\n'; 122*12256Stut line[strlen(line)-1] = NULL; 123*12256Stut trim(line); 124*12256Stut fprintf(fp, "%s %s", 125*12256Stut bibskel[i].keylet, line); 126*12256Stut } 127*12256Stut printf("> "); 128*12256Stut again: 129*12256Stut fgets(line, BUFSIZ, stdin); 130*12256Stut if (line[strlen(line)-2] == '\\') 131*12256Stut { 132*12256Stut line[strlen(line)-2] = '\n'; 133*12256Stut line[strlen(line)-1] = NULL; 134*12256Stut trim(line); 135*12256Stut fputs(line, fp); 136*12256Stut printf("> "); 137*12256Stut goto again; 138*12256Stut } 139*12256Stut trim(line); 140*12256Stut fputs(line, fp); 141*12256Stut } 142*12256Stut else if (line[0] != '\n') 143*12256Stut { 144*12256Stut trim(line); 145*12256Stut fprintf(fp, "%s %s", bibskel[i].keylet, line); 146*12256Stut } 147*12256Stut } 148*12256Stut if (abstract) 149*12256Stut { 150*12256Stut puts(" Abstract: (ctrl-d to end)"); 151*12256Stut firstln = 1; 152*12256Stut while (fgets(line, BUFSIZ, stdin)) 153*12256Stut { 154*12256Stut if (firstln && line[0] != '%') 155*12256Stut { 156*12256Stut fprintf(fp, "%%X "); 157*12256Stut firstln = 0; 158*12256Stut } 159*12256Stut fputs(line, fp); 160*12256Stut } 161*12256Stut } 162*12256Stut fflush(fp); /* write to file at end of each cycle */ 163*12256Stut if (ferror(fp)) 164*12256Stut { 165*12256Stut perror(argv); 166*12256Stut exit(1); 167*12256Stut } 168*12256Stut editloop: 169*12256Stut printf("\nContinue? "); 170*12256Stut fgets(line, BUFSIZ, stdin); 171*12256Stut if (line[0] == 'e' || line[0] == 'v') 172*12256Stut { 173*12256Stut bibedit(fp, line, argv); 174*12256Stut goto editloop; 175*12256Stut } 176*12256Stut if (line[0] == 'q' || line[0] == 'n') 177*12256Stut return; 178*12256Stut } 179*12256Stut } 180*12256Stut 181*12256Stut trim(line) /* trim line of trailing white space */ 182*12256Stut char line[]; 183*12256Stut { 184*12256Stut int n; 185*12256Stut 186*12256Stut n = strlen(line); 187*12256Stut while (--n >= 0) 188*12256Stut { 189*12256Stut if (!isspace(line[n])) 190*12256Stut break; 191*12256Stut } 192*12256Stut line[++n] = '\n'; 193*12256Stut line[++n] = NULL; 194*12256Stut } 195*12256Stut 196*12256Stut bibedit(fp, cmd, arg) /* edit database with edit, ex, or vi */ 197*12256Stut FILE *fp; 198*12256Stut char *cmd, *arg; 199*12256Stut { 200*12256Stut int i = 0, status; 201*12256Stut 202*12256Stut fclose(fp); 203*12256Stut while (!isspace(cmd[i])) 204*12256Stut i++; 205*12256Stut cmd[i] = NULL; 206*12256Stut if (fork() == 0) 207*12256Stut { 208*12256Stut if (cmd[0] == 'v' && cmd[1] == 'i') 209*12256Stut execlp(cmd, cmd, "+$", arg, NULL); 210*12256Stut else /* either ed, ex, or edit */ 211*12256Stut execlp(cmd, cmd, arg, NULL); 212*12256Stut } 213*12256Stut signal(SIGINT, SIG_IGN); 214*12256Stut signal(SIGQUIT, SIG_IGN); 215*12256Stut wait(&status); 216*12256Stut signal(SIGINT, SIG_DFL); 217*12256Stut signal(SIGQUIT, SIG_DFL); 218*12256Stut if ((fp = fopen(arg, "a")) == NULL) 219*12256Stut { 220*12256Stut perror(arg); 221*12256Stut exit(1); 222*12256Stut } 223*12256Stut } 224*12256Stut 225*12256Stut instruct() /* give user elementary directions */ 226*12256Stut { 227*12256Stut putchar('\n'); 228*12256Stut puts("Addbib will prompt you for various bibliographic fields."); 229*12256Stut puts("If you don't need a particular field, just hit RETURN,"); 230*12256Stut puts("\tand that field will not appear in the output file."); 231*12256Stut puts("If you want to return to previous fields in the skeleton,"); 232*12256Stut puts("\ta single minus sign will go back a field at a time."); 233*12256Stut puts("\t(This is the best way to input multiple authors.)"); 234*12256Stut puts("If you have to continue a field or add an unusual field,"); 235*12256Stut puts("\ta trailing backslash will allow a temporary escape."); 236*12256Stut puts("Finally, (without -a) you will be prompted for an abstract."); 237*12256Stut puts("Type in as many lines as you need, and end with a ctrl-d."); 238*12256Stut puts("To quit, type `q' or `n' when asked if you want to continue."); 239*12256Stut puts("To edit the database, type `edit', `vi', or `ex' instead."); 240*12256Stut } 241*12256Stut 242*12256Stut rd_skel(arg) /* redo bibskel from user-supplied file */ 243*12256Stut char *arg; 244*12256Stut { 245*12256Stut FILE *pfp, *fopen(); 246*12256Stut char str[BUFSIZ]; 247*12256Stut int entry, i, j; 248*12256Stut 249*12256Stut if ((pfp = fopen(arg, "r")) == NULL) 250*12256Stut { 251*12256Stut fprintf(stderr, "Promptfile "); 252*12256Stut perror(arg); 253*12256Stut exit(1); 254*12256Stut } 255*12256Stut for (entry = 0; fgets(str, BUFSIZ, pfp); entry++) 256*12256Stut { 257*12256Stut for (i = 0; str[i] != '\t' && str[i] != '\n'; i++) 258*12256Stut bibskel[entry].prompt[i] = str[i]; 259*12256Stut bibskel[entry].prompt[i] = NULL; 260*12256Stut if (str[i] == '\n') 261*12256Stut { 262*12256Stut fprintf(stderr, "No tabs between promptfile fields.\n"); 263*12256Stut fprintf(stderr, "Format: prompt-string <TAB> %%key\n"); 264*12256Stut exit(1); 265*12256Stut } 266*12256Stut for (i++, j = 0; str[i] != '\n'; i++, j++) 267*12256Stut bibskel[entry].keylet[j] = str[i]; 268*12256Stut bibskel[entry].keylet[j] = NULL; 269*12256Stut 270*12256Stut if (entry >= MAXENT) 271*12256Stut { 272*12256Stut fprintf(stderr, "Too many entries in promptfile.\n"); 273*12256Stut exit(1); 274*12256Stut } 275*12256Stut } 276*12256Stut entries = entry; 277*12256Stut fclose(pfp); 278*12256Stut } 279