Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/build-checks.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: Cross-platform Build Checks

on: [push, pull_request]
on:
push:
branches: [main]
pull_request:

jobs:
build:
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,5 @@ CMakeUserPresets.json
*-prefix/

# End of https://www.toptal.com/developers/gitignore/api/cmake,clion

.tmp_dir_path
8 changes: 7 additions & 1 deletion .idea/NoteViewer.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/runConfigurations/NoteViewer.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions .idea/runConfigurations/setup_test_env.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
114 changes: 15 additions & 99 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,120 +4,36 @@
#include <wchar.h>

#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;
}
}
142 changes: 142 additions & 0 deletions parse.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// Created by mayachen on 2025-09-20.
//

#include "parse.h"

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

#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;
}
}
}
12 changes: 12 additions & 0 deletions parse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Created by mayachen on 2025-09-20.
//

#ifndef NOTEVIEWER_PARSE_H
#define NOTEVIEWER_PARSE_H
#include <stdio.h>

#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
Loading
Loading