From 7f6229c26abe0a9d19abf15db40d252dbde34ad5 Mon Sep 17 00:00:00 2001
From: Maya <145165822+MayaChen350@users.noreply.github.com>
Date: Sat, 20 Sep 2025 22:44:38 -0400
Subject: [PATCH 1/2] Confuse Maya with ptrs of ptrs
---
.github/workflows/build-checks.yaml | 8 +-
.gitignore | 2 +
.idea/NoteViewer.iml | 8 +-
.idea/misc.xml | 3 +
.idea/runConfigurations/NoteViewer.xml | 8 ++
.idea/runConfigurations/setup_test_env.xml | 24 ++++
CMakeLists.txt | 7 +-
main.c | 113 ++--------------
parse.c | 142 +++++++++++++++++++++
parse.h | 12 ++
sequence.c | 4 +-
setup_test-env.py | 17 +++
utils.c | 24 ++++
utils.h | 11 ++
14 files changed, 279 insertions(+), 104 deletions(-)
create mode 100644 .idea/runConfigurations/NoteViewer.xml
create mode 100644 .idea/runConfigurations/setup_test_env.xml
create mode 100644 parse.c
create mode 100644 parse.h
create mode 100755 setup_test-env.py
create mode 100644 utils.c
create mode 100644 utils.h
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..d8a126f 100644
--- a/main.c
+++ b/main.c
@@ -4,120 +4,35 @@
#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;
- }
- }
+ const sequence_t main_sequence_of_chars;
+ sequence_t *seq_ptr = &main_sequence_of_chars;
+ 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) {
+ printf("%ls", (*main_sequence_of_chars.next).elem);
// no time to free anything
- start_of_sequence = *start_of_sequence.next;
+ main_sequence_of_chars = *main_sequence_of_chars.next;
}
return 0;
-}
+}
\ No newline at end of file
diff --git a/parse.c b/parse.c
new file mode 100644
index 0000000..08a2043
--- /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 *const*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 *const*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 *const*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 *const*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 const **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..22a1823
--- /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 const**curr_seq_ptr);
+#endif //NOTEVIEWER_PARSE_H
\ No newline at end of file
diff --git a/sequence.c b/sequence.c
index 164a108..ab32347 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;
+ wchar_t *s;
// I'm sure the compiler will be glad to optimize this "scope" :clueless:
{
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
From d94190bf686428bed60d3775be2d2cee3967c45f Mon Sep 17 00:00:00 2001
From: Maya <145165822+MayaChen350@users.noreply.github.com>
Date: Sat, 27 Sep 2025 22:36:08 -0400
Subject: [PATCH 2/2] Fix pointers and etc
---
main.c | 9 +++++----
parse.c | 16 ++++++++--------
parse.h | 2 +-
sequence.c | 22 +++++++++++-----------
4 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/main.c b/main.c
index d8a126f..74319c9 100644
--- a/main.c
+++ b/main.c
@@ -19,19 +19,20 @@ int main(int argc, char **argv) {
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));
- const sequence_t main_sequence_of_chars;
- sequence_t *seq_ptr = &main_sequence_of_chars;
+ 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 (main_sequence_of_chars.next != NULL) {
- printf("%ls", (*main_sequence_of_chars.next).elem);
+ seq_ptr = &main_sequence_of_chars;
+ wprintf(L"%ls", seq_ptr->elem);
// no time to free anything
- main_sequence_of_chars = *main_sequence_of_chars.next;
+ seq_ptr = seq_ptr->next;
}
return 0;
diff --git a/parse.c b/parse.c
index 08a2043..b701bd1 100644
--- a/parse.c
+++ b/parse.c
@@ -12,12 +12,12 @@
// not global functions to give the compiler for dinner //
-void advance_file_ptr_or_fail(FILE *const*file);
+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 *const*stack_of_chunks,
+ sequence_t *stack_of_chunks,
sequence_t **seq_ptr
);
@@ -38,16 +38,16 @@ enum reading_state_t __attribute__((section(".text"))) *const reading_state_ptr
void save_chars(wchar_t current_chunk[CHUNK_SIZE / sizeof(wchar_t)],
const int string_size,
- sequence_t *const*stack_of_chunks,
- sequence_t ***seq_ptr
+ 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);
+ 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 *const*file) {
+void advance_file_ptr_or_fail(FILE **file) {
wchar_t curr_char;
while ((curr_char = fgetc(*file) != '['))
@@ -57,7 +57,7 @@ void advance_file_ptr_or_fail(FILE *const*file) {
*reading_state_ptr = READING_TITLE;
}
-void parse_file_content(FILE *file, const wchar_t *word_to_base_output_on, sequence_t const **curr_seq_ptr) {
+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;
@@ -93,7 +93,7 @@ void parse_file_content(FILE *file, const wchar_t *word_to_base_output_on, seque
case UNDEFINED:
if (curr_char == '[') {
if (*reading_state_ptr == SAVE) {
- save_chars(current_chunk, string_size, &stack_of_chunks, curr_seq_ptr);
+ save_chars(current_chunk, string_size, stack_of_chunks, curr_seq_ptr);
}
*reading_state_ptr = READING_TITLE;
diff --git a/parse.h b/parse.h
index 22a1823..494b180 100644
--- a/parse.h
+++ b/parse.h
@@ -8,5 +8,5 @@
#include "sequence.h"
-void parse_file_content(FILE *file, const wchar_t *word_to_base_output_on, sequence_t const**curr_seq_ptr);
+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 ab32347..b372e59 100644
--- a/sequence.c
+++ b/sequence.c
@@ -20,8 +20,8 @@ sequence_t *attach(sequence_t *curr_seq_ptr, const str new_elem) {
// 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;
- wchar_t *s;
+ void *backup = seq; // Save starting addresses
+ wchar_t *ret_str;
// I'm sure the compiler will be glad to optimize this "scope" :clueless:
{
@@ -32,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;
}