Browse Source

Mission complete

master
Kirill Nikolaev 1 month ago
parent
commit
cfbd66b16b
Signed by: sokket <sokket@oceancraft.ru> GPG Key ID: 082FDA12D688C5C1
1 changed files with 120 additions and 61 deletions
  1. +120
    -61
      main.c

+ 120
- 61
main.c View File

@@ -25,34 +25,6 @@ int str_contains(char *token, char s) {
return 0;
}

int str_contains_all(char *str, char *chars) {
char *src = str;
size_t count = strlen(chars);
int matchesCount = 0;
while (*src) {
if (str_contains(chars, *src))
matchesCount++;
src++;
}
return matchesCount == count;
}

char *str_remove_chr(char *str, char *bad) {
char *src = str, *dst = str;

if (!(str && bad))
return NULL;

while (*src)
if (str_contains(bad, *src))
src++;
else
*dst++ = *src++;

*dst = '\0';
return str;
}

int is_number(char *s) {
while (*s) {
if (!isdigit(*s) && *s != '.')
@@ -85,27 +57,56 @@ typedef struct obj {
char *value;
} Obj;

void log(char *msg) {
//printf("[LOG] %s\n", msg);
}

void printWhiteSpace(int depth) {
for (int i = 0; i < depth; i++)
printf(" ");
}

void printTag(Obj tag) {
void printTag(Obj tag, int nextObjIsValue, int prevObjIsValue, int comma) {
if (tag.type == OPEN) {
printWhiteSpace(tag.depth);
printf("\"%s\": {\n", tag.key);
} else if (tag.type == CLOSE) {
printf("\"%s\": %s", tag.key, nextObjIsValue ? "" : "{\n");
} else if (tag.type == CLOSE && !prevObjIsValue) {
printWhiteSpace(tag.depth);
printf("}\n");
} else if (tag.type == VALUE && strlen(trim(tag.value)) != 0)
for (char *p = strtok(tag.value, "\n"); p; p = strtok(0, "\n")) {
printWhiteSpace(tag.depth);
printf("%s\n", trim(p));
printf("%s\n", comma ? "}," : "}");
} else if (tag.type == VALUE && tag.value) {
if (count(tag.value, '\n') > 1) {
printf("\n");
int printStart = 0;
for (char *p = strtok(tag.value, "\n"); p;) {
printWhiteSpace(tag.depth);
if (!printStart) {
printf("\"");
printStart = 1;
}
printf("%s", trim(p));
p = strtok(0, "\n");
printf("%s\n", p ? "" : "\"");
}
} else {
char *text = trim(tag.value);
if (is_number(text) || !strcmp(text, "true") || !strcmp(text, "false"))
printf("%s%s\n", text, comma ? "," : "");
else
printf("\"%s\"%s\n", text, comma ? "," : "");
}
}
}

int prevIsValue = 0;

void printObjBuffer(Obj *obj, int count) {
for (int i = 0; i < count; ++i) {
printTag(
obj[i],
i + 1 < count && obj[i + 1].type == VALUE,
prevIsValue,
obj[i].type == VALUE
? (i + 3 < count && obj[i + 3].depth == obj[i].depth)
: (i + 1 < count && obj[i + 1].depth == obj[i].depth)
);
prevIsValue = obj[i].type == VALUE;
}
}

char *append(char *str, char c) {
@@ -122,11 +123,24 @@ char *append(char *str, char c) {
return str;
}

void cleanUpObj(Obj obj) {
obj.type = VALUE;
obj.depth = 0;
obj.key = 0;
obj.value = 0;
void initObj(Obj *obj) {
obj->key = 0;
obj->value = 0;
obj->type = VALUE;
obj->depth = 0;
}

void cleanUpObj(Obj *obj) {
if (obj->key) {
free(obj->key);
obj->key = 0;
}
if (obj->value) {
free(obj->value);
obj->value = 0;
}
obj->type = VALUE;
obj->depth = 0;
}

int main() {
@@ -134,19 +148,40 @@ int main() {
if (file) {
char buffer[128];
int ignore_tag_options = 0;
Obj tag_buffer[3];
cleanUpObj(tag_buffer[0]);
int tag_buffer_pos = 0;
int depth = -1;
int init_buffer_size = 4;
int buffer_size = init_buffer_size;
Obj *tag_buffer = malloc(buffer_size * sizeof(Obj));
for (int i = 0; i < buffer_size; i++)
initObj(&tag_buffer[i]);
while (fgets(buffer, 128, file)) {
Obj *tag = &tag_buffer[0];
Obj *tag = &tag_buffer[tag_buffer_pos];
size_t len = strlen(buffer);
for (int i = 0; i < len; i++) {
if (buffer[i] == '<') {
if (tag->value) {
char *old = tag->value;
tag->value = trim(tag->value);
printTag(*tag);
free(old);
tag->value = 0;
if (tag->value && strlen(trim(tag->value)) != 0) {
tag->depth = depth + 1;
if (++tag_buffer_pos == buffer_size) {
if (tag_buffer[buffer_size - 1].type != VALUE
&& tag_buffer[buffer_size - 2].type != VALUE
&& tag_buffer[buffer_size - 3].type != VALUE
) {
printObjBuffer(tag_buffer, buffer_size);
for (int j = init_buffer_size; j < buffer_size; ++j)
cleanUpObj(&tag_buffer[j]);
buffer_size = init_buffer_size;
tag_buffer = realloc(tag_buffer, buffer_size * sizeof(Obj));
tag_buffer_pos = 0;
} else {
buffer_size += 3;
tag_buffer = realloc(tag_buffer, buffer_size * sizeof(Obj));
for (int ib = tag_buffer_pos; ib < buffer_size; ib++)
initObj(&tag_buffer[ib]);
}
}
tag = &tag_buffer[tag_buffer_pos];
cleanUpObj(tag);
}
log("unknown");
tag->type = UNKNOWN;
@@ -161,13 +196,33 @@ int main() {
log("unknown -> open");
tag->type = OPEN;
}
if (tag->type == CLOSE) tag->depth--;
printTag(*tag);
free(tag->key);
tag->key = 0;
if (tag->type == OPEN) tag->depth++;
tag->type = VALUE;
tag->value = 0;

if (tag->type == CLOSE)
tag->depth = depth--;
if (tag->type == OPEN)
tag->depth = ++depth;

if (++tag_buffer_pos == buffer_size) {
if (tag_buffer[buffer_size - 1].type != VALUE
&& tag_buffer[buffer_size - 2].type != VALUE
&& tag_buffer[buffer_size - 3].type != VALUE
) {
printObjBuffer(tag_buffer, buffer_size);
for (int j = init_buffer_size; j < buffer_size; ++j)
cleanUpObj(&tag_buffer[j]);
buffer_size = init_buffer_size;
tag_buffer = realloc(tag_buffer, buffer_size * sizeof(Obj));
tag_buffer_pos = 0;
} else {
buffer_size += 3;
tag_buffer = realloc(tag_buffer, buffer_size * sizeof(Obj));
for (int ib = tag_buffer_pos; ib < buffer_size; ib++)
initObj(&tag_buffer[ib]);
}
}
tag = &tag_buffer[tag_buffer_pos];
cleanUpObj(tag);

} else if (tag->type == UNKNOWN && buffer[i] == ' ')
ignore_tag_options = 1;
else if (tag->type == UNKNOWN && !ignore_tag_options)
@@ -176,6 +231,10 @@ int main() {
tag->value = append(tag->value, buffer[i]);
}
}
printObjBuffer(tag_buffer, tag_buffer_pos);
for (int i = 0; i < buffer_size; ++i)
cleanUpObj(&tag_buffer[i]);
free(tag_buffer);
}
return 0;
}

Loading…
Cancel
Save