xref: /plan9/sys/src/libString/s_getline.c (revision ec46fab06dcae3e636b775c4eaa679036316e1d8)
1*80ee5cbfSDavid du Colombier #include <u.h>
2*80ee5cbfSDavid du Colombier #include <libc.h>
3*80ee5cbfSDavid du Colombier #include <bio.h>
4*80ee5cbfSDavid du Colombier #include "String.h"
5*80ee5cbfSDavid du Colombier 
6*80ee5cbfSDavid du Colombier /* Append an input line to a String.
7*80ee5cbfSDavid du Colombier  *
8*80ee5cbfSDavid du Colombier  * Returns a pointer to the character string (or 0).
9*80ee5cbfSDavid du Colombier  * Leading whitespace and newlines are removed.
10*80ee5cbfSDavid du Colombier  *
11*80ee5cbfSDavid du Colombier  * Empty lines and lines starting with '#' are ignored.
12*80ee5cbfSDavid du Colombier  */
13*80ee5cbfSDavid du Colombier extern char *
s_getline(Biobuf * fp,String * to)14*80ee5cbfSDavid du Colombier s_getline(Biobuf *fp, String *to)
15*80ee5cbfSDavid du Colombier {
16*80ee5cbfSDavid du Colombier 	int c;
17*80ee5cbfSDavid du Colombier 	int len=0;
18*80ee5cbfSDavid du Colombier 
19*80ee5cbfSDavid du Colombier 	s_terminate(to);
20*80ee5cbfSDavid du Colombier 
21*80ee5cbfSDavid du Colombier 	/* end of input */
22*80ee5cbfSDavid du Colombier 	if ((c = Bgetc(fp)) < 0)
23*80ee5cbfSDavid du Colombier 		return 0;
24*80ee5cbfSDavid du Colombier 
25*80ee5cbfSDavid du Colombier 	/* take care of inconsequentials */
26*80ee5cbfSDavid du Colombier 	for(;;) {
27*80ee5cbfSDavid du Colombier 		/* eat leading white */
28*80ee5cbfSDavid du Colombier 		while(c==' ' || c=='\t' || c=='\n' || c=='\r')
29*80ee5cbfSDavid du Colombier 			c = Bgetc(fp);
30*80ee5cbfSDavid du Colombier 
31*80ee5cbfSDavid du Colombier 		if(c < 0)
32*80ee5cbfSDavid du Colombier 			return 0;
33*80ee5cbfSDavid du Colombier 
34*80ee5cbfSDavid du Colombier 		/* take care of comments */
35*80ee5cbfSDavid du Colombier 		if(c == '#'){
36*80ee5cbfSDavid du Colombier 			do {
37*80ee5cbfSDavid du Colombier 				c = Bgetc(fp);
38*80ee5cbfSDavid du Colombier 				if(c < 0)
39*80ee5cbfSDavid du Colombier 					return 0;
40*80ee5cbfSDavid du Colombier 			} while(c != '\n');
41*80ee5cbfSDavid du Colombier 			continue;
42*80ee5cbfSDavid du Colombier 		}
43*80ee5cbfSDavid du Colombier 
44*80ee5cbfSDavid du Colombier 		/* if we got here, we've gotten something useful */
45*80ee5cbfSDavid du Colombier 		break;
46*80ee5cbfSDavid du Colombier 	}
47*80ee5cbfSDavid du Colombier 
48*80ee5cbfSDavid du Colombier 	/* gather up a line */
49*80ee5cbfSDavid du Colombier 	for(;;) {
50*80ee5cbfSDavid du Colombier 		len++;
51*80ee5cbfSDavid du Colombier 		switch(c) {
52*80ee5cbfSDavid du Colombier 		case -1:
53*80ee5cbfSDavid du Colombier 			s_terminate(to);
54*80ee5cbfSDavid du Colombier 			return len ? to->ptr-len : 0;
55*80ee5cbfSDavid du Colombier 		case '\\':
56*80ee5cbfSDavid du Colombier 			c = Bgetc(fp);
57*80ee5cbfSDavid du Colombier 			if (c != '\n') {
58*80ee5cbfSDavid du Colombier 				s_putc(to, '\\');
59*80ee5cbfSDavid du Colombier 				s_putc(to, c);
60*80ee5cbfSDavid du Colombier 			}
61*80ee5cbfSDavid du Colombier 			break;
62*80ee5cbfSDavid du Colombier 		case '\n':
63*80ee5cbfSDavid du Colombier 			s_terminate(to);
64*80ee5cbfSDavid du Colombier 			return len ? to->ptr-len : 0;
65*80ee5cbfSDavid du Colombier 		default:
66*80ee5cbfSDavid du Colombier 			s_putc(to, c);
67*80ee5cbfSDavid du Colombier 			break;
68*80ee5cbfSDavid du Colombier 		}
69*80ee5cbfSDavid du Colombier 		c = Bgetc(fp);
70*80ee5cbfSDavid du Colombier 	}
71*80ee5cbfSDavid du Colombier }
72