diff --git a/.github/workflows/build-checks.yaml b/.github/workflows/build-checks.yaml
index e6c1565..4d899cb 100644
--- a/.github/workflows/build-checks.yaml
+++ b/.github/workflows/build-checks.yaml
@@ -1,6 +1,9 @@
name: Cross-platform Build Checks
-on: [push, pull_request]
+on:
+ push:
+ branches: [main]
+ pull_request:
jobs:
build:
@@ -68,8 +71,9 @@ jobs:
- name: Try compiling
run: cmake --build out
+ # It should work anyway I'm pretty sure
build-freebsd:
- # if: false
+ if: false
strategy:
fail-fast: false
matrix:
diff --git a/.gitignore b/.gitignore
index 6b1a43b..3a25eeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -134,3 +134,5 @@ CMakeUserPresets.json
*-prefix/
# End of https://www.toptal.com/developers/gitignore/api/cmake,clion
+
+.tmp_dir_path
\ No newline at end of file
diff --git a/.idea/NoteViewer.iml b/.idea/NoteViewer.iml
index f08604b..220714a 100644
--- a/.idea/NoteViewer.iml
+++ b/.idea/NoteViewer.iml
@@ -1,2 +1,8 @@
-
\ No newline at end of file
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0b76fe5..684040f 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,5 +1,8 @@
+
+
+
diff --git a/.idea/runConfigurations/NoteViewer.xml b/.idea/runConfigurations/NoteViewer.xml
new file mode 100644
index 0000000..b69b83b
--- /dev/null
+++ b/.idea/runConfigurations/NoteViewer.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/setup_test_env.xml b/.idea/runConfigurations/setup_test_env.xml
new file mode 100644
index 0000000..65b4b13
--- /dev/null
+++ b/.idea/runConfigurations/setup_test_env.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9b49bbb..f0b22ca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,4 +7,9 @@ add_executable(NoteViewer main.c
sequence.h
types.h
sequence.c
- consts.h)
+ consts.h
+ utils.h
+ parse.c
+ parse.h
+ utils.c
+)
diff --git a/main.c b/main.c
index a782048..74319c9 100644
--- a/main.c
+++ b/main.c
@@ -4,120 +4,36 @@
#include
#include "consts.h"
+#include "parse.h"
#include "sequence.h"
#include "types.h"
+
+
int main(int argc, char **argv) {
// TODO: Read each files in the current directory with idk what criteria yet
FILE *file = fopen("test.txt", "r");
- const str word_to_base_output_on = alloca(sizeof(wchar_t)*strlen(argv[1]));
- mbtowc(word_to_base_output_on, argv[1], strlen(argv[1]));
- // TODO: Replace by wchar_t later on
- int curr_char = fgetc(file);
-
- while (curr_char != '[' && curr_char != EOF)
- curr_char = fgetc(file);
-
- int line_counter = 1;
-
- str string_to_save = NULL;
- int string_size = 0;
-
- sequence_t start_of_sequence;
- start_of_sequence.elem = string_to_save;
- start_of_sequence.next = NULL;
-
- sequence_t *current_seq_elem = &start_of_sequence;
-
- enum reading_state_t {
- UNDEFINED,
- READING_TITLE,
- SKIP,
- SAVE
- };
+ const char *arg2 = argv[1];
+ wchar_t *word_to_base_output_on = alloca(sizeof(wchar_t)*strlen(arg2)); // allocated on the stack because speed
+ mbstowcs(word_to_base_output_on, arg2, strlen(arg2));
- enum reading_state_t reading_state = UNDEFINED;
- wchar_t reading_chars[wcslen(word_to_base_output_on) + 1];
- int reading_chars_index = 0;
-
- // Chunk of bytes to consume from the file everytime
- wchar_t current_chunk[CHUNK_SIZE / sizeof(wchar_t)];
- sequence_t *stack_of_chunks;
-
- // TODO: Send to threads and queues
- while (fgetws(current_chunk, CHUNK_SIZE / sizeof(wchar_t), file) != NULL) {
- for (int i = 0; i < CHUNK_SIZE / sizeof(wchar_t); i++) {
- curr_char = current_chunk[i];
- if (curr_char == '\n') {
- line_counter++;
- }
-
- switch (reading_state) {
- case SKIP:
- case SAVE:
- case UNDEFINED:
- if (curr_char == '[') {
- if (reading_state == SAVE) {
- wchar_t chars_saved_so_far[CHUNK_SIZE / sizeof(wchar_t)];
- wcslcpy(chars_saved_so_far, current_chunk, i);
- const str new_string = assemble_str(stack_of_chunks, chars_saved_so_far);
- attach(current_seq_elem, new_string);
- }
-
- reading_state = READING_TITLE;
- stack_of_chunks = malloc(sizeof(sequence_t));
- string_size = 0;
- } else if (reading_state == SAVE) string_size++; // this basically becomes the evil twin chunk index
- break;
- case READING_TITLE:
- if (curr_char == ']') {
- // Error handling
- if (string_size == 0) {
- fprintf(stderr, "Empty tag at %i", line_counter);
- exit(EXIT_FAILURE);
- }
-
- if (wcslen(word_to_base_output_on) != string_size
- || wcpcpy(word_to_base_output_on, reading_chars) != 0) {
- reading_state = SKIP;
- } else {
- reading_state = SAVE;
- }
- } else {
- string_size++;
- if (string_size <= wcslen(word_to_base_output_on)) {
- reading_chars[reading_chars_index] = curr_char;
- reading_chars_index++;
- } else {
- reading_state = SKIP;
- // bzero(reading_chars, strlen(word_to_base_output_on)); /// no need
-
- reading_chars[reading_chars_index] = 0;
- // resetting this index will be enough since it will overwrite the earlier string
- // plus, this string is only compared to its right length
- }
- }
- break;
- }
- }
-
- if (reading_state == SAVE) {
- attach(stack_of_chunks, current_chunk); // if it's null deal with it
- string_size = 0;
- }
- }
+ sequence_t main_sequence_of_chars; // Also the start of sequence
+ sequence_t *seq_ptr = &main_sequence_of_chars; // movable pointer, start at the thing above
+ parse_file_content(file, word_to_base_output_on, &seq_ptr);
+ fclose(file);
// TODO: Formatting
- while (start_of_sequence.next != NULL) {
- printf("%ls", (*start_of_sequence.next).elem);
+ while (main_sequence_of_chars.next != NULL) {
+ seq_ptr = &main_sequence_of_chars;
+ wprintf(L"%ls", seq_ptr->elem);
// no time to free anything
- start_of_sequence = *start_of_sequence.next;
+ seq_ptr = seq_ptr->next;
}
return 0;
-}
+}
\ No newline at end of file
diff --git a/parse.c b/parse.c
new file mode 100644
index 0000000..b701bd1
--- /dev/null
+++ b/parse.c
@@ -0,0 +1,142 @@
+//
+// Created by mayachen on 2025-09-20.
+//
+
+#include "parse.h"
+
+#include
+#include
+#include
+
+#include "sequence.h"
+
+// not global functions to give the compiler for dinner //
+
+void advance_file_ptr_or_fail(FILE **file);
+
+// Insane I finally used pointers of pointers
+void save_chars(wchar_t current_chunk[CHUNK_SIZE / sizeof(wchar_t)],
+ int string_size,
+ sequence_t *stack_of_chunks,
+ sequence_t **seq_ptr
+);
+
+enum reading_state_t {
+ UNDEFINED,
+ READING_TITLE,
+ SKIP,
+ SAVE
+};
+
+// File reading state. (Please use the pointer instead for ARM's sake)
+enum reading_state_t reading_statee;
+
+// ARM cpus will thank me for putting this variable nearby
+//
+// If it's even put nearby
+enum reading_state_t __attribute__((section(".text"))) *const reading_state_ptr = &reading_statee;
+
+void save_chars(wchar_t current_chunk[CHUNK_SIZE / sizeof(wchar_t)],
+ const int string_size,
+ sequence_t *stack_of_chunks,
+ sequence_t **seq_ptr
+) {
+ wchar_t chars_saved_so_far[CHUNK_SIZE / sizeof(wchar_t)];
+ wcslcpy(chars_saved_so_far, current_chunk, string_size);
+ const str new_string = assemble_str(stack_of_chunks, chars_saved_so_far);
+ *seq_ptr = attach(*seq_ptr, new_string);
+}
+
+void advance_file_ptr_or_fail(FILE **file) {
+ wchar_t curr_char;
+
+ while ((curr_char = fgetc(*file) != '['))
+ if (curr_char == EOF)
+ perror("File format error. No tags found!");
+
+ *reading_state_ptr = READING_TITLE;
+}
+
+void parse_file_content(FILE *file, const wchar_t *word_to_base_output_on, sequence_t **curr_seq_ptr) {
+ advance_file_ptr_or_fail(&file);
+
+ int line_counter = 1;
+
+ int string_size = 0;
+
+ sequence_t start_of_sequence;
+ start_of_sequence.elem = NULL;
+ start_of_sequence.next = NULL;
+
+ sequence_t *current_seq_elem = &start_of_sequence;
+
+
+ wchar_t reading_chars[wcslen(word_to_base_output_on) + 1];
+ int reading_chars_index = 0;
+
+ // Chunk of bytes to consume from the file everytime
+ wchar_t current_chunk[CHUNK_SIZE / sizeof(wchar_t)];
+ sequence_t *stack_of_chunks;
+
+ // TODO: Send to threads and queues
+ while (fgetws(current_chunk, CHUNK_SIZE / sizeof(wchar_t), file) != NULL) {
+ wchar_t *curr_char_ptr = alloca(sizeof(wchar_t));
+ for (int i = 0; i < CHUNK_SIZE / sizeof(wchar_t); i++) {
+ wchar_t curr_char = *curr_char_ptr;
+ if (curr_char == '\n') {
+ line_counter++;
+ }
+
+ switch (*reading_state_ptr) {
+ case SKIP:
+ case SAVE:
+ case UNDEFINED:
+ if (curr_char == '[') {
+ if (*reading_state_ptr == SAVE) {
+ save_chars(current_chunk, string_size, stack_of_chunks, curr_seq_ptr);
+ }
+
+ *reading_state_ptr = READING_TITLE;
+ stack_of_chunks = malloc(sizeof(sequence_t));
+ string_size = 0;
+ } else if (*reading_state_ptr == SAVE) string_size++;
+ // this basically becomes the evil twin chunk index
+ break;
+ case READING_TITLE:
+ if (curr_char == ']') {
+ // Error handling
+ if (string_size == 0) {
+ fprintf(stderr, "Empty tag at %i", line_counter);
+ exit(EXIT_FAILURE);
+ }
+
+ if (wcslen(word_to_base_output_on) != string_size
+ || wcscmp(word_to_base_output_on, reading_chars) != 0) {
+ *reading_state_ptr = SKIP;
+ } else {
+ *reading_state_ptr = SAVE;
+ }
+ } else {
+ string_size++;
+ if (string_size <= wcslen(word_to_base_output_on)) {
+ reading_chars[reading_chars_index] = curr_char;
+ reading_chars_index++;
+ } else {
+ *reading_state_ptr = SKIP;
+ // bzero(reading_chars, strlen(word_to_base_output_on)); /// no need
+
+ reading_chars[reading_chars_index] = 0;
+ // resetting this index will be enough since it will overwrite the earlier string
+ // plus, this string is only compared to its right length
+ }
+ }
+ break;
+ }
+ }
+
+ if (*reading_state_ptr == SAVE) {
+ attach(stack_of_chunks, current_chunk); // if it's null deal with it
+ string_size = 0;
+ }
+ }
+}
diff --git a/parse.h b/parse.h
new file mode 100644
index 0000000..494b180
--- /dev/null
+++ b/parse.h
@@ -0,0 +1,12 @@
+//
+// Created by mayachen on 2025-09-20.
+//
+
+#ifndef NOTEVIEWER_PARSE_H
+#define NOTEVIEWER_PARSE_H
+#include
+
+#include "sequence.h"
+
+void parse_file_content(FILE *file, const wchar_t *word_to_base_output_on, sequence_t **curr_seq_ptr);
+#endif //NOTEVIEWER_PARSE_H
\ No newline at end of file
diff --git a/sequence.c b/sequence.c
index 164a108..b372e59 100644
--- a/sequence.c
+++ b/sequence.c
@@ -9,6 +9,7 @@
#include "types.h"
+// Returns a pointer to the `next` element.
sequence_t *attach(sequence_t *curr_seq_ptr, const str new_elem) {
sequence_t *new_seq_ptr = malloc(sizeof(sequence_t));
new_seq_ptr->elem = new_elem;
@@ -17,9 +18,10 @@ sequence_t *attach(sequence_t *curr_seq_ptr, const str new_elem) {
return new_seq_ptr;
}
+// The seq should be NULL at the end
str assemble_str(sequence_t *seq, const wchar_t rest_of_the_chars[CHUNK_SIZE / sizeof(wchar_t)]) {
- void* backup = seq;
- str s;
+ void *backup = seq; // Save starting addresses
+ wchar_t *ret_str;
// I'm sure the compiler will be glad to optimize this "scope" :clueless:
{
@@ -30,25 +32,25 @@ str assemble_str(sequence_t *seq, const wchar_t rest_of_the_chars[CHUNK_SIZE / s
seq = seq->next; // truly the peakest type of loops
}
- s = malloc((len + 1) * sizeof(wchar_t));
+ ret_str = malloc((len + 1) * sizeof(wchar_t));
}
- seq = (sequence_t*)backup;
- backup = s;
+ seq = (sequence_t *) backup;
+ backup = ret_str;
while (seq->elem != NULL) {
- wcscpy(s, seq->elem);
- s += wcslen(seq->elem);
+ wcscpy(ret_str, seq->elem);
+ ret_str += wcslen(seq->elem);
sequence_t *old_seq = seq;
seq = seq->next;
free(old_seq); // it has served its purpose
- // it can now enjoy crystal stasis
+ // it can now enjoy crystal stasis
}
free(seq);
- wcscpy(s, rest_of_the_chars); // it fits well its name
+ wcscpy(ret_str, rest_of_the_chars); // it fits well its name
- s = backup;
+ ret_str = backup;
- return s;
+ return ret_str;
}
diff --git a/setup_test-env.py b/setup_test-env.py
new file mode 100755
index 0000000..6185d4c
--- /dev/null
+++ b/setup_test-env.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+import os
+import tempfile
+
+global tempdir
+pathExist: bool = os.path.exists(os.path.join(os.curdir, ".tmp_dir_path"))
+
+with open(".tmp_dir_path", 'r+t') as f:
+ if pathExist:
+ tempdir = f.readline()
+ else:
+ tempdir = tempfile.mkdtemp()
+ f.write(tempdir)
+ f.write("\n")
+
+os.chdir(tempdir)
\ No newline at end of file
diff --git a/utils.c b/utils.c
new file mode 100644
index 0000000..bb7a585
--- /dev/null
+++ b/utils.c
@@ -0,0 +1,24 @@
+//
+// Created by mayachen on 2025-09-20.
+//
+
+//
+// Created by mayachen on 2025-09-20.
+//
+
+#include "utils.h"
+
+#include
+#include
+
+
+// "Throw with error code"
+void throww_errcode(const char *err_msg, const int err_code) {
+ perror(err_msg);
+ exit(err_code);
+}
+
+// Throw an error like it was a high level language (okay it doesn't print the stack trace)
+inline void throw(const char *err_msg) {
+ throww_errcode(err_msg, 1);
+}
diff --git a/utils.h b/utils.h
new file mode 100644
index 0000000..20832f1
--- /dev/null
+++ b/utils.h
@@ -0,0 +1,11 @@
+//
+// Created by mayachen on 2025-09-20.
+//
+
+#ifndef NOTEVIEWER_UTILS_H
+#define NOTEVIEWER_UTILS_H
+
+inline void throw(const char* err_msg);
+void throww_errcode(const char* err_msg, int err_code);
+
+#endif //NOTEVIEWER_UTILS_H
\ No newline at end of file