Selaa lähdekoodia

Feat: cumulative update

dzp 1 vuosi sitten
vanhempi
sitoutus
66bf3d5d9e
16 muutettua tiedostoa jossa 199 lisäystä ja 119 poistoa
  1. 5 0
      NEWS
  2. 30 0
      SCRIPTS
  3. 6 9
      TODO
  4. 9 0
      mods/igr.mods
  5. 29 25
      src/class.c
  6. 14 9
      src/help.c
  7. 21 2
      src/list.c
  8. 16 8
      src/mapper.c
  9. 13 13
      src/net.c
  10. 25 32
      src/regex.c
  11. 1 1
      src/scan.c
  12. 6 6
      src/show.c
  13. 8 1
      src/substitute.c
  14. 3 5
      src/system.c
  15. 1 1
      src/tintin.h
  16. 12 7
      src/validate

+ 5 - 0
NEWS

@@ -1,6 +1,11 @@
 Due to continuous improvements old tintin scripts aren't always compatible
 Due to continuous improvements old tintin scripts aren't always compatible
 with new versions. This document tries to list most compatibility conflicts.
 with new versions. This document tries to list most compatibility conflicts.
 
 
+TinTin++ 2.02.42
+----------------
+01) %%%s would get escaped to %%s in aliases and actions, this has been changed
+    so only %%%1 gets escaped to %%1, %%%s stays the same.
+
 TinTin++ 2.02.12
 TinTin++ 2.02.12
 ----------------
 ----------------
 01) The behavior of $variable[] is now identical to $variable[%*].
 01) The behavior of $variable[] is now identical to $variable[%*].

+ 30 - 0
SCRIPTS

@@ -771,6 +771,36 @@
 	display
 	display
 }
 }
 
 
+#nop -------------------------------------------------------------------------
+#nop Example script for creating clickable menus in the scrolling region.
+#nop -------------------------------------------------------------------------
+
+#con mouse on
+
+#function link {#var result {\e]68;1;%1;%2\a\e[4m%3\e[24m}}
+
+#event {PRESSED LINK MENU MOUSE BUTTON ONE}
+{
+	#local {link} {%4};
+
+	#foreach {*link[]} {key}
+	{
+		#line {substitute} {variables;functions}
+		{
+			#var link[$key] {@link{MENU_ITEM;$link[$key];<faa>$key}}
+		}
+	};
+	#draw Azure scaled box %0+1 %1 %0+1 %1+9 $link[%*]
+}
+
+#event {PRESSED LINK MENU_ITEM MOUSE BUTTON ONE}
+{
+	#showme {<ffa>%4};
+	#buffer refresh
+}
+
+#showme {Example link: @link{MENU;{{bli}{bla}{blo}{blu}};<128>click me}}
+
 #nop -------------------------------------------------------------------------
 #nop -------------------------------------------------------------------------
 #nop This creates two input lines that can be switched between using the tab
 #nop This creates two input lines that can be switched between using the tab
 #nop key.
 #nop key.

+ 6 - 9
TODO

@@ -1,13 +1,6 @@
-- 3Kingdoms loses color with #config color_patch on
+- Add an example script to display time left on tickers using #info tickers save
 
 
-#SESSION {3k} {3k.org} {3000};
-user
-pass
-#CONFIG {COLOR PATCH} {on};
-#EVENT {RECEIVED PROMPT}
-{
-  #NOP Do Something;
-};
+- comprehensive memory breakdown for variables/triggers/mapper/etc
 
 
 - Problem with restoring true color subs.
 - Problem with restoring true color subs.
 #sub bla {<F00AA00>bla}
 #sub bla {<F00AA00>bla}
@@ -62,6 +55,7 @@ pass
 
 
 - look into invalid { } in MSDP / GMCP handling
 - look into invalid { } in MSDP / GMCP handling
 
 
+- MSLP jump link handling
 
 
 - mapper.c FAST handling
 - mapper.c FAST handling
 
 
@@ -95,6 +89,9 @@ pass
 
 
 - #daemon attach fails under high cpu load
 - #daemon attach fails under high cpu load
 
 
+- https://github.com/scandum/tintin/issues/161
+  Add note to package maintainers
+
 ----------------
 ----------------
   - add shadow session support with access to all events.
   - add shadow session support with access to all events.
 
 

+ 9 - 0
mods/igr.mods

@@ -1,5 +1,14 @@
 Jan 2024        2.02.42
 Jan 2024        2.02.42
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
+substitute.c    %%%s would get escaped to %%s in aliases and actions. This was
+                changed so only %%%1 gets escaped to %%1, %%%s stays the same.
+
+list.c          Added an error message when using #list add on invalid lists.
+
+map.c           #map info save will save to info[MAP] instead of info[map].
+
+system.c        Fixed a bug limiting #script to 50KB of output.
+
 net.c           Fixed a bug causing #config color_patch to strip all colors.
 net.c           Fixed a bug causing #config color_patch to strip all colors.
 
 
 data.c          Classes are properly cleared when removed with #kill.
 data.c          Classes are properly cleared when removed with #kill.

+ 29 - 25
src/class.c

