Scandum 5 lat temu
rodzic
commit
b36056b325
33 zmienionych plików z 1054 dodań i 1256 usunięć
  1. 2 3
      NEWS
  2. 32 0
      SCRIPTS
  3. 15 57
      TODO
  4. 12 3
      mods/igr.mods
  5. 1 1
      src/buffer.c
  6. 39 176
      src/chat.c
  7. 39 0
      src/class.c
  8. 60 1
      src/command.c
  9. 97 0
      src/draw.c
  10. 14 9
      src/files.c
  11. 19 44
      src/gui.h
  12. 10 6
      src/help.c
  13. 13 1
      src/input.c
  14. 127 99
      src/list.c
  15. 11 7
      src/main.c
  16. 3 3
      src/mapper.c
  17. 13 1
      src/misc.c
  18. 44 15
      src/nest.c
  19. 6 6
      src/net.c
  20. 36 0
      src/scan.c
  21. 266 4
      src/screen.c
  22. 6 0
      src/session.c
  23. 0 1
      src/split.c
  24. 23 23
      src/substitute.c
  25. 0 340
      src/tables.c
  26. 29 91
      src/text.c
  27. 27 322
      src/tintin.h
  28. 2 2
      src/tokenize.c
  29. 1 1
      src/update.c
  30. 41 13
      src/utf8.c
  31. 1 1
      src/utils.c
  32. 55 10
      src/variable.c
  33. 10 16
      src/vt102.c

+ 2 - 3
NEWS

@@ -97,7 +97,7 @@ TinTin++ 2.01.90
 
     #prompt {text} {substitution} will stay the same.
     #prompt {text} {substitution} {0} will become invalid.
-    #prompt {test] {substitution} {1} will write to the top line.
+    #prompt {text] {substitution} {1} will write to the top line.
     #prompt {text} {substitution} {-1} will write to the bottom / input line.
     #prompt {text} {substitution} {-2} will write to the 2nd line from the
        bottom, which is the default split line.
@@ -216,7 +216,7 @@ TinTin++ 1.99.1
 TinTin++ 1.96.6
 ---------------
 
-    #PATHDIR is now specificly designed to hold a direction, the opposite
+    #PATHDIR is now specifically designed to hold a direction, the opposite
     direction, and the vector of said direction for the #MAP command.
 
 
@@ -289,7 +289,6 @@ TinTin++ 1.88.0
 
 01) #FORMAT has been introduced and replaces a wide variety of commands.
 
-
 02) #MESSAGE, #CONFIG, #IGNORE, #DEBUG are all you need to configure tintin,
     changes made with #CONFIG are written to file with #WRITE.
 

+ 32 - 0
SCRIPTS

@@ -313,6 +313,38 @@
 
 #substitute {{\b[a-zA-Z]+\b}} {@spellcheck{%1}}
 
+#nop -------------------------------------------------------------------------
+#nop This function and substitution will add a speed reader to the split line
+#nop -------------------------------------------------------------------------
+
+#split
+
+#function spellcheck
+{
+        #format result %S %1;
+        #if {$result == 0}
+        {
+                #var result %1
+        };
+        #else
+        {
+                #var result <118>%1<900>
+        };
+        #list speedread ins -1 {$result}
+}
+
+#substitute {{\b[a-zA-Z]+\b}} {@spellcheck{%1}}
+
+#tick {speedread}
+{
+        #if {&{speedread[]}}
+        {
+                #draw tile -2 1 -2 20 {$speedread[1]};
+                #list speedread delete 1
+        }
+}
+{0.1}
+
 #nop -------------------------------------------------------------------------
 #nop This function tests the random number engine
 #nop -------------------------------------------------------------------------

+ 15 - 57
TODO

@@ -1,17 +1,17 @@
 * BUGS
 
-  - might be \ handling issues in #format %w
+  - Look into escaped color codes in zmp, possibly msdp
+
+  - See about making @$var{} work.
+
+  - See about turning window close into a program termination event.
 
   - finish BUFFER_SIZE replacement.
 
   - WSL faq: #system cmd.exe /c start notepad
 
-  - str_ify ses->more_output
-
   - update msdp scripts with #line msdp feature
 
-  - update the FAQ, and online manual
-
   - refresh input on session switch
 
   - swap arg1, arg2, arg for do_port
@@ -27,8 +27,6 @@
 
 * STUFF THAT IS PROBABLY GONNA GET DONE
 
-  - Editor
-
   - Finish port proxy support: resizing, input, security
 
   - look into transparent drawing
@@ -53,10 +51,7 @@
   - tabbing on directory structure.
   - tabbing on dictionary
 
-  - Enhance #scan with a scan of the directory structure.
-
   - #map list {<exits>} breaks on rooms that have e mapped to eu.
-
   - finish landmarks
   - map sandbox mode support (flags to disable saving?)
   - add ghosting to fix #map flag nofollow exit cmd issues?
@@ -88,16 +83,13 @@
     #draw titanic
 
   - proper vt100 skip detection for improper color codes.
-  - look into VT100 / #split hybrid mode.
 
