#include #include #include #include "aptconf.h" #include "vlistparser.h" PRIVATE char *VLIST_PARSER::parse_line (const char *line) { static char *buf = NULL; static char *pos = NULL; static char *ret = NULL; static char *ret_pos = NULL; static int buf_size = 0; static bool last_is_space = false; static bool eol = true; static bool newline = true; bool no_valid = true; if (line != NULL){ int line_len = strlen(line); int buf_len = (pos == NULL)?0:pos-buf; int new_size = buf_len+line_len+1; if (new_size > buf_size){ buf_size = new_size; buf = (char *) realloc(buf,buf_size); pos = buf+buf_len; int ret_len = (ret_pos == NULL)?0:ret_pos-ret; ret = (char *) realloc(ret,buf_size); ret_pos = ret+ret_len; if (ret_len == 0){ eol = true; } } memcpy(pos, line, line_len); *(pos+line_len) = 0; eol = false; }else if (eol == true){ return NULL; } for (;;){ switch (*pos) { case '#': last_is_space = false; // If this is a comment, copy and return it if (no_valid){ while (*pos != '\n'){ if (*pos == 0){ eol = true; pos = buf; break; } *ret_pos++ = *pos++; } newline = true; *ret_pos = 0; // Reset return pointer ret_pos = ret; return ret; }else{ *ret_pos++ = *pos++; } break; case 0: // End of incoming line if (no_valid && line != NULL) { eol = true; *ret_pos = 0; return ret; } no_valid = true; // Reset buffer pointer pos = buf; return NULL; break; case '{': if (no_valid && !last_is_space){ *ret_pos++ = ' '; } case '}': while (*(pos+1) != '\n' && *(pos+1) != 0){ *ret_pos++ = *pos++; } case ';': last_is_space = false; no_valid = true; newline = true; // Break line and return it *ret_pos++ = *pos++; *ret_pos = 0; // Reset return pointer ret_pos = ret; return ret; break; case '\n': no_valid = true; pos++; break; case '"': if (no_valid && !last_is_space && !newline) *ret_pos++ = ' '; last_is_space = false; no_valid = false; // Jump until next '"' *ret_pos++ = *pos++; while (*pos != '"' && *pos != 0) *ret_pos++ = *pos++; *ret_pos++ = *pos++; break; case ' ': case '\t': last_is_space = true; *ret_pos++ = *pos; while (*pos == ' ' || *pos == '\t') pos++; break; default: if (no_valid && !last_is_space && !newline) *ret_pos++ = ' '; last_is_space = false; no_valid = false; // Just get next char *ret_pos++ = *pos++; break; } newline = false; } return NULL; } PUBLIC void VLIST_PARSER::addline (const char *line) { static bool is_inside = false; char *parsed_line = parse_line(line); while (parsed_line != NULL){ int type; if (is_comment(parsed_line)){ type = VIEWITEM_COMMENT; }else if (!is_inside && *(str_skip(parsed_line))=='s'){ type = VLIST_KEYSTART; is_inside = true; }else if (is_inside && *(str_skip(parsed_line))=='F'){ type = VLIST_FINGERPRINT; }else if (is_inside && *(str_skip(parsed_line))=='N'){ type = VLIST_NAME; }else if (is_inside && *(str_skip(parsed_line))=='}'){ type = VLIST_KEYEND; is_inside = false; }else if (*(str_skip(parsed_line)) == 0){ type = VIEWITEM_EMPTY; }else{ type = VIEWITEM_UNKNOWN; } vi->add(new VIEWITEM(parsed_line,type)); parsed_line = parse_line(NULL); } }