@@ -229,40 +229,44 @@ DO_CLASS(class_close)
 {
 {
 	if (node == NULL)
 	if (node == NULL)
 	{
 	{
-		show_message(ses, LIST_CLASS, "#CLASS {%s} DOES NOT EXIST.", arg1);
+		node = search_node_list(ses->list[LIST_CLASS], arg1);
+
+		if (node == NULL)
+		{
+			show_message(ses, LIST_CLASS, "#CLASS {%s} DOES NOT EXIST.", arg1);
+			return ses;
+		}
+	}
+
+	if (atoi(node->arg3) == 0)
+	{
+		show_message(ses, LIST_CLASS, "#CLASS {%s} IS ALREADY CLOSED.", arg1);
 	}
 	}
 	else
 	else
 	{
 	{
-		if (atoi(node->arg3) == 0)
-		{
-			show_message(ses, LIST_CLASS, "#CLASS {%s} IS ALREADY CLOSED.", arg1);
-		}
-		else
-		{
-			show_message(ses, LIST_CLASS, "#CLASS {%s} HAS BEEN CLOSED.", arg1);
+		show_message(ses, LIST_CLASS, "#CLASS {%s} HAS BEEN CLOSED.", arg1);
 
 
-			update_node_list(ses->list[LIST_CLASS], arg1, "", "0", node->arg4);
+		update_node_list(ses->list[LIST_CLASS], arg1, "", "0", node->arg4);
 
 
-			if (!strcmp(ses->group, arg1))
-			{
-				check_all_events(ses, EVENT_FLAG_CLASS, 0, 1, "CLASS DEACTIVATED", ses->group);
-				check_all_events(ses, EVENT_FLAG_CLASS, 1, 1, "CLASS DEACTIVATED %s", ses->group, ses->group);
+		if (!strcmp(ses->group, arg1))
+		{
+			check_all_events(ses, EVENT_FLAG_CLASS, 0, 1, "CLASS DEACTIVATED", ses->group);
+			check_all_events(ses, EVENT_FLAG_CLASS, 1, 1, "CLASS DEACTIVATED %s", ses->group, ses->group);
 
 
-				node = ses->list[LIST_CLASS]->list[0];
+			node = ses->list[LIST_CLASS]->list[0];
 
 
-				if (atoi(node->arg3))
-				{
-					RESTRING(ses->group, node->arg1);
+			if (atoi(node->arg3))
+			{
+				RESTRING(ses->group, node->arg1);
 
 
-					show_message(ses, LIST_CLASS, "#CLASS {%s} HAS BEEN ACTIVATED.", node->arg1);
+				show_message(ses, LIST_CLASS, "#CLASS {%s} HAS BEEN ACTIVATED.", node->arg1);
 
 
-					check_all_events(ses, EVENT_FLAG_CLASS, 0, 1, "CLASS ACTIVATED", node->arg1);
-					check_all_events(ses, EVENT_FLAG_CLASS, 1, 1, "CLASS ACTIVATED %s", arg1, arg1);
-				}
-				else
-				{
-					RESTRING(ses->group, "");
-				}
+				check_all_events(ses, EVENT_FLAG_CLASS, 0, 1, "CLASS ACTIVATED", node->arg1);
+				check_all_events(ses, EVENT_FLAG_CLASS, 1, 1, "CLASS ACTIVATED %s", arg1, arg1);
+			}
+			else
+			{
+				RESTRING(ses->group, "");
 			}
 			}
 		}
 		}
 	}
 	}

+ 14 - 9
src/help.c

@@ -1378,7 +1378,7 @@ struct help_type help_table[] =
 		"<278>         The edit command can be used to turn the default line editor into a\n"
 		"<278>         The edit command can be used to turn the default line editor into a\n"
 		"<278>         text editor.\n"
 		"<278>         text editor.\n"
 		"\n"
 		"\n"
-		"<278>         <178>#edit create <arguments>\n"
+		"<278>         <178>#edit create [name] [arguments]\n"
 		"<278>           Create an editor, initialize using the provided arguments.\n"
 		"<278>           Create an editor, initialize using the provided arguments.\n"
 		"\n"
 		"\n"
 		"<278>         <178>#edit load <variable>\n"
 		"<278>         <178>#edit load <variable>\n"
@@ -1397,7 +1397,7 @@ struct help_type help_table[] =
 		"<278>           Suspend editing, similar to pressing enter except that no\n"
 		"<278>           Suspend editing, similar to pressing enter except that no\n"
 		"<278>           events are triggered.\n"
 		"<278>           events are triggered.\n"
 		"\n"
 		"\n"
-		"<278>         <178>#edit write <filename\n"
+		"<278>         <178>#edit write [filename]\n"
 		"<278>           Write the editor content to file.\n"
 		"<278>           Write the editor content to file.\n"
 		"\n"
 		"\n"
 		"<178>Example<278>: #edit create {bli}{bla}{blo}\n",
 		"<178>Example<278>: #edit create {bli}{bla}{blo}\n",
@@ -1625,7 +1625,10 @@ struct help_type help_table[] =
 		"<278>         <178>CLASS_LOAD [CLASS]\n"
 		"<278>         <178>CLASS_LOAD [CLASS]\n"
 		"<278>           %0 class name\n"
 		"<278>           %0 class name\n"
 		"\n"
 		"\n"
-
+		"<278>         <128>FORMAT EVENTS\n"
+		"\n"
+		"<278>         <178>REFORMAT <MESSAGE>     <278>Use #return to change MESSAGE\n"
+		"\n"
 		"<278>         <128>GAG EVENTS\n"
 		"<278>         <128>GAG EVENTS\n"
 		"\n"
 		"\n"
 		"<278>         <178>GAG <EVENT>\n"
 		"<278>         <178>GAG <EVENT>\n"
@@ -1771,8 +1774,6 @@ struct help_type help_table[] =
 		"<278>         <178>UNKNOWN COMMAND        <278>%0 raw text\n"
 		"<278>         <178>UNKNOWN COMMAND        <278>%0 raw text\n"
 		"<278>         <178>SIGUSR                 <278>%0 signal\n"
 		"<278>         <178>SIGUSR                 <278>%0 signal\n"
 		"\n"
 		"\n"
-		"<278>         <178>REFORMAT <MESSAGE>     <278>Use #return to change MESSAGE\n"
-		"\n"
 		"<278>         <128>TELNET EVENTS\n"
 		"<278>         <128>TELNET EVENTS\n"
 		"\n"
 		"\n"
 		"<278>         <178>IAC <EVENT>\n"
 		"<278>         <178>IAC <EVENT>\n"
@@ -2536,6 +2537,9 @@ struct help_type help_table[] =
 		"<278>         <178>#line background <argument>\n"
 		"<278>         <178>#line background <argument>\n"
 		"<278>           Prevent new session activation.\n"
 		"<278>           Prevent new session activation.\n"
 		"\n"
 		"\n"
+		"<278>         <178>#line benchmark <argument>\n"
+		"<278>           Argument is executed and the elapsed time is reported after.\n"
+		"\n"
 		"<278>         <178>#line capture <variable> <argument>\n"
 		"<278>         <178>#line capture <variable> <argument>\n"
 		"<278>           Argument is executed and output stored in <variable>.\n"
 		"<278>           Argument is executed and output stored in <variable>.\n"
 		"\n"
 		"\n"
@@ -2625,8 +2629,8 @@ struct help_type help_table[] =
 		"<278>         #list {var} {tokenize} <string>        Create a character list\n"
 		"<278>         #list {var} {tokenize} <string>        Create a character list\n"
 		"\n"
 		"\n"
 		"<278>         The index should be between +1 and the list's size. You can also give\n"
 		"<278>         The index should be between +1 and the list's size. You can also give\n"
-		"<278>         a negative value, in which case -1 equals the last item in the list, -2\n"
-		"<278>         the second last, etc.\n"
+		"<278>         a negative value, in which case -1 equals the last item in the list,\n"
+		"<278>         -2 the second last, etc.\n"
 		"\n"
 		"\n"
 		"<278>         When inserting an item a positive index will prepend the item at the\n"
 		"<278>         When inserting an item a positive index will prepend the item at the\n"
 		"<278>         given index, while a negative index will append the item.\n"
 		"<278>         given index, while a negative index will append the item.\n"
@@ -2644,7 +2648,7 @@ struct help_type help_table[] =
 		"\n"
 		"\n"
 		"<278>         The indexate option prepares a table or list table for order, sort,\n"
 		"<278>         The indexate option prepares a table or list table for order, sort,\n"
 		"<278>         filter, refine, and find operations for the given key. It is similar\n"
 		"<278>         filter, refine, and find operations for the given key. It is similar\n"
-		"<278>         to the SELECT option in SQL.\n"
+		"<278>         to the SELECT option in SQL. The table must have a uniform key layout.\n"
 		"\n"
 		"\n"
 		"<278>         A size of 0 is returned for an empty or non-existent list. You can\n"
 		"<278>         A size of 0 is returned for an empty or non-existent list. You can\n"
 		"<278>         directly access the size of a list using &var[].\n"
 		"<278>         directly access the size of a list using &var[].\n"
@@ -3814,7 +3818,7 @@ struct help_type help_table[] =
 		"<278>         you need to use \\e]68;2;\\a, and they instead trigger the SECURE LINK\n"
 		"<278>         you need to use \\e]68;2;\\a, and they instead trigger the SECURE LINK\n"
 		"<278>         event.\n"
 		"<278>         event.\n"
 		"\n"
 		"\n"
-		"<278>         To creae a link that is not undelined, use \\e]4;24m text \\e]24m.\n"
+		"<278>         To create a link that is not underlined, use \\e]4;24m text \\e]24m.\n"
 		"\n"
 		"\n"
 		"<178>Example<278>: #sub {%* tells %*} {\\e]68;2;EXEC;#cursor set tell %1 \\a\\e[4;24m%0\\e[24m}\n"
 		"<178>Example<278>: #sub {%* tells %*} {\\e]68;2;EXEC;#cursor set tell %1 \\a\\e[4;24m%0\\e[24m}\n"
 		"<178>       <278>  #event {PRESSED SECURE LINK EXEC MOUSE BUTTON ONE} {%4}\n"
 		"<178>       <278>  #event {PRESSED SECURE LINK EXEC MOUSE BUTTON ONE} {%4}\n"
@@ -4103,6 +4107,7 @@ struct help_type help_table[] =
 		"<178>      \\W <278>Match non-letters, numbers, and underscores    [^A-Za-z0-9_]\n"
 		"<178>      \\W <278>Match non-letters, numbers, and underscores    [^A-Za-z0-9_]\n"
 		"<178>      \\x <278>Insert hex character                           \\x\n"
 		"<178>      \\x <278>Insert hex character                           \\x\n"
 		"<178>      \\Z <278>Match end of string                            $\n"
 		"<178>      \\Z <278>Match end of string                            $\n"
+		"<178>      \\\\ <278>Match a backslash                              \\\\\n"
 		"\n"
 		"\n"
 		"<278>         \\s matches one space, \\s+ matches one or multiple spaces, the use\n"
 		"<278>         \\s matches one space, \\s+ matches one or multiple spaces, the use\n"
 		"<278>         of {\\s+} is required for this sequence to work in tintin, \\s by"
 		"<278>         of {\\s+} is required for this sequence to work in tintin, \\s by"

+ 21 - 2
src/list.c

@@ -190,6 +190,25 @@ DO_ARRAY(array_add)
 		list->root = init_list(ses, LIST_VARIABLE, LIST_SIZE);
 		list->root = init_list(ses, LIST_VARIABLE, LIST_SIZE);
 	}
 	}
 
 
