#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_SIZE 1024
typedef struct element {
char *nume;
struct element *next;
} element;
typedef struct category {
char *nume;
element *e;
struct category *next;
} category;
typedef struct root {
int category_length;
category *categorie;
} root;
char *get_sample(FILE *in_file);
root *init();
void generate_categories(root *head, char *buffer);
void add_element(root *head, int here, char *nume);
void completare(root *head, char *buffer);
void afisare(root *head, int level, FILE *out_file);
int main()
{
FILE *in_file = fopen("convertor.in", "r");
FILE *out_file = fopen("convertor.out", "w");
char *buffer;
int level = 0;
buffer = get_sample(in_file);
root *head = init ();
generate_categories(head, buffer);
while(buffer != NULL) {
++level;
completare(head, buffer);
free(buffer);
buffer = get_sample(in_file);
}
afisare(head, level, out_file);
fclose(out_file);
fclose(in_file);
return 0;
}
char *get_sample(FILE *in_file) {
char *buffer;
char *buffer2;
int end;
int balanced;
int i;
int cbs;
buffer = (char*) malloc (BUFFER_SIZE * sizeof(char));
buffer2 = NULL;
cbs = 1;
end = 0;
balanced = 0;
while ( !end ) {
if (fgets(buffer, BUFFER_SIZE, in_file) == NULL)
return NULL;
else {
for(i = 0; i < strlen(buffer); i++) {
if(buffer[i] == '}') {
balanced = 1;
break;
}
}
}
if (balanced == 1) {
fseek(in_file, i - strlen(buffer) + 1, SEEK_CUR);
if(buffer2 != NULL) {
buffer2 = (char*) realloc(buffer2, cbs * BUFFER_SIZE +
strlen(buffer) + 1);
strncat(buffer2, buffer, i);
buffer = buffer2;
}
end = 1;
} else {
cbs+= strlen (buffer);
buffer2 = (char*) realloc (buffer2, cbs);
buffer2[cbs - strlen(buffer) - 1] = 0;
strcat(buffer2, buffer);
}
}
for ( i = strlen(buffer); i >= 0; i--) {
if(buffer[i] == '{') {
buffer = buffer + i;
break;
}
}
return buffer;
}
root *init() {
root *head = (root*)malloc(sizeof(root));
head->category_length = 0;
head->categorie = NULL;
return head;
}
void generate_categories(root *head, char *buffer) {
int j;
char *pct;
char *ghi1, *ghi2, *nume;
int contor;
category *aux;
while ((pct = strstr(buffer, ":")) != NULL){
contor = 0;
for(j = pct - buffer; j >= 0; j--) {
if (buffer[j] == '"') {
contor++;
if(contor == 1)
ghi2 = buffer + j;
else if(contor == 2)
ghi1 = buffer + j;
}
if (contor == 2){
contor = ghi2 - ghi1 - 1;
nume = (char*)calloc((contor + 1), sizeof(char));
strncpy(nume, ghi1 + 1, contor);
category *cat = (category*)malloc(sizeof(category));
cat->nume = nume;
cat->e = NULL;
cat->next = NULL;
head->category_length++;
if(head->categorie == NULL)
head->categorie = cat;
else {
aux = head->categorie;
while (aux->next)
aux = aux->next;
aux->next = cat;
}
break;
}
}
buffer = pct + 1;
}
}
void add_element(root *head, int here, char *nume) {
int i;
category *aux = head->categorie;
for ( i = 0; i < here; i++)
aux = aux->next;
element *el = aux->e;
element *nou = (element*) malloc(sizeof(element));
nou->nume = nume;
nou->next = NULL;
if (el == NULL) {
aux->e = nou;
} else {
while ( el->next ) {
el = el->next;
}
el->next = nou;
}
}
void completare(root *head, char *buffer) {
int i, j, k;
char *pct;
char *ghi1, *nume;
int val;
int size = strlen(buffer);
for(i = 0; i < head->category_length; i++) {
pct = strstr(buffer, ":");
for(j = 0 ;j < buffer + size - pct; j++) {
if(pct[j] == '"') {
ghi1 = pct + j;
for (k = 1; k < buffer + size - pct; k++) {
if(ghi1[k] == '"') {
nume = (char*)calloc((k), sizeof(char));
strncpy(nume, ghi1 + 1, k - 1);
add_element(head, i, nume);
break;
}
}
break;
} else if (pct[j] >= '0' && pct[j] <= '9' ) {
sscanf(pct + j, "%d", &val);
nume = (char*)calloc(10, sizeof(char));
sprintf(nume, "%d", val);
add_element(head, i, nume);
break;
}
}
buffer = pct + 1;
}
}
void afisare(root *head, int level, FILE *out_file) {
int i, j, k;
element *el;
category *aux = head->categorie;
for (i = 0; i < head->category_length; i++) {
fprintf(out_file, "%s,", aux->nume);
aux = aux->next;
}
fprintf(out_file, "\n");
for (i = 0; i < level; i++) {
aux = head->categorie;
for(j = 0; j < head->category_length; j++) {
el = aux->e;
for(k = 0; k < i; k++)
el = el->next;
fprintf(out_file, "%s,", el->nume);
aux = aux->next;
}
if (i < level - 1)
fprintf(out_file, "\n");
}
}