xref: /illumos-gate/usr/src/cmd/refer/addbib.c (revision 7bc3049f)
111a8fa6cSceastha /*
211a8fa6cSceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
311a8fa6cSceastha  * Use is subject to license terms.
411a8fa6cSceastha  */
511a8fa6cSceastha 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
7*7bc3049fSToomas Soome /*	  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 #include <locale.h>
167c478bd9Sstevel@tonic-gate #include <stdio.h>
177c478bd9Sstevel@tonic-gate #include <ctype.h>
187c478bd9Sstevel@tonic-gate #include <signal.h>
1911a8fa6cSceastha #define	MAXENT 50
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate struct skeleton {
227c478bd9Sstevel@tonic-gate 	char prompt[20];	/* prompt user for entry */
23*7bc3049fSToomas Soome 	char keylet[5];		/* key letter for database */
247c478bd9Sstevel@tonic-gate } bibskel[MAXENT] = {
257c478bd9Sstevel@tonic-gate 	"   Author:",	"%A",
267c478bd9Sstevel@tonic-gate 	"    Title:",	"%T",
277c478bd9Sstevel@tonic-gate 	"  Journal:",	"%J",
28*7bc3049fSToomas Soome 	"   Volume:",	"%V",
297c478bd9Sstevel@tonic-gate 	"    Pages:",	"%P",
307c478bd9Sstevel@tonic-gate 	"Publisher:",	"%I",
31*7bc3049fSToomas Soome 	"     City:",	"%C",
32*7bc3049fSToomas Soome 	"     Date:",	"%D",
337c478bd9Sstevel@tonic-gate 	"    Other:",	"%O",
347c478bd9Sstevel@tonic-gate 	" Keywords:",	"%K",	};
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate int entries = 10;	/* total number of entries in bibskel */
377c478bd9Sstevel@tonic-gate int abstract = 1;	/* asking for abstracts is the default */
387c478bd9Sstevel@tonic-gate 
3911a8fa6cSceastha static void addbib(FILE *, char *);
4011a8fa6cSceastha void bibedit(FILE *, char *, char *);
4111a8fa6cSceastha static void instruct(void);
4211a8fa6cSceastha static void rd_skel(char *);
4311a8fa6cSceastha static void trim(char []);
4411a8fa6cSceastha 
4511a8fa6cSceastha static void
usage(void)4611a8fa6cSceastha usage(void)			/* print proper usage and exit */
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate 	puts(gettext("Usage:  addbib [-p promptfile] [-a] database\n\
497c478bd9Sstevel@tonic-gate \t-p: the promptfile defines alternate fields\n\
507c478bd9Sstevel@tonic-gate \t-a: don't include prompting for the abstract\n"));
517c478bd9Sstevel@tonic-gate 	exit(1);
527c478bd9Sstevel@tonic-gate }
537c478bd9Sstevel@tonic-gate 
5411a8fa6cSceastha int
main(int argc,char * argv[])5511a8fa6cSceastha main(int argc, char *argv[])	/* addbib: bibliography entry program */
567c478bd9Sstevel@tonic-gate {
577c478bd9Sstevel@tonic-gate 	FILE *fp, *fopen();
587c478bd9Sstevel@tonic-gate 	int i;
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
6311a8fa6cSceastha #define	TEXT_DOMAIN "SYS_TEST"
647c478bd9Sstevel@tonic-gate #endif
657c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
667c478bd9Sstevel@tonic-gate 
6711a8fa6cSceastha 	if (argc == 1) {
6811a8fa6cSceastha 		puts(gettext(
6911a8fa6cSceastha 		    "You must specify a bibliography file (database)."));
707c478bd9Sstevel@tonic-gate 		usage();
717c478bd9Sstevel@tonic-gate 	}
7211a8fa6cSceastha 	for (i = 1; argv[i][0] == '-'; i++) {
7311a8fa6cSceastha 		if (argv[i][1] == 'p') {
7411a8fa6cSceastha 			if (i >= argc - 2) {
7511a8fa6cSceastha 				puts(gettext("Not enough arguments for "
7611a8fa6cSceastha 				    "-p option."));
777c478bd9Sstevel@tonic-gate 				usage();
787c478bd9Sstevel@tonic-gate 			}
797c478bd9Sstevel@tonic-gate 			rd_skel(argv[++i]);
8011a8fa6cSceastha 		} else if (argv[i][1] == 'a') {
8111a8fa6cSceastha 			if (i >= argc - 1) {
8211a8fa6cSceastha 				puts(gettext(
8311a8fa6cSceastha 				    "No bibliofile specified after -a."));
847c478bd9Sstevel@tonic-gate 				usage();
857c478bd9Sstevel@tonic-gate 			}
867c478bd9Sstevel@tonic-gate 			abstract = 0;
8711a8fa6cSceastha 		} else {	/* neither -p nor -a */
8811a8fa6cSceastha 			printf(gettext(
8911a8fa6cSceastha 			    "Invalid command line flag: %s\n"), argv[i]);
907c478bd9Sstevel@tonic-gate 			usage();
917c478bd9Sstevel@tonic-gate 		}
927c478bd9Sstevel@tonic-gate 	}
9311a8fa6cSceastha 	if (i < argc - 1) {
947c478bd9Sstevel@tonic-gate 		puts(gettext("Too many arguments with no options."));
957c478bd9Sstevel@tonic-gate 		usage();
967c478bd9Sstevel@tonic-gate 	}
9711a8fa6cSceastha 	if ((fp = fopen(argv[i], "a")) == NULL) {
987c478bd9Sstevel@tonic-gate 		perror(argv[i]);
997c478bd9Sstevel@tonic-gate 		exit(1);
1007c478bd9Sstevel@tonic-gate 	}
1017c478bd9Sstevel@tonic-gate 	addbib(fp, argv[i]);	/* loop for input */
10211a8fa6cSceastha 	return (0);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate 
10511a8fa6cSceastha static void
addbib(FILE * fp,char * argv)10611a8fa6cSceastha addbib(FILE *fp, char *argv)	/* add entries to a bibliographic database */
1077c478bd9Sstevel@tonic-gate {
1087c478bd9Sstevel@tonic-gate 	char line[BUFSIZ];
1097c478bd9Sstevel@tonic-gate 	int i = 0, firstln, repeat = 0, escape = 0;
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	printf(gettext("Instructions? "));
1127c478bd9Sstevel@tonic-gate 	fgets(line, BUFSIZ, stdin);
1137c478bd9Sstevel@tonic-gate 	if (line[0] == 'y' || line[0] == 'Y')
1147c478bd9Sstevel@tonic-gate 		instruct();
11511a8fa6cSceastha 	while (1) {
1167c478bd9Sstevel@tonic-gate 		putchar('\n');
1177c478bd9Sstevel@tonic-gate 		putc('\n', fp);
11811a8fa6cSceastha 		for (i = 0; i < entries; i++) {
1197c478bd9Sstevel@tonic-gate 			printf("%s\t", gettext(bibskel[i].prompt));
12011a8fa6cSceastha 			if (fgets(line, BUFSIZ, stdin) == NULL) {
1217c478bd9Sstevel@tonic-gate 				clearerr(stdin);
1227c478bd9Sstevel@tonic-gate 				break;
1237c478bd9Sstevel@tonic-gate 			}
12411a8fa6cSceastha 			if (line[0] == '-' && line[1] == '\n') {
1257c478bd9Sstevel@tonic-gate 				i -= 2;
12611a8fa6cSceastha 				if (i < -1) {
1277c478bd9Sstevel@tonic-gate 					printf(gettext("Too far back.\n"));
1287c478bd9Sstevel@tonic-gate 					i++;
1297c478bd9Sstevel@tonic-gate 				}
1307c478bd9Sstevel@tonic-gate 				continue;
13111a8fa6cSceastha 			} else if (line[strlen(line)-2] == '\\') {
13211a8fa6cSceastha 				if (line[0] != '\\') {
1337c478bd9Sstevel@tonic-gate 					line[strlen(line)-2] = '\n';
134*7bc3049fSToomas Soome 					line[strlen(line)-1] = '\0';
1357c478bd9Sstevel@tonic-gate 					trim(line);
1367c478bd9Sstevel@tonic-gate 					fprintf(fp, "%s %s",
13711a8fa6cSceastha 					    bibskel[i].keylet, line);
1387c478bd9Sstevel@tonic-gate 				}
1397c478bd9Sstevel@tonic-gate 				printf("> ");
1407c478bd9Sstevel@tonic-gate 				again:
1417c478bd9Sstevel@tonic-gate 				fgets(line, BUFSIZ, stdin);
14211a8fa6cSceastha 				if (line[strlen(line)-2] == '\\') {
1437c478bd9Sstevel@tonic-gate 					line[strlen(line)-2] = '\n';
144*7bc3049fSToomas Soome 					line[strlen(line)-1] = '\0';
1457c478bd9Sstevel@tonic-gate 					trim(line);
1467c478bd9Sstevel@tonic-gate 					fputs(line, fp);
1477c478bd9Sstevel@tonic-gate 					printf("> ");
1487c478bd9Sstevel@tonic-gate 					goto again;
1497c478bd9Sstevel@tonic-gate 				}
1507c478bd9Sstevel@tonic-gate 				trim(line);
1517c478bd9Sstevel@tonic-gate 				fputs(line, fp);
15211a8fa6cSceastha 			} else if (line[0] != '\n') {
1537c478bd9Sstevel@tonic-gate 				trim(line);
1547c478bd9Sstevel@tonic-gate 				fprintf(fp, "%s %s", bibskel[i].keylet, line);
1557c478bd9Sstevel@tonic-gate 			}
1567c478bd9Sstevel@tonic-gate 		}
15711a8fa6cSceastha 		if (abstract) {
1587c478bd9Sstevel@tonic-gate 			puts(gettext(" Abstract: (ctrl-d to end)"));
1597c478bd9Sstevel@tonic-gate 			firstln = 1;
16011a8fa6cSceastha 			while (fgets(line, BUFSIZ, stdin)) {
16111a8fa6cSceastha 				if (firstln && line[0] != '%') {
1627c478bd9Sstevel@tonic-gate 					fprintf(fp, "%%X ");
1637c478bd9Sstevel@tonic-gate 					firstln = 0;
1647c478bd9Sstevel@tonic-gate 				}
1657c478bd9Sstevel@tonic-gate 				fputs(line, fp);
1667c478bd9Sstevel@tonic-gate 			}
1677c478bd9Sstevel@tonic-gate 			clearerr(stdin);
1687c478bd9Sstevel@tonic-gate 		}
1697c478bd9Sstevel@tonic-gate 		fflush(fp);	/* write to file at end of each cycle */
17011a8fa6cSceastha 		if (ferror(fp)) {
1717c478bd9Sstevel@tonic-gate 			perror(argv);
1727c478bd9Sstevel@tonic-gate 			exit(1);
1737c478bd9Sstevel@tonic-gate 		}
1747c478bd9Sstevel@tonic-gate 		editloop:
1757c478bd9Sstevel@tonic-gate 		printf(gettext("\nContinue? "));
1767c478bd9Sstevel@tonic-gate 			fgets(line, BUFSIZ, stdin);
17711a8fa6cSceastha 		if (line[0] == 'e' || line[0] == 'v') {
1787c478bd9Sstevel@tonic-gate 			bibedit(fp, line, argv);
1797c478bd9Sstevel@tonic-gate 			goto editloop;
1807c478bd9Sstevel@tonic-gate 		}
1817c478bd9Sstevel@tonic-gate 		if (line[0] == 'q' || line[0] == 'n')
1827c478bd9Sstevel@tonic-gate 			return;
1837c478bd9Sstevel@tonic-gate 	}
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate 
18611a8fa6cSceastha static void
trim(char line[])18711a8fa6cSceastha trim(char line[])		/* trim line of trailing white space */
1887c478bd9Sstevel@tonic-gate {
1897c478bd9Sstevel@tonic-gate 	int n;
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 	n = strlen(line);
19211a8fa6cSceastha 	while (--n >= 0) {
1937c478bd9Sstevel@tonic-gate 		if (!isspace(line[n]))
1947c478bd9Sstevel@tonic-gate 			break;
1957c478bd9Sstevel@tonic-gate 	}
1967c478bd9Sstevel@tonic-gate 	line[++n] = '\n';
197*7bc3049fSToomas Soome 	line[++n] = '\0';
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
20011a8fa6cSceastha void
bibedit(FILE * fp,char * cmd,char * arg)20111a8fa6cSceastha bibedit(FILE *fp, char *cmd, char *arg)	/* edit database with edit, ex, or vi */
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 	int i = 0, status;
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	fclose(fp);
2067c478bd9Sstevel@tonic-gate 	while (!isspace(cmd[i]))
2077c478bd9Sstevel@tonic-gate 		i++;
208*7bc3049fSToomas Soome 	cmd[i] = '\0';
20911a8fa6cSceastha 	if (fork() == 0) {
2107c478bd9Sstevel@tonic-gate 		if (cmd[0] == 'v' && cmd[1] == 'i')
2117c478bd9Sstevel@tonic-gate 			execlp(cmd, cmd, "+$", arg, NULL);
2127c478bd9Sstevel@tonic-gate 		else /* either ed, ex, or edit */
2137c478bd9Sstevel@tonic-gate 			execlp(cmd, cmd, arg, NULL);
2147c478bd9Sstevel@tonic-gate 	}
2157c478bd9Sstevel@tonic-gate 	signal(SIGINT, SIG_IGN);
2167c478bd9Sstevel@tonic-gate 	signal(SIGQUIT, SIG_IGN);
2177c478bd9Sstevel@tonic-gate 	wait(&status);
2187c478bd9Sstevel@tonic-gate 	signal(SIGINT, SIG_DFL);
2197c478bd9Sstevel@tonic-gate 	signal(SIGQUIT, SIG_DFL);
22011a8fa6cSceastha 	if ((fp = fopen(arg, "a")) == NULL) {
2217c478bd9Sstevel@tonic-gate 		perror(arg);
2227c478bd9Sstevel@tonic-gate 		exit(1);
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate 
22611a8fa6cSceastha static void
instruct(void)22711a8fa6cSceastha instruct(void)		/* give user elementary directions */
2287c478bd9Sstevel@tonic-gate {
2297c478bd9Sstevel@tonic-gate 	putchar('\n');
23011a8fa6cSceastha 	puts(gettext(
23111a8fa6cSceastha 	    "Addbib will prompt you for various bibliographic fields.\n"
2327c478bd9Sstevel@tonic-gate "If you don't need a particular field, just hit RETURN,\n"
2337c478bd9Sstevel@tonic-gate "\tand that field will not appear in the output file.\n"
2347c478bd9Sstevel@tonic-gate "If you want to return to previous fields in the skeleton,\n"
2357c478bd9Sstevel@tonic-gate "\ta single minus sign will go back a field at a time.\n"
2367c478bd9Sstevel@tonic-gate "\t(This is the best way to input multiple authors.)\n"
2377c478bd9Sstevel@tonic-gate "If you have to continue a field or add an unusual field,\n"
2387c478bd9Sstevel@tonic-gate "\ta trailing backslash will allow a temporary escape.\n"
2397c478bd9Sstevel@tonic-gate "Finally, (without -a) you will be prompted for an abstract\n"
2407c478bd9Sstevel@tonic-gate "Type in as many lines as you need, and end with a ctrl-d.\n"
2417c478bd9Sstevel@tonic-gate "To quit, type `q' or `n' when asked if you want to continue.\n"
2427c478bd9Sstevel@tonic-gate "To edit the database, type `edit', `vi', or `ex' instead."));
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate 
24611a8fa6cSceastha static void
rd_skel(char * arg)24711a8fa6cSceastha rd_skel(char *arg)		/* redo bibskel from user-supplied file */
2487c478bd9Sstevel@tonic-gate {
2497c478bd9Sstevel@tonic-gate 	FILE *pfp, *fopen();
2507c478bd9Sstevel@tonic-gate 	char str[BUFSIZ];
2517c478bd9Sstevel@tonic-gate 	int entry, i, j;
2527c478bd9Sstevel@tonic-gate 
25311a8fa6cSceastha 	if ((pfp = fopen(arg, "r")) == NULL) {
2547c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Promptfile "));
2557c478bd9Sstevel@tonic-gate 		perror(arg);
2567c478bd9Sstevel@tonic-gate 		exit(1);
2577c478bd9Sstevel@tonic-gate 	}
25811a8fa6cSceastha 	for (entry = 0; fgets(str, BUFSIZ, pfp); entry++) {
2597c478bd9Sstevel@tonic-gate 		for (i = 0; str[i] != '\t' && str[i] != '\n'; i++)
2607c478bd9Sstevel@tonic-gate 			bibskel[entry].prompt[i] = str[i];
261*7bc3049fSToomas Soome 		bibskel[entry].prompt[i] = '\0';
26211a8fa6cSceastha 		if (str[i] == '\n') {
26311a8fa6cSceastha 			fprintf(stderr, gettext(
26411a8fa6cSceastha 			    "No tabs between promptfile fields.\n"));
26511a8fa6cSceastha 			fprintf(stderr, gettext(
26611a8fa6cSceastha 			    "Format: prompt-string <TAB> %%key\n"));
2677c478bd9Sstevel@tonic-gate 			exit(1);
2687c478bd9Sstevel@tonic-gate 		}
26911a8fa6cSceastha 		for (i++, j = 0; str[i] != '\n'; i++, j++)
2707c478bd9Sstevel@tonic-gate 			bibskel[entry].keylet[j] = str[i];
271*7bc3049fSToomas Soome 		bibskel[entry].keylet[j] = '\0';
2727c478bd9Sstevel@tonic-gate 
27311a8fa6cSceastha 		if (entry >= MAXENT) {
27411a8fa6cSceastha 			fprintf(stderr, gettext(
27511a8fa6cSceastha 			    "Too many entries in promptfile.\n"));
2767c478bd9Sstevel@tonic-gate 			exit(1);
2777c478bd9Sstevel@tonic-gate 		}
2787c478bd9Sstevel@tonic-gate 	}
2797c478bd9Sstevel@tonic-gate 	entries = entry;
2807c478bd9Sstevel@tonic-gate 	fclose(pfp);
2817c478bd9Sstevel@tonic-gate }
282