Index: code/gamehelp/contexthelp.cpp
===================================================================
--- code/gamehelp/contexthelp.cpp	(revision 10856)
+++ code/gamehelp/contexthelp.cpp	(working copy)
@@ -411,11 +411,13 @@
 			help_overlaylist[overlay_id].lbracketlist.push_back(lbracket_temp);
 		}
 		
+		int type;
 		// read in all elements for this overlay
-		while (!(optional_string("$end")))  {
+		while ((type = required_string_one_of(5, "+pline", "+text", "+right_bracket", "+left_bracket", "$end")) != 4) {	// Doing it this way means an error lists "$end" at the end, which seems appropriate. -MageKing17
 
-			if (optional_string("+pline")) {
-
+			switch (type) {
+			case 0:	// +pline
+				required_string("+pline");
 				currcount = help_overlaylist[overlay_id].plinecount;
 				int a, b;		// temp vars to read in int before cast to float;
 
@@ -422,9 +424,9 @@
 				// read number of pline vertices
 				stuff_int(&vtxcount);
 				// get vertex coordinates for each resolution
-				for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
+				for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
 					help_overlaylist[overlay_id].plinelist.at(i).push_back(pline_temp2);
-					for (j=0; j<vtxcount; j++) {
+					for (j = 0; j < vtxcount; j++) {
 						help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.push_back(vec3d_temp);
 						help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtxcount = vtxcount;
 						stuff_int(&a);
@@ -436,13 +438,13 @@
 				}
 
 				help_overlaylist[overlay_id].plinecount++;
-
-			} else if (optional_string("+text")) {
-
+				break;
+			case 1:	// +text
+				required_string("+text");
 				currcount = help_overlaylist[overlay_id].textcount;
 
 				// get coordinates for each resolution
-				for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
+				for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
 					help_overlaylist[overlay_id].textlist.at(i).push_back(text_temp2);
 					stuff_int(&(help_overlaylist[overlay_id].textlist.at(i).at(currcount).x_coord));
 					stuff_int(&(help_overlaylist[overlay_id].textlist.at(i).at(currcount).y_coord));
@@ -453,13 +455,13 @@
 				help_overlaylist[overlay_id].textlist.at(0).at(currcount).string = vm_strdup(buf);
 
 				help_overlaylist[overlay_id].textcount++;
-
-			} else if (optional_string("+right_bracket")) {
-
+				break;
+			case 2: // +right_bracket
+				required_string("+right_bracket");
 				currcount = help_overlaylist[overlay_id].rbracketcount;
 
 				// get coordinates for each resolution
-				for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
+				for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
 					help_overlaylist[overlay_id].rbracketlist.at(i).push_back(rbracket_temp2);
 					stuff_int(&(help_overlaylist[overlay_id].rbracketlist.at(i).at(currcount).x_coord));
 					stuff_int(&(help_overlaylist[overlay_id].rbracketlist.at(i).at(currcount).y_coord));
@@ -466,13 +468,13 @@
 				}
 
 				help_overlaylist[overlay_id].rbracketcount++;
-
-			} else if (optional_string("+left_bracket")) {
-
+				break;
+			case 3: // +left_bracket
+				required_string("+left_bracket");
 				currcount = help_overlaylist[overlay_id].lbracketcount;
 
 				// get coordinates for each resolution
-				for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
+				for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
 					help_overlaylist[overlay_id].lbracketlist.at(i).push_back(lbracket_temp2);
 					stuff_int(&(help_overlaylist[overlay_id].lbracketlist.at(i).at(currcount).x_coord));
 					stuff_int(&(help_overlaylist[overlay_id].lbracketlist.at(i).at(currcount).y_coord));
@@ -479,14 +481,17 @@
 				}
 
 				help_overlaylist[overlay_id].lbracketcount++;
-
-			} else {
-				// help.tbl is corrupt
-				Assert(0);
-
-			}		// end if
-
+				break;
+			case -1:
+				// -noparseerrors is set
+				break;
+			case 4: // $end
+			default:
+				Assertion(false, "This should never happen.\n");
+				break;
+			}
 		}		// end while
+		required_string("$end");
 	}		// end while
 
 	// close localization
Index: code/parse/parselo.cpp
===================================================================
--- code/parse/parselo.cpp	(revision 10856)
+++ code/parse/parselo.cpp	(working copy)
@@ -740,6 +740,56 @@
 	return -1;
 }
 
+// Generic version of old required_string_3 and required_string_4; written by ngld, with some tweaks by MageKing17
+int required_string_one_of(int arg_count, ...)
+{
+	Assertion(arg_count > 0, "required_string_one_of() called with arg_count of %d; get a coder!\n", arg_count);
+	int count = 0;
+	int idx;
+	char *expected;
+	SCP_string message = "";
+	va_list vl;
+
+	ignore_white_space();
+
+	while (count < RS_MAX_TRIES) {
+		va_start(vl, arg_count);
+		for (idx = 0; idx < arg_count; idx++) {
+			expected = va_arg(vl, char*);
+			if (strnicmp(expected, Mp, strlen(expected)) == 0) {
+				diag_printf("Found required string [%s]", token_found = expected);
+				return idx;
+			}
+		}
+		va_end(vl);
+
+		if (!message.compare("")) {
+			va_start(vl, arg_count);
+			message = "Required token = ";
+			for (idx = 0; idx < arg_count; idx++) {
+				message += "[";
+				message += va_arg(vl, char*);
+				message += "]";
+				if (arg_count == 2 && idx == 0) {
+					message += " or ";
+				} else if (idx == arg_count - 2) {
+					message += ", or ";
+				} else if (idx < arg_count - 2) {
+					message += ", ";
+				}
+			}
+			va_end(vl);
+		}
+
+		error_display(1, "%s, found [%.32s]\n", message.c_str(), next_tokens());
+		advance_to_eoln(NULL);
+		ignore_white_space();
+		count++;
+	}
+
+	return -1;
+}
+
 int required_string_either_fred(char *str1, char *str2)
 {
 	ignore_white_space();
Index: code/parse/parselo.h
===================================================================
--- code/parse/parselo.h	(revision 10856)
+++ code/parse/parselo.h	(working copy)
@@ -113,6 +113,7 @@
 extern int required_string_either(char *str1, char *str2);
 extern int required_string_3(char *str1, char *str2, char *str3);
 extern int required_string_4(char *str1, char *str2, char *str3, char *str4);
+extern int required_string_one_of(int arg_count, ...);
 
 // stuff
 extern void copy_to_eoln(char *outstr, char *more_terminators, char *instr, int max);