+	if (list->root->used)
+	{
+		int numerate = atoi(list->root->list[0]->arg1) == 1 && atoi(list->root->list[list->root->used - 1]->arg1) == list->root->used;
+
+		if (numerate == 0)
+		{
+			for (index = 0 ; index < list->root->used ; index++)
+			{
+				if (atoi(list->root->list[index]->arg1) != index + 1)
+				{
+					break;
+				}
+			}
+			show_error(ses, LIST_COMMAND, "#ERROR: #LIST {%s} ADD: INVALID LIST. INDEX %d IS SET TO {%s}.", var, index + 1, list->root->list[index]->arg1);
+
+			return ses;
+		}
+	}
+
 	index = list->root->used + 1;
 	index = list->root->used + 1;
 
 
 	while (*arg)
 	while (*arg)
@@ -599,7 +618,7 @@ DO_ARRAY(array_indexate)
 			}
 			}
 			else
 			else
 			{
 			{
-				show_error(ses, LIST_COMMAND, "#ERROR: #LIST {%s} INDEXATE: FAILED TO POPULATE INDEX {%s}.", var, list->root->list[cnt]->arg1);
+				show_error(ses, LIST_COMMAND, "#ERROR: #LIST {%s} INDEXATE: ABORTED DUE TO INVALID INDEX {%s}.", var, list->root->list[cnt]->arg1);
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -625,7 +644,7 @@ DO_ARRAY(array_indexate)
 			}
 			}
 			else
 			else
 			{
 			{
-				show_error(ses, LIST_COMMAND, "#ERROR: #LIST {%s} INDEXATE: FAILED TO POPULATE INDEX {%s}.", var, list->root->list[cnt]->arg1);
+				show_error(ses, LIST_COMMAND, "#ERROR: #LIST {%s} INDEXATE: ABORTED DUE TO INVALID INDEX {%s}.", var, list->root->list[cnt]->arg1);
 				break;
 				break;
 			}
 			}
 		}
 		}

