#include #include #include #include void parse_range(char *k, int *l1, int *l2) { *l1 = 0; *l2 = 0; while (k[0] == ' ' || k[0] == '\t') k++; while (k[0] >= '0' && k[0] <= '9') { (*l1) *= 10; (*l1) += (k[0] - '0'); k++; } if (k[0] == '-') { k++; while (k[0] >= '0' && k[0] <= '9') { (*l2) *= 10; (*l2) += (k[0] - '0'); k++; } } if (k[0] != 0) { *l1 = 0; } if (*l2 == 0) *l2 = *l1; if (*l1 == 0 || *l2 < *l1) { printf("Invalid range."); *l1 = 0; } } int main(int argc, char **args) { int linecount; char **lines; int i, j; readline_history hist; hist.str = 0; hist.max = 10; if (args[1] == 0) { printf("Usage: %s filename\n", args[0]); } else { // load file file_info info; int e = stat(args[1], &info); if (e == E_NOT_FOUND) { printf("File not found. Creating new file.\n"); linecount = 0; lines = malloc(1 * sizeof(char*)); lines[0] = 0; } else if (info.type & FT_FILE) { int f = open(args[1], FM_READ); char* buff = (char*)malloc(info.size); read(f, 0, info.size, buff); close(f); // count newlines linecount = 1; for (i = 0; i < info.size; i++) { if (buff[i] == '\n') linecount++; } lines = malloc(linecount * sizeof(char*)); // copy lines i = 0; int p = 0, l = 0; while (i <= info.size) { if ((i == info.size && buff[i-1] != 0) || buff[i] == '\n') { lines[l] = malloc(i - p + 1); for (j = 0; j < i-p; j++) lines[l][j] = buff[p+j]; lines[l][i-p] = 0; l++; p = i+1; } i++; } while (l < linecount) linecount--; if (linecount > 0 && lines[linecount-1][0] == 0) { free(lines[linecount-1]); linecount--; } // free buffer free(buff); } else { printf("%s is not a file. Exiting.\n", args[1]); return -1; } // run while (lines) { printf("[%d lines] ", linecount); char *s = freadline(stdin, &hist); if (strcmp(s, "q") == 0) { break; } else if (strcmp(s, "l") == 0) { for (i = 0; i < linecount; i++) { printf("%d\t%s\n", i + 1, lines[i]); } } else if (s[0] == 'l') { int l1, l2; parse_range(s + 1, &l1, &l2); if (l1 != 0) { if (l2 > linecount) { printf("There are only %d lines.\n", linecount); } else { for (i = l1; i <= l2; i++) { printf("%d\t%s\n", i, lines[i-1]); } } } } else if (strcmp(s, "w") == 0) { // calculate buffer size int buffsz = 0; for (i = 0; i < linecount; i++) { buffsz += strlen(lines[i]) + 1; } //write buffer char *buff = malloc(buffsz); char *p = buff; for (i = 0; i < linecount; i++) { for (j = 0; lines[i][j]; j++) { *(p++) = lines[i][j]; } *(p++) = '\n'; } // write buffer int f = open(args[1], FM_WRITE | FM_TRUNC | FM_CREATE | FT_FILE); if (f > 0) { write(f, 0, buffsz, buff); close(f); printf("%s written, %d lines, %d characters\n", args[1], linecount, buffsz); } else { printf("Error %d in opening %s\n", f, args[1]); } free(buff); } else if (s[0] >= '1' && s[0] <= '9') { int line = 0; i = 0; while (s[i] >= '0' && s[i] <= '9') { line *= 10; line += (s[i] - '0'); i++; } if(s[i] == ' ' || s[i] == '\t') i++; char *nl = s + i; if (line < 1) { printf("Invalid line number.\n"); continue; } if (line > linecount) { char **lines2 = malloc(line * sizeof(char*)); for (i = 0; i < linecount; i++) { lines2[i] = lines[i]; } for (i = linecount; i < line; i++) { lines2[i] = strdup(""); } free(lines); //PB lines = lines2; linecount = line; } free(lines[line-1]); lines[line-1] = strdup(nl); } else if (s[0] == 'd') { int l1, l2; parse_range(s + 1, &l1, &l2); if (l1 != 0) { l1--; for (i = l1; i < l2; i++) { free(lines[i]); } for (i = l2; i < linecount; i++) { lines[i - (l2 - l1)] = lines[i]; } linecount -= (l2 - l1); } } else { printf("Unknown command: %s\n", s); } } } return 0; }