#include "dk.h"
#include "dkmem.h"
#include "dktypes.h"
#include "dksto.h"
#include "dkstr.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *famname;
char *surname;
unsigned long age;
} Person;
static dk_storage_t *s1;
static dk_storage_t *s2;
static dk_storage_t *s3;
static dk_storage_t *s4;
static dk_storage_iterator_t *i1, *i2, *i3, *i4;
static int can_continue;
static int stdin_is_tty = 1;
static void read_file(FILE *);
unsigned long age_fct(void *p, int cr)
{
unsigned long back;
switch(cr) {
case 1: {
back = *((unsigned long *)p);
} break;
default: {
back = ((Person *)p)->age;
} break;
}
return back;
}
int compare_fct(void *p1, void *p2, int cr)
{
int back = 0;
switch(cr) {
case 0: {
back = strcmp(((Person *)p1)->famname, ((Person *)p2)->famname);
} break;
case 1: {
back = strcmp(((Person *)p1)->famname, (char *)p2);
} break;
case 2: {
back = strcmp(((Person *)p1)->surname, ((Person *)p2)->surname);
} break;
case 3: {
back = strcmp(((Person *)p1)->surname, (char *)p2);
} break;
}
return back;
}
static void print_prompt(void)
{
if(stdin_is_tty) {
printf("\nstotest: ");
}
}
static void print_person(Person *pers, FILE *fout)
{
fprintf(
fout,
"%s %s %lu\n",
((pers->surname) ? pers->surname : "-"),
((pers->famname) ? pers->famname : "-"),
pers->age
);
}
static void print_it(dk_storage_iterator_t *i, FILE *fout)
{
void *p;
dksto_it_reset(i);
while((p = dksto_it_next(i)) != NULL) {
print_person((Person *)p, fout);
fprintf(fout, "\n");
}
}
void print_node(dk_storage_node_t *n, int num, FILE *f, char c)
{
int i;
Person *pers;
if(n) {
for(i = 0; i < num; i++) {
fprintf(f, " ");
}
fprintf(f, "%c %5d (%d)", c, num, n->b);
pers = (Person *)(n->o);
if(pers) {
if(pers->surname) fprintf(f, " %s ", pers->surname);
else fprintf(f, " - ");
if(pers->famname) fprintf(f, " %s ", pers->famname);
else fprintf(f, " - ");
fprintf(f, " %lu", pers->age);
}
fprintf(f, " \tparent:");
if(n->p) {
if((n->p)->o) {
pers = (Person *)((n->p)->o);
if(pers->surname) fprintf(f, " %s ", pers->surname);
else fprintf(f, " - ");
if(pers->famname) fprintf(f, "%s ", pers->famname);
else fprintf(f, "- ");
fprintf(f, " %lu", pers->age);
}
}
fprintf(f, "\n");
print_node(n->l, (num+1), f, 'l');
print_node(n->r, (num+1), f, 'r');
}
}
void print_tree(dk_storage_t *s, FILE *f)
{
if((s->h) && (s->t)) {
print_node(s->r, 0, f, '+');
}
}
static void free_person(Person *pers)
{
char *cptr;
if(pers) {
cptr = pers->famname;
if(cptr) { dkmem_free(cptr); }
cptr = pers->surname;
if(cptr) { dkmem_free(cptr); }
pers->famname = pers->surname = NULL;
dkmem_free(pers);
}
}
static
void
handle_cmd_1(char *str)
{
if(strcasecmp(str, "quit") == 0) {
can_continue = 0;
}
if(strcasecmp(str, "print") == 0) {
fprintf(stdout, "Sorted by family name:\n");
print_it(i1, stdout);
fprintf(stdout, "Sorted by surname:\n");
print_it(i2, stdout);
fprintf(stdout, "Sorted by age:\n");
print_it(i3, stdout);
fprintf(stdout, "Unsorted:\n");
print_it(i4, stdout);
}
if(strcasecmp(str, "tree") == 0) {
fprintf(stdout, "Sorted by family name:\n");
print_tree(s1, stdout);
fprintf(stdout, "Sorted by surname:\n");
print_tree(s2, stdout);
fprintf(stdout, "Sorted by age:\n");
print_tree(s3, stdout);
fprintf(stdout, "Unsorted:\n");
print_tree(s4, stdout);
}
}
static void handle_cmd_2(char *cmd, char *arg1)
{
if(strcasecmp(cmd, "read") == 0) {
FILE *in;
in = fopen(arg1, "r");
if(in) {
read_file(in);
fclose(in);
}
}
}
static void handle_cmd_3(char *cmd, char *arg1, char *arg2)
{
void *p;
if(strcasecmp(cmd, "find") == 0) {
if(strcasecmp(arg1, "f") == 0) {
p = dksto_it_find_like(i1, arg2, 1);
if(p) {
print_person(p,stdout); printf("\n");
}
printf("Followers:\n");
while((p = (Person *)dksto_it_next(i1)) != NULL) {
print_person(p,stdout); printf("\n");
}
}
if(strcasecmp(arg1, "s") == 0) {
p = dksto_it_find_like(i2, arg2, 3);
if(p) {
print_person(p,stdout); printf("\n");
}
printf("Followers:\n");
while((p = (Person *)dksto_it_next(i2)) != NULL) {
print_person(p,stdout); printf("\n");
}
}
if(strcasecmp(arg1, "a") == 0) {
unsigned long age;
if(sscanf(arg2, "%lu", &age) == 1) {
p = dksto_it_find_like(i3, (void *)(&age), 1);
if(p) {
print_person(p,stdout); printf("\n");
}
printf("Followers:\n");
while((p = (Person *)dksto_it_next(i3)) != NULL) {
print_person(p,stdout); printf("\n");
}
}
}
}
if(strcasecmp(cmd, "del") == 0) {
if(strcasecmp(arg1, "f") == 0) {
while((p = dksto_it_find_like(i1, arg2, 1)) != NULL) {
dksto_remove(s1,p);
dksto_remove(s2,p);
dksto_remove(s3,p);
dksto_remove(s4,p);
free_person(p);
}
}
if(strcasecmp(arg1, "s") == 0) {
while((p = dksto_it_find_like(i2, arg2, 3)) != NULL) {
dksto_remove(s1,p);
dksto_remove(s2,p);
dksto_remove(s3,p);
dksto_remove(s4,p);
free_person(p);
}
}
if(strcasecmp(arg1, "a") == 0) {
unsigned long age;
if(sscanf(arg2, "%lu", &age) == 1) {
while((p = dksto_it_find_like(i3, (void *)(&age), 1)) != NULL) {
dksto_remove(s1,p);
dksto_remove(s2,p);
dksto_remove(s3,p);
dksto_remove(s4,p);
free_person(p);
}
}
}
}
}
static void handle_cmd_4(char *cmd, char *arg1, char *arg2, char *arg3)
{
if(strcasecmp(cmd, "add") == 0) {
unsigned long age;
Person *pers;
if(sscanf(arg3, "%lu", &age) == 1) {
pers = dk_new(Person,1);
if(pers) {
pers->famname = dkstr_dup(arg2);
pers->surname = dkstr_dup(arg1);
pers->age = age;
if(!((pers->famname) && (pers->surname))) {
free_person(pers);
} else {
if(!dksto_add(s4, (void *)pers)) {
free_person(pers);
} else {
dksto_add(s1, (void *)pers);
dksto_add(s2, (void *)pers);
dksto_add(s3, (void *)pers);
}
}
}
}
}
}
void read_file(FILE *in)
{
char line[1024];
char *lbegin;
int i;
char str1[sizeof(line)];
char str2[sizeof(line)];
char str3[sizeof(line)];
char str4[sizeof(line)];
int old_can_continue;
old_can_continue = can_continue;
can_continue = 1;
while(can_continue) {
if(in == stdin) print_prompt();
if(fgets(line, sizeof(line), in)) {
lbegin = dkstr_start(line, NULL);
if(lbegin) {
dkstr_chomp(lbegin, NULL);
printf("# Processing \"%s\"\n", lbegin);
i = sscanf(lbegin, "%s %s %s %s", str1, str2, str3, str4);
switch(i) {
case 1: {
handle_cmd_1(str1);
} break;
case 2: {
handle_cmd_2(str1, str2);
} break;
case 3: {
handle_cmd_3(str1, str2, str3);
} break;
case 4: {
handle_cmd_4(str1, str2, str3, str4);
} break;
}
}
} else {
can_continue = 0;
}
}
can_continue = old_can_continue;
}
int main(int argc, char *argv[])
{
void *p; Person *pers; char *cptr;
stdin_is_tty = dksf_echo_test_tty();
s1 = dksto_open(0);
s2 = dksto_open(0);
s3 = dksto_open(0);
s4 = dksto_open(0);
if(s1 && s2 && s3 && s4) {
dksto_set_comp(s1, compare_fct, 0);
dksto_set_comp(s2, compare_fct, 2);
dksto_set_eval_ul(s3, age_fct, 0);
i1 = dksto_it_open(s1);
i2 = dksto_it_open(s2);
i3 = dksto_it_open(s3);
i4 = dksto_it_open(s4);
if(i1 && i2 && i3 && i4) {
read_file(stdin);
dksto_it_reset(i4);
while((p = dksto_it_next(i4)) != NULL) {
free_person((Person *)p);
}
}
}
if(i1) dksto_it_close(i1);
if(i2) dksto_it_close(i2);
if(i3) dksto_it_close(i3);
if(i4) dksto_it_close(i4);
if(s1) dksto_close(s1);
if(s2) dksto_close(s2);
if(s3) dksto_close(s3);
if(s4) dksto_close(s4);
exit(0); return 0;
}
#ifndef LINT
static char sccs_id[] = {
"@(#)stotest.ctr 1.19 02/03/09\t(krause) - dksto demo program"
};
#endif