|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)addbib.c 4.2 (Berkeley) 11/2/84";
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: if (fgets(line, BUFSIZ, stdin) == NULL)
107: {
108: clearerr(stdin);
109: break;
110: }
111: if (line[0] == '-' && line[1] == '\n')
112: {
113: i -= 2;
114: if (i < -1)
115: {
116: printf("Too far back.\n");
117: i++;
118: }
119: continue;
120: }
121: else if (line[strlen(line)-2] == '\\')
122: {
123: if (line[0] != '\\')
124: {
125: line[strlen(line)-2] = '\n';
126: line[strlen(line)-1] = NULL;
127: trim(line);
128: fprintf(fp, "%s %s",
129: bibskel[i].keylet, line);
130: }
131: printf("> ");
132: again:
133: fgets(line, BUFSIZ, stdin);
134: if (line[strlen(line)-2] == '\\')
135: {
136: line[strlen(line)-2] = '\n';
137: line[strlen(line)-1] = NULL;
138: trim(line);
139: fputs(line, fp);
140: printf("> ");
141: goto again;
142: }
143: trim(line);
144: fputs(line, fp);
145: }
146: else if (line[0] != '\n')
147: {
148: trim(line);
149: fprintf(fp, "%s %s", bibskel[i].keylet, line);
150: }
151: }
152: if (abstract)
153: {
154: puts(" Abstract: (ctrl-d to end)");
155: firstln = 1;
156: while (fgets(line, BUFSIZ, stdin))
157: {
158: if (firstln && line[0] != '%')
159: {
160: fprintf(fp, "%%X ");
161: firstln = 0;
162: }
163: fputs(line, fp);
164: }
165: clearerr(stdin);
166: }
167: fflush(fp); /* write to file at end of each cycle */
168: if (ferror(fp))
169: {
170: perror(argv);
171: exit(1);
172: }
173: editloop:
174: printf("\nContinue? ");
175: fgets(line, BUFSIZ, stdin);
176: if (line[0] == 'e' || line[0] == 'v')
177: {
178: bibedit(fp, line, argv);
179: goto editloop;
180: }
181: if (line[0] == 'q' || line[0] == 'n')
182: return;
183: }
184: }
185:
186: trim(line) /* trim line of trailing white space */
187: char line[];
188: {
189: int n;
190:
191: n = strlen(line);
192: while (--n >= 0)
193: {
194: if (!isspace(line[n]))
195: break;
196: }
197: line[++n] = '\n';
198: line[++n] = NULL;
199: }
200:
201: bibedit(fp, cmd, arg) /* edit database with edit, ex, or vi */
202: FILE *fp;
203: char *cmd, *arg;
204: {
205: int i = 0, status;
206:
207: fclose(fp);
208: while (!isspace(cmd[i]))
209: i++;
210: cmd[i] = NULL;
211: if (fork() == 0)
212: {
213: if (cmd[0] == 'v' && cmd[1] == 'i')
214: execlp(cmd, cmd, "+$", arg, NULL);
215: else /* either ed, ex, or edit */
216: execlp(cmd, cmd, arg, NULL);
217: }
218: signal(SIGINT, SIG_IGN);
219: signal(SIGQUIT, SIG_IGN);
220: wait(&status);
221: signal(SIGINT, SIG_DFL);
222: signal(SIGQUIT, SIG_DFL);
223: if ((fp = fopen(arg, "a")) == NULL)
224: {
225: perror(arg);
226: exit(1);
227: }
228: }
229:
230: instruct() /* give user elementary directions */
231: {
232: putchar('\n');
233: puts("Addbib will prompt you for various bibliographic fields.");
234: puts("If you don't need a particular field, just hit RETURN,");
235: puts("\tand that field will not appear in the output file.");
236: puts("If you want to return to previous fields in the skeleton,");
237: puts("\ta single minus sign will go back a field at a time.");
238: puts("\t(This is the best way to input multiple authors.)");
239: puts("If you have to continue a field or add an unusual field,");
240: puts("\ta trailing backslash will allow a temporary escape.");
241: puts("Finally, (without -a) you will be prompted for an abstract.");
242: puts("Type in as many lines as you need, and end with a ctrl-d.");
243: puts("To quit, type `q' or `n' when asked if you want to continue.");
244: puts("To edit the database, type `edit', `vi', or `ex' instead.");
245: }
246:
247: rd_skel(arg) /* redo bibskel from user-supplied file */
248: char *arg;
249: {
250: FILE *pfp, *fopen();
251: char str[BUFSIZ];
252: int entry, i, j;
253:
254: if ((pfp = fopen(arg, "r")) == NULL)
255: {
256: fprintf(stderr, "Promptfile ");
257: perror(arg);
258: exit(1);
259: }
260: for (entry = 0; fgets(str, BUFSIZ, pfp); entry++)
261: {
262: for (i = 0; str[i] != '\t' && str[i] != '\n'; i++)
263: bibskel[entry].prompt[i] = str[i];
264: bibskel[entry].prompt[i] = NULL;
265: if (str[i] == '\n')
266: {
267: fprintf(stderr, "No tabs between promptfile fields.\n");
268: fprintf(stderr, "Format: prompt-string <TAB> %%key\n");
269: exit(1);
270: }
271: for (i++, j = 0; str[i] != '\n'; i++, j++)
272: bibskel[entry].keylet[j] = str[i];
273: bibskel[entry].keylet[j] = NULL;
274:
275: if (entry >= MAXENT)
276: {
277: fprintf(stderr, "Too many entries in promptfile.\n");
278: exit(1);
279: }
280: }
281: entries = entry;
282: fclose(pfp);
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.