+ 16 - 8
src/mapper.c

@@ -367,15 +367,23 @@ struct room_data *create_room(struct session *ses, char *format, ...)
 		newroom->weight = 1;
 		newroom->weight = 1;
 	}
 	}
 
 
-	if (newroom->vnum > 0 && newroom->vnum < ses->map->size)
+	if (newroom->vnum <= 0)
+	{
+		return newroom;
+	}
+
+	if (newroom->vnum < ses->map->size)
 	{
 	{
 		ses->map->room_list[newroom->vnum] = newroom;
 		ses->map->room_list[newroom->vnum] = newroom;
 	}
 	}
 
 
-	if (!HAS_BIT(ses->map->flags, MAP_FLAG_READ) && newroom->vnum)
+	if (gtd->level->debug || !HAS_BIT(ses->map->flags, MAP_FLAG_READ))
 	{
 	{
 		show_message(ses, LIST_PATH, "#MAP CREATE ROOM %5d {%s}.", newroom->vnum, newroom->name);
 		show_message(ses, LIST_PATH, "#MAP CREATE ROOM %5d {%s}.", newroom->vnum, newroom->name);
+	}
 
 
+	if (!HAS_BIT(ses->map->flags, MAP_FLAG_READ))
+	{
 		check_all_events(ses, EVENT_FLAG_MAP, 0, 2, "MAP CREATE ROOM", ntos(newroom->vnum), newroom->name);
 		check_all_events(ses, EVENT_FLAG_MAP, 0, 2, "MAP CREATE ROOM", ntos(newroom->vnum), newroom->name);
 	}
 	}
 
 
