From 342ad58b516a6b951017e46a55d69ad64dfcaffe Mon Sep 17 00:00:00 2001 From: Odweta Date: Sun, 24 Dec 2023 12:44:13 +0100 Subject: [PATCH] made work: line numbers in files with the correct indentation level (tested on a > 1000 lines file) --- Makefile | 14 +++++++---- README.md | 3 +-- demo.c | 37 +++++++++++++++++++++++++++-- examples/file/filedemo.c | 33 +++++++++++++++++++++++++- include/file.h | 2 ++ include/util.h | 10 ++++++++ src/file.c | 34 +++++++++++++++++++++++++++ src/util.c | 51 ++++++++++++++++++++++++++++++++++++++++ src/vector.c | 8 +++++-- test.txt | 1 - 10 files changed, 180 insertions(+), 13 deletions(-) create mode 100644 include/util.h create mode 100644 src/util.c diff --git a/Makefile b/Makefile index d0a8e28..764291a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC := gcc CFLAGS := -Wall -Werror -LIBS := -lvector -lfile -llist +LIBS := -lvector -lfile -llist -lutil LIBSPATH := -L/usr/lib/odweta/ INCLUDEDIR := -I/usr/include/odweta/ PATCH := -Wl,-rpath=/usr/lib/odweta/ @@ -9,7 +9,7 @@ PATCH := -Wl,-rpath=/usr/lib/odweta/ default: demo -demo: demo.c libvector.so libfile.so liblist.so +demo: demo.c libvector.so libfile.so liblist.so libutil.so sudo $(CC) $(CFLAGS) -o $@ $< $(PATCH) $(INCLUDEDIR) $(LIBSPATH) $(LIBS) libvector.so: src/vector.c @@ -24,15 +24,19 @@ liblist.so: src/list.c sudo $(CC) -c -fpic $< -o /usr/lib/odweta/list.o sudo $(CC) -shared -o /usr/lib/odweta/$@ /usr/lib/odweta/list.o +libutil.so: src/util.c + sudo $(CC) -c -fpic $< -o /usr/lib/odweta/util.o + sudo $(CC) -shared -o /usr/lib/odweta/$@ /usr/lib/odweta/util.o + install: sudo mkdir -p /usr/include/odweta/ sudo mkdir -p /usr/lib/odweta/ - sudo cp src/vector.c src/file.c src/list.c include/vector.h include/file.h include/list.h /usr/include/odweta/ - sudo make libvector.so libfile.so liblist.so + sudo cp src/vector.c src/file.c src/list.c src/util.c include/vector.h include/file.h include/list.h include/util.h /usr/include/odweta/ + sudo make libvector.so libfile.so liblist.so libutil.so sudo ldconfig # update ldconfig cache clean: - sudo rm -f main /usr/lib/odweta/vector.o /usr/lib/odweta/file.o /usr/lib/odweta/libvector.so /usr/lib/odweta/libfile.so /usr/lib/odweta/list.o /usr/lib/odweta/liblist.so + sudo rm -f main /usr/lib/odweta/vector.o /usr/lib/odweta/file.o /usr/lib/odweta/list.o /usr/lib/odweta/util.o /usr/lib/odweta/libvector.so /usr/lib/odweta/libfile.so /usr/lib/odweta/liblist.so /usr/lib/odweta/libutil.so cleanrepo: rm -fr ./demo ./moved_copy_of_test.txt ./copy_of_test.txt diff --git a/README.md b/README.md index 2117b12..8d42df8 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,10 @@ Examples of this work of art are in the `/examples/` directory of this repo. 5. Moving (renaming) a file to another file 6. Deleting a file 7. Checking if a file exists +8. Add line numbers at the beggining of each line in a file (with correct indentation) #### TODO: -1. Add line numbers at the beggining of each line in a file - + You tell me ## Vectors (dynamic arrays) diff --git a/demo.c b/demo.c index c7040a3..b5bd377 100644 --- a/demo.c +++ b/demo.c @@ -1,3 +1,18 @@ +// #include +// #include +// +// int main() { +// char* string = intToString(1729843); +// +// printf("final string: %s\n", string); +// +// char* sstring = intToString(123); +// +// printf("final string: %s\n", sstring); +// +// return 0; +// } + #include #include @@ -10,7 +25,7 @@ int main() { printf("\nconvering the file contents into a string (char*)\n"); char* string = fileToString(f); - printf("\"%s\"\n", string); + printf("\"\"\"\n%s\"\"\"\n", string); printf("writing is quite simple, just call the 'fileWrite(file_t*, char*)' or 'fileWriteln(file_t*, char*)' function, where the second argument is the string you want to write into a file\nthe 'fileWriteln()' function writes the specified string AND a '\\n' after it, whereas the 'fileWrite()' function does not append the '\\n'\n"); fileWrite(f, "'this will not end with a \"\\n\"' "); @@ -40,9 +55,27 @@ int main() { filePrint(move_dst); fileCleanup(src); - printf("DO NOT cleanup a deleted file! (dst, in this case) it is already done for you by the 'fileMove(file_t*)' function\n"); + printf("DO NOT cleanup a deleted file! (dst, in this case) it is already done for you by the 'fileMove(file_t*, char*)' function\n"); // fileCleanup(dst); fileCleanup(move_dst); + printf("when copying and moving files, the first argument is a file_t* (source file) and the second argument is a char* (the path of the destination file), not a file_t*!\n"); + + printf("prepending line numbers at the beggining of each line in a file\n"); + + file_t* g = fileInit("test.txt"); + fileCopy(g, "copy_of_test.txt"); + file_t* g_copy = fileInit("copy_of_test.txt"); + fileNumberLines(g_copy); + + printf("file withOUT prepended numbers:\n"); + filePrint(g); + + printf("file with prepended numbers:\n"); + filePrint(g_copy); + + fileCleanup(g); + //fileCleanup(g_copy); + return 0; } diff --git a/examples/file/filedemo.c b/examples/file/filedemo.c index 4a223c6..b5bd377 100644 --- a/examples/file/filedemo.c +++ b/examples/file/filedemo.c @@ -1,3 +1,18 @@ +// #include +// #include +// +// int main() { +// char* string = intToString(1729843); +// +// printf("final string: %s\n", string); +// +// char* sstring = intToString(123); +// +// printf("final string: %s\n", sstring); +// +// return 0; +// } + #include #include @@ -10,7 +25,7 @@ int main() { printf("\nconvering the file contents into a string (char*)\n"); char* string = fileToString(f); - printf("\"%s\"\n", string); + printf("\"\"\"\n%s\"\"\"\n", string); printf("writing is quite simple, just call the 'fileWrite(file_t*, char*)' or 'fileWriteln(file_t*, char*)' function, where the second argument is the string you want to write into a file\nthe 'fileWriteln()' function writes the specified string AND a '\\n' after it, whereas the 'fileWrite()' function does not append the '\\n'\n"); fileWrite(f, "'this will not end with a \"\\n\"' "); @@ -46,5 +61,21 @@ int main() { printf("when copying and moving files, the first argument is a file_t* (source file) and the second argument is a char* (the path of the destination file), not a file_t*!\n"); + printf("prepending line numbers at the beggining of each line in a file\n"); + + file_t* g = fileInit("test.txt"); + fileCopy(g, "copy_of_test.txt"); + file_t* g_copy = fileInit("copy_of_test.txt"); + fileNumberLines(g_copy); + + printf("file withOUT prepended numbers:\n"); + filePrint(g); + + printf("file with prepended numbers:\n"); + filePrint(g_copy); + + fileCleanup(g); + //fileCleanup(g_copy); + return 0; } diff --git a/include/file.h b/include/file.h index c228af8..6decd7c 100644 --- a/include/file.h +++ b/include/file.h @@ -32,4 +32,6 @@ int fileExists(file_t* f); // 1 = yes, 0 = no void fileCreateEmpty(char* path); // create an empty file with the given name +void fileNumberLines(file_t* f); // prepend line numbers in front of each line in a file + #endif diff --git a/include/util.h b/include/util.h new file mode 100644 index 0000000..66c2265 --- /dev/null +++ b/include/util.h @@ -0,0 +1,10 @@ +#ifndef UTIL_H +#define UTIL_H + +char* intToString(int x); // convert an int into a string + +long pow(int x, int n); // x^n + +int maxLowerPowerOf10(int x); // biggest power of 10 that is < x + +#endif diff --git a/src/file.c b/src/file.c index 6627322..522990b 100644 --- a/src/file.c +++ b/src/file.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -189,6 +190,7 @@ fileCopy(file_t* src, char* dst) { FILE* fd = fopen(dst, "w"); if (!fd) { fprintf(stderr, "could not open file for writing\n"); + fclose(fd); exit(EXIT_FAILURE); } @@ -213,6 +215,7 @@ fileDelete(file_t* f) { // fileCleanup(f); // don't know if this is necessary... :shrug: // exit(EXIT_FAILURE); } + fileCleanup(f); } @@ -222,3 +225,34 @@ fileMove(file_t* src, char* dst) { fileDelete(src); } + +void +fileNumberLines(file_t* f) { + FILE* fd = fopen(f->path, "w"); + if (!fd) { + fprintf(stderr, "could not open file for writing\n"); + fclose(fd); + exit(EXIT_FAILURE); + } + + int mlp = maxLowerPowerOf10(f->length); + + for (int i = 0; i < f->length; i++) { + // print to the file descriptor + fprintf(fd, "%d %s\n", i+1, (char*)vectorToString((vector_t *)vectorGetAt(f->lines, i))); + + // print to f->lines + vectorInsertAt((vector_t*)vectorGetAt(f->lines, i), 0, &(char){' '}); + char* string = intToString(i+1); + for (int j = strlen(string)-1; j >= 0; j--) { + vectorInsertAt((vector_t*)vectorGetAt(f->lines, i), 0, &(char){string[j]}); + } + + // prepend the correct amount of ' ' + for (int j = 0; j < strlen(intToString(mlp))-strlen(intToString(i+1)); j++) { + vectorInsertAt((vector_t*)vectorGetAt(f->lines, i), 0, &(char){' '}); + } + } + + fclose(fd); +} diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..c3debdc --- /dev/null +++ b/src/util.c @@ -0,0 +1,51 @@ +#include +#include + +char* +intToString(int x) { + vector_t* string = vectorInit(CHAR); + + if (x > 0 && x < 10) { + vectorPush(string, &(char){x+48}); + char* retval = (char*)vectorToString(string); + vectorCleanup(string); + return retval; + } else { + while (x > 0) { + int lastDigit = x % 10; + x /= 10; + vectorInsertAt(string, 0, &(char){lastDigit+48}); + } + vectorPop(string); + char* retval = (char*)vectorToString(string); + vectorCleanup(string); + return retval; + } +} + +long +pow(int x, int n) { + long retval = 1; + + for (int i = 0; i < n; i++) { + retval *= x; + } + + return retval; +} + +int +maxLowerPowerOf10(int x) { + int i = 0; + long prev = pow(10, i++); + + while (1) { + long now = pow(10, i); + if (now >= x) { + return (int)prev; + } + prev = now; + i++; + } + +} diff --git a/src/vector.c b/src/vector.c index e0eb657..05065ed 100644 --- a/src/vector.c +++ b/src/vector.c @@ -324,7 +324,9 @@ vectorGetAt(vector_t* v, int index) { void vectorSetAt(vector_t* v, int index, void* element) { - if (index >= v->size) { + if (v->size == 0) { + vectorPush(v, element); + } else if (index >= v->size) { fprintf(stderr, "index out of range\n"); exit(EXIT_FAILURE); } @@ -350,7 +352,9 @@ vectorSetAt(vector_t* v, int index, void* element) { void vectorInsertAt(vector_t* v, int index, void* element) { - if (index >= v->size) { + if (v->size == 0) { + vectorPush(v, element); + } else if (index >= v->size) { fprintf(stderr, "index out of range\n"); exit(EXIT_FAILURE); } diff --git a/test.txt b/test.txt index 99b8c1e..9985556 100644 --- a/test.txt +++ b/test.txt @@ -4,4 +4,3 @@ and this was an empty line !#%!@# <- symbols! -'this will not end with a "\n"' this line was appended