1 /**
2 *	nsf :- nakamura version of sf (see unix magagine 89.7 page 122- )
3 **/
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <signal.h>
7 #include <string.h>
8 #define MAIN
9 #include "nsf.h"
10 
usage()11 static int usage(){
12 	fprintf(stderr,"usage: nsf [-flags] < infile > outfile\n");
13 	fprintf(stderr,"\t-b\toutput is for bsh (default csh)\n");
14 	fprintf(stderr,"\t-c 3\tcursol initial postion.\n");
15 	fprintf(stderr,"\t-m message\tinitial wornning.\n");
16 	fprintf(stderr,"\t-i infile\tuse infile instead of stdin.\n");
17 	fprintf(stderr,"\t-o outfile\tuse outfile instead of stdout.\n");
18 	fprintf(stderr,"\t-u \tuse under line for input field.\n");
19 	exit(0);
20 }
21 /**
22 *	done()
23 **/
done()24 void done(){
25 	move(LINES-1,0);
26 	clrtoeol();
27 	refresh();
28 	endwin();
29 }
30 /**
31 *	laydef()
32 **/
laydef()33 void laydef(){
34 	void user_interrupt();
35 	int	y,x;
36 	unsigned char	c;
37 	int	sts;
38 	struct	INFLD *p;
39 	char	buf[BUFSIZ];
40 	char	*s,*gets();
41 
42 	signal(SIGINT,user_interrupt);	/* interrupt proc */
43 	initscr();		/* initialize curses */
44 	keypad(stdscr,TRUE);	/* use of arrow keys */
45 	noecho();		/* no echo on input */
46 	cbreak();		/* character operation on input */
47 	meta(stdscr,TRUE);	/* enable 8 bit handling */
48 	nonl();			/* disable nl <--> cr,lf */
49 	leaveok(stdscr,TRUE);	/* do not care the cursor position */
50 
51 
52 	while(1){
53 		if ((s = fgets(buf,sizeof(buf),fpin)) == NULL) break;
54 		if (*s == 0x0c) break;
55 		if (*s == '@' && (*(s+1) == '\n' || *(s+1) == '\0'))
56 			break;
57 		sts = 0;
58 		for(;(c = *s) != '\0' && c != '\n' ; ++s){
59 		    if (c == '~'){
60 			if (sts == 0){ 	/* new field */
61 				if (nfld >= MAXFLD){
62 					done();
63 					fprintf(stderr,"\ntoo many field\n");
64 					exit(1);
65 				}
66 				if (use_uline) attron(A_UNDERLINE);
67 				getyx(stdscr,y,x);
68 				addch(' ');
69 				sts = 1;
70 				p = &fld[nfld];
71 				p->y = y;
72 				p->x = x;
73 				p->len = 1;
74 				p->nopt = 0;
75 				p->attr = 0;
76 				p->help[0] = '\0';
77 				p->ver[0] = '\0';
78 				p->def[0] = '\0';
79 				p->inp[0] = '\0';
80 				nfld++;
81 			}else{
82 				if (p->len >= MAXLEN){
83 					done();
84 					fprintf(stderr,"\ntoo long field\n");
85 					exit(1);
86 				}
87 				addch(' ');
88 				p->len++;
89 			}
90 		    }else{
91 			if (sts == 1){
92 				sts = 0;
93 				if (use_uline) attroff(A_UNDERLINE);
94 			}
95 			addch(c);
96 		    }
97 		}
98 		if (sts == 1){
99 			if (use_uline) attroff(A_UNDERLINE);
100 			sts = 0;
101 		}
102 		addch('\n');
103 	}
104 	refresh();
105 }
user_interrupt()106 void user_interrupt(){
107 	done();
108 	exit(0);
109 }
perse_option(i,s)110 static void perse_option(i,s)
111 int	i;
112 char	*s;
113 {
114 	char	dlm,*t;
115 	int	n;
116 	s += 2;		/* skip "s=" of "s=:opt1:opt2:opt3" */
117 	dlm = *s++;	/* get ":" */
118 	for (n = 0 ;;){
119 		t = strchr(s,dlm);
120 		if (t != NULL) *t = '\0';
121 		if (n >= MAXOPT) break;
122 		strcpy(fld[i].opt[n++],s);	/* get "opt1" "opt2" .. */
123 		if (t == NULL) break;
124 		s = ++t;
125 	}
126 	fld[i].nopt = n;
127 }
128 /**
129 *	flddef()
130 **/
flddef()131 void flddef(){
132 	char	dlm;
133 	char	buf[BUFSIZ],*s,*t,*gets(),*strchr();
134 	int	i,j,k;
135 
136 	i = 0;
137 	while (1){
138 		if (i >= nfld) break;
139 		if ((s = fgets(buf,sizeof(buf),fpin)) == NULL) goto error;
140 		dlm = *s++;
141 		for(j = i ; ((j+1) < nfld) && (fld[j+1].y == fld[i].y) ; ++j) ;
142 		k = j-i+1;
143 		while(1){
144 			if ((t = strchr(s,dlm)) != NULL) *t = '\0';
145 			if (!memcmp(s,"v=",2)){
146 				if (fld[i].ver[0] != '\0') i++;
147 				if (--k < 0) goto error;
148 				strcpy(fld[i].ver,s+2);
149 			}else if (!memcmp(s,"d=",2)){
150 				strcpy(fld[i].def,s+2);
151 			}else if (!memcmp(s,"h=",2)){
152 				strcpy(fld[i].help,s+2);
153 			}else if (!memcmp(s,"s=",2)){
154 				perse_option(i,s);
155 				fld[i].attr |= SF_SELECT;
156 			}else if (!memcmp(s,"a=",2)){
157 				for(s+=2;*s != '\0';++s) switch(*s){
158 				case 'a': fld[i].attr |= SF_ASCEND; break;
159 				case 'd': fld[i].attr |= SF_DIGITS; break;
160 				case 'u': fld[i].attr |= SF_UCASE; break;
161 				case 'l': fld[i].attr |= SF_LCASE; break;
162 				case 'f': fld[i].attr |= SF_FORCE; break;
163 				case 'r': fld[i].attr |= SF_REAL; break;
164 				}
165 			}else if (*s == '\0' || *s == '\n'){
166 				break;
167 			}else{
168 				goto error;
169 			}
170 			if (t == NULL) break;
171 			s = ++t;
172 		}
173 		if (k > 0) goto error;
174 		++i;
175 	}
176 	/* field def result check */
177 	for(i = 0 ; i < nfld ; ++i){
178 		if ((fld[i].attr & SF_SELECT) && fld[i].nopt < 0) goto error;
179 		if (fld[i].ver[0] == '\0') goto error;
180 	}
181 	return;
182 error:
183 	done();
184 	fprintf(stderr,"\nfield definition format error.\n");
185 	exit(1);
186 }
187 /**
188 *	datout()
189 **/
datout()190 void datout(){
191 	int	i;
192 	FILE	*fp;
193 	if (fout == NULL ) fp = stdout;
194 	else fp = fopen(fout,"w");
195 	if (fp == NULL){
196 		perror(fout);
197 		exit(1);
198 	}
199 	for (i = 0 ; i < nfld ; ++i)
200 	if (bsh_format) fprintf(fp,"%s=%s\n",fld[i].ver,fld[i].inp);
201 	else fprintf(fp,"set %s = %s\n",fld[i].ver,fld[i].inp);
202 	if (fp != stdout) fclose(fp);
203 }
204 /**
205 *	main()
206 **/
main(argc,argv)207 int main(argc,argv)
208 int	argc;
209 char	*argv[];
210 {
211 	int	opt;
212 	extern char *optarg;
213 	extern void iloop();
214 	while ((opt = getopt(argc,argv,"um:dc:bi:o:")) != EOF) switch(opt){
215 	case 'b':
216 		bsh_format = 1;
217 		break;
218 	case 'c':
219 		cfld = atoi(optarg);
220 		break;
221 	case 'd':
222 		debug_on = 1;
223 		break;
224 	case 'i':
225 		fpin = fopen(optarg,"r");
226 		if (fpin == NULL){
227 			perror(optarg);
228 			exit(1);
229 		}
230 		break;
231 	case 'o':
232 		fout = optarg;
233 		break;
234 	case 'm':
235 		strcpy(initmesg,optarg);
236 		break;
237 	case 'u':
238 		use_uline = 1;
239 		break;
240 	case '?':
241 		usage();
242 	}
243 	if (fpin == NULL) fpin = stdin;
244 	laydef();	/* perse layout definition part of stdin data */
245 	flddef();	/* perse field definition part of stdin data */
246 	if (fpin == stdin){ /* for the case of stdin is redirected. */
247 		if (freopen("/dev/tty","r",stdin) == NULL){
248 			perror("/dev/tty");
249 			exit(1);
250 		}
251 	}
252 	iloop();	/* loop proccess for user input */
253 	done();		/* end curses */
254 	datout();	/* output the result */
255 	exit(0);
256 }
257