changeset 271:899175e8dff0

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.
author markus schnalke <meillo@marmaro.de>
date Fri, 03 Dec 2010 13:05:59 -0300
parents 0c44b239c7fe
children 681863fdafbb
files src/parse.c
diffstat 1 files changed, 234 insertions(+), 201 deletions(-) [+]
line wrap: on
line diff
--- 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 <meillo@marmaro.de>
 
     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);
-#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);
+		g_print("after read_word_with_dots: %s\n", p);
 #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;
+		/* 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);
+			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);
+			if (*p == '@') {
+				p++;	/* skip @ */
+				/* now the domain */
+				if (!read_domain(p, &b, &e)) {
 					return FALSE;
 				}
-			} else
-				return FALSE;
-		}
-		/* trailing spaces and angle brackets */
-#ifdef PARSE_TEST
-		g_print("down counting trailing '>'\n");
-#endif
-		while (*p && (isspace(*p) || (*p == '>'))) {
-			if (*p == '>')
-				angle_brackets--;
-			p++;
-		}
+				p = e;
+				*domain_begin = b;
+				*domain_end = e;
+			} else {
+				/* unqualified? */
+				*domain_begin = *domain_end = NULL;
+			}
+			break;
 
-		*address_end = p;
+		} 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;
 
-		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");
+		} 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;
-		} 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;
 }
 
 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
+		*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
-		while (*p && (isspace(*p) || (*p == '>'))) {
-			if (*p == '>')
-				angle_brackets--;
+		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);
+
+		if (!addr) {
+			break;
+		}
 
-			addr_list = g_list_append(addr_list, addr);
-			p = end;
-		} else
-			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;
 }