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