#include #include #include #include #include #include #include "../xmlparse.h" #include "../global.h" #include "../survey.h" #include "shared_survey_util.h" #include "shared_survey_string.h" #include "shared_lock.h" #include "shared_cs_util.h" char *buffer_big; int max_buffer_big = 1000; static void startElement(void *userData, const char *name, const char **atts) { SURVEY_LIST *list = userData; char *tag = malloc_str(name); int i; /* is_likert_tag is in shared_survey_util.c */ if(strcmp(tag, "title") == 0 || is_likert_tag(tag) || strcmp(tag, "choice") ==0 || strcmp(tag, "text") ==0 || strcmp(tag, "memo") == 0 || strcmp(tag, "custom") == 0) { if(!list->head) { list->head = (SURVEY_DATA*)malloc(sizeof(SURVEY_DATA)); list->current = list->head; list->current->head = 0; list->current->steps_bgcolor = 0; list->current->current = 0; list->head->next = 0; } else { list->current->next=(SURVEY_DATA*)malloc(sizeof(SURVEY_DATA)); list->current = list->current->next; list->current->next = 0; list->current->head = 0; list->current->steps_bgcolor = 0; list->current->current = 0; } } if(strcmp(tag, "title") == 0) { list->current->tag_name = malloc_str(tag); for(i = 0; atts[i]; i = i+2) { if(strcmp(atts[i], "id") == 0) list->current->id = atoi(atts[i +1]); else if(strcmp(atts[i], "bgcolor") == 0) list->current->steps_bgcolor = malloc_str(atts[i +1]); else list->current->left_cols = malloc_str(atts[i +1]); } list->current->caption = 0; list->current->right_rows = 0; } else if(is_likert_tag(tag)) /* shared_survey_util.c */ { list->current->tag_name = malloc_str(tag); for(i = 0; atts[i]; i = i+2) { if(strcmp(atts[i], "id") == 0) list->current->id = atoi(atts[i+1]); else if(strcmp(atts[i], "steps") == 0) list->current->steps_bgcolor = malloc_str(atts[i +1]); else if(strcmp(atts[i], "lefttag") == 0) list->current->left_cols = malloc_str(atts[i +1]); else if(strcmp(atts[i], "righttag") ==0) list->current->right_rows = malloc_str(atts[i +1]); } list->current->caption = 0; } else if(strcmp(tag, "memo") == 0) { list->current->tag_name = malloc_str(tag); for(i = 0; atts[i]; i = i+2) { if(strcmp(atts[i], "id") == 0) list->current->id = atoi(atts[i+1]); else if(strcmp(atts[i], "cols") == 0) list->current->left_cols = malloc_str(atts[i +1]); else if(strcmp(atts[i], "rows") ==0) list->current->right_rows = malloc_str(atts[i +1]); } list->current->caption = 0; list->current->steps_bgcolor = 0; } else if(strcmp(tag, "text") == 0 || strcmp(tag, "custom") ==0 ) { list->current->tag_name = malloc_str(tag); for(i = 0; atts[i]; i = i+2) { if(strcmp(atts[i], "id") == 0) list->current->id = atoi(atts[i+1]); } list->current->caption = 0; list->current->steps_bgcolor = 0; list->current->left_cols = 0; list->current->right_rows = 0; } else if(strcmp(tag, "choice") == 0) { list->current->tag_name = malloc_str(tag); for(i = 0; atts[i]; i = i+2) { if(strcmp(atts[i], "id") == 0) list->current->id = atoi(atts[i+1]); if(strcmp(atts[i], "multi") ==0) list->current->steps_bgcolor = malloc_str(atts[i +1]); } if(!list->current->steps_bgcolor) list->current->steps_bgcolor = malloc_str("no"); list->current->caption = 0; list->current->left_cols = 0; list->current->right_rows = 0; } else if(strcmp(tag, "element_choice")==0) { if(!list->current->head) { list->current->head = (ELE_CHOICE*)malloc(sizeof(ELE_CHOICE)); list->current->current = list->current->head; list->current->current->next = 0; } else { list->current->current->next = (ELE_CHOICE*)malloc(sizeof(ELE_CHOICE)); list->current->current = list->current->current->next; list->current->current->next = 0; } } free(tag); memset(buffer_big, 0, max_buffer_big); } static void endElement(void *userData, const char *name) { SURVEY_LIST *list = userData; char *tag = malloc_str(name); if(strcmp(tag, "title") == 0 || is_likert_tag(tag) || strcmp(tag, "choice") ==0 || strcmp(tag, "text") ==0 || strcmp(tag, "memo") == 0 || strcmp(tag, "custom") == 0) { strtrim(buffer_big); list->current->caption = malloc_str(buffer_big); } else if(strcmp(tag, "element_choice") == 0) { strtrim(buffer_big); list->current->current->choice = malloc_str(buffer_big); } memset(buffer_big, 0, max_buffer_big); free(tag); } static void startCharacter(void *userData, const char *text, int len) { if( (int)(strlen(text) + strlen(buffer_big)) >= max_buffer_big) { max_buffer_big = max_buffer_big * 2; buffer_big = realloc(buffer_big, sizeof(char)*(max_buffer_big)); } strncat(buffer_big, text, len); } void free_survey_data_list(SURVEY_LIST *list) { SURVEY_DATA *ptr; ELE_CHOICE *ele_ptr; list->current = list->head; while(list->current) { ptr = list->current; if(ptr->tag_name) free(ptr->tag_name); if(ptr->steps_bgcolor) free(ptr->steps_bgcolor); if(ptr->caption) free(ptr->caption); if(ptr->left_cols) free(ptr->left_cols); if(ptr->right_rows) free(ptr->right_rows); if(list->current->head) { list->current->current = list->current->head; while(list->current->current) { ele_ptr = list->current->current; if(ele_ptr->choice) free(ele_ptr->choice); list->current->current = list->current->current->next; free(ele_ptr); } } list->current = list->current->next; free(ptr); } free(list); } void * survey_data_parser(char *filename) { char *buf, *error_buf; SURVEY_LIST *list; /* survey.h */ FILE *fp; struct stat file_stat; XML_Parser parser; /* buffer_big and max_buffer_big are globals at the top of this file */ buffer_big = (char *)malloc(sizeof(char)*(max_buffer_big)); /*initialize list */ list = (SURVEY_LIST *)malloc(sizeof(SURVEY_LIST)); list->head = 0; list->current = 0; if(stat(filename, &file_stat)) cs_critical_error( ERR_STAT_FAILED, filename); buf = (char*)malloc(file_stat.st_size); if(!buf) cs_critical_error( ERR_MALLOC_FAILED, "survey_data_parser()"); fp = fopen(filename, "r"); if(!fp) cs_critical_error( ERR_FOPEN_READ_FAILED, filename); get_shared_lock(fileno(fp), 1); /* shared_lock.h */ if(fread(buf, file_stat.st_size, 1, fp) != 1) cs_critical_error(ERR_FREAD_FAILED, filename); release_lock(fileno(fp)); /* shared_lock.c */ fclose(fp); parser = XML_ParserCreate(NULL); XML_SetUserData(parser, list); XML_SetElementHandler(parser, startElement, endElement); XML_SetCharacterDataHandler(parser, startCharacter); if(!XML_Parse(parser, buf, file_stat.st_size, 1)) { error_buf = malloc_str(XML_ErrorString(XML_GetErrorCode(parser))); cs_critical_error( ERR_XML_PARSER, error_buf); free(error_buf); } XML_ParserFree(parser); free(buf); free(buffer_big); return list; }