diff --git a/examples/hanoi.c b/examples/hanoi.c new file mode 100644 index 0000000..056f793 --- /dev/null +++ b/examples/hanoi.c @@ -0,0 +1,73 @@ +#include +#include + +CMC_GENERATE_STACK(stk, stack, int) + +struct +{ + stack *from; + stack *aux; + stack *to; +} print_aux = {NULL}; + +void print_stacks() +{ + for (int i = 9; i >= 0; i--) + { + int ia = print_aux.from->buffer[i]; + int ib = print_aux.aux->buffer[i]; + int ic = print_aux.to->buffer[i]; + + printf("| %c | %c | %c |\n", + ia == 0 ? 32 : ia + 48, + ib == 0 ? 32 : ib + 48, + ic == 0 ? 32 : ic + 48); + } + + printf("+---+---+---+\n\n"); +} + +void move(stack *from, stack *to) +{ + stk_push(to, stk_top(from)); + + stk_pop(from); +} + +void hanoi(int n, stack *from, stack *aux, stack *to) +{ + if (n == 0) + return; + + hanoi(n - 1, from, to, aux); + + move(from, to); + + print_stacks(); + + hanoi(n - 1, aux, from, to); +} + +int main(int argc, char const *argv[]) +{ + stack *from = stk_new(10); + stack *to = stk_new(10); + stack *aux = stk_new(10); + + for (int i = 4; i >= 1; i--) + stk_push(from, i); + + print_aux.from = from; + print_aux.aux = aux; + print_aux.to = to; + + print_stacks(); + + hanoi(stk_count(from), from, aux, to); + + stk_free(from, NULL); + stk_free(to, NULL); + stk_free(aux, NULL); + + return 0; +} diff --git a/examples/printer.c b/examples/printer.c new file mode 100644 index 0000000..d22828a --- /dev/null +++ b/examples/printer.c @@ -0,0 +1,208 @@ +#include +#include + +#define TAB_SIZE 4 +#define ROW_INI_CAP DOC_LETTERS_IN_ROW +#define DOC_LETTERS_IN_ROW 100 +#define DOC_ROWS_IN_PAGE 50 +#define DOC_MARGIN 4 + +CMC_GENERATE_LIST(row, row, char) +CMC_GENERATE_LIST(doc, document, row *) + +void row_deallocator(row *r) +{ + row_free(r, NULL); +} + +document *document_load(const char *file_name); +void document_empty_line(FILE *fptr); +void document_page_outline(FILE *fptr, int outline); +void document_page_margin(FILE *fptr, int margin); +void document_print(document *doc, FILE *fptr); + +document *document_load(const char *file_name) +{ + FILE *file = fopen(file_name, "r"); + + if (!file) + { + cmc_log_error("File %s not found\n", file_name); + return NULL; + } + + row *initial_row = row_new(ROW_INI_CAP); + + document *doc = doc_new(100); + doc_push_back(doc, initial_row); + + int ch; + + while ((ch = getc(file)) != EOF) + { + char c = (char)ch; + + row *current_row = doc_back(doc); + + if (c == '\n') + { + row *new_row = row_new(ROW_INI_CAP); + doc_push_back(doc, new_row); + } + else if (c == '\t') + { + intmax_t left = TAB_SIZE; + + while (left > 0 && row_count(current_row) < DOC_LETTERS_IN_ROW) + { + row_push_back(current_row, ' '); + left--; + } + + if (left > 0) + { + row *new_row = row_new(ROW_INI_CAP); + doc_push_back(doc, new_row); + + while (left > 0) + { + row_push_back(new_row, ' '); + left--; + } + } + } + else if (DOC_LETTERS_IN_ROW == row_count(current_row)) + { + row *new_row = row_new(ROW_INI_CAP); + row_push_back(new_row, c); + doc_push_back(doc, new_row); + } + else + row_push_back(current_row, c); + } + + return doc; +} + +void document_empty_line(FILE *fptr) +{ + fputs("|", fptr); + for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2; i++) + { + fputc(' ', fptr); + } + fputs("|\n", fptr); +} + +void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */) +{ + if (outline == 1) + { + document_empty_line(fptr); +#ifdef DOC_PAGE_NUMBER + static intmax_t page = 1; + + fputs("|", fptr); + for (size_t i = 0; i < (DOC_LETTERS_IN_ROW + DOC_MARGIN) - 8; i++) + { + fputc(' ', fptr); + } + + fprintf(fptr, "%8" PRIdMAX "", page); + page++; + + document_page_margin(fptr, 1); + document_empty_line(fptr); +#endif + } + + fputs("+", fptr); + for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2; i++) + { + fputc('-', fptr); + } + fputs("+\n", fptr); + + if (outline == 0) + document_empty_line(fptr); +} + +void document_page_margin(FILE *fptr, int margin /* 0 - first margin, 1 - second margin */) +{ + if (margin == 0) + fputs("|", fptr); + + for (size_t i = 0; i < DOC_MARGIN; i++) + { + fputc(' ', fptr); + } + + if (margin == 1) + fputs("|\n", fptr); +} + +void document_print(document *doc, FILE *fptr) +{ + fputc('\n', fptr); + + intmax_t current_page_row = 0, total_rows = doc_count(doc); + + // Print document + for (intmax_t i = 0; i < total_rows; i++, current_page_row++) + { + if (current_page_row == 0) + document_page_outline(fptr, 0); + + row *current_row = doc_get(doc, i); + + if (!current_row) + cmc_log_fatal("Unexpected NULL pointer for %s", "current_row"); + + document_page_margin(fptr, 0); + + for (size_t k = 0; k < row_count(current_row); k++) + fputc(row_get(current_row, k), fptr); + + // Trailing margin + for (size_t k = 0; k < DOC_LETTERS_IN_ROW - row_count(current_row); k++) + fputc(' ', fptr); + + document_page_margin(fptr, 1); + + // Print the end of the page and reset + if (current_page_row == DOC_ROWS_IN_PAGE - 1) + { + document_page_outline(fptr, 1); + current_page_row = -1; + fputc('\n', fptr); + } + } + + // Print trailing page + if (total_rows % DOC_ROWS_IN_PAGE != 0) + { + for (size_t i = 0; i < DOC_ROWS_IN_PAGE - current_page_row; i++) + document_empty_line(fptr); + + document_page_outline(fptr, 1); + } + + fputc('\n', fptr); +} + +int main(int argc, char const *argv[]) +{ + if (argc != 2) + { + cmc_log_error("Please define one argument only for %s", argv[0]); + return 1; + } + + document *doc = document_load(argv[1]); + + document_print(doc, stdout); + + doc_free(doc, row_deallocator); + + return 0; +}