xref: /titanic_41/usr/src/cmd/refer/addbib.c (revision 11a8fa6cb17403e630122ac19b39a323c6e64142)
1*11a8fa6cSceastha /*
2*11a8fa6cSceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3*11a8fa6cSceastha  * Use is subject to license terms.
4*11a8fa6cSceastha  */
5*11a8fa6cSceastha 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
127c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
157c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate #include <locale.h>
197c478bd9Sstevel@tonic-gate #include <stdio.h>
207c478bd9Sstevel@tonic-gate #include <ctype.h>
217c478bd9Sstevel@tonic-gate #include <signal.h>
227c478bd9Sstevel@tonic-gate #define	MAXENT 50
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate struct skeleton {
257c478bd9Sstevel@tonic-gate 	char prompt[20];	/* prompt user for entry */
267c478bd9Sstevel@tonic-gate 	char keylet[5]; 	/* key letter for database */
277c478bd9Sstevel@tonic-gate } bibskel[MAXENT] = {
287c478bd9Sstevel@tonic-gate 	"   Author:",	"%A",
297c478bd9Sstevel@tonic-gate 	"    Title:",	"%T",
307c478bd9Sstevel@tonic-gate 	"  Journal:",	"%J",
317c478bd9Sstevel@tonic-gate 	"   Volume:", 	"%V",
327c478bd9Sstevel@tonic-gate 	"    Pages:",	"%P",
337c478bd9Sstevel@tonic-gate 	"Publisher:",	"%I",
347c478bd9Sstevel@tonic-gate 	"     City:", 	"%C",
357c478bd9Sstevel@tonic-gate 	"     Date:", 	"%D",
367c478bd9Sstevel@tonic-gate 	"    Other:",	"%O",
377c478bd9Sstevel@tonic-gate 	" Keywords:",	"%K",	};
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate int entries = 10;	/* total number of entries in bibskel */
407c478bd9Sstevel@tonic-gate int abstract = 1;	/* asking for abstracts is the default */
417c478bd9Sstevel@tonic-gate 
42*11a8fa6cSceastha static void addbib(FILE *, char *);
43*11a8fa6cSceastha void bibedit(FILE *, char *, char *);
44*11a8fa6cSceastha static void instruct(void);
45*11a8fa6cSceastha static void rd_skel(char *);
46*11a8fa6cSceastha static void trim(char []);
47*11a8fa6cSceastha 
48*11a8fa6cSceastha static void
usage(void)49*11a8fa6cSceastha usage(void)			/* print proper usage and exit */
507c478bd9Sstevel@tonic-gate {
517c478bd9Sstevel@tonic-gate 	puts(gettext("Usage:  addbib [-p promptfile] [-a] database\n\
527c478bd9Sstevel@tonic-gate \t-p: the promptfile defines alternate fields\n\
537c478bd9Sstevel@tonic-gate \t-a: don't include prompting for the abstract\n"));
547c478bd9Sstevel@tonic-gate 	exit(1);
557c478bd9Sstevel@tonic-gate }
567c478bd9Sstevel@tonic-gate 
57*11a8fa6cSceastha int
main(int argc,char * argv[])58*11a8fa6cSceastha main(int argc, char *argv[])	/* addbib: bibliography entry program */
597c478bd9Sstevel@tonic-gate {
607c478bd9Sstevel@tonic-gate 	FILE *fp, *fopen();
617c478bd9Sstevel@tonic-gate 	int i;
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
667c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
677c478bd9Sstevel@tonic-gate #endif
687c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
697c478bd9Sstevel@tonic-gate 
70*11a8fa6cSceastha 	if (argc == 1) {
71*11a8fa6cSceastha 		puts(gettext(
72*11a8fa6cSceastha 		    "You must specify a bibliography file (database)."));
737c478bd9Sstevel@tonic-gate 		usage();
747c478bd9Sstevel@tonic-gate 	}
75*11a8fa6cSceastha 	for (i = 1; argv[i][0] == '-'; i++) {
76*11a8fa6cSceastha 		if (argv[i][1] == 'p') {
77*11a8fa6cSceastha 			if (i >= argc - 2) {
78*11a8fa6cSceastha 				puts(gettext("Not enough arguments for "
79*11a8fa6cSceastha 				    "-p option."));
807c478bd9Sstevel@tonic-gate 				usage();
817c478bd9Sstevel@tonic-gate 			}
827c478bd9Sstevel@tonic-gate 			rd_skel(argv[++i]);
83*11a8fa6cSceastha 		} else if (argv[i][1] == 'a') {
84*11a8fa6cSceastha 			if (i >= argc - 1) {
85*11a8fa6cSceastha 				puts(gettext(
86*11a8fa6cSceastha 				    "No bibliofile specified after -a."));
877c478bd9Sstevel@tonic-gate 				usage();
887c478bd9Sstevel@tonic-gate 			}
897c478bd9Sstevel@tonic-gate 			abstract = 0;
90*11a8fa6cSceastha 		} else {	/* neither -p nor -a */
91*11a8fa6cSceastha 			printf(gettext(
92*11a8fa6cSceastha 			    "Invalid command line flag: %s\n"), argv[i]);
937c478bd9Sstevel@tonic-gate 			usage();
947c478bd9Sstevel@tonic-gate 		}
957c478bd9Sstevel@tonic-gate 	}
96*11a8fa6cSceastha 	if (i < argc - 1) {
977c478bd9Sstevel@tonic-gate 		puts(gettext("Too many arguments with no options."));
987c478bd9Sstevel@tonic-gate 		usage();
997c478bd9Sstevel@tonic-gate 	}
100*11a8fa6cSceastha 	if ((fp = fopen(argv[i], "a")) == NULL) {
1017c478bd9Sstevel@tonic-gate 		perror(argv[i]);
1027c478bd9Sstevel@tonic-gate 		exit(1);
1037c478bd9Sstevel@tonic-gate 	}
1047c478bd9Sstevel@tonic-gate 	addbib(fp, argv[i]);	/* loop for input */
105*11a8fa6cSceastha 	return (0);
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate 
108*11a8fa6cSceastha static void
addbib(FILE * fp,char * argv)109*11a8fa6cSceastha addbib(FILE *fp, char *argv)	/* add entries to a bibliographic database */
1107c478bd9Sstevel@tonic-gate {
1117c478bd9Sstevel@tonic-gate 	char line[BUFSIZ];
1127c478bd9Sstevel@tonic-gate 	int i = 0, firstln, repeat = 0, escape = 0;
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 	printf(gettext("Instructions? "));
1157c478bd9Sstevel@tonic-gate 	fgets(line, BUFSIZ, stdin);
1167c478bd9Sstevel@tonic-gate 	if (line[0] == 'y' || line[0] == 'Y')
1177c478bd9Sstevel@tonic-gate 		instruct();
118*11a8fa6cSceastha 	while (1) {
1197c478bd9Sstevel@tonic-gate 		putchar('\n');
1207c478bd9Sstevel@tonic-gate 		putc('\n', fp);
121*11a8fa6cSceastha 		for (i = 0; i < entries; i++) {
1227c478bd9Sstevel@tonic-gate 			printf("%s\t", gettext(bibskel[i].prompt));
123*11a8fa6cSceastha 			if (fgets(line, BUFSIZ, stdin) == NULL) {
1247c478bd9Sstevel@tonic-gate 				clearerr(stdin);
1257c478bd9Sstevel@tonic-gate 				break;
1267c478bd9Sstevel@tonic-gate 			}
127*11a8fa6cSceastha 			if (line[0] == '-' && line[1] == '\n') {
1287c478bd9Sstevel@tonic-gate 				i -= 2;
129*11a8fa6cSceastha 				if (i < -1) {
1307c478bd9Sstevel@tonic-gate 					printf(gettext("Too far back.\n"));
1317c478bd9Sstevel@tonic-gate 					i++;
1327c478bd9Sstevel@tonic-gate 				}
1337c478bd9Sstevel@tonic-gate 				continue;
134*11a8fa6cSceastha 			} else if (line[strlen(line)-2] == '\\') {
135*11a8fa6cSceastha 				if (line[0] != '\\') {
1367c478bd9Sstevel@tonic-gate 					line[strlen(line)-2] = '\n';
1377c478bd9Sstevel@tonic-gate 					line[strlen(line)-1] = NULL;
1387c478bd9Sstevel@tonic-gate 					trim(line);
1397c478bd9Sstevel@tonic-gate 					fprintf(fp, "%s %s",
1407c478bd9Sstevel@tonic-gate 					    bibskel[i].keylet, line);
1417c478bd9Sstevel@tonic-gate 				}
1427c478bd9Sstevel@tonic-gate 				printf("> ");
1437c478bd9Sstevel@tonic-gate 				again:
1447c478bd9Sstevel@tonic-gate 				fgets(line, BUFSIZ, stdin);
145*11a8fa6cSceastha 				if (line[strlen(line)-2] == '\\') {
1467c478bd9Sstevel@tonic-gate 					line[strlen(line)-2] = '\n';
1477c478bd9Sstevel@tonic-gate 					line[strlen(line)-1] = NULL;
1487c478bd9Sstevel@tonic-gate 					trim(line);
1497c478bd9Sstevel@tonic-gate 					fputs(line, fp);
1507c478bd9Sstevel@tonic-gate 					printf("> ");
1517c478bd9Sstevel@tonic-gate 					goto again;
1527c478bd9Sstevel@tonic-gate 				}
1537c478bd9Sstevel@tonic-gate 				trim(line);
1547c478bd9Sstevel@tonic-gate 				fputs(line, fp);
155*11a8fa6cSceastha 			} else if (line[0] != '\n') {
1567c478bd9Sstevel@tonic-gate 				trim(line);
1577c478bd9Sstevel@tonic-gate 				fprintf(fp, "%s %s", bibskel[i].keylet, line);
1587c478bd9Sstevel@tonic-gate 			}
1597c478bd9Sstevel@tonic-gate 		}
160*11a8fa6cSceastha 		if (abstract) {
1617c478bd9Sstevel@tonic-gate 			puts(gettext(" Abstract: (ctrl-d to end)"));
1627c478bd9Sstevel@tonic-gate 			firstln = 1;
163*11a8fa6cSceastha 			while (fgets(line, BUFSIZ, stdin)) {
164*11a8fa6cSceastha 				if (firstln && line[0] != '%') {
1657c478bd9Sstevel@tonic-gate 					fprintf(fp, "%%X ");
1667c478bd9Sstevel@tonic-gate 					firstln = 0;
1677c478bd9Sstevel@tonic-gate 				}
1687c478bd9Sstevel@tonic-gate 				fputs(line, fp);
1697c478bd9Sstevel@tonic-gate 			}
1707c478bd9Sstevel@tonic-gate 			clearerr(stdin);
1717c478bd9Sstevel@tonic-gate 		}
1727c478bd9Sstevel@tonic-gate 		fflush(fp);	/* write to file at end of each cycle */
173*11a8fa6cSceastha 		if (ferror(fp)) {
1747c478bd9Sstevel@tonic-gate 			perror(argv);
1757c478bd9Sstevel@tonic-gate 			exit(1);
1767c478bd9Sstevel@tonic-gate 		}
1777c478bd9Sstevel@tonic-gate 		editloop:
1787c478bd9Sstevel@tonic-gate 		printf(gettext("\nContinue? "));
1797c478bd9Sstevel@tonic-gate 			fgets(line, BUFSIZ, stdin);
180*11a8fa6cSceastha 		if (line[0] == 'e' || line[0] == 'v') {
1817c478bd9Sstevel@tonic-gate 			bibedit(fp, line, argv);
1827c478bd9Sstevel@tonic-gate 			goto editloop;
1837c478bd9Sstevel@tonic-gate 		}
1847c478bd9Sstevel@tonic-gate 		if (line[0] == 'q' || line[0] == 'n')
1857c478bd9Sstevel@tonic-gate 			return;
1867c478bd9Sstevel@tonic-gate 	}
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate 
189*11a8fa6cSceastha static void
trim(char line[])190*11a8fa6cSceastha trim(char line[])		/* trim line of trailing white space */
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate 	int n;
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	n = strlen(line);
195*11a8fa6cSceastha 	while (--n >= 0) {
1967c478bd9Sstevel@tonic-gate 		if (!isspace(line[n]))
1977c478bd9Sstevel@tonic-gate 			break;
1987c478bd9Sstevel@tonic-gate 	}
1997c478bd9Sstevel@tonic-gate 	line[++n] = '\n';
2007c478bd9Sstevel@tonic-gate 	line[++n] = NULL;
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate 
203*11a8fa6cSceastha void
bibedit(FILE * fp,char * cmd,char * arg)204*11a8fa6cSceastha bibedit(FILE *fp, char *cmd, char *arg)	/* edit database with edit, ex, or vi */
2057c478bd9Sstevel@tonic-gate {
2067c478bd9Sstevel@tonic-gate 	int i = 0, status;
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	fclose(fp);
2097c478bd9Sstevel@tonic-gate 	while (!isspace(cmd[i]))
2107c478bd9Sstevel@tonic-gate 		i++;
2117c478bd9Sstevel@tonic-gate 	cmd[i] = NULL;
212*11a8fa6cSceastha 	if (fork() == 0) {
2137c478bd9Sstevel@tonic-gate 		if (cmd[0] == 'v' && cmd[1] == 'i')
2147c478bd9Sstevel@tonic-gate 			execlp(cmd, cmd, "+$", arg, NULL);
2157c478bd9Sstevel@tonic-gate 		else /* either ed, ex, or edit */
2167c478bd9Sstevel@tonic-gate 			execlp(cmd, cmd, arg, NULL);
2177c478bd9Sstevel@tonic-gate 	}
2187c478bd9Sstevel@tonic-gate 	signal(SIGINT, SIG_IGN);
2197c478bd9Sstevel@tonic-gate 	signal(SIGQUIT, SIG_IGN);
2207c478bd9Sstevel@tonic-gate 	wait(&status);
2217c478bd9Sstevel@tonic-gate 	signal(SIGINT, SIG_DFL);
2227c478bd9Sstevel@tonic-gate 	signal(SIGQUIT, SIG_DFL);
223*11a8fa6cSceastha 	if ((fp = fopen(arg, "a")) == NULL) {
2247c478bd9Sstevel@tonic-gate 		perror(arg);
2257c478bd9Sstevel@tonic-gate 		exit(1);
2267c478bd9Sstevel@tonic-gate 	}
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate 
229*11a8fa6cSceastha static void
instruct(void)230*11a8fa6cSceastha instruct(void)		/* give user elementary directions */
2317c478bd9Sstevel@tonic-gate {
2327c478bd9Sstevel@tonic-gate 	putchar('\n');
233*11a8fa6cSceastha 	puts(gettext(
234*11a8fa6cSceastha 	    "Addbib will prompt you for various bibliographic fields.\n"
2357c478bd9Sstevel@tonic-gate "If you don't need a particular field, just hit RETURN,\n"
2367c478bd9Sstevel@tonic-gate "\tand that field will not appear in the output file.\n"
2377c478bd9Sstevel@tonic-gate "If you want to return to previous fields in the skeleton,\n"
2387c478bd9Sstevel@tonic-gate "\ta single minus sign will go back a field at a time.\n"
2397c478bd9Sstevel@tonic-gate "\t(This is the best way to input multiple authors.)\n"
2407c478bd9Sstevel@tonic-gate "If you have to continue a field or add an unusual field,\n"
2417c478bd9Sstevel@tonic-gate "\ta trailing backslash will allow a temporary escape.\n"
2427c478bd9Sstevel@tonic-gate "Finally, (without -a) you will be prompted for an abstract\n"
2437c478bd9Sstevel@tonic-gate "Type in as many lines as you need, and end with a ctrl-d.\n"
2447c478bd9Sstevel@tonic-gate "To quit, type `q' or `n' when asked if you want to continue.\n"
2457c478bd9Sstevel@tonic-gate "To edit the database, type `edit', `vi', or `ex' instead."));
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate 
249*11a8fa6cSceastha static void
rd_skel(char * arg)250*11a8fa6cSceastha rd_skel(char *arg)		/* redo bibskel from user-supplied file */
2517c478bd9Sstevel@tonic-gate {
2527c478bd9Sstevel@tonic-gate 	FILE *pfp, *fopen();
2537c478bd9Sstevel@tonic-gate 	char str[BUFSIZ];
2547c478bd9Sstevel@tonic-gate 	int entry, i, j;
2557c478bd9Sstevel@tonic-gate 
256*11a8fa6cSceastha 	if ((pfp = fopen(arg, "r")) == NULL) {
2577c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Promptfile "));
2587c478bd9Sstevel@tonic-gate 		perror(arg);
2597c478bd9Sstevel@tonic-gate 		exit(1);
2607c478bd9Sstevel@tonic-gate 	}
261*11a8fa6cSceastha 	for (entry = 0; fgets(str, BUFSIZ, pfp); entry++) {
2627c478bd9Sstevel@tonic-gate 		for (i = 0; str[i] != '\t' && str[i] != '\n'; i++)
2637c478bd9Sstevel@tonic-gate 			bibskel[entry].prompt[i] = str[i];
2647c478bd9Sstevel@tonic-gate 		bibskel[entry].prompt[i] = NULL;
265*11a8fa6cSceastha 		if (str[i] == '\n') {
266*11a8fa6cSceastha 			fprintf(stderr, gettext(
267*11a8fa6cSceastha 			    "No tabs between promptfile fields.\n"));
268*11a8fa6cSceastha 			fprintf(stderr, gettext(
269*11a8fa6cSceastha 			    "Format: prompt-string <TAB> %%key\n"));
2707c478bd9Sstevel@tonic-gate 			exit(1);
2717c478bd9Sstevel@tonic-gate 		}
2727c478bd9Sstevel@tonic-gate 		for (i++, j = 0; str[i] != '\n'; i++, j++)
2737c478bd9Sstevel@tonic-gate 			bibskel[entry].keylet[j] = str[i];
2747c478bd9Sstevel@tonic-gate 		bibskel[entry].keylet[j] = NULL;
2757c478bd9Sstevel@tonic-gate 
276*11a8fa6cSceastha 		if (entry >= MAXENT) {
277*11a8fa6cSceastha 			fprintf(stderr, gettext(
278*11a8fa6cSceastha 			    "Too many entries in promptfile.\n"));
2797c478bd9Sstevel@tonic-gate 			exit(1);
2807c478bd9Sstevel@tonic-gate 		}
2817c478bd9Sstevel@tonic-gate 	}
2827c478bd9Sstevel@tonic-gate 	entries = entry;
2837c478bd9Sstevel@tonic-gate 	fclose(pfp);
2847c478bd9Sstevel@tonic-gate }
285