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