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