Added two working examples, hanoi and printer
This commit is contained in:
1 parent
b870649627
commit
8483eda701
2 files changed
+281
No files matched your search
@@ -0,0 +1,73 @@
|
||||
#include <cmc/stack.h>
|
||||
#include <utl/log.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
#include <cmc/list.h>
|
||||
#include <utl/log.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in new issue
Block a user