Skip to content

Commit

Permalink
string_view, ugly hack in assembler
Browse files Browse the repository at this point in the history
  • Loading branch information
mmamayka committed Nov 24, 2020
1 parent 6cd3a95 commit 532390e
Show file tree
Hide file tree
Showing 54 changed files with 1,717 additions and 397 deletions.
48 changes: 48 additions & 0 deletions Akinator/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
LDFLAGS := ../ttrack-lib/lib/ttrack-lib.a -lm
CFLAGS := \
-Wall -Wextra \
-g \
-I../ttrack-lib/hdr

DOCPATH := doc-html
OBJPATH := obj
SRCPATH := src
BINPATH := bin

BINNAME := akinator
DOXCONF := doxygen

run: $(BINPATH)/$(BINNAME)
./$<

build: $(BINPATH)/$(BINNAME)

doc: $(DOCPATH)

clean:
-rm -rf $(OBJPATH)/*
-rm -rf $(BINPATH)/*
-rm -rf $(DOCPATH)


_CFILES := $(wildcard $(SRCPATH)/*.c)
_HFILES := $(wildcard $(SRCPATH)/*.h)
_OFILES := $(patsubst $(SRCPATH)/%.c, $(OBJPATH)/%.o, $(_CFILES))
_DFILES := $(patsubst $(SRCPATH)/%.c, $(OBJPATH)/%.d, $(_CFILES))

include $(_DFILES)

$(DOCPATH): $(_CFILES) $(_HFILES)
doxygen $(DOXCONF)

$(OBJPATH)/%.o: $(SRCPATH)/%.c
$(CC) -c $< -o $@ $(CFLAGS)

$(OBJPATH)/%.d: $(SRCPATH)/%.c
$(CC) -MM $< | sed 's/.*:/$(OBJPATH)\/$*.o $(OBJPATH)\/$*.d:/g' > $@

$(BINPATH)/$(BINNAME): $(_OFILES)
$(CC) -o $@ $^ $(LDFLAGS)

.PHONY: all clean doc build

94 changes: 94 additions & 0 deletions Akinator/src/io.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <ttrack/dbg.h>
#include "io.h"

int const read_word(char buf[], size_t size)
{$_
ASSERT(buf != NULL);

size_t const LINEBUF_SIZE = 32;
char linebuf[LINEBUF_SIZE];

if(fgets(linebuf, LINEBUF_SIZE, stdin) == NULL) {
RETURN(0);
}

size_t linebuf_len = strlen(linebuf);
if(linebuf[linebuf_len - 1] == '\n') { // whole line was read
linebuf[linebuf_len - 1] = ' ';

char* space_pos = strchr(linebuf, ' ');
*space_pos = '\0';

size_t len = space_pos - linebuf + 1;
if(len > size) {
RETURN(0);
}

memcpy(buf, linebuf, len);
RETURN(1);
}
else { // overflow, need to clear stdin
scanf("%*[^\n]");
getc(stdin);

RETURN(0);
}
$$
}
int const read_line(char buf[], size_t size)
{$_
ASSERT(buf != NULL);

if(fgets(buf, size, stdin) == NULL) {
RETURN(0);
}

size_t len = strlen(buf);
if(buf[len - 1] != '\n') {
scanf("%*[^\n]");
getc(stdin);

RETURN(0);
}

buf[len - 1] = '\0';

RETURN(1);
$$
}

static void string_to_lower(char* string)
{$_
ASSERT(string != NULL);

for(; *string != '\0'; ++string) {
*string = (char)tolower((int)*string);
}
$$
}


int const yes_or_no()
{$_
for(;;) {
printf("Print \'yes\' if you are agree, \'no\' otherwise: ");
fflush(stdout);

char buf[4];
if(read_word(buf, 4)) {
string_to_lower(buf);

if(strcmp(buf, "no") == 0) {
RETURN(0);
}
if(strcmp(buf, "yes") == 0) {
RETURN(1);
}
}

}
$$
}
10 changes: 10 additions & 0 deletions Akinator/src/io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef IO_H
#define IO_H

#include <stddef.h>

int const read_word(char buf[], size_t size);
int const read_line(char buf[], size_t size);
int const yes_or_no();

#endif
228 changes: 228 additions & 0 deletions Akinator/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ttrack/dbg.h>
#include <ttrack/binbuf.h>

#include "node.h"
#include "io.h"

typedef enum {
TREE_ERR_OK,
TREE_ERR_LOOP,
TREE_ERR_NODE,
TREE_ERR_NULL,

TREE_NERRORS
} tree_err_t;

char const* tree_errstr(tree_err_t err)
{$_
ASSERT(err >= 0 && err < TREE_NERRORS);

char const* TABLE[TREE_NERRORS] = {
"ok",
"loop",

};

RETURN(TABLE[err]);
$$
}

tree_err_t tree_check(node_t const* root)
{$_
node_err_t node_err = node_check(root);
if(node_err != NODE_ERR_OK) {
switch(node_err) {
case NODE_ERR_LOOP:
RETURN(TREE_ERR_LOOP);
break;

default:
RETURN(TREE_ERR_NODE);
break;
}
}

if(root->lch == NULL) {
RETURN(TREE_ERR_OK);
}

((node_t*)root)->color = 1;

tree_err_t lerr = tree_check(root->lch);
if(lerr != TREE_ERR_OK) {
((node_t*)root)->color = 0;
RETURN(lerr);
}

tree_err_t rerr = tree_check(root->rch);
if(rerr != TREE_ERR_OK) {
((node_t*)root)->color = 0;
RETURN(rerr);
}

((node_t*)root)->color = 0;

RETURN(TREE_ERR_OK);
}

void tree__dump_body(node_t const* root) {
if(root != NULL) {
node_dump(root);
if(((node_t*)root)->color == 1) {
dump("cycle found\n");
}
else {
((node_t*)root)->color = 1;
tree__dump_body(root->lch);
tree__dump_body(root->rch);
((node_t*)root)->color = 0;
}
}

}

void tree__dump(node_t const* root, char const* funcname, char const* filename,
size_t nline)
{$_
tree_err_t err = tree_check(root);
dump("tree dump from %s (%s %i), reason %i (%s) {\n",
funcname, filename, nline, err, tree_errstr(err));

DUMP_DEPTH += 1;
tree__dump_body(root);
DUMP_DEPTH -= 1;

dump("}\n");
$$
}

#define tree_dump(root) \
tree__dump(root, __func__, __FILE__, __LINE__)

void tree__assert(node_t const* root, char const* funcname, char const* filename,
size_t nline)
{$_
if(tree_check(root) != TREE_ERR_OK) {
tree__dump(root, funcname, filename, nline);
ASSERT(0);
}
$$
}

#define tree_assert(root) \
tree__assert(root, __func__, __FILE__, __LINE__)

void tree__traversal(node_t* node)
{$_
if(node->lch == NULL) {
printf("Is it %s?\n", node->data);
fflush(stdout);

int answer = yes_or_no();

if(answer == 0) {
node_t* node_answ = node_read_answer();
node_t* node_question = node_read_question(NULL, NULL);

node_question->lch = node_question;
node_question->rch = node_answ;

node_swap(node_question, node);
}
else {
printf("That\'s cool!\n");
fflush(stdout);
}
}
else {
printf("%s\n", node->data);
fflush(stdout);

int answer = yes_or_no();

if(answer == 0) {
tree__traversal(node->lch);
}
else {
tree__traversal(node->rch);
}
}
$$
}

void tree_traversal(node_t* root)
{$_
tree_assert(root);
tree__traversal(root);
tree_assert(root);
$$
}

void tree__free(node_t* root)
{$_
if(root != NULL) {
tree__free(root->lch);
tree__free(root->rch);
node_free(root);
}
$$
}

void tree_free(node_t* root)
{$_
tree_assert(root);
tree__free(root);
$$
}

int const tree__write(node_t const* root)
{$_
if(root == NULL) {
size_t zero = 0;
RETURN( binbuf_write_value(size_t, zero) == BINBUF_ERR_OK );
}
else {
size_t len = strlen(root->data);

if(binbuf_write_value(size_t, len) == BINBUF_ERR_OK &&
binbuf_write(root->data, len) == BINBUF_ERR_OK) {
RETURN( tree__write(root->lch) && tree__write(root->rch) );
}
else {
RETURN(0);
}
}
$$
}

int const tree_write(node_t const* root, FILE* stream)
{$_
tree_assert(root);
stream_assert(stream);

if(tree__write(root) && binbuf_flushh(stream) == BINBUF_ERR_OK) {
binbuf_free();
RETURN(1);
}

RETURN(0);
$$
}

int main() {
node_t* root = node_make("dog", NULL, NULL);
while(1) {
printf("Do you want to play?\n");
int answer = yes_or_no();

if(!answer)
break;

tree_traversal(root);
}

tree_free(root);
}
Loading

0 comments on commit 532390e

Please sign in to comment.