# HG changeset patch # User markus schnalke # Date 1291392359 10800 # Node ID 899175e8dff09d8d66c6697b25808e5e4374595c # Parent 0c44b239c7fe78856b3602c86bb4556df7b3c465 heavy refactoring in the small of parse.c I really hope I didn't change any behavior. This reminds me that we really need a test framework. diff -r 0c44b239c7fe -r 899175e8dff0 src/parse.c --- a/src/parse.c Fri Dec 03 13:02:45 2010 -0300 +++ b/src/parse.c Fri Dec 03 13:05:59 2010 -0300 @@ -1,5 +1,6 @@ /* MasqMail Copyright (C) 1999-2001 Oliver Kurth + Copyright (C) 2010 markus schnalke This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,8 +45,9 @@ p++; while (*p && *p != ')') { p++; - if (*p == '(') + if (*p == '(') { p = skip_comment(p); + } } p++; @@ -59,21 +61,24 @@ g_print("read_word: %s\n", p); #endif /* eat leading spaces */ - while (*p && isspace(*p)) + while (*p && isspace(*p)) { p++; + } *b = p; /* b = &p; */ if (*p == '\"') { /* quoted-string */ p++; - while (*p && (*p != '\"')) + while (*p && (*p != '\"')) { p++; + } p++; } else { /* atom */ - while (*p && !strchr(specials, *p) && !iscntrl(*p) && !isspace(*p)) + while (*p && !strchr(specials, *p) && !iscntrl(*p) && !isspace(*p)) { p++; + } } *e = p; return TRUE; @@ -88,11 +93,13 @@ g_print("read_word_with_dots: %s\n", p); #endif while (TRUE) { - if (!read_word(p, b, e)) + if (!read_word(p, b, e)) { return FALSE; + } p = *e; - if (*p != '.') + if (*p != '.') { break; + } p++; } *b = b0; @@ -108,12 +115,14 @@ #endif *b = p; if (*p != '[') { - while (isalnum(*p) || (*p == '-') || (*p == '.')) + while (isalnum(*p) || (*p == '-') || (*p == '.')) { p++; + } } else { p++; - while (isalpha(*p) || (*p == '.')) + while (isalpha(*p) || (*p == '.')) { p++; + } if (*p != ']') { parse_error = g_strdup_printf("']' expected at end of literal address %s", *b); return FALSE; @@ -144,122 +153,130 @@ /* leading spaces and angle brackets */ while (*p && (isspace(*p) || (*p == '<'))) { - if (*p == '<') + if (*p == '<') { angle_brackets++; + } p++; } - if (*p) { - while (TRUE) { - if (read_word_with_dots(p, &b, &e)) { - p = e; + if (!*p) { + return FALSE; + } + + while (TRUE) { + if (!read_word_with_dots(p, &b, &e)) { + return FALSE; + } + + p = e; #ifdef PARSE_TEST - g_print("after read_word_with_dots: %s\n", p); + g_print("after read_word_with_dots: %s\n", p); #endif - /* eat white spaces and comments */ - while ((*p && (isspace(*p))) || (*p == '(')) { - if (*p == '(') { - if (!(p = skip_comment(p))) { - parse_error = g_strdup("missing right bracket ')'"); - return FALSE; - } - } else - p++; - } - /* we now have a non-space char that is not - the beginning of a comment */ - - if (*p == '@') { - /* the last word was the local_part - of an addr-spec */ - *local_begin = b; - *local_end = e; -#ifdef PARSE_TEST - g_print("found local part: %s\n", *local_begin); -#endif - if (*p == '@') { - p++; /* skip @ */ - /* now the domain */ - if (read_domain(p, &b, &e)) { - p = e; - *domain_begin = b; - *domain_end = e; - } else - return FALSE; - } else { - /* unqualified? */ - *domain_begin = *domain_end = NULL; - } - break; - } else if (*p == '<') { - /* addr-spec follows */ - while (isspace(*p) || (*p == '<')) { - if (*p == '<') - angle_brackets++; - p++; - } - if (read_word_with_dots(p, &b, &e)) { - p = e; - *local_begin = b; - *local_end = e; -#ifdef PARSE_TEST - g_print("found local part: %s\n", *local_begin); -#endif - } else - return FALSE; - if (*p == '@') { - p++; - if (read_domain(p, &b, &e)) { - p = e; - *domain_begin = b; - *domain_end = e; - } else - return FALSE; - } else { - /* may be unqualified address */ - *domain_begin = *domain_end = NULL; - } - break; - } else if (!*p || *p == '>') { - *local_begin = b; - *local_end = e; -#ifdef PARSE_TEST - g_print("found local part: %s\n", *local_begin); -#endif - *domain_begin = *domain_end = NULL; - break; - } else if (strchr(specials, *p) || iscntrl(*p) || isspace(*p)) { - parse_error = g_strdup_printf("unexpected character: %c", *p); + /* eat white spaces and comments */ + while ((*p && (isspace(*p))) || (*p == '(')) { + if (*p == '(') { + if (!(p = skip_comment(p))) { + parse_error = g_strdup("missing right bracket ')'"); return FALSE; } - } else + } else { + p++; + } + } + /* we now have a non-space char that is not + the beginning of a comment */ + + if (*p == '@') { + /* the last word was the local_part of an addr-spec */ + *local_begin = b; + *local_end = e; +#ifdef PARSE_TEST + g_print("found local part: %s\n", *local_begin); +#endif + if (*p == '@') { + p++; /* skip @ */ + /* now the domain */ + if (!read_domain(p, &b, &e)) { + return FALSE; + } + p = e; + *domain_begin = b; + *domain_end = e; + } else { + /* unqualified? */ + *domain_begin = *domain_end = NULL; + } + break; + + } else if (*p == '<') { + /* addr-spec follows */ + while (isspace(*p) || (*p == '<')) { + if (*p == '<') { + angle_brackets++; + } + p++; + } + if (!read_word_with_dots(p, &b, &e)) { return FALSE; + } + p = e; + *local_begin = b; + *local_end = e; +#ifdef PARSE_TEST + g_print("found local part: %s\n", *local_begin); +#endif + if (*p == '@') { + p++; + if (!read_domain(p, &b, &e)) { + return FALSE; + } + p = e; + *domain_begin = b; + *domain_end = e; + } else { + /* may be unqualified address */ + *domain_begin = *domain_end = NULL; + } + break; + + } else if (!*p || *p == '>') { + *local_begin = b; + *local_end = e; +#ifdef PARSE_TEST + g_print("found local part: %s\n", *local_begin); +#endif + *domain_begin = *domain_end = NULL; + break; + + } else if (strchr(specials, *p) || iscntrl(*p) || isspace(*p)) { + parse_error = g_strdup_printf("unexpected character: %c", *p); + return FALSE; } - /* trailing spaces and angle brackets */ + } + + /* trailing spaces and angle brackets */ #ifdef PARSE_TEST - g_print("down counting trailing '>'\n"); + g_print("down counting trailing '>'\n"); #endif - while (*p && (isspace(*p) || (*p == '>'))) { - if (*p == '>') - angle_brackets--; - p++; + while (*p && (isspace(*p) || (*p == '>'))) { + if (*p == '>') { + angle_brackets--; } + p++; + } - *address_end = p; + *address_end = p; - if (angle_brackets != 0) { - if (angle_brackets > 0) - parse_error = g_strdup("missing '>' at end of string"); - else - parse_error = g_strdup("superfluous '>' at end of string"); - return FALSE; - } else { - /* we successfully parsed the address */ - return TRUE; - } - /* we never get here */ + if (angle_brackets > 0) { + parse_error = g_strdup("missing '>' at end of string"); + return FALSE; + } else if (angle_brackets < 0) { + parse_error = g_strdup("superfluous '>' at end of string"); + return FALSE; } - return FALSE; + + /* we successfully parsed the address */ + return TRUE; } gboolean @@ -282,68 +299,71 @@ /* leading spaces and angle brackets */ while (*p && (isspace(*p) || (*p == '<'))) { - if (*p == '<') + if (*p == '<') { angle_brackets++; + } p++; } - if (*p) { - while (TRUE) { - if (read_word_with_dots(p, &b, &e)) { - p = e; -#ifdef PARSE_TEST - g_print("after read_word_with_dots: %s\n", p); -#endif - *local_begin = b; - *local_end = e; -#ifdef PARSE_TEST - g_print("found local part: %s\n", *local_begin); - g_print("local_end = %s\n", *local_end); -#endif - if (!(*p) || isspace(*p) || (*p == '>')) { - /* unqualified ? */ - domain_begin = domain_end = NULL; - break; - } else if (*p == '@') { - p++; - if (read_domain(p, &b, &e)) { - p = e; - *domain_begin = b; - *domain_end = e; - } - break; - } else { - parse_error = g_strdup_printf ("unexpected character after local part '%c'", *p); - return FALSE; - } - } else - return FALSE; + if (!*p) { + return FALSE; + } + + while (TRUE) { + if (!read_word_with_dots(p, &b, &e)) { + return FALSE; } - /* trailing spaces and angle brackets */ + p = e; #ifdef PARSE_TEST - g_print("down counting trailing '>'\n"); + g_print("after read_word_with_dots: %s\n", p); #endif - while (*p && (isspace(*p) || (*p == '>'))) { - if (*p == '>') - angle_brackets--; + *local_begin = b; + *local_end = e; +#ifdef PARSE_TEST + g_print("found local part: %s\n", *local_begin); + g_print("local_end = %s\n", *local_end); +#endif + if (!(*p) || isspace(*p) || (*p == '>')) { + /* unqualified ? */ + domain_begin = domain_end = NULL; + break; + } else if (*p == '@') { p++; + if (read_domain(p, &b, &e)) { + p = e; + *domain_begin = b; + *domain_end = e; + } + break; + } else { + parse_error = g_strdup_printf ("unexpected character after local part '%c'", *p); + return FALSE; } - *address_end = p; + } - if (angle_brackets != 0) { - if (angle_brackets > 0) - parse_error = g_strdup("missing '>' at end of string"); - else - parse_error = g_strdup("superfluous '>' at end of string"); - return FALSE; - } else { - /* we successfully parsed the address */ - return TRUE; + /* trailing spaces and angle brackets */ +#ifdef PARSE_TEST + g_print("down counting trailing '>'\n"); +#endif + while (*p && (isspace(*p) || (*p == '>'))) { + if (*p == '>') { + angle_brackets--; } - /* we never get here */ + p++; } - return FALSE; + *address_end = p; + + if (angle_brackets > 0) { + parse_error = g_strdup("missing '>' at end of string"); + return FALSE; + } else if (angle_brackets < 0) { + parse_error = g_strdup("superfluous '>' at end of string"); + return FALSE; + } + + /* we successfully parsed the address */ + return TRUE; } /* @@ -360,60 +380,66 @@ gchar *loc_beg, *loc_end; gchar *dom_beg, *dom_end; gchar *addr_end; + gboolean ret; - if (string && (string[0] == 0)) { + if (string && (string[0] == '\0')) { address *addr = g_malloc(sizeof(address)); addr->address = g_strdup(""); addr->local_part = g_strdup(""); - addr->domain = g_strdup(""); /* 'NULL' address (failure notice), - "" makes sure it will not be qualified with a hostname */ + /* 'NULL' address (failure notice), + "" makes sure it will not be qualified with a hostname */ + addr->domain = g_strdup(""); return addr; } - if (is_rfc821 - ? parse_address_rfc821(string, &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end) - : parse_address_rfc822(string, &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end)) - { - address *addr = g_malloc(sizeof(address)); - gchar *p = addr_end; + if (is_rfc821) { + ret = parse_address_rfc821(string, &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end); + } else { + ret = parse_address_rfc822(string, &loc_beg, &loc_end, &dom_beg, &dom_end, &addr_end); + } + if (!ret) { + return NULL; + } - memset(addr, 0, sizeof(address)); + address *addr = g_malloc(sizeof(address)); + gchar *p = addr_end; - if (loc_beg[0] == '|') { - parse_error = g_strdup("no pipe allowed for RFC 822/821 address"); - return NULL; - } + memset(addr, 0, sizeof(address)); - while (*p && (*p != ',')) - p++; - addr->address = g_strndup(string, p - string); + if (loc_beg[0] == '|') { + parse_error = g_strdup("no pipe allowed for RFC 822/821 address"); + return NULL; + } - addr->local_part = g_strndup(loc_beg, loc_end - loc_beg); + while (*p && (*p != ',')) { + p++; + } + addr->address = g_strndup(string, p - string); + addr->local_part = g_strndup(loc_beg, loc_end - loc_beg); #ifdef PARSE_TEST - g_print("addr->local_part = %s\n", addr->local_part); + g_print("addr->local_part = %s\n", addr->local_part); #endif - if (dom_beg != NULL) { - addr->domain = g_strndup(dom_beg, dom_end - dom_beg); - } else { - if (addr->local_part[0] == 0) - addr->domain = g_strdup(""); /* 'NULL' address (failure notice), - "" makes sure it will not be qualified with a hostname */ - else - addr->domain = NULL; - } + if (dom_beg != NULL) { + addr->domain = g_strndup(dom_beg, dom_end - dom_beg); + } else if (addr->local_part[0] == 0) { + /* 'NULL' address (failure notice), + "" makes sure it will not be qualified with a hostname */ + addr->domain = g_strdup(""); + } else { + addr->domain = NULL; + } - if (end != NULL) - *end = p; + if (end != NULL) { + *end = p; + } #ifndef PARSE_TEST - addr_unmark_delivered(addr); + addr_unmark_delivered(addr); #endif - return addr; - } - return NULL; + return addr; } address* @@ -436,17 +462,24 @@ while (*p) { address *addr = _create_address(p, &end, FALSE); - if (addr) { - if (domain) - if (addr->domain == NULL) - addr->domain = g_strdup(domain); + fprintf(stderr, "string: %s\n", p); - addr_list = g_list_append(addr_list, addr); - p = end; - } else + if (!addr) { break; - while (*p == ',' || isspace(*p)) + } + + fprintf(stderr, " addr: %s (%s<@>%s)\n", addr->address, addr->local_part, addr->domain); + if (domain && !addr->domain) { + addr->domain = g_strdup(domain); + } + fprintf(stderr, " %s (%s<@>%s)\n", addr->address, addr->local_part, addr->domain); + + addr_list = g_list_append(addr_list, addr); + p = end; + + while (*p == ',' || isspace(*p)) { p++; + } } return addr_list; }