@@ -6554,9 +6562,9 @@ DO_MAP(map_info)
 
 
 	if (is_abbrev(arg1, "SAVE"))
 	if (is_abbrev(arg1, "SAVE"))
 	{
 	{
-		set_nest_node_ses(ses, "info[map]", "{DIRECTION}{%d}", ses->map->dir);
-		add_nest_node_ses(ses, "info[map]", "{EXITS}{%d}", exits);
-		add_nest_node_ses(ses, "info[map]", "{FLAGS}{{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}}",
+		set_nest_node_ses(ses, "info[MAP]", "{DIRECTION}{%d}", ses->map->dir);
+		add_nest_node_ses(ses, "info[MAP]", "{EXITS}{%d}", exits);
+		add_nest_node_ses(ses, "info[MAP]", "{FLAGS}{{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}{%s}{%d}}",
 			"ASCIIGRAPHICS", HAS_BIT(ses->map->flags, MAP_FLAG_ASCIIGRAPHICS) != 0,
 			"ASCIIGRAPHICS", HAS_BIT(ses->map->flags, MAP_FLAG_ASCIIGRAPHICS) != 0,
 			"ASCIILENGTH", HAS_BIT(ses->map->flags, MAP_FLAG_ASCIILENGTH) != 0,
 			"ASCIILENGTH", HAS_BIT(ses->map->flags, MAP_FLAG_ASCIILENGTH) != 0,
 			"ASCIIVNUMS", HAS_BIT(ses->map->flags, MAP_FLAG_ASCIIVNUMS) != 0,
 			"ASCIIVNUMS", HAS_BIT(ses->map->flags, MAP_FLAG_ASCIIVNUMS) != 0,
@@ -6570,9 +6578,9 @@ DO_MAP(map_info)
 			"SYMBOLGRAPHICS", HAS_BIT(ses->map->flags, MAP_FLAG_SYMBOLGRAPHICS) != 0,
 			"SYMBOLGRAPHICS", HAS_BIT(ses->map->flags, MAP_FLAG_SYMBOLGRAPHICS) != 0,
 			"TERRAIN", HAS_BIT(ses->map->flags, MAP_FLAG_TERRAIN) != 0,
 			"TERRAIN", HAS_BIT(ses->map->flags, MAP_FLAG_TERRAIN) != 0,
 			"UNICODEGRAPHICS", HAS_BIT(ses->map->flags, MAP_FLAG_UNICODEGRAPHICS) != 0);
 			"UNICODEGRAPHICS", HAS_BIT(ses->map->flags, MAP_FLAG_UNICODEGRAPHICS) != 0);
-		add_nest_node_ses(ses, "info[map]", "{LAST_ROOM}{%d}", ses->map->last_room);
-		add_nest_node_ses(ses, "info[map]", "{ROOMS}{%d}", cnt);
-		add_nest_node_ses(ses, "info[map]", "{ROOMS_MAX}{%d}", ses->map->size);
+		add_nest_node_ses(ses, "info[MAP]", "{LAST_ROOM}{%d}", ses->map->last_room);
+		add_nest_node_ses(ses, "info[MAP]", "{ROOMS}{%d}", cnt);
+		add_nest_node_ses(ses, "info[MAP]", "{ROOMS_MAX}{%d}", ses->map->size);
 
 
 		return;
 		return;
 	}
 	}

+ 13 - 13
src/net.c

@@ -440,7 +440,7 @@ int detect_prompt(struct session *ses, char *original)
 void readmud(struct session *ses)
 void readmud(struct session *ses)
 {
 {
 	char *line, *next_line/*, *strip*/;
 	char *line, *next_line/*, *strip*/;
-	char linebuf[BUFFER_SIZE];
+	char linebuf[STRING_SIZE];
 	int len;
 	int len;
 	struct session *cts;
 	struct session *cts;
 
 
@@ -574,7 +574,7 @@ void readmud(struct session *ses)
 		}
 		}
 		gtd->mud_output_line = linebuf;
 		gtd->mud_output_line = linebuf;
 
 
-		process_mud_output(ses, linebuf, next_line == NULL);
+		process_one_line(ses, linebuf, next_line == NULL);
 
 
 		gtd->mud_output_line = gtd->mud_output_buf + gtd->mud_output_len;
 		gtd->mud_output_line = gtd->mud_output_buf + gtd->mud_output_len;
 	}
 	}
@@ -623,7 +623,7 @@ void process_more_output(struct session *ses, char *append, int prompt)
 	str_cpy(&ses->more_output, "");
 	str_cpy(&ses->more_output, "");
 	ses->check_output = 0;
 	ses->check_output = 0;
 
 
-	process_mud_output(ses, line, prompt);
+	process_one_line(ses, line, prompt);
 
 
 	if (readmud == 0)
 	if (readmud == 0)
 	{
 	{
@@ -636,19 +636,19 @@ void process_more_output(struct session *ses, char *append, int prompt)
 	}
 	}
 }
 }
 
 