-  - I'll look and see if I can make { match both a { and \x7B as it's an annoying issue to debug.
+  - Make { match both a { and \x7B as it's an annoying issue to debug.
 
   - Add VT100 filter to make outside sources respect terminal size constraints, also needed to run bash in vsplit mode.
 
   - Remote script loading
 
-  - make #path load bi-directional.
-
   - add class specific debug
   - better class event and class size handling ?
 
@@ -109,8 +101,6 @@
 
   - Add #log delete/remove option.
 
-  - See about filling COMMAND_LIST table.
-
   - See about adding SESSIONS to the list table.
 
   - Add debugger to syntax highlighter, substitution highlighing, 256 color support, and variable expansion.
@@ -130,16 +120,8 @@
 
   - Add JSON support to #scan
 
-  - fix \x00 showme
-
-  - support strikethrough html logging.
-
   - see if #break 2 is possible, maybe #continue 2 as well.
 
-  - Add options to #cursor to implement custom behaviour.
-
-  - toggle global flags with #message all on, #debug all on, etc.
-
   - http://tintin.sourceforge.net/board/viewtopic.php?p=9625 (map undo issue) (not a big issue)
 
   - http://tintin.sourceforge.net/board/viewtopic.php?t=2339 (map area data)
@@ -194,6 +176,8 @@
 
   - Allow converting tt++ scripts to C.
 
+  - session proxies
+
 --------------------------------------------------------------------------------
 
 * STUFF THAT MIGHT BE IMPLEMENTED
@@ -210,13 +194,9 @@
 
   - SGA disabling
 
-  - CHARSET TELOPT support.
-
   - BINARY TELOPT support.
 
-  - Split pane scrollback (event system?)
-
-  - add #line gag {lines} option or #lines {lines} {gag}.
+  - add #line gag {lines} option
 
   - Add something like #log append $dir/logs/log.txt {%D %H:%M:%S}
 
@@ -243,8 +223,6 @@
 
   - There's a bug with prompt repetitions with packet patch set.
 
-  - garbage collection for deleted nodes.
-
   - Deal with escaping { } / ; in #script variables.
 
   - Make tintin char setting by session instead of global.
@@ -291,36 +269,21 @@
 
 --------------------------------------------------------------------------------
 
-
-* MISCELANEOUS
-
-- look into Launchpad PPA
-
---------------------------------------------------------------------------------
-
 * STUFF FOR A RAINY DAY
 
-- nestable functions
-
-- Buffer safe strings.
-
 - Fix up ipv6 support in chat.
 
 - Look into packet defragmentation for chat.
 
-- Color code compression, particularly useful with vt map drawing.
-
-- Events for prompt lines.
-
-- Lua scripting
-
 - Look into using speech-dispatcher for text to speech.
 
-- MXP script http://tintin.sourceforge.net/board/viewtopic.php?t=1396
-
 - Add %U (upper) %L (lower) support.
   check https://www.boost.org/doc/libs/1_50_0/libs/regex/doc/html/boost_regex/syntax/basic_extended.html
 
+- cursor extension for vim
+
+- interactive script tutorial
+
 -------------------------------------------------------------------------------
 
 * STUFF I'M NOT SURE ABOUT
@@ -331,14 +294,9 @@
 
 -------------------------------------------------------------------------------
 
-* NEW STUFF
+* STUFF THAT WON'T BE IMPLEMENTED
 
-- xterm mouse
-- path improvements
-- remote session
-- map sharing
-- cursor extension for vim
-- interactive script tutorial
+- Lua or any other scripting language, focus is on developing tintin scripting.
 
 -------------------------------------------------------------------------------
 

+ 12 - 3
mods/igr.mods

@@ -1,3 +1,15 @@
+Oct 2020        2.02.05
+------------------------------------------------------------------------------
+
+variables.c     Added the #unlocal command.
+
+files.c         Table variables are now written to file with indentation.
+
+utf8.c          Decreased the memory footprint of BIG-5 / GBK-1 support.
+
+variable.c      The VARIABLE UPDATE event now reports the path in the %2
+                argument.
+
 May 2020        2.02.04
 ------------------------------------------------------------------------------
 
@@ -151,9 +163,6 @@ draw.c          Added the SCALED drawing option. When used the size of the
                 square is increased depending on the size of the inputted
                 text.
 
-documentation   Added docs/link.txt file with the initial documentation for
-                link handling.
-
 buffer.c        #buffer find now places the found keyword at the top instead
                 of at the bottom of the page.
 

+ 1 - 1
src/buffer.c

@@ -355,7 +355,7 @@ void buffer_print(struct session *ses, int index, int start, int end)
 	{
 		if (HAS_BIT(ses->flags, SES_FLAG_PRINTBUFFER) || ses->scroll->line == ses->scroll->used - 1)
 		{
-			word_wrap_split(ses, ses->scroll->input, temp, ses->wrap, 0, 1, WRAP_FLAG_NONE, &height, &width);
+			word_wrap_split(ses, ses->scroll->input, temp, ses->wrap, 0, 1, WRAP_FLAG_SPLIT, &height, &width);
 		}
 		else
 		{

+ 39 - 176
src/chat.c

@@ -70,9 +70,11 @@ extern struct chat_data *find_group(char *arg);
 
 DO_COMMAND(do_chat)
 {
-	char cmd[BUFFER_SIZE];
+	char *cmd;
 	int cnt;
 
+	cmd = str_alloc_stack(0);
+
 	arg = get_arg_in_braces(ses, arg, cmd, GET_ONE);
 
 	if (*cmd == 0)
@@ -262,12 +264,12 @@ int chat_new(int s)
 	return 0;
 }
 
-// getaddrinfo should be universally supported anno 2019, if not, let me know.
+// getaddrinfo should be universally supported anno 2020
 
 void *threaded_chat_call(void *arg)
 {
 	int sock, error;
-	char host[BUFFER_SIZE], port[BUFFER_SIZE], name[BUFFER_SIZE];
+	char host[NAME_SIZE], port[NAME_SIZE], name[NAME_SIZE];
 	struct addrinfo *address;
 	static struct addrinfo hints;
 	struct chat_data *new_buddy;
@@ -437,165 +439,6 @@ void *threaded_chat_call(void *arg)
 	return NULL;
 }
 
-/*
-void *threaded_chat_call(void *arg)
-{
-	int sock, dig;
-	char host[BUFFER_SIZE], port[BUFFER_SIZE], name[BUFFER_SIZE];
-	struct sockaddr_in dest_addr;
-	struct chat_data *new_buddy;
-	struct timeval to;
-	fd_set wds, rds;
-
-	chat_printf("Attempting to call %s ...", arg);
-
-	to.tv_sec = CALL_TIMEOUT;
-	to.tv_usec = 0;
-
-	arg = (void *) get_arg_in_braces(gtd->ses, (char *) arg, host, GET_ONE);
-	arg = (void *) get_arg_in_braces(gtd->ses, (char *) arg, port, GET_ONE);
-
-	if (*port == 0)
-	{
-		sprintf(port, "%d", DEFAULT_PORT);
-	}
-
-	if (sscanf(host, "%d.%d.%d.%d", &dig, &dig, &dig, &dig) == 4)
-	{
-		dest_addr.sin_addr.s_addr = inet_addr(host);
-	}
-	else
-	{
-		struct hostent *hp;
-		int addr, address[4];
-
-		if ((hp = gethostbyname(host)) == NULL)
-		{
-			chat_printf("Failed to call %s, unknown host.", host);
-
-			return NULL;
-		}
-		memcpy((char *)&dest_addr.sin_addr, hp->h_addr, sizeof(dest_addr.sin_addr));
-
-		addr = ntohl(dest_addr.sin_addr.s_addr);
-
-		address[0] = ( addr >> 24 ) & 0xFF ; 
-		address[1] = ( addr >> 16 ) & 0xFF ;
-		address[2] = ( addr >>  8 ) & 0xFF ;
-		address[3] = ( addr       ) & 0xFF ;
-
-		sprintf(host, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]);
-	}
-
-	if (is_number(port))
-	{
-		dest_addr.sin_port = htons(atoi(port));
-	}
-	else
-	{
-		chat_printf("The port should be a number.");
-
-		return NULL;
-	}
-
-	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-	{
-		syserr_printf(gtd->ses, "old_threaded_chat_call: socket");
-
-		return NULL;
-	}
-
-	dest_addr.sin_family = AF_INET;
-
-	if (connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) != 0)
-	{
-		chat_printf("Failed to connect to %s:%s", host, port);
-
-		close(sock);
-
-		return NULL;
-	}
-
-	FD_ZERO(&wds);
-
-	FD_SET(sock, &wds);
-
-	if (select(FD_SETSIZE, NULL, &wds, NULL, &to) == -1)
-	{
-		chat_printf("Failed to connect to %s %s", host, port);
-
-		close(sock);
-
-		return NULL;
-	}
-
-	if (!FD_ISSET(sock, &wds))
-	{
-		chat_printf("Connection timed out.");
-
-		close(sock);
-
-		return NULL;
-	}
-
-	new_buddy = (struct chat_data *) calloc(1, sizeof(struct chat_data));
-
-	new_buddy->fd       = sock;
-	new_buddy->port     = atoi(port);
-
-	new_buddy->download = strdup("");
-	new_buddy->group    = strdup("");
-	new_buddy->ip       = strdup(host);
-	new_buddy->name     = strdup("");
-	new_buddy->version  = strdup("");
-
-	strip_vt102_codes(gtd->chat->name, name);
-
-	chat_socket_printf(new_buddy, "CHAT:%s\n%s%-5u", name, gtd->chat->ip, gtd->chat->port);
-
-	chat_printf("Socket connected, negotiating protocol...");
-
-	FD_ZERO(&rds);
-	FD_SET(sock, &rds);
-
-	to.tv_sec  = CALL_TIMEOUT;
-	to.tv_usec = 0;
-
-	if (select(FD_SETSIZE, &rds, NULL, NULL, &to) == -1)
-	{
-		close_chat(new_buddy, FALSE);
-
-		return NULL;
-	}
-
-	if (process_chat_input(new_buddy) == -1)
-	{
-		FD_CLR(new_buddy->fd, &rds);
-		close_chat(new_buddy, FALSE);
-
-		return NULL;
-	}
-
-	if (gtd->chat == NULL || *new_buddy->name == 0)
-	{
-		close_chat(new_buddy, FALSE);
-	}
-	else
-	{
-		if (fcntl(sock, F_SETFL, O_NDELAY|O_NONBLOCK) == -1)
-		{
-			syserr_printf(gtd->ses, "chat_new: fcntl O_NDELAY|O_NONBLOCK");
-		}
-
-		LINK(new_buddy, gtd->chat->next, gtd->chat->prev);
-		chat_printf("Connection made to %s.", new_buddy->name);
-	}
-
-	return NULL;
-}
-
-*/
-
 #ifdef HAVE_LIBPTHREAD
 
 DO_CHAT(chat_call)
@@ -624,8 +467,14 @@ DO_CHAT(chat_call)
 
 DO_CHAT(chat_call)
 {
-	char buf[BUFFER_SIZE];
+	char buf[NAME_SIZE];
+
+	if (strlen(arg1) + strlen(arg2) + 5 >= 200)
+	{
+		chat_printf("The call arguments {%s} and {%s} exceed the maximum length of 200 characters.", arg1, arg2);
 
+		return;
+	}
 	sprintf(buf, "{%s} {%s}", arg1, arg2);
 
 	threaded_chat_call((void *) buf);
@@ -711,22 +560,26 @@ void process_chat_connections(fd_set *read_set, fd_set *write_set, fd_set *exc_s
 
 void chat_socket_printf(struct chat_data *buddy, char *format, ...)
 {
-	char buf[BUFFER_SIZE];
+	char *buf;
+	int len;
 	va_list args;
 
 	va_start(args, format);
-	vsnprintf(buf, BUFFER_SIZE / 3, format, args);
+
+	len = vasprintf(&buf, format, args);
+
 	va_end(args);
 
 	if (!HAS_BIT(buddy->flags, CHAT_FLAG_LINKLOST))
 	{
-		if (write(buddy->fd, buf, strlen(buf)) < 0)
+		if (write(buddy->fd, buf, len) < 0)
 		{
 			chat_printf("%s went link lost.", buddy->name);
 
 			SET_BIT(buddy->flags, CHAT_FLAG_LINKLOST);
 		}
 	}
+	free(buf);
 }
 
 void chat_printf(char *format, ...)
@@ -782,12 +635,13 @@ void chat_printf(char *format, ...)
 int process_chat_input(struct chat_data *buddy)
 {
 	struct chat_data *node;
-
-	char buf[BUFFER_SIZE], name[BUFFER_SIZE], temp[BUFFER_SIZE], ip[BUFFER_SIZE], *sep;
+	char *buf, *name, *temp, *ip, *sep;
 	int size;
 
 	push_call("process_chat_input(%p)",buddy);
 
+	buf = str_alloc_stack(0);
+
 	size = read(buddy->fd, buf, BUFFER_SIZE / 3);
 
 	if (size <= 0)
@@ -796,6 +650,10 @@ int process_chat_input(struct chat_data *buddy)
 		return -1;
 	}
 
+	name = str_alloc_stack(0);
+	temp = str_alloc_stack(0);
+	ip   = str_alloc_stack(0);
+
 	buf[size] = 0;
 
 	if (!strncmp(buf, "CHAT:", 5))
@@ -915,12 +773,14 @@ int process_chat_input(struct chat_data *buddy)
 
 void get_chat_commands(struct chat_data *buddy, char *buf, int len)
 {
-	char txt[BUFFER_SIZE];
+	char *txt;
 	unsigned char *pto, *pti, ptc;
 	int size;
 
 	push_call("get_chat_commands(%s,%d,%s)",buddy->name,len,buf);
 
+	txt = str_alloc_stack(0);
+
 	pti = (unsigned char *) buf;
 	pto = (unsigned char *) txt;
 
@@ -1094,14 +954,12 @@ void get_chat_commands(struct chat_data *buddy, char *buf, int len)
 
 void chat_name_change(struct chat_data *buddy, char *txt)
 {
-	char temp[BUFFER_SIZE], name[BUFFER_SIZE];
+	char name[BUFFER_SIZE];
 	struct chat_data *node;
 
-	strip_vt102_codes(txt, name);
-
 	if (strlen(name) > 20)
 	{
-		chat_socket_printf(buddy, "%c\n%s has refused your name change because your name is too long.\n%c", CHAT_MESSAGE, gtd->chat->name, name, CHAT_END_OF_COMMAND);
+		chat_socket_printf(buddy, "%c\n%s has refused your name change because your name is too long.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
 
 		chat_printf("Refusing connection from %.21s:%d, name too long. (%d characters)", buddy->ip, buddy->port, strlen(name));
 
@@ -1137,11 +995,9 @@ void chat_name_change(struct chat_data *buddy, char *txt)
 
 	if (strcmp(name, buddy->name))
 	{
-		strcpy(temp, buddy->name);
+		chat_printf("%s changed their name to %s.", buddy->name, name);
 
 		RESTRING(buddy->name, name);
-
-		chat_printf("%s is now %s.", temp, txt);
 	}
 }
 
@@ -1535,6 +1391,13 @@ DO_CHAT(chat_name)
 		return;
 	}
 
+	if (strlen(arg1) > 200)
+	{
+		chat_printf("Your name cannot be longer than 200 bytes.");
+
+		return;
+	}
+
 	RESTRING(gtd->chat->name, arg1);
 
 	for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)

+ 39 - 0
src/class.c

@@ -26,6 +26,45 @@
 
 #include "tintin.h"
 
+#define DO_CLASS(class) struct session *class(struct session *ses, struct listnode *node, char *arg1, char *arg2)
+
+extern DO_CLASS(class_assign);
+extern DO_CLASS(class_clear);
+extern DO_CLASS(class_close);
+extern DO_CLASS(class_kill);
+extern DO_CLASS(class_list);
+extern DO_CLASS(class_load);
+extern DO_CLASS(class_open);
+extern DO_CLASS(class_read);
+extern DO_CLASS(class_save);
+extern DO_CLASS(class_size);
+extern DO_CLASS(class_write);
+
+typedef struct session *CLASS(struct session *ses, struct listnode *node, char *arg1, char *arg2);
+
+struct class_type
+{
+	char                  * name;
+	CLASS                 * fun;
+};
+
+struct class_type class_table[] =
+{
+	{    "ASSIGN",            class_assign           },
+	{    "CLEAR",             class_clear            },
+	{    "CLOSE",             class_close            },
+	{    "KILL",              class_kill             },
+	{    "LIST",              class_list             },
+	{    "LOAD",              class_load             },
+	{    "OPEN",              class_open             },
+	{    "READ",              class_read             },
+	{    "SAVE",              class_save             },
+	{    "SIZE",              class_size             },
+	{    "WRITE",             class_write            },
+	{    "",                  NULL                   },
+};
+
+int count_class(struct session *ses, struct listnode *group);
 
 DO_COMMAND(do_class)
 {

+ 60 - 1
src/command.c

@@ -25,7 +25,7 @@
 
 #include "tintin.h"
 
-extern struct command_type command_table[];
+struct command_type command_table[];
 
 DO_COMMAND(do_commands)
 {
@@ -159,6 +159,64 @@ struct session *command(struct session *ses, COMMAND *cmd, char *format, ...)
 	return ses;
 }
 
+extern DO_COMMAND(do_action);
+extern DO_COMMAND(do_alias);
+extern DO_COMMAND(do_all);
+extern DO_COMMAND(do_bell);
+extern DO_COMMAND(do_button);
+extern DO_COMMAND(do_cat);
+extern DO_COMMAND(do_class);
+extern DO_COMMAND(do_commands);
+extern DO_COMMAND(do_cr);
+extern DO_COMMAND(do_debug);
+extern DO_COMMAND(do_echo);
+extern DO_COMMAND(do_event);
+extern DO_COMMAND(do_format);
+extern DO_COMMAND(do_function);
+extern DO_COMMAND(do_gag);
+extern DO_COMMAND(do_highlight);
+extern DO_COMMAND(do_ignore);
+extern DO_COMMAND(do_info);
+extern DO_COMMAND(do_killall);
+extern DO_COMMAND(do_log);
+extern DO_COMMAND(do_local);
+extern DO_COMMAND(do_list);
+extern DO_COMMAND(do_macro);
+extern DO_COMMAND(do_math);
+extern DO_COMMAND(do_message);
+extern DO_COMMAND(do_path);
+extern DO_COMMAND(do_port);
+extern DO_COMMAND(do_prompt);
+extern DO_COMMAND(do_replace);
+extern DO_COMMAND(do_run);
+extern DO_COMMAND(do_scan);
+extern DO_COMMAND(do_script);
+extern DO_COMMAND(do_send);
+extern DO_COMMAND(do_showme);
+extern DO_COMMAND(do_ssl);
+extern DO_COMMAND(do_substitute);
+extern DO_COMMAND(do_system);
+extern DO_COMMAND(do_tab);
+extern DO_COMMAND(do_textin);
+extern DO_COMMAND(do_tick);
+extern DO_COMMAND(do_unaction);
+extern DO_COMMAND(do_unalias);
+extern DO_COMMAND(do_unbutton);
+extern DO_COMMAND(do_undelay);
+extern DO_COMMAND(do_unevent);
+extern DO_COMMAND(do_unfunction);
+extern DO_COMMAND(do_ungag);
+extern DO_COMMAND(do_unhighlight);
+extern DO_COMMAND(do_unlocal);
+extern DO_COMMAND(do_unmacro);
+extern DO_COMMAND(do_unpathdir);
+extern DO_COMMAND(do_unprompt);
+extern DO_COMMAND(do_unsubstitute);
+extern DO_COMMAND(do_untab);
+extern DO_COMMAND(do_untick);
+extern DO_COMMAND(do_unvariable);
+extern DO_COMMAND(do_variable);
+
 struct command_type command_table[] =
 {
 	{    "action",            do_action,            3, TOKEN_TYPE_COMMAND },
@@ -247,6 +305,7 @@ struct command_type command_table[] =
 	{    "unfunction",        do_unfunction,        0, TOKEN_TYPE_COMMAND },
 	{    "ungag",             do_ungag,             0, TOKEN_TYPE_COMMAND },
 	{    "unhighlight",       do_unhighlight,       0, TOKEN_TYPE_COMMAND },
+	{    "unlocal",           do_unlocal,           1, TOKEN_TYPE_COMMAND },
 	{    "unmacro",           do_unmacro,           0, TOKEN_TYPE_COMMAND },
 	{    "unpathdir",         do_unpathdir,         1, TOKEN_TYPE_COMMAND },
 	{    "unprompt",          do_unprompt,          0, TOKEN_TYPE_COMMAND },

+ 97 - 0
src/draw.c

@@ -28,6 +28,101 @@ static int  draw_cnt;
 
 #include "tintin.h"
 
+#define DRAW_FLAG_NONE                   0
+#define DRAW_FLAG_ASCII               BV01
+#define DRAW_FLAG_BLANKED             BV02
+#define DRAW_FLAG_BOT                 BV03
+#define DRAW_FLAG_BOXED               BV04
+#define DRAW_FLAG_BUMP                BV05
+#define DRAW_FLAG_CIRCLED             BV06
+#define DRAW_FLAG_COLOR1              BV07
+#define DRAW_FLAG_COLOR2              BV08
+#define DRAW_FLAG_CONVERT             BV09
+#define DRAW_FLAG_CORNERED            BV10
+#define DRAW_FLAG_CROSSED             BV11
+#define DRAW_FLAG_FILLED              BV12
+#define DRAW_FLAG_FOREGROUND          BV13
+#define DRAW_FLAG_GRID                BV14
+#define DRAW_FLAG_HOR                 BV15
+#define DRAW_FLAG_HUGE                BV16
+#define DRAW_FLAG_JEWELED             BV17
+#define DRAW_FLAG_LEFT                BV18
+//#define DRAW_FLAG_LINED               BV19 unused / obsolete
+#define DRAW_FLAG_NUMBERED            BV20
+#define DRAW_FLAG_PRUNED              BV21
+#define DRAW_FLAG_RIGHT               BV22
+#define DRAW_FLAG_ROUNDED             BV23
+#define DRAW_FLAG_SCALED              BV24
+#define DRAW_FLAG_SCROLL              BV25
+#define DRAW_FLAG_SHADOWED            BV26
+#define DRAW_FLAG_TEED                BV27
+#define DRAW_FLAG_TOP                 BV28
+#define DRAW_FLAG_TRACED              BV29
+#define DRAW_FLAG_TUBED               BV30
+#define DRAW_FLAG_UTF8                BV31
+#define DRAW_FLAG_VER                 BV32
+
+#define DRAW_FLAG_CURSIVE             BV33
+#define DRAW_FLAG_FAT                 BV34
+#define DRAW_FLAG_SANSSERIF           BV35
+#define DRAW_FLAG_CALIGN              BV36
+#define DRAW_FLAG_LALIGN              BV37
+#define DRAW_FLAG_RALIGN              BV38
+#define DRAW_FLAG_TALIGN              BV39
+#define DRAW_FLAG_UALIGN              BV40
+
+#define DRAW_FLAG_APPENDIX            DRAW_FLAG_CIRCLED|DRAW_FLAG_CORNERED|DRAW_FLAG_CROSSED|DRAW_FLAG_JEWELED|DRAW_FLAG_PRUNED|DRAW_FLAG_ROUNDED|DRAW_FLAG_TEED
+
+
+
+#define DO_DRAW(draw) void draw (struct session *ses, int top_row, int top_col, int bot_row, int bot_col, int rows, int cols, long long flags, char *color, char *arg, char *arg1, char *arg2, char *arg3)
+
+extern DO_DRAW(draw_blank);
+extern DO_DRAW(draw_bot_side);
+//extern DO_DRAW(draw_arg);
+extern DO_DRAW(draw_box);
+extern DO_DRAW(draw_buffer);
+extern DO_DRAW(draw_corner);
+extern DO_DRAW(draw_horizontal_line);
+extern DO_DRAW(draw_left_side);
+extern DO_DRAW(draw_line);
+extern DO_DRAW(draw_map);
+extern DO_DRAW(draw_right_side);
+extern DO_DRAW(draw_side);
+extern DO_DRAW(draw_square);
+extern DO_DRAW(draw_rain);
+extern DO_DRAW(draw_table_grid);
+extern DO_DRAW(draw_text);
+extern DO_DRAW(draw_top_side);
+extern DO_DRAW(draw_vertical_lines);
+
+typedef void DRAW(struct session *ses, int top_row, int top_col, int bot_row, int bot_col, int rows, int cols, long long flags, char *color, char *arg, char *arg1, char *arg2, char *arg3);
+
+struct draw_type
+{
+	char                  * name;
+	char                  * desc;
+	int                     flags;
+	DRAW                  * fun;
+};
+
+struct draw_type draw_table[] =
+{
+	{       "BOX",       "Draw four sides of a box.",         DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT, draw_box },
+	{       "BUFFER",    "Draw the scrollback buffer.",       DRAW_FLAG_NONE, draw_buffer },
+	{       "CORNER",    "Draw a corner",                     DRAW_FLAG_CORNERED, draw_corner },
+	{       "LINE",      "Draw a line.",                      DRAW_FLAG_NONE, draw_line },
+	{       "MAP",       "Draw the map.",                     DRAW_FLAG_NONE, draw_map },
+	{       "RAIN",      "Draw digital rain.",                DRAW_FLAG_NONE, draw_rain },
+	{       "SIDE",      "Draw a line with corners.",         DRAW_FLAG_BOXED, draw_side },
+	{       "TABLE",     "Draw a table.",                     DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT, draw_table_grid },
+	{       "TILE",      "Draw a tile.",                      DRAW_FLAG_NONE, draw_square },
+	{       "",          "",                                  DRAW_FLAG_NONE, NULL }
+};
+
+
+void scale_drawing(struct session *ses, int *top_row, int *top_col, int *bot_row, int *bot_col, int *rows, int *cols, int index, long long flags, char *arg);
+
 DO_COMMAND(do_draw)
 {
 	char *color, *code1, *code2, *input;
@@ -1292,6 +1387,7 @@ DO_DRAW(draw_bot_side)
 	}
 }
 
+/*
 DO_DRAW(draw_arg)
 {
 	arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
@@ -1315,6 +1411,7 @@ DO_DRAW(draw_arg)
 
 	restore_pos(ses);
 }
+*/
 
 DO_DRAW(draw_box)
 {

+ 14 - 9
src/files.c

@@ -499,8 +499,6 @@ void write_node(struct session *ses, int list, struct listnode *node, FILE *file
 {
 	char *result, *str;
 	int val = 0;
-	int llen = UMAX(20, strlen(node->arg1));
-	int rlen = UMAX(25, strlen(node->arg2));
 
 	push_call("write_node(%d,%p,%p)",list,node,file);
 
@@ -528,10 +526,17 @@ void write_node(struct session *ses, int list, struct listnode *node, FILE *file
 		case LIST_VARIABLE:
 			str = str_alloc_stack(0);
 
-			show_nest_node(node, &str, 1);
-
-			val = asprintf(&result, "%c%-16s {%s} %*s {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, 20 - llen, "", str);
+//			show_nest_node(node, &str, 1);
+			view_nest_node(node, &str, 0, TRUE, FALSE);
 
+			if (node->root)
+			{
+				val = asprintf(&result, "%c%s {%s}\n{\n%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, str);
+			}
+			else
+			{
+				val = asprintf(&result, "%c%s {%s} {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, str);
+			}
 			break;
 
 		default:
@@ -541,16 +546,16 @@ void write_node(struct session *ses, int list, struct listnode *node, FILE *file
 					result = strdup("");
 					break;
 				case 1:
-					val = asprintf(&result, "%c%-16s {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1);
+					val = asprintf(&result, "%c%s {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1);
 					break;
 				case 2:
-					val = asprintf(&result, "%c%-16s {%s} %*s {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, 20 - llen, "", node->arg2);
+					val = asprintf(&result, "%c%s {%s} {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, node->arg2);
 					break;
 				case 3:
-					val = asprintf(&result, "%c%-16s {%s} %*s {%s} %*s {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, 20 - llen, "", node->arg2, 25 - rlen, "", node->arg3);
+					val = asprintf(&result, "%c%s {%s} {%s} {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, node->arg2, node->arg3);
 					break;
 				case 4:
-					val = asprintf(&result, "%c%-16s {%s} %*s {%s} %*s {%s} {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, 20 - llen, "", node->arg2, 25 - rlen, "", node->arg3, node->arg4);
+					val = asprintf(&result, "%c%s {%s} {%s} {%s} {%s}\n", gtd->tintin_char, list_table[list].name, node->arg1, node->arg2, node->arg3, node->arg4);
 					break;
 			}
 			break;

+ 19 - 44
src/gui.h

@@ -1,4 +1,4 @@
-char *tt_gui = "#line QUIET #port INIT gui 0\n"
+char *tt_gui = "#line quiet #port init gui 0\n"
 "\n"
 "#function gui_link\n"
 "{\n"
@@ -16,30 +16,6 @@ char *tt_gui = "#line QUIET #port INIT gui 0\n"
 "	#return $gui[link]\n"
 "}\n"
 "\n"
-"/*\n"
-"#function input_link\n"
-"{\n"
-"	#line sub esc\n"
-"	{\n"
-"		#var result\n"
-"		{\n"
-"			\e]68;2;INPUT;{{top_row}{%1}{top_col}{%2}{bot_row}{%3}{bot_col}{%4}{name}{%5}{data}{%6}}\a\e[4;24m%7\e[24m\n"
-"		}\n"
-"	}\n"
-"}\n"
-"\n"
-"#event {PRESSED SECURE LINK INPUT MOUSE BUTTON ONE}\n"
-"{\n"
-"	#local link %4;\n"
-"\n"
-"	#screen inputregion {$link[top_row]} {$link[bot_row]} {$link[bot_row]} {$link[bot_col]} {$link[name]};\n"
-"\n"
-"	#cursor clear;\n"
-"\n"
-"	#cursor set {$link[data]}\n"
-"}\n"
-"*/\n"
-"\n"
 "#event {PRESSED SECURE LINK COMMAND MOUSE BUTTON ONE} {%4}\n"
 "\n"
 "#event {PRESSED SECURE LINK COMMAND MOUSE BUTTON THREE}\n"
@@ -79,13 +55,13 @@ char *tt_gui = "#line QUIET #port INIT gui 0\n"
 "\n"
 "	#if {{$gui[world_tab]} == {worlds}}\n"
 "	{\n"
-"		#draw jade Azure  rounded calign box 1  1 3 13 {@gui_link{COMMAND;{profile_tab_cancel;world_tab worlds;draw_worlds 0};worlds}};\n"
-"		#draw jade Silver rounded calign box 1 14 3 26 {@gui_link{COMMAND;{profile_tab_cancel;world_tab sponsors;draw_sponsors 0};sponsors}}\n"
+"		#draw jade Yellow rounded calign box 1  1 3 13 {@gui_link{COMMAND;{profile_tab_cancel;world_tab worlds;draw_worlds 0};worlds}};\n"
+"		#draw jade Azure  rounded calign box 1 14 3 26 {@gui_link{COMMAND;{profile_tab_cancel;world_tab sponsors;draw_sponsors 0};sponsors}}\n"
 "	};\n"
 "	#else\n"
 "	{\n"
-"		#draw jade Silver rounded calign box 1  1 3 13 {@gui_link{COMMAND;{profile_tab_cancel;world_tab worlds;draw_worlds 0};worlds}};\n"
-"		#draw jade Azure  rounded calign box 1 14 3 26 {@gui_link{COMMAND;{profile_tab_cancel;world_tab sponsors;draw_sponsors 0};sponsors}}\n"
+"		#draw jade Azure  rounded calign box 1  1 3 13 {@gui_link{COMMAND;{profile_tab_cancel;world_tab worlds;draw_worlds 0};worlds}};\n"
+"		#draw jade Yellow rounded calign box 1 14 3 26 {@gui_link{COMMAND;{profile_tab_cancel;world_tab sponsors;draw_sponsors 0};sponsors}}\n"
 "	};\n"
 "\n"
 "	#draw jade Green rounded calign box -3  1 -1 13 {@gui_link{COMMAND;gui_new;new}};\n"
@@ -586,13 +562,12 @@ char *tt_gui = "#line QUIET #port INIT gui 0\n"
 "\n"
 "#alias {gui_reload}\n"
 "{\n"
-"	#nop gts #SPLIT 1 3 27 27;\n"
-"	#SPLIT 1 3 27 27;\n"
+"	#split 1 3 27 27;\n"
 "	#screen clear split;\n"
 "	#screen inputregion -2 28 -2 -28 profile_tab_INPUT;\n"
 "\n"
-"	#screen get ROWS gui[rows];\n"
-"	#screen get COLS gui[cols];\n"
+"	#screen get rows gui[rows];\n"
+"	#screen get cols gui[cols];\n"
 "\n"
 "	#math gui[cols] $gui[cols] - 54;\n"
 "\n"
@@ -617,16 +592,16 @@ char *tt_gui = "#line QUIET #port INIT gui 0\n"
 "\n"
 "#alias {gui_init}\n"
 "{\n"
-"	#config MOUSE ON;\n"
-"	#config SCROLL_LOCK OFF;\n"
+"	#config mouse on;\n"
+"	#config scroll_lock off;\n"
 "\n"
-"	#class WORLDS ASSIGN #VARIABLE {worldlist} {};\n"
+"	#class WORLDS assign #variable {worldlist} {};\n"
 "\n"
-"	#info SYSTEM SAVE;\n"
+"	#info system save;\n"
 "\n"
 "	#banner save;\n"
 "\n"
-"	#line QUIET #read $info[SYSTEM][TINTIN]/worlds.tin;\n"
+"	#line quiet #read $info[SYSTEM][TINTIN]/worlds.tin;\n"
 "\n"
 "	#var gui[pause] 0;\n"
 "	#var gui[profile_tab] 0;\n"
@@ -641,18 +616,18 @@ char *tt_gui = "#line QUIET #port INIT gui 0\n"
 "	#if {$gui[cols] > 75}\n"
 "	{\n"
 "		#draw Silver huge traced scroll tile 1 1 6 73 { TINTIN++};\n"
-"		#draw Silver calign scroll tile 1 1 2 75 {\n\n$info[SYSTEM][CLIENT_VERSION]};\n"
-"		#draw Silver calign scroll tile 1 1 3 75 {\n\nCode by Peter Unold, Bill Reiss, and Igor van den Hoven\n}\n"
+"		#draw Silver calign scroll tile 1 1 2 75 {}{$info[SYSTEM][CLIENT_VERSION]};\n"
+"		#draw Silver calign scroll tile 1 1 3 75 {}{Code by Peter Unold, Bill Reiss, and Igor van den Hoven}\n"
 "	};\n"
 "	#elseif {$gui[cols] > 40}\n"
 "	{\n"
 "		#draw Silver huge traced scroll tile 1 1 6 40 { TT++};\n"
-"		#draw Silver calign scroll tile 1 1 2 40 {\n\n$info[SYSTEM][CLIENT_VERSION]};\n"
-"		#draw Silver calign scroll tile 1 1 3 40 {\n\nCode by Peter Unold, Bill Reiss,\nand Igor van den Hoven\n}\n"
+"		#draw Silver calign scroll tile 1 1 2 40 {}{$info[SYSTEM][CLIENT_VERSION]};\n"
+"		#draw Silver calign scroll tile 1 1 4 40 {}{Code by Peter Unold, Bill Reiss,}{}{and Igor van den Hoven}\n"
 "	};\n"
 "	#elseif {$gui[cols] > 18}\n"
 "	{\n"
-"		#draw Silver calign scroll tile 1 1 14 $gui[cols] {T I N T I N + +\n\n$info[SYSTEM][CLIENT_VERSION]\n\nCode by\n\nPeter Unold\n\nBill Reiss\n\nand\n\nIgor van den Hoven\n};\n"
+"		#draw Silver calign scroll tile 1 1 14 $gui[cols] {T I N T I N + +}{}{$info[SYSTEM][CLIENT_VERSION]}{}{Code by}{}{Peter Unold}{}{Bill Reiss}{}{and}{}{Igor van den Hoven};\n"
 "	};\n"
 "	#elseif {$gui[cols] > 8}\n"
 "	{\n"
@@ -664,7 +639,7 @@ char *tt_gui = "#line QUIET #port INIT gui 0\n"
 "	};\n"
 "	#elseif {$gui[cols] > 1}\n"
 "	{\n"
-"		#draw Silver calign scroll tile 1 1 8 $gui[cols] {T\ni\nn\nT\ni\nn\n+\n+}\n"
+"		#draw Silver calign scroll tile 1 1 8 $gui[cols] {T}{i}{n}{T}{i}{n}{+}{+}\n"
 "	}\n"
 "}\n"
 "\n"

+ 10 - 6
src/help.c

@@ -622,8 +622,8 @@ struct help_type help_table[] =
 		"\n"
 		"\\        An input line starting with a backslash is send verbatim if you are\n"
 		"         connected to a server. This character can be configured with\n"
-		"         #config, and is itself send verbatim when the verbatim config mode\n",
-		"         is enabled.\n"
+		"         #config, and is itself send verbatim when the verbatim config mode\n"
+		"         is enabled.\n",
 
 		"colors escape function mathematics pcre variable"
 	},
@@ -1479,8 +1479,8 @@ struct help_type help_table[] =
 		"\n"
 		"         <128>VARIABLE EVENTS<278>\n"
 		"\n"
-		"         VARIABLE UPDATE [VAR]  %0 name %1 new value\n"
-		"         VARIABLE UPDATED [VAR] %0 name %1 new value\n"
+		"         VARIABLE UPDATE <VAR>  %0 name %1 new value %2 path\n"
+		"         VARIABLE UPDATED <VAR> %0 name %1 new value %2 path\n"
 		"\n"
 		"         <128>VT100 EVENTS<278>\n"
 		"\n"
@@ -2221,7 +2221,7 @@ struct help_type help_table[] =
 		"         #list {var} {delete} {index} {number}  Delete the item at {index},\n"
 		"                                                the {number} is optional.\n"
 		"         #list {var} {explode}                  Turn list into a character list\n"
-		"         #list {var} {index}                    Index a list table for sorting\n"
+		"         #list {var} {indexate}                 Index a list table for sorting\n"
 		"         #list {var} {insert} {index} {string}  Insert {string} at given index\n"
 		"         #list {var} {find} {string} {variable} Return the found index\n"
 		"         #list {var} {get} {index} {variable}   Copy an item to {variable}\n"
@@ -2541,7 +2541,9 @@ struct help_type help_table[] =
 		"\n"
 		"         Avoid setting the result variable as local in a function.\n"
 		"\n"
-		"<178>Example<278>: #alias {swap} {#local x %0;#replace x {e} {u};#show $x}\n",
+		"<178>Example<278>: #alias {swap} {#local x %0;#replace x {e} {u};#show $x}\n"
+		"\n"
+		"<178>Comment<278>: You can remove a local variable with the #unlocal command.\n",
 
 		"format function math replace script variable"
 	},
@@ -3909,6 +3911,7 @@ struct help_type help_table[] =
 		"\n"
 		"         <178>#screen swap\n"
 		"         <278>  Swap the input and scroll region.\n",
+
 		"bell"
 	},
 
@@ -4449,6 +4452,7 @@ struct help_type help_table[] =
 		"",
 		TOKEN_TYPE_COMMAND,
 		"",
+
 		""
 	}
 };

+ 13 - 1
src/input.c

@@ -223,6 +223,14 @@ void read_line(char *input, int len)
 		}
 	}
 
+	if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_EUC) && is_euc_head(gtd->ses, gtd->macro_buf))
+	{
+		if (gtd->macro_buf[1] == 0)
+		{
+			return;
+		}
+	}
+
 	if (HAS_BIT(gtd->ses->event_flags, EVENT_FLAG_INPUT))
 	{
 		check_all_events(gtd->ses, EVENT_FLAG_INPUT, 0, 2, "RECEIVED KEYPRESS", input, ntos(index));
@@ -272,10 +280,14 @@ void read_line(char *input, int len)
 				break;
 
 			default:
-				if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) && gtd->macro_buf[0] & 128 && gtd->macro_buf[1])
+				if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(gtd->macro_buf) && gtd->macro_buf[1])
 				{
 					size = get_utf8_width(gtd->macro_buf, &width);
 				}
+				else if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_EUC) && is_euc_head(gtd->ses, gtd->macro_buf) && gtd->macro_buf[1])
+				{
+					size = get_euc_width(gtd->ses, gtd->macro_buf, &width);
+				}
 				else
 				{
 					size = get_ascii_width(gtd->macro_buf, &width);

+ 127 - 99
src/list.c

@@ -27,6 +27,62 @@
 
 #include "tintin.h"
 
+#define DO_ARRAY(array) struct session *array (struct session *ses, struct listnode *list, char *arg, char *var, char *arg1, char *arg2)
+
+extern DO_ARRAY(array_add);
+extern DO_ARRAY(array_clear);
+extern DO_ARRAY(array_collapse);
+extern DO_ARRAY(array_create);
+extern DO_ARRAY(array_delete);
+extern DO_ARRAY(array_explode);
+extern DO_ARRAY(array_find);
+extern DO_ARRAY(array_get);
+extern DO_ARRAY(array_index);
+extern DO_ARRAY(array_insert);
+extern DO_ARRAY(array_order);
+extern DO_ARRAY(array_reverse);
+extern DO_ARRAY(array_set);
+extern DO_ARRAY(array_shuffle);
+extern DO_ARRAY(array_simplify);
+extern DO_ARRAY(array_size);
+extern DO_ARRAY(array_sort);
+extern DO_ARRAY(array_tokenize);
+
+typedef struct session *ARRAY(struct session *ses, struct listnode *list, char *arg, char *var, char *arg1, char *arg2);
+
+struct array_type
+{
+	char                  * name;
+	ARRAY                 * fun;
+	char                  * desc;
+};
+
+struct array_type array_table[] =
+{
+	{     "ADD",              array_add,         "Add an item to a list table"             },
+	{     "CLEAR",            array_clear,       "Clear a list"                            },
+	{     "CLR",              array_clear,       NULL                                      },
+	{     "COLLAPSE",         array_collapse,    "Collapse the list into a variable"       },
+	{     "CREATE",           array_create,      "Create a list table with given items"    },
+	{     "DELETE",           array_delete,      "Delete a list item with given index"     },
+	{     "EXPLODE",          array_explode,     "Explode the variable into a list"        },
+	{     "FIND",             array_find,        "Find a list item with given regex"       },
+	{     "FND",              array_find,        NULL                                      },
+	{     "GET",              array_get,         "Retrieve a list item with given index"   },
+	{     "INDEXATE",         array_index,       "Indexate a list table for sorting"       },
+	{     "INSERT",           array_insert,      "Insert a list item at given index"       },
+	{     "ORDER",            array_order,       "Sort a list table numerically"           },
+	{     "LENGTH",           array_size,        NULL                                      },
+	{     "REVERSE",          array_reverse,     "Sort a list table in reverse order"      },
+	{     "SET",              array_set,         "Change a list item at given index"       },
+	{     "SHUFFLE",          array_shuffle,     "Sort a list table in random order"       },
+	{     "SIMPLIFY",         array_simplify,    "Turn a list table into a simple list"    },
+	{     "SIZE",             array_size,        NULL                                      },
+	{     "SORT",             array_sort,        "Sort a list table alphabetically"        },
+	{     "SRT",              array_sort,        NULL                                      },
+	{     "TOKENIZE",         array_tokenize,    "Create a list with given characters"     },
+	{     "",                 NULL,              ""                                        }
+};
 
 DO_COMMAND(do_list)
 {
@@ -88,6 +144,32 @@ DO_COMMAND(do_list)
 	return ses;
 }
 
+int get_list_index(struct session *ses, struct listroot *root, char *arg)
+{
+	int toi;
+
+	toi = get_number(ses, arg);
+
+	if (toi > 0)
+	{
+		if (toi <= root->used)
+		{
+			return toi - 1;
+		}
+		return -1;
+	}
+
+	if (toi < 0)
+	{
+		if (root->used + toi >= 0)
+		{
+			return root->used + toi;
+		}
+		return -1;
+	}
+	return -1;
+}
+
 DO_ARRAY(array_add)
 {
 	char *str;
@@ -212,24 +294,31 @@ DO_ARRAY(array_delete)
 		arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
 		arg = get_arg_in_braces(ses, arg, arg2, GET_ALL);
 
-		loop = *arg2 ? (int) get_number(ses, arg2) : 1;
+		index = get_list_index(ses, list->root, arg1);
 
-		while (loop--)
+		if (*arg2)
+		{
+			loop = URANGE(1, (int) get_number(ses, arg2), list->root->used - index);
+		}
+		else
 		{
-			index = search_nest_index(list->root, arg1);
+			loop = 1;
+		}
 
-			if (atoi(arg1) == 0 || index == -1)
-			{
-				show_error(ses, LIST_VARIABLE, "#LIST DEL: Invalid index: %s", arg1);
+		if (index == -1)
+		{
+			show_error(ses, LIST_VARIABLE, "#LIST {%s} DEL: Invalid index: %s", var, arg1);
 
-				return ses;
-			}
+			return ses;
+		}
 
-			for (cnt = index + 1 ; cnt < list->root->used ; cnt++)
-			{
-				str_cpy_printf(&list->root->list[cnt]->arg1, "%d", cnt);
-			}
+		for (cnt = index + loop ; cnt < list->root->used ; cnt++)
+		{
+			str_cpy_printf(&list->root->list[cnt]->arg1, "%d", cnt + 1 - loop);
+		}
 
+		while (loop--)
+		{
 			delete_index_list(list->root, index);
 		}
 	}
@@ -297,89 +386,31 @@ DO_ARRAY(array_explode)
 
 DO_ARRAY(array_find)
 {
-	char *arg3;
-	int cnt, index;
-
-	arg3 = str_alloc_stack(0);
+	int index;
 
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
 	arg = sub_arg_in_braces(ses, arg, arg2, GET_ONE, SUB_VAR|SUB_FUN);
-	arg = sub_arg_in_braces(ses, arg, arg3, GET_ALL, SUB_VAR|SUB_FUN);
 
 	if (*arg2 == 0)
 	{
-		show_error(ses, LIST_VARIABLE, "#SYNTAX: #LIST {variable} FIND [nest] {string} {variable}");
+		show_error(ses, LIST_VARIABLE, "#SYNTAX: #LIST {variable} FIND {string} {variable}");
 
 		return ses;
 	}
 
 	if (list->root)
 	{
-		if (*arg3 == 0)
+		for (index = 0 ; index < list->root->used ; index++)
 		{
-			for (index = 0 ; index < list->root->used ; index++)
-			{
-				if (match(ses, list->root->list[index]->arg2, arg1, SUB_NONE))
-				{
-					break;
-				}
-			}
-			if (index < list->root->used)
+			if (match(ses, list->root->list[index]->arg2, arg1, SUB_NONE))
 			{
 				set_nest_node_ses(ses, arg2, "%d", index + 1);
-			}
-			else
-			{
-				set_nest_node_ses(ses, arg2, "0");
-			}
-			return ses;
-		}
-		else
-		{
-			if (list->root->list[0]->root == NULL)
-			{
-				show_error(ses, LIST_COMMAND, "#ERROR: #LIST {%s} FIND: NOT AN INDEXABLE LIST TABLE.");
-		
+
 				return ses;
 			}
-		
-			if (list->root->used > 1)
-			{
-				int index = search_index_list(list->root->list[0]->root, arg1, "");
-		
-				if (index == -1)
-				{
-					show_error(ses, LIST_COMMAND, "#ERROR: #LIST {%s} FIND {%s}: FAILED TO FIND NEST.", var, arg1);
-		
-					return ses;
-				}
-		
-				for (cnt = 0 ; cnt < list->root->used ; cnt++)
-				{
-					if (list->root->list[cnt]->root && list->root->list[cnt]->root->used > index)
-					{
-						if (match(ses, list->root->list[cnt]->root->list[index]->arg2, arg2, SUB_NONE))
-						{
-							break;
-						}
-					}
-				}
-
-				if (cnt < list->root->used)
-				{
-					set_nest_node_ses(ses, arg3, "%d", cnt + 1);
-				}
-				else
-				{
-					set_nest_node_ses(ses, arg3, "%d", 0);
-				}
-			}
 		}
 	}
-	else
-	{
-		set_nest_node_ses(ses, arg2, "0");
-	}
+	set_nest_node_ses(ses, arg2, "0");
 
 	return ses;
 }
@@ -387,6 +418,8 @@ DO_ARRAY(array_find)
 
 DO_ARRAY(array_get)
 {
+	int index;
+
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
 	arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
 
@@ -399,22 +432,16 @@ DO_ARRAY(array_get)
 
 	if (list->root)
 	{
-		int index = search_nest_index(list->root, arg1);
+		index = get_list_index(ses, list->root, arg1);
 
-		if (atoi(arg1) == 0 || index == -1)
-		{
-			set_nest_node_ses(ses, arg2, "0");
-		}
-		else
+		if (index != -1)
 		{
 			set_nest_node_ses(ses, arg2, "%s", list->root->list[index]->arg2);
+
+			return ses;
 		}
-		return ses;
-	}
-	else
-	{
-		set_nest_node_ses(ses, arg2, "0");
 	}
+	set_nest_node_ses(ses, arg2, "0");
 
 	return ses;
 }
@@ -461,7 +488,7 @@ DO_ARRAY(array_index)
 
 DO_ARRAY(array_insert)
 {
-	int cnt, index;
+	int cnt, toi, index;
 
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
 	arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
@@ -471,16 +498,18 @@ DO_ARRAY(array_insert)
 		list->root = init_list(ses, LIST_VARIABLE, LIST_SIZE);
 	}
 
-	index = search_nest_index(list->root, arg1);
+	toi = get_number(ses, arg1);
 
-	if (atoi(arg1) == 0)
+	if (toi == 0)
 	{
 		show_error(ses, LIST_VARIABLE, "#LIST INS: Invalid index: %s", arg1);
-		
+
 		return ses;
 	}
 
-	if (index == -1 || atoi(arg1) < 0)
+	index = get_list_index(ses, list->root, arg1);
+
+	if (index == -1 || toi < 0)
 	{
 		index++;
 	}
@@ -645,22 +674,21 @@ DO_ARRAY(array_size)
 
 DO_ARRAY(array_set)
 {
+	int index;
+
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
 	arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
 
 	if (list->root)
 	{
-		int index = search_nest_index(list->root, arg1);
+		index = get_list_index(ses, list->root, arg1);
 
-		if (atoi(arg1) == 0 || index == -1)
+		if (index == -1)
 		{
-			show_error(ses, LIST_VARIABLE, "#LIST SET: Invalid index: %s", arg1);
-			
+			show_error(ses, LIST_VARIABLE, "#LIST {%s} SET: Invalid index: %s", var, arg1);
+
 			return ses;
 		}
-
-//		set_nest_node(list->root, ntos(index + 1), "%s", arg2);
-
 		str_cpy(&list->root->list[index]->arg2, arg2);
 
 		return ses;

+ 11 - 7
src/main.c

@@ -150,7 +150,7 @@ void trap_handler(int signal)
 int main(int argc, char **argv)
 {
 	int c, i = 0, greeting = 0;
-	char filename[PATH_SIZE];
+
 	char arg[BUFFER_SIZE];
 
 	#ifdef SOCKS
@@ -286,12 +286,6 @@ int main(int argc, char **argv)
 
 	init_tintin(greeting);
 
-	sprintf(filename, "%s/%s", gtd->system->tt_dir, HISTORY_FILE);
-
-	if (access(filename, F_OK ) != -1)
-	{
-		command(gts, do_history, "read %s", filename);
-	}
 
 	RESTRING(gtd->vars[1], argv[0]);
 
@@ -426,6 +420,7 @@ int main(int argc, char **argv)
 
 void init_tintin(int greeting)
 {
+	char filename[PATH_SIZE];
 	int index;
 
 	gtd                 = (struct tintin_data *) calloc(1, sizeof(struct tintin_data));
@@ -526,6 +521,8 @@ void init_tintin(int greeting)
 	gts->lognext_name   = strdup("");
 	gts->logline_name   = strdup("");
 
+	gts->more_output    = str_dup("");
+
 	gtd->ses = gts;
 
 	for (index = 0 ; index < LIST_MAX ; index++)
@@ -591,6 +588,13 @@ void init_tintin(int greeting)
 	command(gts, do_pathdir, "se nw  6");
 	command(gts, do_pathdir, "sw ne 12");
 
+	sprintf(filename, "%s/%s", gtd->system->tt_dir, HISTORY_FILE);
+
+	if (access(filename, F_OK ) != -1)
+	{
+		command(gts, do_history, "read %s", filename);
+	}
+
 	gtd->level->input--;
 
 	if (HAS_BIT(greeting,  STARTUP_FLAG_VERBOSE))

+ 3 - 3
src/mapper.c

@@ -2414,10 +2414,10 @@ char *draw_room(struct session *ses, struct room_data *room, int line, int x, in
 		if (HAS_BIT(room->flags, ROOM_FLAG_PATH) && room->search_stamp == ses->map->search->stamp)
 		{
 			room_color = ses->map->color[MAP_COLOR_PATH];
-
 			if (symsize > 1)
 			{
-				symsize = 0;
+				strcpy(room_symbol, " ");
+				symsize = 1;
 			}
 		}
 		else if (*room->color)
@@ -7190,7 +7190,7 @@ DO_MAP(map_map)
 			break;
 
 		case 'D':
-			draw_arg(ses, 1, 2, 3, 4, 5, 6, 7, "", arg4, arg2, arg1, arg3);
+			command(ses, do_draw, "tile %s {%s}", arg4, arg1);
 			break;
 
 		case 'S':

+ 13 - 1
src/misc.c

@@ -221,11 +221,22 @@ DO_COMMAND(do_send)
 }
 
 
-
 DO_COMMAND(do_test)
 {
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
 
+/*	if (!strcmp(arg1, "bla"))
+	{
+		int size = sizeof(_gbk1_to_unicode_table) / sizeof(struct interval_type);
+
+		printf("size: %d\n", size);
+
+		for (int i = 0 ; i < size ; i++)
+		{
+			command(ses, do_line, "log tmp %d,", _gbk1_to_unicode_table[i].tail);
+		}
+	}
+*/
 	if (!strcmp(arg1, "rain"))
 	{
 		strcpy(arg2, "9");
@@ -250,6 +261,7 @@ DO_COMMAND(do_test)
 
 		return ses;
 	}
+
 	return ses;
 }
 

+ 44 - 15
src/nest.c

@@ -815,7 +815,7 @@ void show_nest_node(struct listnode *node, char **str_result, int initialize)
 	}
 }
 
-void view_nest_node(struct listnode *node, char **str_result, int nest, int initialize)
+void view_nest_node(struct listnode *node, char **str_result, int nest, int initialize, int color)
 {
 	if (initialize == TRUE)
 	{
@@ -830,7 +830,14 @@ void view_nest_node(struct listnode *node, char **str_result, int nest, int init
 		}
 		else
 		{
-			str_cat_printf(str_result, COLOR_BRACE "{" COLOR_STRING "%s" COLOR_BRACE "}\n", node->arg2);
+			if (color)
+			{
+				str_cat_printf(str_result, COLOR_BRACE "{" COLOR_STRING "%s" COLOR_BRACE "}\n", node->arg2);
+			}
+			else
+			{
+				str_cat_printf(str_result, "{%s}\n", node->arg2);
+			}
 		}
 	}
 	else
@@ -840,23 +847,44 @@ void view_nest_node(struct listnode *node, char **str_result, int nest, int init
 
 		if (initialize == FALSE)
 		{
-			str_cat_printf(str_result, "\n" COLOR_BRACE "%s{\n", indent(nest));
+			if (color)
+			{
+				str_cat_printf(str_result, "\n" COLOR_BRACE "%s{\n", indent(nest));
+			}
+			else
+			{
+				str_cat_printf(str_result, "\n%s{\n", indent(nest));
+			}
 		}
 
 		nest++;
 
 		for (i = 0 ; i < root->used ; i++)
 		{
-			str_cat_printf(str_result, COLOR_BRACE "%s{" COLOR_STRING "%s" COLOR_BRACE "} ", indent(nest), root->list[i]->arg1);
+			if (color)
+			{
+				str_cat_printf(str_result, COLOR_BRACE "%s{" COLOR_STRING "%s" COLOR_BRACE "} ", indent(nest), root->list[i]->arg1);
+			}
+			else
+			{
+				str_cat_printf(str_result, "%s{%s} ", indent(nest), root->list[i]->arg1);
+			}
 
-			view_nest_node(root->list[i], str_result, nest, FALSE);
+			view_nest_node(root->list[i], str_result, nest, FALSE, color);
 		}
 
 		nest--;
 
 		if (initialize == FALSE)
 		{
-			str_cat_printf(str_result, COLOR_BRACE "%s}\n", indent(nest), "");
+			if (color)
+			{
+				str_cat_printf(str_result, COLOR_BRACE "%s}\n", indent(nest), "");
+			}
+			else
+			{
+				str_cat_printf(str_result, "%s}\n", indent(nest), "");
+			}
 		}
 	}
 }
@@ -883,7 +911,7 @@ struct listnode *set_nest_node_ses(struct session *ses, char *arg1, char *format
 
 	if (HAS_BIT(ses->event_flags, EVENT_FLAG_VARIABLE))
 	{
-		check_all_events(ses, EVENT_FLAG_VARIABLE, 1, 2, "VARIABLE UPDATE %s", name, name, arg2);
+		check_all_events(ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATE %s", name, name, arg2, arg1);
 	}
 
 	root = search_nest_base_ses(ses, name);
@@ -896,7 +924,7 @@ struct listnode *set_nest_node_ses(struct session *ses, char *arg1, char *format
 		}
 		else
 		{
-			root = ses->list[LIST_VARIABLE];
+                      root = ses->list[LIST_VARIABLE];
 		}
 		node = NULL;
 	}
@@ -946,7 +974,7 @@ struct listnode *set_nest_node_ses(struct session *ses, char *arg1, char *format
 
 	if (HAS_BIT(root->ses->event_flags, EVENT_FLAG_VARIABLE))
 	{
-		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 1, "VARIABLE UPDATED %s", name, name, arg2);
+		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATED %s", name, name, arg2, arg1);
 	}
 	free(arg2);
 
@@ -977,7 +1005,7 @@ struct listnode *add_nest_node_ses(struct session *ses, char *arg1, char *format
 
 	if (HAS_BIT(ses->event_flags, EVENT_FLAG_VARIABLE))
 	{
-		check_all_events(ses, EVENT_FLAG_VARIABLE, 1, 2, "VARIABLE UPDATE %s", name, name, arg2);
+		check_all_events(ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATE %s", name, name, arg2, arg1);
 	}
 
 	root = search_nest_base_ses(ses, name);
@@ -1035,7 +1063,7 @@ struct listnode *add_nest_node_ses(struct session *ses, char *arg1, char *format
 
 	if (HAS_BIT(root->ses->event_flags, EVENT_FLAG_VARIABLE))
 	{
-		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 1, "VARIABLE UPDATED %s", name, name, arg2);
+		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATED %s", name, name, arg2, arg1);
 	}
 	free(arg2);
 
@@ -1065,7 +1093,7 @@ struct listnode *set_nest_node(struct listroot *root, char *arg1, char *format,
 
 	if (HAS_BIT(root->ses->event_flags, EVENT_FLAG_VARIABLE))
 	{
-		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 2, "VARIABLE UPDATE %s", name, name, arg2);
+		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATE %s", name, name, arg2, arg1);
 	}
 
 	if (HAS_BIT(gtd->flags, TINTIN_FLAG_LOCAL))
@@ -1119,7 +1147,7 @@ struct listnode *set_nest_node(struct listroot *root, char *arg1, char *format,
 
 	if (HAS_BIT(root->ses->event_flags, EVENT_FLAG_VARIABLE))
 	{
-		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 1, "VARIABLE UPDATED %s", name, name, arg2);
+		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATED %s", name, name, arg2, arg1);
 	}
 
 	free(arg2);
@@ -1140,6 +1168,7 @@ struct listnode *add_nest_node(struct listroot *root, char *arg1, char *format,
 	push_call("add_nest_node(%p,%s,%p,...)",root,arg1,format);
 
 	va_start(args, format);
+
 	if (vasprintf(&arg2, format, args) == -1)
 	{
 		syserr_printf(root->ses, "add_nest_node: vasprintf");
@@ -1151,7 +1180,7 @@ struct listnode *add_nest_node(struct listroot *root, char *arg1, char *format,
 
 	if (HAS_BIT(root->ses->event_flags, EVENT_FLAG_VARIABLE))
 	{
-		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 2, "VARIABLE UPDATE %s", name, name, arg2);
+		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATE %s", name, name, arg2, arg1);
 	}
 
 	if (HAS_BIT(gtd->flags, TINTIN_FLAG_LOCAL))
@@ -1208,7 +1237,7 @@ struct listnode *add_nest_node(struct listroot *root, char *arg1, char *format,
 
 	if (HAS_BIT(root->ses->event_flags, EVENT_FLAG_VARIABLE))
 	{
-		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 1, "VARIABLE UPDATED %s", name, name, arg2);
+		check_all_events(root->ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATED %s", name, name, arg2, arg1);
 	}
 
 	free(arg2);

+ 6 - 6
src/net.c

@@ -480,13 +480,13 @@ void readmud(struct session *ses)
 				*next_line++ = 0;
 			}
 
-			if (strlen(ses->more_output) < BUFFER_SIZE / 3)
+			if (str_len(ses->more_output) < BUFFER_SIZE / 3)
 			{
 				if (!HAS_BIT(ses->telopts, TELOPT_FLAG_PROMPT))
 				{
 					if (ses->packet_patch)
 					{
-						strcat(ses->more_output, line);
+						str_cat(&ses->more_output, line);
 						ses->check_output = utime() + ses->packet_patch;
 
 						break;
@@ -497,14 +497,14 @@ void readmud(struct session *ses)
 						{
 							if (!detect_prompt(ses, line))
 							{
-								strcat(ses->more_output, line);
+								str_cat(&ses->more_output, line);
 								ses->check_output = utime() + 500000ULL;
 								break;
 							}
 						}
 						else if (HAS_BIT(ses->config_flags, CONFIG_FLAG_AUTOPROMPT))
 						{
-							strcat(ses->more_output, line);
+							str_cat(&ses->more_output, line);
 							ses->check_output = utime() + 500000ULL;
 							break;
 						}
@@ -517,10 +517,10 @@ void readmud(struct session *ses)
 		{
 			if (ses->check_output)
 			{
-				strcat(ses->more_output, line);
+				str_cat(&ses->more_output, line);
 				strcpy(linebuf, ses->more_output);
 
-				ses->more_output[0] = 0;
+				str_cpy(&ses->more_output, "");
 			}
 			else
 			{

+ 36 - 0
src/scan.c

@@ -34,6 +34,42 @@
 #endif
 #include <dirent.h>
 
+#define DO_SCAN(scan) struct session *scan(struct session *ses, FILE *fp, char *arg, char *arg1, char *arg2)
+
+DO_SCAN(scan_abort);
+DO_SCAN(scan_csv);
+DO_SCAN(scan_dir);
+DO_SCAN(scan_file);
+DO_SCAN(scan_forward);
+DO_SCAN(scan_tsv);
+DO_SCAN(scan_txt);
+
+#define SCAN_FLAG_NONE                0
+#define SCAN_FLAG_FILE                BV01
+#define SCAN_FLAG_SCAN                BV02
+
+typedef struct session *SCAN(struct session *ses, FILE *fp, char *arg, char *arg1, char *arg2);
+
+struct scan_type
+{
+	char                  * name;
+	SCAN                  * fun;
+	int                     flags;
+	char                  * desc;
+};
+
+struct scan_type scan_table[] =
+{
+	{       "ABORT",            scan_abort,   SCAN_FLAG_NONE,                "Abort a scan currently in progress."},
+	{       "CSV",              scan_csv,     SCAN_FLAG_FILE|SCAN_FLAG_SCAN, "Scan a comma separated value file." },
+	{       "DIR",              scan_dir,     SCAN_FLAG_FILE,                "Scan a directory to a variable."    },
+	{       "FILE",             scan_file,    SCAN_FLAG_FILE,                "Scan a file all at once."           },
+	{       "FORWARD",          scan_forward, SCAN_FLAG_FILE,                "Scan a file and send each line."    },
+	{       "TSV",              scan_tsv,     SCAN_FLAG_FILE|SCAN_FLAG_SCAN, "Scan a tab separated value file."   },
+	{       "TXT",              scan_txt,     SCAN_FLAG_FILE|SCAN_FLAG_SCAN, "Scan a text file line by line."     },
+	{       "",                 NULL,         0,                             ""                                   }
+};
+
 DO_COMMAND(do_scan)
 {
 	char cmd[BUFFER_SIZE];

+ 266 - 4
src/screen.c

@@ -26,6 +26,252 @@
 #include "tintin.h"
 #include "telnet.h"
 
+#define DO_SCREEN(screen)               void screen (struct session *ses, int ind, char *arg, char *arg1, char *arg2)
+
+extern DO_SCREEN(screen_blur);
+extern DO_SCREEN(screen_clear);
+extern DO_SCREEN(screen_cursor);
+extern DO_SCREEN(screen_dump);
+extern DO_SCREEN(screen_fill);
+extern DO_SCREEN(screen_focus);
+extern DO_SCREEN(screen_fullscreen);
+extern DO_SCREEN(screen_get);
+extern DO_SCREEN(screen_info);
+extern DO_SCREEN(screen_inputregion);
+extern DO_SCREEN(screen_load);
+extern DO_SCREEN(screen_maximize);
+extern DO_SCREEN(screen_minimize);
+extern DO_SCREEN(screen_move);
+extern DO_SCREEN(screen_print);
+extern DO_SCREEN(screen_raise);
+extern DO_SCREEN(screen_refresh);
+extern DO_SCREEN(screen_resize);
+extern DO_SCREEN(screen_rescale);
+extern DO_SCREEN(screen_save);
+extern DO_SCREEN(screen_scrollbar);
+extern DO_SCREEN(screen_scrollregion);
+extern DO_SCREEN(screen_set);
+extern DO_SCREEN(screen_swap);
+
+typedef void            SCREEN  (struct session *ses, int ind, char *arg, char *arg1, char *arg2);
+
+struct screen_type
+{
+	char                  * name;
+	char                  * desc;
+	int                     get1;
+	int                     get2;
+	int                     flags;
+	SCREEN                * fun;
+};
+
+struct screen_type screen_table[] =
+{
+	{
+		"BLUR",
+		"Shuffle the screen to the back of the desktop.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_blur
+	},
+	{
+		"CLEAR",
+		"Clear the screen.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_NONE,
+		SCREEN_FLAG_CSIP,
+		screen_clear
+	},
+	{
+		"CURSOR",
+		"Cursor settings.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_cursor
+	},
+
+	{
+		"DUMP",
+		"Dump the screen buffer.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_dump
+	},
+
+	{
+		"FILL",
+		"Fill given region with given character.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_fill
+	},
+	{
+		"FOCUS",
+		"Shuffle the screen to the front of the desktop.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_focus
+	},
+	{
+		"FULLSCREEN",
+		"Toggle fullscreen mode.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_fullscreen
+	},
+	{
+		"GET",
+		"Save screen information to given variable.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_get
+	},
+	{
+		"INFO",
+		"Show some debugging information.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_info
+	},
+	{
+		"INPUTREGION",
+		"Set the input region to {square}.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_inputregion
+	},
+
+	{
+		"LOAD",
+		"Load screen information from memory.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_OSCT,
+		screen_load
+	},
+	{
+		"MAXIMIZE",
+		"Maximize or restore the screen.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_maximize
+	},
+
+	{
+		"MINIMIZE",
+		"Minimize or restore the screen.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_minimize
+	},
+	{
+		"MOVE",
+		"Move the screen to the given position.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_move
+	},
+	{
+		"PRINT",
+		"Print the screen dump to the screen.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_print
+	},
+	{
+		"RAISE",
+		"Raise a screen event.",
+		SCREEN_FLAG_GET_ALL,
+		SCREEN_FLAG_GET_ALL,
+		SCREEN_FLAG_CSIP,
+		screen_raise
+	},
+	{
+		"REFRESH",
+		"Force a refresh of the screen.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_refresh
+	},
+	{
+		"RESCALE",
+		"Rescale the screen to {height} {width} pixels.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_rescale
+	},
+	{
+		"RESIZE",
+		"Resize the screen to {rows} {cols} characters.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_resize
+	},
+	{
+		"SAVE",
+		"Save screen information to memory.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_save
+	},
+
+	{
+		"SCROLLREGION",
+		"Set the scroll region to {square}.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_scrollregion
+	},
+
+	{
+		"SCROLLBAR",
+		"Scrollbar settings.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_scrollbar
+	},
+
+
+	{
+		"SET",
+		"Set screen information.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_OSCT,
+		screen_set
+	},
+	{
+		"SWAP",
+		"Swap the input and scroll region.",
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_GET_ONE,
+		SCREEN_FLAG_CSIP,
+		screen_swap
+	},
+	{
+		"", "", 0, 0, 0, NULL
+	}
+};
+
 void screen_osc(char *arg1, char *arg2);
 void screen_csi(char *cmd, char *arg1, char *arg2, char *arg3, char *tc);
 void screen_csit(struct session *ses, char *arg1, char *arg2, char *tc);
@@ -138,6 +384,11 @@ DO_SCREEN(screen_clear)
 {
 	int top_row, top_col, bot_row, bot_col;
 
+	if (ses != gtd->ses)
+	{
+		return;
+	}
+
 	if (is_abbrev(arg1, "ALL"))
 	{
 		print_stdout(0, 0, "\e[2J");
@@ -301,12 +552,12 @@ DO_SCREEN(screen_fill)
 		{
 			if (ses->split->sav_top_col)
 			{
-				command(ses, do_draw, "%s VERTICAL LINE %d %d %d %d", arg2, ses->split->top_row, ses->split->top_col - 1, ses->split->bot_row, ses->split->top_col - 1);
+				command(ses, do_draw, "%s BOT TEED LINE %d %d %d %d", arg2, ses->split->top_row, ses->split->top_col - 1, ses->split->bot_row + 1, ses->split->top_col - 1);
 			}
 
 			if (ses->split->sav_bot_col)
 			{
-				command(ses, do_draw, "%s VERTICAL LINE %d %d %d %d", arg2, ses->split->top_row, ses->split->bot_col + 1, ses->split->bot_row, ses->split->bot_col + 1);
+				command(ses, do_draw, "%s BOT TEED LINE %d %d %d %d", arg2, ses->split->top_row, ses->split->bot_col + 1, ses->split->bot_row + 1, ses->split->bot_col + 1);
 			}
 		}
 	}
@@ -1883,7 +2134,12 @@ void destroy_screen()
 
 void print_scroll_region(struct session *ses)
 {
-	int cnt;
+	char *wrap;
+	int cnt, height, width;
+
+	push_call("print_scroll_region(%p)",ses);
+
+	wrap = str_alloc_stack(0);
 
 	save_pos(ses);
 
@@ -1891,9 +2147,15 @@ void print_scroll_region(struct session *ses)
 	{
 		print_stdout(0, 0, "\e[%d;%dH\e[%dX%s", cnt, ses->split->top_col, ses->wrap, gtd->screen->line[cnt - 1]->str);
 	}
-	print_stdout(0, 0, "\e[%d;%dH\e[%dX%s", cnt, ses->split->top_col, ses->wrap, ses->scroll->input);
+
+	word_wrap_split(ses, ses->scroll->input, wrap, ses->wrap, 0, 1, WRAP_FLAG_SPLIT, &height, &width);
+
+	print_stdout(0, 0, "\e[%d;%dH\e[%dX%s", cnt, ses->split->top_col, ses->wrap, wrap);
 
 	restore_pos(ses);
+
+	pop_call();
+	return;
 }
 
 void print_screen()

+ 6 - 0
src/session.c

@@ -310,6 +310,8 @@ struct session *activate_session(struct session *ses)
 
 	if (!check_all_events(ses, EVENT_FLAG_GAG, 0, 1, "GAG SESSION ACTIVATED", ses->name))
 	{
+		buffer_refresh(ses, "", "", "");
+
 		show_message(ses, LIST_COMMAND, "#SESSION '%s' ACTIVATED.", ses->name);
 	}
 
@@ -393,6 +395,8 @@ struct session *new_session(struct session *ses, char *name, char *arg, int desc
 	newses->logline_name   = strdup("");
 	newses->rand           = utime();
 
+	newses->more_output    = str_dup("");
+
 	LINK(newses, gts->next, gts->prev);
 
 	if (HAS_BIT(gtd->flags, TINTIN_FLAG_INHERITANCE))
@@ -760,6 +764,8 @@ void dispose_session(struct session *ses)
 	free(ses->split);
 	free(ses->input);
 
+	str_free(ses->more_output);
+
 	free(ses);
 
 	pop_call();

+ 0 - 1
src/split.c

@@ -184,7 +184,6 @@ void init_split(struct session *ses, int top_row, int top_col, int bot_row, int
 		SET_BIT(ses->flags, SES_FLAG_UPDATEVTMAP);
 	}
 
-
 	check_all_events(ses, EVENT_FLAG_SCREEN, 0, 4, "SCREEN SPLIT FILL", ntos(ses->split->top_row), ntos(ses->split->top_col), ntos(ses->split->bot_row), ntos(ses->split->bot_col), ntos(ses->split->sav_top_row), ntos(ses->split->sav_bot_row), ntos(ses->split->sav_top_col), ntos(ses->split->sav_bot_col));
 
 	if (!check_all_events(ses, EVENT_FLAG_CATCH, 0, 8, "CATCH SCREEN SPLIT FILL", ntos(ses->split->top_row), ntos(ses->split->top_col), ntos(ses->split->bot_row), ntos(ses->split->bot_col), ntos(ses->split->sav_top_row), ntos(ses->split->sav_bot_row), ntos(ses->split->sav_top_col), ntos(ses->split->sav_bot_col)))

+ 23 - 23
src/substitute.c

@@ -1103,11 +1103,9 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 					{
 						brace = TRUE;
 
-						ptt = get_arg_in_braces(ses, &pti[i], buf, GET_ALL);
+						sub_arg_in_braces(ses, &pti[i], buf, GET_ONE, flags_neol);
 
-						i += strlen(buf) + 2;
-
-						substitute(ses, buf, temp, flags_neol);
+						get_arg_to_brackets(ses, buf, temp);
 					}
 					else
 					{
@@ -1124,14 +1122,17 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 
 					if (*temp)
 					{
-						root = local_list(ses);
+						root = search_nest_base_ses(ses, temp);
 
-						if ((node = search_node_list(root, temp)) == NULL)
+						if (root)
 						{
-							root = ses->list[LIST_VARIABLE];
-
 							node = search_node_list(root, temp);
 						}
+						else
+						{
+							root = ses->list[LIST_VARIABLE];
+							node = NULL;
+						}
 					}
 					else
 					{
@@ -1165,7 +1166,7 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 					}
 					else
 					{
-						pti = ptt;
+						pti = get_arg_in_braces(ses, &pti[i], temp, GET_ONE);
 					}
 
 					substitute(ses, temp, buf, flags_neol);
@@ -1208,11 +1209,9 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 					{
 						brace = TRUE;
 
-						ptt = get_arg_in_braces(ses, &pti[i], buf, GET_ALL);
+						sub_arg_in_braces(ses, &pti[i], buf, GET_ONE, flags_neol);
 
-						i += strlen(buf) + 2;
-
-						substitute(ses, buf, temp, flags_neol);
+						get_arg_to_brackets(ses, buf, temp);
 					}
 					else
 					{
@@ -1273,7 +1272,7 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 					}
 					else
 					{
-						pti = ptt;
+						pti = get_arg_in_braces(ses, &pti[i], temp, GET_ONE);
 					}
 
 					substitute(ses, temp, buf, flags_neol);
@@ -1283,7 +1282,6 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 					get_nest_node_val(root, buf, &str, brace);
 
 					substitute(ses, str, pto, flags_neol - SUB_VAR);
-//					substitute(ses, str, pto, flags_neol);
 
 					pto += strlen(pto);
 
@@ -1345,11 +1343,9 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 					{
 						brace = TRUE;
 
-						ptt = get_arg_in_braces(ses, &pti[i], buf, GET_ALL);
-
-						i += strlen(buf) + 2;
+						sub_arg_in_braces(ses, &pti[i], buf, GET_ONE, flags_neol);
 
-						substitute(ses, buf, temp, flags_neol);
+						get_arg_to_brackets(ses, buf, temp);
 					}
 					else
 					{
@@ -1366,13 +1362,17 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 
 					if (*temp)
 					{
-						root = local_list(ses);
+						root = search_nest_base_ses(ses, temp);
 
-						if ((node = search_node_list(root, temp)) == NULL)
+						if (root)
 						{
-							root = ses->list[LIST_VARIABLE];
 							node = search_node_list(root, temp);
 						}
+						else
+						{
+							root = ses->list[LIST_VARIABLE];
+							node = NULL;
+						}
 					}
 					else
 					{
@@ -1406,7 +1406,7 @@ int substitute(struct session *ses, char *string, char *result, int flags)
 					}
 					else
 					{
-						pti = ptt;
+						pti = get_arg_in_braces(ses, &pti[i], temp, GET_ONE);
 					}
 
 					substitute(ses, temp, buf, flags_neol);

+ 0 - 340
src/tables.c

@@ -728,23 +728,6 @@ struct color_type map_color_table[] =
 	{     NULL,               "<888>" }
 };
 
-struct class_type class_table[] =
-{
-	{    "ASSIGN",            class_assign           },
-	{    "CLEAR",             class_clear            },
-	{    "CLOSE",             class_close            },
-	{    "KILL",              class_kill             },
-	{    "LIST",              class_list             },
-	{    "LOAD",              class_load             },
-	{    "OPEN",              class_open             },
-	{    "READ",              class_read             },
-	{    "SAVE",              class_save             },
-	{    "SIZE",              class_size             },
-	{    "WRITE",             class_write            },
-
-	{    "",                  NULL                   },
-};
-
 struct chat_type chat_table[] =
 {
 	{     "ACCEPT",           chat_accept,         0, 1, "Accept a file transfer"		              },
@@ -818,33 +801,6 @@ struct rank_type rank_table[] =
 	{     "SCOUT",            RANK_FLAG_SCOUT     }
 };
 
-struct array_type array_table[] =
-{
-	{     "ADD",              array_add,         "Add an item to a list table"             },
-	{     "CLEAR",            array_clear,       "Clear a list"                            },
-	{     "CLR",              array_clear,       NULL                                      },
-	{     "COLLAPSE",         array_collapse,    "Collapse the list into a variable"       },
-	{     "CREATE",           array_create,      "Create a list table with given items"    },
-	{     "DELETE",           array_delete,      "Delete a list item with given index"     },
-	{     "EXPLODE",          array_explode,     "Explode the variable into a list"        },
-	{     "FIND",             array_find,        "Find a list item with given regex"       },
-	{     "FND",              array_find,        NULL                                      },
-	{     "GET",              array_get,         "Retrieve a list item with given index"   },
-	{     "INDEX",            array_index,       "Index a list table for sorting"          },
-	{     "INSERT",           array_insert,      "Insert a list item at given index"       },
-	{     "ORDER",            array_order,       "Sort a list table numerically"           },
-	{     "LENGTH",           array_size,        NULL                                      },
-	{     "REVERSE",          array_reverse,     "Sort a list table in reverse order"      },
-	{     "SET",              array_set,         "Change a list item at given index"       },
-	{     "SHUFFLE",          array_shuffle,     "Sort a list table in random order"       },
-	{     "SIMPLIFY",         array_simplify,    "Turn a list table into a simple list"    },
-	{     "SIZE",             array_size,        NULL                                      },
-	{     "SORT",             array_sort,        "Sort a list table alphabetically"        },
-	{     "SRT",              array_sort,        NULL                                      },
-	{     "TOKENIZE",         array_tokenize,    "Create a list with given characters"     },
-	{     "",                 NULL,                                                        }
-};
-
 // 0 no map, 1 has map, 2 is inside map
 
 struct map_type map_table[] =
@@ -979,80 +935,6 @@ struct cursor_type cursor_table[] =
 	{     "",                   "",                                               "",                               0,    NULL,                         ""          }
 };
 
-struct draw_type draw_table[] =
-{
-	{
-		"BOX",
-		"Draw four sides of a box.",
-		DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT,
-		draw_box
-	},
-
-	{
-		"BUFFER",
-		"Draw the scrollback buffer.",
-		0,
-		draw_buffer
-	},
-
-	{
-		"CORNER",
-		"Draw a corner",
-		DRAW_FLAG_CORNERED,
-		draw_corner
-	},
-
-	{
-		"LINE",
-		"Draw a line.",
-		DRAW_FLAG_NONE,
-		draw_line
-	},
-
-	{
-		"MAP",
-		"Draw the map.",
-		0,
-		draw_map
-	},
-
-	{
-		"RAIN",
-		"Draw digital rain.",
-		0,
-		draw_rain
-	},
-
-	{
-		"SIDE",
-		"Draw a line with corners.",
-		DRAW_FLAG_BOXED,
-		draw_side
-	},
-
-	{
-		"TABLE",
-		"Draw a table.",
-		DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT,
-		draw_table_grid
-	},
-
-	{
-		"TILE",
-		"Draw a tile.",
-		0,
-		draw_square
-	},
-
-	{
-		"",
-		"",
-		0,
-		NULL
-	}
-};
-
-
 struct edit_type edit_table[] =
 {
 	{      "CREATE",            edit_create,         "Create an editor"                  },
@@ -1065,227 +947,6 @@ struct edit_type edit_table[] =
 	{      "",                  NULL,                ""                                  },
 };
 
-
-struct scan_type scan_table[] =
-{
-	{       "ABORT",            scan_abort,   SCAN_FLAG_NONE,                "Abort a scan currently in progress."},
-	{       "CSV",              scan_csv,     SCAN_FLAG_FILE|SCAN_FLAG_SCAN, "Scan a comma separated value file." },
-	{       "DIR",              scan_dir,     SCAN_FLAG_FILE,                "Scan a directory to a variable."    },
-	{       "FILE",             scan_file,    SCAN_FLAG_FILE,                "Scan a file all at once."           },
-	{       "FORWARD",          scan_forward, SCAN_FLAG_FILE,                "Scan a file and send each line."    },
-	{       "TSV",              scan_tsv,     SCAN_FLAG_FILE|SCAN_FLAG_SCAN, "Scan a tab separated value file."   },
-	{       "TXT",              scan_txt,     SCAN_FLAG_FILE|SCAN_FLAG_SCAN, "Scan a text file line by line."     },
-	{       "",                 NULL,         0,                             ""                                   }
-};
-
-struct screen_type screen_table[] =
-{
-	{
-		"BLUR",
-		"Shuffle the screen to the back of the desktop.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_blur
-	},
-	{
-		"CLEAR",
-		"Clear the screen.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_NONE,
-		SCREEN_FLAG_CSIP,
-		screen_clear
-	},
-	{
-		"CURSOR",
-		"Cursor settings.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_cursor
-	},
-
-	{
-		"DUMP",
-		"Dump the screen buffer.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_dump
-	},
-
-	{
-		"FILL",
-		"Fill given region with given character.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_fill
-	},
-	{
-		"FOCUS",
-		"Shuffle the screen to the front of the desktop.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_focus
-	},
-	{
-		"FULLSCREEN",
-		"Toggle fullscreen mode.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_fullscreen
-	},
-	{
-		"GET",
-		"Save screen information to given variable.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_get
-	},
-	{
-		"INFO",
-		"Show some debugging information.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_info
-	},
-	{
-		"INPUTREGION",
-		"Set the input region to {square}.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_inputregion
-	},
-
-	{
-		"LOAD",
-		"Load screen information from memory.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_OSCT,
-		screen_load
-	},
-	{
-		"MAXIMIZE",
-		"Maximize or restore the screen.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_maximize
-	},
-
-	{
-		"MINIMIZE",
-		"Minimize or restore the screen.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_minimize
-	},
-	{
-		"MOVE",
-		"Move the screen to the given position.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_move
-	},
-	{
-		"PRINT",
-		"Print the screen dump to the screen.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_print
-	},
-	{
-		"RAISE",
-		"Raise a screen event.",
-		SCREEN_FLAG_GET_ALL,
-		SCREEN_FLAG_GET_ALL,
-		SCREEN_FLAG_CSIP,
-		screen_raise
-	},
-	{
-		"REFRESH",
-		"Force a refresh of the screen.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_refresh
-	},
-	{
-		"RESCALE",
-		"Rescale the screen to {height} {width} pixels.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_rescale
-	},
-	{
-		"RESIZE",
-		"Resize the screen to {rows} {cols} characters.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_resize
-	},
-	{
-		"SAVE",
-		"Save screen information to memory.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_save
-	},
-
-	{
-		"SCROLLREGION",
-		"Set the scroll region to {square}.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_scrollregion
-	},
-
-	{
-		"SCROLLBAR",
-		"Scrollbar settings.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_scrollbar
-	},
-
-
-	{
-		"SET",
-		"Set screen information.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_OSCT,
-		screen_set
-	},
-	{
-		"SWAP",
-		"Swap the input and scroll region.",
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_GET_ONE,
-		SCREEN_FLAG_CSIP,
-		screen_swap
-	},
-	{
-		"", "", 0, 0, 0, NULL
-	}
-};
-
-
 struct timer_type timer_table[] =
 {
 	{    "Update Input"                },
@@ -1359,7 +1020,6 @@ struct event_type event_table[] =
 	{    "PRESSED ",                               0, EVENT_FLAG_MOUSE,    "MOUSE",     "mouse button is pressed"    },
 	{    "PROCESSED KEYPRESS",                     0, EVENT_FLAG_INPUT,    "INPUT",     "after a regular keypress"   },
 	{    "PROGRAM START",                          0, EVENT_FLAG_SYSTEM,   "SYSTEM",    "main session starts"        },
-
 	{    "PROGRAM TERMINATION",                    0, EVENT_FLAG_SYSTEM,   "SYSTEM",    "main session exists"        },
 	{    "READ ERROR",                             0, EVENT_FLAG_SYSTEM,   "SYSTEM",    "the read command fails"     },
 	{    "RECEIVED ERROR",                         0, EVENT_FLAG_SYSTEM,   "SYSTEM",    "an error is received"       },

+ 29 - 91
src/text.c

@@ -214,7 +214,9 @@ int word_wrap(struct session *ses, char *textin, char *textout, int flags, int *
 			lis = pti;
 		}
 
-		if (ses->cur_col > wrap)
+		size = get_vt102_width(ses, pti, &tab);
+
+		if (ses->cur_col > 1 && ses->cur_col + tab > wrap + 1)
 		{
 			cur_height++;
 
@@ -253,29 +255,7 @@ int word_wrap(struct session *ses, char *textin, char *textout, int flags, int *
 		}
 		else
 		{
-			if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
-			{
-				size = get_euc_width(ses, pti, &tab);
-
-				while (size--)
-				{
-					*pto++ = *pti++;
-				}
-				cur_width += tab;
-				ses->cur_col += tab;
-			}
-			else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(pti))
-			{
-				size = get_utf8_width(pti, &tab);
-
-				while (size--)
-				{
-					*pto++ = *pti++;
-				}
-				cur_width += tab;
-				ses->cur_col += tab;
-			}
-			else if (*pti == '\t')
+			if (*pti == '\t')
 			{
 				tab = ses->tab_width - (ses->cur_col - 1) % ses->tab_width;
 
@@ -292,10 +272,12 @@ int word_wrap(struct session *ses, char *textin, char *textout, int flags, int *
 			}
 			else
 			{
-				*pto++ = *pti++;
-
-				cur_width++;
-				ses->cur_col++;
+				while (size--)
+				{
+					*pto++ = *pti++;
+				}
+				cur_width += tab;
+				ses->cur_col += tab;
 			}
 		}
 	}
@@ -427,7 +409,9 @@ int word_wrap_split(struct session *ses, char *textin, char *textout, int wrap,
 			los = pto;
 		}
 
-		if (cur_col > wrap)
+		size = get_vt102_width(ses, pti, &tab);
+
+		if (cur_col > 1 && cur_col + tab > wrap + 1)
 		{
 			if (!HAS_BIT(flags, WRAP_FLAG_SPLIT) || (cur_height >= start && cur_height < end))
 			{
@@ -494,86 +478,40 @@ int word_wrap_split(struct session *ses, char *textin, char *textout, int wrap,
 			continue;
 		}
 
-		if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
+		if (*pti == '\t')
 		{
-			size = get_euc_width(ses, pti, &tab);
+			tab = ses->tab_width - (cur_col - 1) % ses->tab_width;
 
-			if (!HAS_BIT(flags, WRAP_FLAG_SPLIT) || (cur_height >= start && cur_height < end))
+			if (cur_col + tab >= wrap)
 			{
-				while (size--)
-				{
-					*pto++ = *pti++;
-				}
+				tab = (wrap - cur_col);
 			}
-			else
+
+			if (!HAS_BIT(flags, WRAP_FLAG_SPLIT) || (cur_height >= start && cur_height < end))
 			{
-				pti += size;
+				pto += sprintf(pto, "%.*s", tab, "                ");
 			}
+			pti++;
+
 			cur_width += tab;
 			cur_col += tab;
-		}
-		else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(pti))
-		{
-			size = get_utf8_width(pti, &tab);
-
-			if (size)
-			{
-				if (!HAS_BIT(flags, WRAP_FLAG_SPLIT) || (cur_height >= start && cur_height < end))
-				{
-					while (size--)
-					{
-						*pto++ = *pti++;
-					}
-				}
-				else
-				{
-					pti += size;
-				}
-				cur_width += tab;
-				cur_col += tab;
-			}
-			else
-			{
-				print_stdout(0, 0, "debug: word_wrap_split: utf8 error\n");
-				*pto++ = *pti++;
-				cur_width++;
-				cur_col++;
-			}
+			cur_space = cur_col;
 		}
 		else
 		{
-			if (*pti == '\t')
+			if (!HAS_BIT(flags, WRAP_FLAG_SPLIT) || (cur_height >= start && cur_height < end))
 			{
-				tab = ses->tab_width - (cur_col - 1) % ses->tab_width;
-
-				if (cur_col + tab >= wrap)
-				{
-					tab = (wrap - cur_col);
-				}
-
-				if (!HAS_BIT(flags, WRAP_FLAG_SPLIT) || (cur_height >= start && cur_height < end))
+				while (size--)
 				{
-					pto += sprintf(pto, "%.*s", tab, "                ");
+					*pto++ = *pti++;
 				}
-				pti++;
-
-				cur_width += tab;
-				cur_col += tab;
-				cur_space = cur_col;
 			}
 			else
 			{
-				if (!HAS_BIT(flags, WRAP_FLAG_SPLIT) || (cur_height >= start && cur_height < end))
-				{
-					*pto++ = *pti++;
-				}
-				else
-				{
-					pti++;
-				}
-				cur_width++;
-				cur_col++;
+				pti += size;
 			}
+			cur_width += tab;
+			cur_col += tab;
 		}
 	}
 	*pto = 0;

+ 27 - 322
src/tintin.h

@@ -203,7 +203,7 @@
 #define STRING_SIZE        2 * BUFFER_SIZE
 
 #define CLIENT_NAME              "TinTin++"
-#define CLIENT_VERSION           "2.02.04 "
+#define CLIENT_VERSION           "2.02.05 "
 
 
 #define XT_E                            0x27
@@ -471,51 +471,6 @@ enum operators
 #define CHAT_FLAG_DND                 BV08
 #define CHAT_FLAG_LINKLOST            BV09
 
-#define DRAW_FLAG_NONE                   0
-#define DRAW_FLAG_ASCII               BV01
-#define DRAW_FLAG_BLANKED             BV02
-#define DRAW_FLAG_BOT                 BV03
-#define DRAW_FLAG_BOXED               BV04
-#define DRAW_FLAG_BUMP                BV05
-#define DRAW_FLAG_CIRCLED             BV06
-#define DRAW_FLAG_COLOR1              BV07
-#define DRAW_FLAG_COLOR2              BV08
-#define DRAW_FLAG_CONVERT             BV09
-#define DRAW_FLAG_CORNERED            BV10
-#define DRAW_FLAG_CROSSED             BV11
-#define DRAW_FLAG_FILLED              BV12
-#define DRAW_FLAG_FOREGROUND          BV13
-#define DRAW_FLAG_GRID                BV14
-#define DRAW_FLAG_HOR                 BV15
-#define DRAW_FLAG_HUGE                BV16
-#define DRAW_FLAG_JEWELED             BV17
-#define DRAW_FLAG_LEFT                BV18
-//#define DRAW_FLAG_LINED               BV19 unused / obsolete
-#define DRAW_FLAG_NUMBERED            BV20
-#define DRAW_FLAG_PRUNED              BV21
-#define DRAW_FLAG_RIGHT               BV22
-#define DRAW_FLAG_ROUNDED             BV23
-#define DRAW_FLAG_SCALED              BV24
-#define DRAW_FLAG_SCROLL              BV25
-#define DRAW_FLAG_SHADOWED            BV26
-#define DRAW_FLAG_TEED                BV27
-#define DRAW_FLAG_TOP                 BV28
-#define DRAW_FLAG_TRACED              BV29
-#define DRAW_FLAG_TUBED               BV30
-#define DRAW_FLAG_UTF8                BV31
-#define DRAW_FLAG_VER                 BV32
-
-#define DRAW_FLAG_CURSIVE             BV33
-#define DRAW_FLAG_FAT                 BV34
-#define DRAW_FLAG_SANSSERIF           BV35
-#define DRAW_FLAG_CALIGN              BV36
-#define DRAW_FLAG_LALIGN              BV37
-#define DRAW_FLAG_RALIGN              BV38
-#define DRAW_FLAG_TALIGN              BV39
-#define DRAW_FLAG_UALIGN              BV40
-
-#define DRAW_FLAG_APPENDIX            DRAW_FLAG_CIRCLED|DRAW_FLAG_CORNERED|DRAW_FLAG_CROSSED|DRAW_FLAG_JEWELED|DRAW_FLAG_PRUNED|DRAW_FLAG_ROUNDED|DRAW_FLAG_TEED
-
 #define INPUT_FLAG_EDIT               BV01
 #define INPUT_FLAG_HISTORYBROWSE      BV02
 #define INPUT_FLAG_HISTORYSEARCH      BV03
@@ -564,10 +519,6 @@ enum operators
 #define MTTS_FLAG_PROXY               BV08
 #define MTTS_FLAG_TRUECOLOR           BV09
 
-#define SCAN_FLAG_NONE                0
-#define SCAN_FLAG_FILE                BV01
-#define SCAN_FLAG_SCAN                BV02
-
 #define SCREEN_FLAG_CSIP              BV01
 #define SCREEN_FLAG_OSCT              BV02
 #define SCREEN_FLAG_OMIT              BV03
@@ -644,13 +595,13 @@ enum operators
 #define TINTIN_FLAG_INHERITANCE       BV04
 #define TINTIN_FLAG_INSERTINPUT       BV05
 #define TINTIN_FLAG_CHILDLOCK         BV06
-#define TINTIN_FLAG_TERMINATE         BV06
-#define TINTIN_FLAG_MOUSETRACKING     BV07
-#define TINTIN_FLAG_DISPLAYUPDATE     BV08
-#define TINTIN_FLAG_DAEMONIZE         BV09
-#define TINTIN_FLAG_HIDDENCURSOR      BV10
-#define TINTIN_FLAG_LOCAL             BV11
-#define TINTIN_FLAG_PRESERVEMACRO     BV12
+#define TINTIN_FLAG_TERMINATE         BV07
+#define TINTIN_FLAG_MOUSETRACKING     BV08
+#define TINTIN_FLAG_DISPLAYUPDATE     BV09
+#define TINTIN_FLAG_DAEMONIZE         BV10
+#define TINTIN_FLAG_HIDDENCURSOR      BV11
+#define TINTIN_FLAG_LOCAL             BV12
+#define TINTIN_FLAG_PRESERVEMACRO     BV13
 
 
 #define CONFIG_FLAG_AUTOPATCH         BV01
@@ -1045,7 +996,7 @@ enum operators
 
 #define SCROLL(ses)               ((ses)->cur_row == 0 || ((ses)->cur_row >= (ses)->split->top_row && (ses)->cur_row <= (ses)->split->bot_row) || ((ses)->cur_row >= ses->input->top_row && (ses)->cur_row <= ses->input->bot_row))
 
-#define VERBATIM(ses)             (gtd->level->verbatim || (gtd->level->input == 0 && HAS_BIT((ses)->config_flags, CONFIG_FLAG_VERBATIM)) || HAS_BIT(gtd->flags, TINTIN_FLAG_CHILDLOCK))
+#define VERBATIM(ses)             (gtd->level->verbatim || (gtd->level->input == 0 && (HAS_BIT((ses)->config_flags, CONFIG_FLAG_VERBATIM) || HAS_BIT(gtd->flags, TINTIN_FLAG_CHILDLOCK))))
 
 
 
@@ -1232,7 +1183,8 @@ struct session
 	int                     read_max;
 	unsigned long long      connect_retry;
 	int                     connect_error;
-	char                    more_output[BUFFER_SIZE];
+//	char                    more_output[BUFFER_SIZE];
+	char                  * more_output;
 	int                     color;
 	char                    color_patch[100];
 	unsigned long long      packet_patch;
@@ -1631,10 +1583,8 @@ struct window_data
 	struct input_data      **buffer;
 };
 
-#define DO_ARRAY(array)       struct session *array (struct session *ses, struct listnode *list, char *arg, char *var, char *arg1, char *arg2)
 #define DO_BUFFER(buffer)               void buffer (struct session *ses, char *arg, char *arg1, char *arg2)
 #define DO_CHAT(chat)                     void chat (char *arg1, char *arg2)
-#define DO_CLASS(class)       struct session *class (struct session *ses, struct listnode *node, char *arg1, char *arg2)
 #define DO_COMMAND(command) struct session *command (struct session *ses, char *arg, char *arg1, char *arg2, char *arg3, char *arg4)
 #define DO_CONFIG(config)    struct session *config (struct session *ses, char *arg1, char *arg2, int index)
 #define DO_CURSOR(cursor)               void cursor (struct session *ses, char *arg)
@@ -1646,9 +1596,7 @@ struct window_data
 #define DO_MAP(map)                        void map (struct session *ses, char *arg, char *arg1, char *arg2)
 #define DO_PATH(path)                     void path (struct session *ses, char *arg)
 #define DO_PORT(port)          struct session *port (struct session *ses, char *arg1, char *arg2, char *arg)
-#define DO_SCAN(scan)          struct session *scan (struct session *ses, FILE *fp, char *arg, char *arg1, char *arg2)
-#define DO_SCREEN(screen)               void screen (struct session *ses, int ind, char *arg, char *arg1, char *arg2)
-#define DO_DRAW(draw)                     void draw (struct session *ses, int top_row, int top_col, int bot_row, int bot_col, int rows, int cols, long long flags, char *color, char *arg, char *arg1, char *arg2, char *arg3)
+
 
 /*
 	Typedefs
@@ -1656,15 +1604,12 @@ struct window_data
 
 typedef int             CMPFUNC (const void *a, const void *b);
 
-typedef struct session *ARRAY   (struct session *ses, struct listnode *list, char *arg, char *var, char *arg1, char *arg2);
 typedef void            BUFFER  (struct session *ses, char *arg, char *arg1, char *arg2);
 typedef void            CHAT    (char *arg1, char *arg2);
-typedef struct session *CLASS   (struct session *ses, struct listnode *node, char *left, char *right);
 typedef struct session *CONFIG  (struct session *ses, char *arg1, char *arg2, int index);
 typedef struct session *COMMAND (struct session *ses, char *arg, char *arg1, char *arg2, char *arg3, char *arg4);
 typedef void            CURSOR  (struct session *ses, char *arg);
 typedef void            DAEMON  (struct session *ses, char *arg, char *arg1, char *arg2);
-typedef void            DRAW    (struct session *ses, int top_row, int top_col, int bot_row, int bot_col, int rows, int cols, long long flags, char *color, char *arg, char *arg1, char *arg2, char *arg3);
 typedef struct session *EDIT    (struct session *ses, char *arg, char *arg1, char *arg2);
 typedef void            HISTORY (struct session *ses, char *arg, char *arg1, char *arg2);
 typedef void            LOG     (struct session *ses, char *arg, char *arg1, char *arg2);
@@ -1673,23 +1618,12 @@ typedef void            MAP     (struct session *ses, char *arg, char *arg1, cha
 typedef void            MSDP    (struct session *ses, struct port_data *buddy, int index);
 typedef void            PATH    (struct session *ses, char *arg);
 typedef struct session *PORT    (struct session *ses, char *arg1, char *arg2, char *arg);
-typedef struct session *SCAN    (struct session *ses, FILE *fp, char *arg, char *arg1, char *arg2);
-typedef void            SCREEN  (struct session *ses, int ind, char *arg, char *arg1, char *arg2);
-
-
 
 
 /*
 	Structures for tables.c
 */
 
-struct array_type
-{
-	char                  * name;
-	ARRAY                 * fun;
-	char                  * desc;
-};
-
 struct buffer_type
 {
 	char                  * name;
@@ -1706,12 +1640,6 @@ struct chat_type
 	char                  * desc;
 };
 
-struct class_type
-{
-	char                  * name;
-	CLASS                 * fun;
-};
-
 struct color_type
 {
 	char                  * name;
@@ -1752,14 +1680,6 @@ struct daemon_type
 	char                  * desc;
 };
 
-struct draw_type
-{
-	char                  * name;
-	char                  * desc;
-	int                     flags;
-	DRAW                  * fun;
-};
-
 struct edit_type
 {
 	char                  * name;
@@ -1886,25 +1806,6 @@ struct rank_type
 	int                     flags;
 };
 
-struct scan_type
-{
-	char                  * name;
-	SCAN                  * fun;
-	int                   flags;
-	char                  * desc;
-};
-
-struct screen_type
-{
-	char                  * name;
-	char                  * desc;
-	int                     get1;
-	int                     get2;
-	int                     flags;
-	SCREEN                * fun;
-};
-
-
 struct stamp_type
 {
 	char                  * name;
@@ -1930,14 +1831,6 @@ struct telopt_type
 	int                     flags;
 };
 
-
-
-
-/*
-	Various structures
-*/
-
-
 #endif
 
 
@@ -1946,34 +1839,6 @@ struct telopt_type
 */
 
 
-
-#ifndef __ARRAY_H__
-#define __ARRAY_H__
-
-extern DO_COMMAND(do_list);
-
-extern DO_ARRAY(array_add);
-extern DO_ARRAY(array_clear);
-extern DO_ARRAY(array_collapse);
-extern DO_ARRAY(array_create);
-extern DO_ARRAY(array_delete);
-extern DO_ARRAY(array_explode);
-extern DO_ARRAY(array_find);
-extern DO_ARRAY(array_get);
-extern DO_ARRAY(array_index);
-extern DO_ARRAY(array_insert);
-extern DO_ARRAY(array_order);
-extern DO_ARRAY(array_reverse);
-extern DO_ARRAY(array_set);
-extern DO_ARRAY(array_shuffle);
-extern DO_ARRAY(array_simplify);
-extern DO_ARRAY(array_size);
-extern DO_ARRAY(array_sort);
-extern DO_ARRAY(array_tokenize);
-
-#endif
-
-
 #ifndef __BANNER_H__
 #define __BANNER_H__
 
@@ -2071,34 +1936,9 @@ extern DO_CHAT(chat_zap);
 
 #endif
 
-
-#ifndef __CLASS_H__
-#define __CLASS_H__
-
-extern DO_COMMAND(do_class);
-
-extern  int count_class(struct session *ses, struct listnode *group);
-extern void parse_class(struct session *ses, char *input, struct listnode *group);
-
-extern DO_CLASS(class_assign);
-extern DO_CLASS(class_clear);
-extern DO_CLASS(class_close);
-extern DO_CLASS(class_kill);
-extern DO_CLASS(class_list);
-extern DO_CLASS(class_load);
-extern DO_CLASS(class_open);
-extern DO_CLASS(class_read);
-extern DO_CLASS(class_save);
-extern DO_CLASS(class_size);
-extern DO_CLASS(class_write);
-
-#endif
-
 #ifndef __COMMAND_H__
 #define __COMMAND_H__
 
-extern DO_COMMAND(do_commands);
-
 extern void init_commands(void);
 
 #endif
@@ -2256,8 +2096,6 @@ extern DO_MAP(map_write);
 #ifndef __TT_MATH_H__
 #define __TT_MATH_H__
 
-extern DO_COMMAND(do_math);
-
 extern int is_math(struct session *ses, char *str);
 extern int get_ellipsis(struct listroot *root, char *name, int *min, int *max);
 extern long double get_number(struct session *ses, char *str);
@@ -2341,11 +2179,6 @@ extern void winch_daemon(void);
 #define __DATA_H__
 
 extern DO_COMMAND(do_kill);
-extern DO_COMMAND(do_killall);
-extern DO_COMMAND(do_message);
-extern DO_COMMAND(do_ignore);
-extern DO_COMMAND(do_debug);
-
 
 extern void kill_list(struct listroot *root);
 extern void free_list(struct listroot *root);
@@ -2428,36 +2261,14 @@ extern void remove_line(struct edit_data *edit, int index);
 
 extern DO_COMMAND(do_draw);
 
-extern void scale_drawing(struct session *ses, int *top_row, int *top_col, int *bot_row, int *bot_col, int *rows, int *cols, int index, long long flags, char *arg);
-
-extern DO_DRAW(draw_blank);
-extern DO_DRAW(draw_bot_side);
-extern DO_DRAW(draw_arg);
-extern DO_DRAW(draw_box);
-extern DO_DRAW(draw_buffer);
-extern DO_DRAW(draw_corner);
-extern DO_DRAW(draw_horizontal_line);
-extern DO_DRAW(draw_left_side);
-extern DO_DRAW(draw_line);
-extern DO_DRAW(draw_map);
-extern DO_DRAW(draw_right_side);
-extern DO_DRAW(draw_side);
-extern DO_DRAW(draw_square);
-extern DO_DRAW(draw_rain);
-extern DO_DRAW(draw_table_grid);
-extern DO_DRAW(draw_text);
-extern DO_DRAW(draw_top_side);
-//extern DO_DRAW(draw_vertical_line);
-extern DO_DRAW(draw_vertical_lines);
-
 #endif
 
 
 #ifndef __EVENT_H__
 #define __EVENT_H__
 
-extern DO_COMMAND(do_event);
-extern DO_COMMAND(do_unevent);
+//extern DO_COMMAND(do_event);
+//extern DO_COMMAND(do_unevent);
 
 extern  int check_all_events(struct session *ses, int flags, int args, int vars, char *fmt, ...);
 extern void mouse_handler(struct session *ses, int val1, int val2, int val3);
@@ -2490,6 +2301,7 @@ extern DO_COMMAND(do_help);
 #define __HISTORY_H__
 
 extern DO_COMMAND(do_history);
+
 extern void add_line_history(struct session *ses, char *line);
 extern void insert_line_history(struct session *ses, char *line);
 extern struct session *repeat_history(struct session *ses, char *line);
@@ -2512,6 +2324,7 @@ DO_HISTORY(history_write);
 #define __LINE_H__
 
 extern DO_COMMAND(do_line);
+
 extern DO_LINE(line_background);
 extern DO_LINE(line_benchmark);
 extern DO_LINE(line_capture);
@@ -2538,8 +2351,6 @@ extern DO_LINE(line_verbose);
 #ifndef __LOG_H__
 #define __LOG_H__
 
-extern DO_COMMAND(do_log);
-
 DO_LOG(log_append);
 DO_LOG(log_info);
 DO_LOG(log_overwrite);
@@ -2626,20 +2437,9 @@ extern char *str_alloc_stack(int size);
 #ifndef __MISC_H__
 #define __MISC_H__
 
-extern DO_COMMAND(do_all);
-extern DO_COMMAND(do_bell);
-
-extern DO_COMMAND(do_cr);
-extern DO_COMMAND(do_echo);
 extern DO_COMMAND(do_end);
-extern DO_COMMAND(do_forall);
-extern DO_COMMAND(do_info);
 extern DO_COMMAND(do_nop);
-extern DO_COMMAND(do_send);
-extern DO_COMMAND(do_snoop);
-extern DO_COMMAND(do_suspend);
 extern DO_COMMAND(do_test);
-extern DO_COMMAND(do_zap);
 
 #endif
 
@@ -2691,7 +2491,7 @@ extern struct listnode *get_nest_node_key(struct listroot *root, char *variable,
 extern struct listnode *get_nest_node_val(struct listroot *root, char *variable, char **result, int def);
 extern int get_nest_index(struct listroot *root, char *variable, char **result, int def);
 extern void show_nest_node(struct listnode *node, char **result, int initialize);
-extern void view_nest_node(struct listnode *node, char **str_result, int nest, int initialize);
+extern void view_nest_node(struct listnode *node, char **str_result, int nest, int initialize, int color);
 extern struct listnode *set_nest_node_ses(struct session *ses, char *arg1, char *format, ...);
 extern struct listnode *add_nest_node_ses(struct session *ses, char *arg1, char *format, ...);
 extern struct listnode *set_nest_node(struct listroot *root, char *arg1, char *format, ...);
@@ -2751,9 +2551,7 @@ extern void do_one_line(char *line, struct session *ses);
 #ifndef __PATH_H__
 #define __PATH_H__
 
-extern DO_COMMAND(do_path);
 extern DO_COMMAND(do_pathdir);
-extern DO_COMMAND(do_unpathdir);
 
 int is_pathdir(struct session *ses, char *dir);
 int exit_to_dir(struct session *ses, char *name);
@@ -2793,8 +2591,6 @@ extern DO_PATH(path_end);
 #ifndef __PORT_H__
 #define __PORT_H__
 
-
-extern DO_COMMAND(do_port);
 extern DO_PORT(port_call);
 extern DO_PORT(port_color);
 extern DO_PORT(port_flag);
@@ -2831,51 +2627,11 @@ extern struct port_data *find_port_group(struct session *ses, char *arg);
 
 #endif
 
-#ifndef __SCAN_H__
-#define __SCAN_H__
-
-extern DO_COMMAND(do_scan);
-
-DO_SCAN(scan_abort);
-DO_SCAN(scan_csv);
-DO_SCAN(scan_dir);
-DO_SCAN(scan_file);
-DO_SCAN(scan_forward);
-DO_SCAN(scan_tsv);
-DO_SCAN(scan_txt);
-
-#endif
-
 #ifndef __SCREEN_H__
 #define __SCREEN_H__
 
 extern DO_COMMAND(do_screen);
 
-extern DO_SCREEN(screen_blur);
-extern DO_SCREEN(screen_clear);
-extern DO_SCREEN(screen_cursor);
-extern DO_SCREEN(screen_dump);
-extern DO_SCREEN(screen_fill);
-extern DO_SCREEN(screen_focus);
-extern DO_SCREEN(screen_fullscreen);
-extern DO_SCREEN(screen_get);
-extern DO_SCREEN(screen_info);
-extern DO_SCREEN(screen_inputregion);
-extern DO_SCREEN(screen_load);
-extern DO_SCREEN(screen_maximize);
-extern DO_SCREEN(screen_minimize);
-extern DO_SCREEN(screen_move);
-extern DO_SCREEN(screen_print);
-extern DO_SCREEN(screen_raise);
-extern DO_SCREEN(screen_refresh);
-extern DO_SCREEN(screen_resize);
-extern DO_SCREEN(screen_rescale);
-extern DO_SCREEN(screen_save);
-extern DO_SCREEN(screen_scrollbar);
-extern DO_SCREEN(screen_scrollregion);
-extern DO_SCREEN(screen_set);
-extern DO_SCREEN(screen_swap);
-
 extern void init_inputregion(struct session *ses, int top_row, int top_col, int bot_row, int bot_col);
 extern  int get_row_index(struct session *ses, int val);
 extern  int get_col_index(struct session *ses, int val);
@@ -2923,6 +2679,9 @@ extern void get_word_screen(char *str, int row, int col);
 #define __SESSION_H__
 
 extern DO_COMMAND(do_session);
+extern DO_COMMAND(do_snoop);
+extern DO_COMMAND(do_zap);
+
 extern struct session *session_command(char *arg, struct session *ses);
 extern void show_session(struct session *ses, struct session *ptr);
 extern struct session *find_session(char *name);
@@ -2939,8 +2698,6 @@ extern void dispose_session(struct session *ses);
 #ifndef __SHOW_H__
 #define __SHOW_H__
 
-extern DO_COMMAND(do_showme);
-
 extern void show_message(struct session *ses, int index, char *format, ...);
 extern void show_error(struct session *ses, int index, char *format, ...);
 extern void show_debug(struct session *ses, int index, char *format, ...);
@@ -2988,8 +2745,6 @@ extern void split_show(struct session *ses, char *prompt, char *row, char *col);
 #ifndef __SSL_H__
 #define __SSL_H__
 
-extern DO_COMMAND(do_ssl);
-
 extern gnutls_session_t ssl_negotiate(struct session *ses);
 
 #endif
@@ -3036,12 +2791,7 @@ extern int substitute_color(char *input, char *output, int colors);
 #ifndef __SYSTEM_H__
 #define __SYSTEM_H__
 
-
-extern DO_COMMAND(do_run);
-
-extern DO_COMMAND(do_script);
-extern DO_COMMAND(do_system);
-extern DO_COMMAND(do_textin);
+extern DO_COMMAND(do_suspend);
 
 #endif
 
@@ -3049,18 +2799,15 @@ extern DO_COMMAND(do_textin);
 #ifndef __TABLES_H__
 #define __TABLES_H__
 
-extern struct array_type array_table[];
 extern struct buffer_type buffer_table[];
 extern struct chat_type chat_table[];
 extern   char character_table[];
-extern struct class_type class_table[];
 extern struct color_type color_table[];
 extern struct color_type map_color_table[];
-//extern struct command_type command_table[];
 extern struct config_type config_table[];
 extern struct cursor_type cursor_table[];
 extern struct daemon_type daemon_table[];
-extern struct draw_type draw_table[];
+//extern struct draw_type draw_table[];
 extern struct edit_type edit_table[];
 extern struct event_type event_table[];
 extern struct history_type history_table[];
@@ -3071,13 +2818,13 @@ extern struct map_type map_table[];
 extern struct path_type path_table[];
 extern struct port_type port_table[];
 extern struct rank_type rank_table[];
-extern struct scan_type scan_table[];
+//extern struct scan_type scan_table[];
 extern struct stamp_type huge_stamp_table[];
 extern struct substitution_type substitution_table[];
 extern struct telopt_type telopt_table[];
 extern   char *telcmds[];
 extern struct timer_type timer_table[];
-extern struct screen_type screen_table[];
+//extern struct screen_type screen_table[];
 extern struct map_legend_type map_legend_table[];
 extern struct map_legend_group_type map_legend_group_table[];
 
@@ -3167,50 +2914,16 @@ extern char *script_viewer(struct session *ses, char *str);
 #ifndef __TRIGGER_H__
 #define __TRIGGER_H__
 
+extern DO_COMMAND(do_delay);
 
-DO_COMMAND(do_action);
-DO_COMMAND(do_unaction);
 extern void check_all_actions(struct session *ses, char *original, char *line, char *buf);
-
-DO_COMMAND(do_alias);
-DO_COMMAND(do_unalias);
-extern int check_all_aliases(struct session *ses, char *input);
-
-DO_COMMAND(do_button);
-DO_COMMAND(do_unbutton);
+extern  int check_all_aliases(struct session *ses, char *input);
 extern void check_all_buttons(struct session *ses, short row, short col, char *arg1, char *arg2, char *word, char *line);
-
-extern DO_COMMAND(do_delay);
-extern DO_COMMAND(do_undelay);
-
-extern DO_COMMAND(do_function);
-extern DO_COMMAND(do_unfunction);
-
-extern DO_COMMAND(do_gag);
-extern DO_COMMAND(do_ungag);
 extern void check_all_gags(struct session *ses, char *original, char *line);
-
-extern DO_COMMAND(do_highlight);
-extern DO_COMMAND(do_unhighlight);
 extern void check_all_highlights(struct session *ses, char *original, char *line);
-
-extern DO_COMMAND(do_macro);
-extern DO_COMMAND(do_unmacro);
-
-extern DO_COMMAND(do_prompt);
-extern DO_COMMAND(do_unprompt);
-extern int check_all_prompts(struct session *ses, char *original, char *line);
-
-extern DO_COMMAND(do_substitute);
-extern DO_COMMAND(do_unsubstitute);
+extern  int check_all_prompts(struct session *ses, char *original, char *line);
 extern void check_all_substitutions(struct session *ses, char *original, char *line);
 
-extern DO_COMMAND(do_tab);
-extern DO_COMMAND(do_untab);
-
-extern DO_COMMAND(do_tick);
-extern DO_COMMAND(do_untick);
-
 #endif
 
 // update.c
@@ -3291,14 +3004,6 @@ extern int utf8_to_cp1251(char *input, char *output);
 #ifndef __VARIABLE_H__
 #define __VARIABLE_H__
 
-extern DO_COMMAND(do_variable);
-extern DO_COMMAND(do_unvariable);
-extern DO_COMMAND(do_local);
-extern DO_COMMAND(do_cat);
-extern DO_COMMAND(do_format);
-extern DO_COMMAND(do_replace);
-
-
 extern  int valid_variable(struct session *ses, char *arg);
 extern  int string_raw_str_len(struct session *ses, char *str, int start, int end);
 extern  int string_str_raw_len(struct session *ses, char *str, int start, int end);

+ 2 - 2
src/tokenize.c

@@ -893,7 +893,7 @@ struct scriptnode *parse_script(struct scriptroot *root, int lvl, struct scriptn
 
 				if (*token->data->arg == 0)
 				{
-					token->type++;
+//					token->type++;
 
 					do
 					{
@@ -958,7 +958,7 @@ struct scriptnode *parse_script(struct scriptroot *root, int lvl, struct scriptn
 
 					if (*token->data->arg == 0)
 					{
-						token->type++;
+//						token->type++;
 
 						do
 						{

+ 1 - 1
src/update.c

@@ -1016,7 +1016,7 @@ void packet_update(void)
 			{
 				strcpy(result, ses->more_output);
 			}
-			ses->more_output[0] = 0;
+			str_cpy(&ses->more_output, "");
 
 			process_mud_output(ses, result, TRUE);
 

Plik diff jest za duży
+ 41 - 13
src/utf8.c


+ 1 - 1
src/utils.c

@@ -505,7 +505,7 @@ char *indent(int len)
 
 	if (outbuf[len][0] == 0)
 	{
-		sprintf(outbuf[len], "%*s", len * 5, "");
+		sprintf(outbuf[len], "%*s", len * 4, "");
 	}
 
 	return outbuf[len];

+ 55 - 10
src/variable.c

@@ -51,7 +51,7 @@ DO_COMMAND(do_variable)
 
 				str_result = str_alloc_stack(0);
 
-				view_nest_node(node, &str_result, 0, 1);
+				view_nest_node(node, &str_result, 0, TRUE, TRUE);
 
 				print_lines(ses, SUB_NONE, COLOR_TINTIN "%c" COLOR_COMMAND "%s " COLOR_BRACE "{" COLOR_STRING "%s" COLOR_BRACE "}\n{\n" COLOR_STRING "%s" COLOR_BRACE "}" COLOR_RESET "\n", gtd->tintin_char, list_table[LIST_VARIABLE].name, node->arg1, str_result);
 			}
@@ -96,6 +96,27 @@ DO_COMMAND(do_variable)
 	return ses;
 }
 
+DO_COMMAND(do_unvariable)
+{
+	arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
+
+	do
+	{
+		if (delete_nest_node(ses->list[LIST_VARIABLE], arg1))
+		{
+			show_message(ses, LIST_VARIABLE, "#OK. {%s} IS NO LONGER A VARIABLE.", arg1);
+		}
+		else
+		{
+			delete_node_with_wild(ses, LIST_VARIABLE, arg1);
+		}
+		arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
+	}
+	while (*arg1);
+
+	return ses;
+}
+
 DO_COMMAND(do_local)
 {
 	char *str;
@@ -162,19 +183,41 @@ DO_COMMAND(do_local)
 	return ses;
 }
 
-DO_COMMAND(do_unvariable)
+DO_COMMAND(do_unlocal)
 {
+	struct listroot *root;
+	int index, found;
+
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
 
+	root = local_list(ses);
+
 	do
 	{
-		if (delete_nest_node(ses->list[LIST_VARIABLE], arg1))
+		if (delete_nest_node(root, arg1))
 		{
-			show_message(ses, LIST_VARIABLE, "#OK. {%s} IS NO LONGER A VARIABLE.", arg1);
+			show_message(ses, LIST_VARIABLE, "#OK. {%s} IS NO LONGER A LOCAL VARIABLE.", arg1);
 		}
 		else
 		{
-			delete_node_with_wild(ses, LIST_VARIABLE, arg1);
+			found = FALSE;
+
+			for (index = root->used - 1 ; index >= 0 ; index--)
+			{
+				if (match(ses, root->list[index]->arg1, arg1, SUB_VAR|SUB_FUN))
+				{
+					show_message(ses, LIST_VARIABLE, "#OK. {%s} IS NO LONGER A LOCAL VARIABLE.", root->list[index]->arg1);
+
+					delete_index_list(root, index);
+
+					found = TRUE;
+				}
+			}
+
+			if (found == 0)
+			{
+				show_message(ses, LIST_VARIABLE, "#UNLOCAL: NO MATCHES FOUND FOR {%s}.", arg1);
+			}
 		}
 		arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
 	}
@@ -185,7 +228,7 @@ DO_COMMAND(do_unvariable)
 
 DO_COMMAND(do_cat)
 {
-	char *str;
+	char *str, name[BUFFER_SIZE];
 	struct listroot *root;
 	struct listnode *node;
 
@@ -203,17 +246,19 @@ DO_COMMAND(do_cat)
 		{
 			arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
 
-			node = set_nest_node(ses->list[LIST_VARIABLE], arg1, "%s", str);
+			node = set_nest_node(ses->list[LIST_VARIABLE], arg1, "");
 		}
 
 		root = search_nest_base_ses(ses, arg1);
 
+		get_arg_to_brackets(ses, arg1, name);
+
+		check_all_events(ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATE %s", name, name, node->arg2, arg1);
+
 		while (*arg)
 		{
 			arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
 
-			check_all_events(ses, EVENT_FLAG_VARIABLE, 1, 2, "VARIABLE UPDATE %s", arg1, arg1, str);
-
 			if (*str)
 			{
 				if (node->root)
@@ -227,7 +272,7 @@ DO_COMMAND(do_cat)
 			}
 		}
 
-		check_all_events(ses, EVENT_FLAG_VARIABLE, 1, 1, "VARIABLE UPDATED %s", arg1, arg1, str);
+		check_all_events(ses, EVENT_FLAG_VARIABLE, 1, 3, "VARIABLE UPDATED %s", name, name, node->arg2, arg1);
 
 		show_nest_node(node, &str, 1);
 

+ 10 - 16
src/vt102.c

@@ -136,16 +136,17 @@ void scroll_region(struct session *ses, int top, int bot)
 {
 	push_call("scroll_region(%p,%d,%d)",ses,top,bot);
 
-	if (top != 1)
-	{
-//		print_stdout(0, 0, "\e[?1047h\e[?1007h\e[?7786h\e[?7787h\e[%d;%dr", top, bot);
-		print_stdout(0, 0, "\e[?1047h\e[?7787h\e[%d;%dr", top, bot);
-	}
-	else
+	if (ses == gtd->ses)
 	{
-		print_stdout(0, 0, "\e[?1047l\e[?7787l\e[%d;%dr", top, bot);
+		if (top != 1)
+		{
+			print_stdout(0, 0, "\e[?1047h\e[?7787h\e[%d;%dr", top, bot);
+		}
+		else
+		{
+			print_stdout(0, 0, "\e[?1047l\e[?7787l\e[%d;%dr", top, bot);
+		}
 	}
-
 	ses->split->top_row = top;
 	ses->split->bot_row = bot;
 
@@ -159,14 +160,7 @@ void reset_scroll_region(struct session *ses)
 {
 	if (ses == gtd->ses)
 	{
-		if (ses->split->top_row != 1)
-		{
-			print_stdout(0, 0, "\e[?1047l\e[?7787l\e[r");
-		}
-		else
-		{
-			print_stdout(0, 0, "\e[r");
-		}
+		print_stdout(0, 0, "\e[?1047l\e[?7787l\e[r");
 	}
 	ses->split->top_row = 1;
 	ses->split->top_col = 1;

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików