Rewrite foldline() in fold(1)
After the audit, I had this noted down as a TODO-item, but considered the function to be tested enough to hold the line until I came to rewrite it. Admittedly, I didn't take a closer look at the previous loop and there probably were some edge-cases which caused trouble, but so far so good, the new version of this commit should be safe and considered audited.
This commit is contained in:
		
							
								
								
									
										80
									
								
								fold.c
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								fold.c
									
									
									
									
									
								
							| @@ -3,6 +3,7 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
| #include "util.h" | #include "util.h" | ||||||
|  |  | ||||||
| @@ -11,46 +12,41 @@ static int    sflag = 0; | |||||||
| static size_t width = 80; | static size_t width = 80; | ||||||
|  |  | ||||||
| static void | static void | ||||||
| foldline(const char *str) | foldline(const char *str) { | ||||||
| { | 	const char *p, *spacesect = NULL; | ||||||
| 	size_t i = 0, n = 0, col, j; | 	size_t col, off; | ||||||
| 	int space; |  | ||||||
| 	char c; |  | ||||||
|  |  | ||||||
| 	do { | 	for (p = str, col = 0; *p && *p != '\n'; p++) { | ||||||
| 		space = 0; | 		if (!UTF8_POINT(*p) && !bflag) | ||||||
| 		for (j = i, col = 0; str[j] && col <= width; j++) { | 			continue; | ||||||
| 			c = str[j]; | 		if (col >= width) { | ||||||
| 			if (!UTF8_POINT(c) && !bflag) | 			off = (sflag && spacesect) ? spacesect - str : p - str; | ||||||
| 				continue; | 			if (fwrite(str, 1, off, stdout) != off) | ||||||
| 			if (sflag && isspace(c)) { | 				eprintf("fwrite <stdout>:"); | ||||||
| 				space = 1; |  | ||||||
| 				n = j + 1; |  | ||||||
| 			} else if (!space) { |  | ||||||
| 				n = j; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (!bflag && iscntrl(c)) { |  | ||||||
| 				switch(c) { |  | ||||||
| 				case '\b': |  | ||||||
| 					col--; |  | ||||||
| 					break; |  | ||||||
| 				case '\r': |  | ||||||
| 					col = 0; |  | ||||||
| 					break; |  | ||||||
| 				case '\t': |  | ||||||
| 					col += (col + 1) % 8; |  | ||||||
| 					break; |  | ||||||
| 				} |  | ||||||
| 			} else { |  | ||||||
| 				col++; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if (fwrite(str + i, 1, n - i, stdout) != n - i) |  | ||||||
| 			eprintf("fwrite <stdout>:"); |  | ||||||
| 		if (str[n]) |  | ||||||
| 			putchar('\n'); | 			putchar('\n'); | ||||||
| 	} while (str[i = n] && str[i] != '\n'); | 			spacesect = NULL; | ||||||
|  | 			col = 0; | ||||||
|  | 			p = str += off; | ||||||
|  | 		} | ||||||
|  | 		if (sflag && isspace(*p)) | ||||||
|  | 			spacesect = p + 1; | ||||||
|  | 		if (!bflag && iscntrl(*p)) { | ||||||
|  | 			switch(*p) { | ||||||
|  | 			case '\b': | ||||||
|  | 				col -= (col > 0); | ||||||
|  | 				break; | ||||||
|  | 			case '\r': | ||||||
|  | 				col = 0; | ||||||
|  | 				break; | ||||||
|  | 			case '\t': | ||||||
|  | 				col += (col + 1) % 8; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			col++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	fputs(str, stdout); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| @@ -69,7 +65,7 @@ fold(FILE *fp, const char *fname) | |||||||
| static void | static void | ||||||
| usage(void) | usage(void) | ||||||
| { | { | ||||||
| 	eprintf("usage: %s [-bs] [-w width | -width] [FILE...]\n", argv0); | 	eprintf("usage: %s [-bs] [-w num | -num] [FILE ...]\n", argv0); | ||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| @@ -102,10 +98,10 @@ main(int argc, char *argv[]) | |||||||
| 			if (!(fp = fopen(*argv, "r"))) { | 			if (!(fp = fopen(*argv, "r"))) { | ||||||
| 				weprintf("fopen %s:", *argv); | 				weprintf("fopen %s:", *argv); | ||||||
| 				ret = 1; | 				ret = 1; | ||||||
| 				continue; | 			} else { | ||||||
|  | 				fold(fp, *argv); | ||||||
|  | 				fclose(fp); | ||||||
| 			} | 			} | ||||||
| 			fold(fp, *argv); |  | ||||||
| 			fclose(fp); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user