-void process_mud_output(struct session *ses, char *linebuf, int prompt)
+void process_one_line(struct session *ses, char *linebuf, int prompt)
 {
 {
-	char line[STRING_SIZE], temp[STRING_SIZE];
+	char temp[STRING_SIZE];
 	int str_len, raw_len;
 	int str_len, raw_len;
 
 
-	push_call("process_mud_output(%p,%p,%d)",ses,linebuf,prompt);
+	push_call("process_one_line(%p,%p,%d)",ses,linebuf,prompt);
 
 
 	raw_len = strlen(linebuf);
 	raw_len = strlen(linebuf);
-	str_len = strip_vt102_codes(linebuf, line);
+	str_len = strip_vt102_codes(linebuf, temp);
 
 
-	check_all_events(ses, SUB_SEC|EVENT_FLAG_OUTPUT, 0, 2, "RECEIVED LINE", linebuf, line);
+	check_all_events(ses, SUB_SEC|EVENT_FLAG_OUTPUT, 0, 2, "RECEIVED LINE", linebuf, temp);
 
 
-	if (check_all_events(ses, SUB_SEC|EVENT_FLAG_CATCH, 0, 2, "CATCH RECEIVED LINE", linebuf, line))
+	if (check_all_events(ses, SUB_SEC|EVENT_FLAG_CATCH, 0, 2, "CATCH RECEIVED LINE", linebuf, temp))
 	{
 	{
 		pop_call();
 		pop_call();
 		return;
 		return;
@@ -656,9 +656,9 @@ void process_mud_output(struct session *ses, char *linebuf, int prompt)
 
 
 	if (str_len && prompt)
 	if (str_len && prompt)
 	{
 	{
-		check_all_events(ses, SUB_SEC|EVENT_FLAG_OUTPUT, 0, 4, "RECEIVED PROMPT", linebuf, line, ntos(raw_len), ntos(str_len));
+		check_all_events(ses, SUB_SEC|EVENT_FLAG_OUTPUT, 0, 4, "RECEIVED PROMPT", linebuf, temp, ntos(raw_len), ntos(str_len));
 
 
-		if (check_all_events(ses, SUB_SEC|EVENT_FLAG_CATCH, 0, 4, "CATCH RECEIVED PROMPT", linebuf, line, ntos(raw_len), ntos(str_len)))
+		if (check_all_events(ses, SUB_SEC|EVENT_FLAG_CATCH, 0, 4, "CATCH RECEIVED PROMPT", linebuf, temp, ntos(raw_len), ntos(str_len)))
 		{
 		{
 			pop_call();
 			pop_call();
 			return;
 			return;
@@ -667,11 +667,11 @@ void process_mud_output(struct session *ses, char *linebuf, int prompt)
 
 
 	if (HAS_BIT(ses->config_flags, CONFIG_FLAG_COLORPATCH))
 	if (HAS_BIT(ses->config_flags, CONFIG_FLAG_COLORPATCH))
 	{
 	{
-		sprintf(line, "%s%s%s", ses->color_patch, linebuf, "\e[0m");
+		sprintf(temp, "%s%s%s", ses->color_patch, linebuf, "\e[0m");
 
 
 		get_color_codes(ses->color_patch, linebuf, ses->color_patch, GET_ALL);
 		get_color_codes(ses->color_patch, linebuf, ses->color_patch, GET_ALL);
 
 
-		linebuf = line;
+		strcpy(linebuf, temp);
 	}
 	}
 
 
 	check_one_line(ses, linebuf);   /* changes linebuf */
 	check_one_line(ses, linebuf);   /* changes linebuf */

+ 25 - 32
src/regex.c

@@ -252,23 +252,14 @@ int get_regex_range(char *in, char *out, int *var, int *arg)
 	pti = in;
 	pti = in;
 	ptr = range;
 	ptr = range;
 
 
-	switch (*pti)
+	if (in[-2] != '!')
 	{
 	{
-		case '0':
-		case '1':
-		case '2':
-		case '3':
-		case '4':
-		case '5':
-		case '6':
-		case '7':
-		case '8':
-		case '9':
-			*ptr++ = *pti++;
-			break;
+		*pto++ = '(';
+	}
 
 
-		default:
-			goto end;
+	if (*pti < '0' || *pti > '9')
+	{
+		goto end;
 	}
 	}
 
 
 	while (*pti)
 	while (*pti)
@@ -302,46 +293,46 @@ int get_regex_range(char *in, char *out, int *var, int *arg)
 				continue;
 				continue;
 
 
 			case 'a':
 			case 'a':
-				pto += sprintf(pto, "%s", "([^\\0]");
+				pto += sprintf(pto, "%s", "[^\\0]");
 				break;
 				break;
 			case 'A':
 			case 'A':
-				pto += sprintf(pto, "%s", "(\\n");
+				pto += sprintf(pto, "%s", "\\n");
 				break;
 				break;
 			case 'c':
 			case 'c':
-				pto += sprintf(pto, "%s", "((?:\\e\\[[0-9;]*m)");
+				pto += sprintf(pto, "%s", "(?:\\e\\[[0-9;]*m)");
 				break;
 				break;
 			case 'd':
 			case 'd':
-				pto += sprintf(pto, "%s", "([0-9]");
+				pto += sprintf(pto, "%s", "[0-9]");
 				break;
 				break;
 			case 'D':
 			case 'D':
-				pto += sprintf(pto, "%s", "([^0-9]");
+				pto += sprintf(pto, "%s", "[^0-9]");
 				break;
 				break;
 			case 'p':
 			case 'p':
-				pto += sprintf(pto, "%s", "([\\x20-\\xfe]");
+				pto += sprintf(pto, "%s", "[\\x20-\\xfe]");
 				break;
 				break;
 			case 'P':
 			case 'P':
-				pto += sprintf(pto, "%s", "([^\\x20-\\xfe]");
+				pto += sprintf(pto, "%s", "[^\\x20-\\xfe]");
 				break;
 				break;
 			case 's':
 			case 's':
-				pto += sprintf(pto, "%s", "(\\s");
+				pto += sprintf(pto, "%s", "\\s");
 				break;
 				break;
 			case 'S':
 			case 'S':
-				pto += sprintf(pto, "%s", "(\\S");
+				pto += sprintf(pto, "%s", "\\S");
 				break;
 				break;
 			case 'u':
 			case 'u':
-				pto += sprintf(pto, "%s", "((?:[\\x00-\\x7F]|[\\xC0-\\xF4][\\x80-\\xC0]{1,3})");
+				pto += sprintf(pto, "%s", "(?:[\\x00-\\x7F]|[\\xC0-\\xF4][\\x80-\\xC0]{1,3})");
 				break;
 				break;
 			case 'U':
 			case 'U':
-				pto += sprintf(pto, "%s", "([\\xF5-\\xFF]");
+				pto += sprintf(pto, "%s", "[\\xF5-\\xFF]");
 				break;
 				break;
 			case 'w':
 			case 'w':
-				pto += sprintf(pto, "%s", "(\\w");
+				pto += sprintf(pto, "%s", "\\w");
 				break;
 				break;
 			case 'W':
 			case 'W':
-				pto += sprintf(pto, "%s", "(\\W");
+				pto += sprintf(pto, "%s", "\\W");
 				break;
 				break;
 			case '*':
 			case '*':
-				pto += sprintf(pto, "%s", "(.");
+				pto += sprintf(pto, "%s", ".");
 				break;
 				break;
 
 
 			default:
 			default:
@@ -350,7 +341,7 @@ int get_regex_range(char *in, char *out, int *var, int *arg)
 		*ptr = 0;
 		*ptr = 0;
 		pti++;
 		pti++;
 
 
-		pto += sprintf(pto, "{%s}%s", range, *pti ? "?)" : ")");
+		pto += sprintf(pto, "{%s}%s%s", range, *pti ? "?" : "", in[-2] != '!' ? ")" : "");
 
 
 		return pti - in;
 		return pti - in;
 	}
 	}
@@ -360,7 +351,8 @@ int get_regex_range(char *in, char *out, int *var, int *arg)
 	{
 	{
 		gtd->args[next_arg(*var)] = next_arg(*arg);
 		gtd->args[next_arg(*var)] = next_arg(*arg);
 	}*/
 	}*/
-	strcpy(out, *pti ? "(.+?)" : "(.+)");
+
+	pto += sprintf(pto, "%s%s", *in ? ".+?" : ".+", in[-2] != '!' ? ")" : "");
 
 
 	return 0;
 	return 0;
 }
 }
@@ -789,7 +781,7 @@ int tintin_regexp(struct session *ses, pcre *nodepcre, char *str, char *exp, int
 								break;
 								break;
 
 
 							case '+':
 							case '+':
-								pti += 3 + get_regex_range(&pti[3], pto, NULL, NULL);
+								pti += 3 + get_regex_range(pti + 3, pto, NULL, NULL);
 								pto += strlen(pto);
 								pto += strlen(pto);
 								break;
 								break;
 
 
@@ -1138,6 +1130,7 @@ pcre *tintin_regexp_compile(struct session *ses, struct listnode *node, char *ex
 
 
 							case '+':
 							case '+':
 								pti += 3 + get_regex_range(&pti[3], pto, NULL, NULL);
 								pti += 3 + get_regex_range(&pti[3], pto, NULL, NULL);
+								pto += strlen(pto);
 								break;
 								break;
 
 
 							case '.':
 							case '.':

+ 1 - 1
src/scan.c

@@ -591,7 +591,7 @@ DO_SCAN(scan_txt)
 		}
 		}
 		line[BUFFER_SIZE / 2] = 0;
 		line[BUFFER_SIZE / 2] = 0;
 
 
-		process_mud_output(ses, line, FALSE);
+		process_one_line(ses, line, FALSE);
 
 
 		if (HAS_BIT(ses->flags, SES_FLAG_SCANABORT))
 		if (HAS_BIT(ses->flags, SES_FLAG_SCANABORT))
 		{
 		{

+ 6 - 6
src/show.c

@@ -157,7 +157,7 @@ void show_message(struct session *ses, int index, char *format, ...)
 
 
 	display:
 	display:
 
 
-	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_SYSTEM, 1, 0, "REFORMAT %s", format))
+	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_REFORMAT, 1, 0, "REFORMAT %s", format))
 	{
 	{
 		format = get_variable_def(ses, "result", format);
 		format = get_variable_def(ses, "result", format);
 	}
 	}
@@ -216,7 +216,7 @@ void show_error(struct session *ses, int index, char *format, ...)
 
 
 	push_call("show_error(%p,%p,%p)",ses,index,format);
 	push_call("show_error(%p,%p,%p)",ses,index,format);
 
 
-	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_SYSTEM, 1, 0, "REFORMAT %s", format))
+	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_REFORMAT, 1, 0, "REFORMAT %s", format))
 	{
 	{
 		format = get_variable_def(ses, "result", format);
 		format = get_variable_def(ses, "result", format);
 	}
 	}
