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