@@ -288,7 +288,7 @@ void show_debug(struct session *ses, int index, char *format, ...)
 		return;
 		return;
 	}
 	}
 
 
-	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_SYSTEM, 1, 0, "REFORMAT %s", format))
+	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_REFORMAT, 1, 0, "REFORMAT %s", format))
 	{
 	{
 		format = get_variable_def(ses, "result", format);
 		format = get_variable_def(ses, "result", format);
 	}
 	}
@@ -451,7 +451,7 @@ void tintin_header(struct session *ses, int width, char *format, ...)
 		return;
 		return;
 	}
 	}
 
 
-	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_SYSTEM, 1, 0, "REFORMAT %s", format))
+	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_REFORMAT, 1, 0, "REFORMAT %s", format))
 	{
 	{
 		format = get_variable_def(ses, "result", format);
 		format = get_variable_def(ses, "result", format);
 	}
 	}
@@ -500,7 +500,7 @@ void tintin_printf(struct session *ses, char *format, ...)
 
 
 	push_call("tintin_printf(%p,%p,...)",ses,format);
 	push_call("tintin_printf(%p,%p,...)",ses,format);
 
 
-	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_SYSTEM, 1, 0, "REFORMAT %s", format))
+	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_REFORMAT, 1, 0, "REFORMAT %s", format))
 	{
 	{
 		format = get_variable_def(ses, "result", format);
 		format = get_variable_def(ses, "result", format);
 	}
 	}
@@ -524,7 +524,7 @@ void tintin_printf2(struct session *ses, char *format, ...)
 
 
 	push_call("tintin_printf2(%p,%p,...)",ses,format);
 	push_call("tintin_printf2(%p,%p,...)",ses,format);
 
 
-	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_SYSTEM, 1, 0, "REFORMAT %s", format))
+	if (HAS_BIT(gtd->event_flags, EVENT_FLAG_REFORMAT) && check_all_events(ses, EVENT_FLAG_REFORMAT, 1, 0, "REFORMAT %s", format))
 	{
 	{
 		format = get_variable_def(ses, "result", format);
 		format = get_variable_def(ses, "result", format);
 	}
 	}

+ 8 - 1
src/substitute.c

@@ -1621,7 +1621,14 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 						{
 						{
 							*pto++ = *pti++;
 							*pto++ = *pti++;
 						}
 						}
-						pti++;
+						if (is_digit(pti[1]))
+						{
+							pti++;
+						}
+						else
+						{
+							*pto++ = *pti++;
+						}
 					}
 					}
 					else
 					else
 					{
 					{

+ 3 - 5
src/system.c

@@ -95,7 +95,7 @@ DO_COMMAND(do_run)
 
 
 DO_COMMAND(do_script)
 DO_COMMAND(do_script)
 {
 {
-	char *cptr, buf[BUFFER_SIZE], var[BUFFER_SIZE], tmp[BUFFER_SIZE];
+	char *cptr, buf[BUFFER_SIZE], tmp[BUFFER_SIZE];
 	FILE *script;
 	FILE *script;
 	int index;
 	int index;
 
 
@@ -139,7 +139,7 @@ DO_COMMAND(do_script)
 
 
 		if (script)
 		if (script)
 		{
 		{
-			var[0] = 0;
+			set_nest_node_ses(ses, arg1, "");
 
 
 			while (fgets(buf, BUFFER_SIZE - 1, script))
 			while (fgets(buf, BUFFER_SIZE - 1, script))
 			{
 			{
@@ -152,11 +152,9 @@ DO_COMMAND(do_script)
 
 
 				substitute(ses, buf, tmp, SUB_SEC);
 				substitute(ses, buf, tmp, SUB_SEC);
 
 
-				cat_sprintf(var, "{%d}{%s}", index++, tmp);
+				add_nest_node_ses(ses, arg1, "{%d}{%s}", index++, tmp);
 			}
 			}
 
 
-			set_nest_node_ses(ses, arg1, "%s", var);
-
 			pclose(script);
 			pclose(script);
 		}
 		}
 		else
 		else

+ 1 - 1
src/tintin.h

@@ -2518,7 +2518,7 @@ extern void write_line_mud(struct session *ses, char *line, int size);
 extern int read_buffer_mud(struct session *ses);
 extern int read_buffer_mud(struct session *ses);
 extern void readmud(struct session *ses);
 extern void readmud(struct session *ses);
 extern void process_more_output(struct session *ses, char *append, int prompt);
 extern void process_more_output(struct session *ses, char *append, int prompt);
-extern void process_mud_output(struct session *ses, char *linebuf, int prompt);
+extern void process_one_line(struct session *ses, char *linebuf, int prompt);
 
 
 #endif
 #endif
 
 

+ 12 - 7
src/validate

@@ -1,11 +1,11 @@
 #!./tt++ -G
 #!./tt++ -G
 
 
-#nop   1: #math
-#nop   2: #line
-#nop   3: #return
-#nop   4: #buffer
-#nop   5: #switch
-#nop   6: #class
+#0   1: #math
+#0   2: #line
+#0   3: #return
+#0   4: #buffer
+#0   5: #switch
+#0   6: #class
 
 
 
 
 #line sub arg #var arg {%0}
 #line sub arg #var arg {%0}
@@ -510,7 +510,12 @@ sethash blo hello
 
 
 #regex {blibla} {%10bli%+3..3a} {#if {"&11" !== "bla"} {error 34.1: regex argument indexing (&11)}}
 #regex {blibla} {%10bli%+3..3a} {#if {"&11" !== "bla"} {error 34.1: regex argument indexing (&11)}}
 #regex {blibla} {%.%+%.%*}      {#if {"&4" !== "bla"}  {error 34.2: regex argument indexing (&4)}}
 #regex {blibla} {%.%+%.%*}      {#if {"&4" !== "bla"}  {error 34.2: regex argument indexing (&4)}}
-#regex {blibla} {%99bli%+3..3*}      {#if {"&99" !== "bla"} {error 34.3: regex argument indexing (&99)}}
+#regex {blibla} {%99bli%+3..3*} {#if {"&99" !== "bla"} {error 34.3: regex argument indexing (&99)}}
+#regex {blibla} {bli%!+}        {#if {"&1" !== ""}     {error 34.4: regex argument indexing (&1)}}
+#regex {blibla} {%+2*%+3*}      {#if {"&2" !== "ibl"}  {error 34.5: regex argument indexing (&2)}}
+#regex {blibla} {%+1..2*}       {#if {"&1" !== "bl"}   {error 34.6: regex argument indexing (&1)}}
+#regex {blibla} {%!+5*%*}       {#if {"&1" !== "a"}    {error 34.7: regex argument indexing (&1)}}
+#regex {blibla} {%+%*}          {#if {"&1" !== "b"}    {error 34.8: regex argument indexing (&1)}}
 
 
 #0 )=-=( ERROR 35 )=-=( 0#
 #0 )=-=( ERROR 35 )=-=( 0#