xref: /titanic_50/usr/src/cmd/mdb/common/mdb/mdb_cmdbuf.c (revision cd31838b5d981a4341d3522bb2b1dda71efd9fea)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5b2a1c443Svb160487  * Common Development and Distribution License (the "License").
6b2a1c443Svb160487  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*cd31838bSvb160487  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * The MDB command buffer is a simple structure that keeps track of the
307c478bd9Sstevel@tonic-gate  * command history list, and provides operations to manipulate the current
317c478bd9Sstevel@tonic-gate  * buffer according to the various emacs editing options.  The terminal
327c478bd9Sstevel@tonic-gate  * code uses this code to keep track of the actual contents of the command
337c478bd9Sstevel@tonic-gate  * line, and then uses this content to perform redraw operations.
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <strings.h>
377c478bd9Sstevel@tonic-gate #include <stdio.h>
387c478bd9Sstevel@tonic-gate #include <ctype.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
417c478bd9Sstevel@tonic-gate #include <mdb/mdb_cmdbuf.h>
427c478bd9Sstevel@tonic-gate #include <mdb/mdb_debug.h>
437c478bd9Sstevel@tonic-gate #include <mdb/mdb.h>
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #define	CMDBUF_LINELEN	BUFSIZ		/* Length of each buffer line */
467c478bd9Sstevel@tonic-gate #define	CMDBUF_TABLEN	8		/* Length of a tab in spaces */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate static void
cmdbuf_shiftr(mdb_cmdbuf_t * cmd,size_t nbytes)497c478bd9Sstevel@tonic-gate cmdbuf_shiftr(mdb_cmdbuf_t *cmd, size_t nbytes)
507c478bd9Sstevel@tonic-gate {
517c478bd9Sstevel@tonic-gate 	bcopy(&cmd->cmd_buf[cmd->cmd_bufidx],
527c478bd9Sstevel@tonic-gate 	    &cmd->cmd_buf[cmd->cmd_bufidx + nbytes],
537c478bd9Sstevel@tonic-gate 	    cmd->cmd_buflen - cmd->cmd_bufidx);
547c478bd9Sstevel@tonic-gate }
557c478bd9Sstevel@tonic-gate 
56b2a1c443Svb160487 static void
mdb_cmdbuf_allocchunk(mdb_cmdbuf_t * cmd)57b2a1c443Svb160487 mdb_cmdbuf_allocchunk(mdb_cmdbuf_t *cmd)
58b2a1c443Svb160487 {
59b2a1c443Svb160487 	int i;
60b2a1c443Svb160487 	char **newhistory;
61b2a1c443Svb160487 	ssize_t newhalloc = cmd->cmd_halloc + MDB_DEF_HISTLEN;
62b2a1c443Svb160487 
63b2a1c443Svb160487 	if (newhalloc > cmd->cmd_histlen)
64b2a1c443Svb160487 		newhalloc = cmd->cmd_histlen;
65b2a1c443Svb160487 	newhistory = mdb_alloc(newhalloc * sizeof (char *), UM_SLEEP);
66b2a1c443Svb160487 	bcopy(cmd->cmd_history, newhistory, cmd->cmd_halloc * sizeof (char *));
67b2a1c443Svb160487 	mdb_free(cmd->cmd_history, cmd->cmd_halloc * sizeof (char *));
68b2a1c443Svb160487 	for (i = cmd->cmd_halloc; i < newhalloc; i++)
69b2a1c443Svb160487 		newhistory[i] = mdb_alloc(CMDBUF_LINELEN, UM_SLEEP);
70b2a1c443Svb160487 	cmd->cmd_history = newhistory;
71b2a1c443Svb160487 	cmd->cmd_halloc = newhalloc;
72b2a1c443Svb160487 }
73b2a1c443Svb160487 
747c478bd9Sstevel@tonic-gate void
mdb_cmdbuf_create(mdb_cmdbuf_t * cmd)757c478bd9Sstevel@tonic-gate mdb_cmdbuf_create(mdb_cmdbuf_t *cmd)
767c478bd9Sstevel@tonic-gate {
777c478bd9Sstevel@tonic-gate 	size_t i;
787c478bd9Sstevel@tonic-gate 
79b2a1c443Svb160487 	cmd->cmd_halloc = MDB_DEF_HISTLEN < mdb.m_histlen ?
80b2a1c443Svb160487 	    MDB_DEF_HISTLEN : mdb.m_histlen;
81b2a1c443Svb160487 
82b2a1c443Svb160487 	cmd->cmd_history = mdb_alloc(cmd->cmd_halloc * sizeof (char *),
83b2a1c443Svb160487 	    UM_SLEEP);
847c478bd9Sstevel@tonic-gate 	cmd->cmd_linebuf = mdb_alloc(CMDBUF_LINELEN, UM_SLEEP);
857c478bd9Sstevel@tonic-gate 
86b2a1c443Svb160487 	for (i = 0; i < cmd->cmd_halloc; i++)
877c478bd9Sstevel@tonic-gate 		cmd->cmd_history[i] = mdb_alloc(CMDBUF_LINELEN, UM_SLEEP);
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	cmd->cmd_buf = cmd->cmd_history[0];
907c478bd9Sstevel@tonic-gate 	cmd->cmd_linelen = CMDBUF_LINELEN;
917c478bd9Sstevel@tonic-gate 	cmd->cmd_histlen = mdb.m_histlen;
927c478bd9Sstevel@tonic-gate 	cmd->cmd_buflen = 0;
937c478bd9Sstevel@tonic-gate 	cmd->cmd_bufidx = 0;
947c478bd9Sstevel@tonic-gate 	cmd->cmd_hold = 0;
957c478bd9Sstevel@tonic-gate 	cmd->cmd_hnew = 0;
967c478bd9Sstevel@tonic-gate 	cmd->cmd_hcur = 0;
977c478bd9Sstevel@tonic-gate 	cmd->cmd_hlen = 0;
987c478bd9Sstevel@tonic-gate }
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate void
mdb_cmdbuf_destroy(mdb_cmdbuf_t * cmd)1017c478bd9Sstevel@tonic-gate mdb_cmdbuf_destroy(mdb_cmdbuf_t *cmd)
1027c478bd9Sstevel@tonic-gate {
1037c478bd9Sstevel@tonic-gate 	size_t i;
1047c478bd9Sstevel@tonic-gate 
105b2a1c443Svb160487 	for (i = 0; i < cmd->cmd_halloc; i++)
1067c478bd9Sstevel@tonic-gate 		mdb_free(cmd->cmd_history[i], CMDBUF_LINELEN);
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 	mdb_free(cmd->cmd_linebuf, CMDBUF_LINELEN);
109b2a1c443Svb160487 	mdb_free(cmd->cmd_history, cmd->cmd_halloc * sizeof (char *));
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_caninsert(mdb_cmdbuf_t * cmd,size_t nbytes)1137c478bd9Sstevel@tonic-gate mdb_cmdbuf_caninsert(mdb_cmdbuf_t *cmd, size_t nbytes)
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate 	return (cmd->cmd_buflen + nbytes < cmd->cmd_linelen);
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_atstart(mdb_cmdbuf_t * cmd)1197c478bd9Sstevel@tonic-gate mdb_cmdbuf_atstart(mdb_cmdbuf_t *cmd)
1207c478bd9Sstevel@tonic-gate {
1217c478bd9Sstevel@tonic-gate 	return (cmd->cmd_bufidx == 0);
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_atend(mdb_cmdbuf_t * cmd)1257c478bd9Sstevel@tonic-gate mdb_cmdbuf_atend(mdb_cmdbuf_t *cmd)
1267c478bd9Sstevel@tonic-gate {
1277c478bd9Sstevel@tonic-gate 	return (cmd->cmd_bufidx == cmd->cmd_buflen);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_insert(mdb_cmdbuf_t * cmd,int c)1317c478bd9Sstevel@tonic-gate mdb_cmdbuf_insert(mdb_cmdbuf_t *cmd, int c)
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate 	if (c == '\t') {
1347c478bd9Sstevel@tonic-gate 		if (cmd->cmd_buflen + CMDBUF_TABLEN < cmd->cmd_linelen) {
1357c478bd9Sstevel@tonic-gate 			int i;
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 			if (cmd->cmd_buflen != cmd->cmd_bufidx)
1387c478bd9Sstevel@tonic-gate 				cmdbuf_shiftr(cmd, CMDBUF_TABLEN);
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 			for (i = 0; i < CMDBUF_TABLEN; i++)
1417c478bd9Sstevel@tonic-gate 				cmd->cmd_buf[cmd->cmd_bufidx++] = ' ';
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 			cmd->cmd_buflen += CMDBUF_TABLEN;
1447c478bd9Sstevel@tonic-gate 			return (0);
1457c478bd9Sstevel@tonic-gate 		}
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 		return (-1);
1487c478bd9Sstevel@tonic-gate 	}
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	if (c < ' ' || c > '~')
1517c478bd9Sstevel@tonic-gate 		return (-1);
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	if (cmd->cmd_buflen < cmd->cmd_linelen) {
1547c478bd9Sstevel@tonic-gate 		if (cmd->cmd_buflen != cmd->cmd_bufidx)
1557c478bd9Sstevel@tonic-gate 			cmdbuf_shiftr(cmd, 1);
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 		cmd->cmd_buf[cmd->cmd_bufidx++] = (char)c;
1587c478bd9Sstevel@tonic-gate 		cmd->cmd_buflen++;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 		return (0);
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	return (-1);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate const char *
mdb_cmdbuf_accept(mdb_cmdbuf_t * cmd)1677c478bd9Sstevel@tonic-gate mdb_cmdbuf_accept(mdb_cmdbuf_t *cmd)
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx < cmd->cmd_linelen) {
170*cd31838bSvb160487 		int is_repeating = 0;
171*cd31838bSvb160487 
1727c478bd9Sstevel@tonic-gate 		cmd->cmd_buf[cmd->cmd_buflen++] = '\0';
1737c478bd9Sstevel@tonic-gate 		(void) strcpy(cmd->cmd_linebuf, cmd->cmd_buf);
1747c478bd9Sstevel@tonic-gate 
175*cd31838bSvb160487 		if (cmd->cmd_hold != cmd->cmd_hnew) {
176*cd31838bSvb160487 			int lastidx = cmd->cmd_hnew == 0 ? cmd->cmd_halloc - 1 :
177*cd31838bSvb160487 			    cmd->cmd_hnew - 1;
178*cd31838bSvb160487 
179*cd31838bSvb160487 			is_repeating = strcmp(cmd->cmd_buf,
180*cd31838bSvb160487 			    cmd->cmd_history[lastidx]) == 0;
181*cd31838bSvb160487 		}
182*cd31838bSvb160487 
1837c478bd9Sstevel@tonic-gate 		/*
184*cd31838bSvb160487 		 * Don't bother inserting empty or repeating buffers into the
185*cd31838bSvb160487 		 * history ring.
1867c478bd9Sstevel@tonic-gate 		 */
187*cd31838bSvb160487 		if (cmd->cmd_buflen > 1 && !is_repeating) {
1887c478bd9Sstevel@tonic-gate 			cmd->cmd_hnew = (cmd->cmd_hnew + 1) % cmd->cmd_histlen;
189b2a1c443Svb160487 			if (cmd->cmd_hnew >= cmd->cmd_halloc)
190b2a1c443Svb160487 				mdb_cmdbuf_allocchunk(cmd);
191b2a1c443Svb160487 
1927c478bd9Sstevel@tonic-gate 			cmd->cmd_buf = cmd->cmd_history[cmd->cmd_hnew];
1937c478bd9Sstevel@tonic-gate 			cmd->cmd_hcur = cmd->cmd_hnew;
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 			if (cmd->cmd_hlen + 1 == cmd->cmd_histlen)
1967c478bd9Sstevel@tonic-gate 				cmd->cmd_hold =
1977c478bd9Sstevel@tonic-gate 				    (cmd->cmd_hold + 1) % cmd->cmd_histlen;
1987c478bd9Sstevel@tonic-gate 			else
1997c478bd9Sstevel@tonic-gate 				cmd->cmd_hlen++;
200*cd31838bSvb160487 		} else if (is_repeating) {
201*cd31838bSvb160487 			cmd->cmd_hcur = cmd->cmd_hnew;
2027c478bd9Sstevel@tonic-gate 		}
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 		cmd->cmd_bufidx = 0;
2057c478bd9Sstevel@tonic-gate 		cmd->cmd_buflen = 0;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 		return ((const char *)cmd->cmd_linebuf);
2087c478bd9Sstevel@tonic-gate 	}
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	return (NULL);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2147c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_backspace(mdb_cmdbuf_t * cmd,int c)2157c478bd9Sstevel@tonic-gate mdb_cmdbuf_backspace(mdb_cmdbuf_t *cmd, int c)
2167c478bd9Sstevel@tonic-gate {
2177c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx > 0) {
2187c478bd9Sstevel@tonic-gate 		if (cmd->cmd_buflen != cmd->cmd_bufidx) {
2197c478bd9Sstevel@tonic-gate 			bcopy(&cmd->cmd_buf[cmd->cmd_bufidx],
2207c478bd9Sstevel@tonic-gate 			    &cmd->cmd_buf[cmd->cmd_bufidx - 1],
2217c478bd9Sstevel@tonic-gate 			    cmd->cmd_buflen - cmd->cmd_bufidx);
2227c478bd9Sstevel@tonic-gate 		}
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 		cmd->cmd_bufidx--;
2257c478bd9Sstevel@tonic-gate 		cmd->cmd_buflen--;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 		return (0);
2287c478bd9Sstevel@tonic-gate 	}
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	return (-1);
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2347c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_delchar(mdb_cmdbuf_t * cmd,int c)2357c478bd9Sstevel@tonic-gate mdb_cmdbuf_delchar(mdb_cmdbuf_t *cmd, int c)
2367c478bd9Sstevel@tonic-gate {
2377c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx < cmd->cmd_buflen) {
2387c478bd9Sstevel@tonic-gate 		if (cmd->cmd_bufidx < --cmd->cmd_buflen) {
2397c478bd9Sstevel@tonic-gate 			bcopy(&cmd->cmd_buf[cmd->cmd_bufidx + 1],
2407c478bd9Sstevel@tonic-gate 			    &cmd->cmd_buf[cmd->cmd_bufidx],
2417c478bd9Sstevel@tonic-gate 			    cmd->cmd_buflen - cmd->cmd_bufidx);
2427c478bd9Sstevel@tonic-gate 		}
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 		return (0);
2457c478bd9Sstevel@tonic-gate 	}
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	return (-1);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2517c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_fwdchar(mdb_cmdbuf_t * cmd,int c)2527c478bd9Sstevel@tonic-gate mdb_cmdbuf_fwdchar(mdb_cmdbuf_t *cmd, int c)
2537c478bd9Sstevel@tonic-gate {
2547c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx < cmd->cmd_buflen) {
2557c478bd9Sstevel@tonic-gate 		cmd->cmd_bufidx++;
2567c478bd9Sstevel@tonic-gate 		return (0);
2577c478bd9Sstevel@tonic-gate 	}
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	return (-1);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2637c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_backchar(mdb_cmdbuf_t * cmd,int c)2647c478bd9Sstevel@tonic-gate mdb_cmdbuf_backchar(mdb_cmdbuf_t *cmd, int c)
2657c478bd9Sstevel@tonic-gate {
2667c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx > 0) {
2677c478bd9Sstevel@tonic-gate 		cmd->cmd_bufidx--;
2687c478bd9Sstevel@tonic-gate 		return (0);
2697c478bd9Sstevel@tonic-gate 	}
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	return (-1);
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_transpose(mdb_cmdbuf_t * cmd,int c)2757c478bd9Sstevel@tonic-gate mdb_cmdbuf_transpose(mdb_cmdbuf_t *cmd, int c)
2767c478bd9Sstevel@tonic-gate {
2777c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx > 0 && cmd->cmd_buflen > 1) {
2787c478bd9Sstevel@tonic-gate 		c = cmd->cmd_buf[cmd->cmd_bufidx - 1];
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 		if (cmd->cmd_bufidx == cmd->cmd_buflen) {
2817c478bd9Sstevel@tonic-gate 			cmd->cmd_buf[cmd->cmd_bufidx - 1] =
2827c478bd9Sstevel@tonic-gate 			    cmd->cmd_buf[cmd->cmd_bufidx - 2];
2837c478bd9Sstevel@tonic-gate 			cmd->cmd_buf[cmd->cmd_bufidx - 2] = (char)c;
2847c478bd9Sstevel@tonic-gate 		} else {
2857c478bd9Sstevel@tonic-gate 			cmd->cmd_buf[cmd->cmd_bufidx - 1] =
2867c478bd9Sstevel@tonic-gate 			    cmd->cmd_buf[cmd->cmd_bufidx];
2877c478bd9Sstevel@tonic-gate 			cmd->cmd_buf[cmd->cmd_bufidx++] = (char)c;
2887c478bd9Sstevel@tonic-gate 		}
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 		return (0);
2917c478bd9Sstevel@tonic-gate 	}
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 	return (-1);
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2977c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_home(mdb_cmdbuf_t * cmd,int c)2987c478bd9Sstevel@tonic-gate mdb_cmdbuf_home(mdb_cmdbuf_t *cmd, int c)
2997c478bd9Sstevel@tonic-gate {
3007c478bd9Sstevel@tonic-gate 	cmd->cmd_bufidx = 0;
3017c478bd9Sstevel@tonic-gate 	return (0);
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3057c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_end(mdb_cmdbuf_t * cmd,int c)3067c478bd9Sstevel@tonic-gate mdb_cmdbuf_end(mdb_cmdbuf_t *cmd, int c)
3077c478bd9Sstevel@tonic-gate {
3087c478bd9Sstevel@tonic-gate 	cmd->cmd_bufidx = cmd->cmd_buflen;
3097c478bd9Sstevel@tonic-gate 	return (0);
3107c478bd9Sstevel@tonic-gate }
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate static size_t
fwdword_index(mdb_cmdbuf_t * cmd)3137c478bd9Sstevel@tonic-gate fwdword_index(mdb_cmdbuf_t *cmd)
3147c478bd9Sstevel@tonic-gate {
3157c478bd9Sstevel@tonic-gate 	size_t i = cmd->cmd_bufidx + 1;
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 	ASSERT(cmd->cmd_bufidx < cmd->cmd_buflen);
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	while (i < cmd->cmd_buflen && isspace(cmd->cmd_buf[i]))
3207c478bd9Sstevel@tonic-gate 		i++;
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	while (i < cmd->cmd_buflen && !isspace(cmd->cmd_buf[i]) &&
3237c478bd9Sstevel@tonic-gate 	    !isalnum(cmd->cmd_buf[i]) && cmd->cmd_buf[i] != '_')
3247c478bd9Sstevel@tonic-gate 		i++;
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 	while (i < cmd->cmd_buflen &&
3277c478bd9Sstevel@tonic-gate 	    (isalnum(cmd->cmd_buf[i]) || cmd->cmd_buf[i] == '_'))
3287c478bd9Sstevel@tonic-gate 		i++;
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	return (i);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3347c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_fwdword(mdb_cmdbuf_t * cmd,int c)3357c478bd9Sstevel@tonic-gate mdb_cmdbuf_fwdword(mdb_cmdbuf_t *cmd, int c)
3367c478bd9Sstevel@tonic-gate {
3377c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx == cmd->cmd_buflen)
3387c478bd9Sstevel@tonic-gate 		return (-1);
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 	cmd->cmd_bufidx = fwdword_index(cmd);
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate 	return (0);
3437c478bd9Sstevel@tonic-gate }
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3467c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_killfwdword(mdb_cmdbuf_t * cmd,int c)3477c478bd9Sstevel@tonic-gate mdb_cmdbuf_killfwdword(mdb_cmdbuf_t *cmd, int c)
3487c478bd9Sstevel@tonic-gate {
3497c478bd9Sstevel@tonic-gate 	size_t i;
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx == cmd->cmd_buflen)
3527c478bd9Sstevel@tonic-gate 		return (-1);
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate 	i = fwdword_index(cmd);
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 	bcopy(&cmd->cmd_buf[i], &cmd->cmd_buf[cmd->cmd_bufidx],
3577c478bd9Sstevel@tonic-gate 	    cmd->cmd_buflen - i);
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 	cmd->cmd_buflen -= i - cmd->cmd_bufidx;
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 	return (0);
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate static size_t
backword_index(mdb_cmdbuf_t * cmd)3657c478bd9Sstevel@tonic-gate backword_index(mdb_cmdbuf_t *cmd)
3667c478bd9Sstevel@tonic-gate {
3677c478bd9Sstevel@tonic-gate 	size_t i = cmd->cmd_bufidx - 1;
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 	ASSERT(cmd->cmd_bufidx != 0);
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	while (i != 0 && isspace(cmd->cmd_buf[i]))
3727c478bd9Sstevel@tonic-gate 		i--;
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate 	while (i != 0 && !isspace(cmd->cmd_buf[i]) &&
3757c478bd9Sstevel@tonic-gate 	    !isalnum(cmd->cmd_buf[i]) && cmd->cmd_buf[i] != '_')
3767c478bd9Sstevel@tonic-gate 		i--;
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	while (i != 0 && (isalnum(cmd->cmd_buf[i]) || cmd->cmd_buf[i] == '_'))
3797c478bd9Sstevel@tonic-gate 		i--;
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 	if (i != 0)
3827c478bd9Sstevel@tonic-gate 		i++;
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate 	return (i);
3857c478bd9Sstevel@tonic-gate }
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3887c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_backword(mdb_cmdbuf_t * cmd,int c)3897c478bd9Sstevel@tonic-gate mdb_cmdbuf_backword(mdb_cmdbuf_t *cmd, int c)
3907c478bd9Sstevel@tonic-gate {
3917c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx == 0)
3927c478bd9Sstevel@tonic-gate 		return (-1);
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate 	cmd->cmd_bufidx = backword_index(cmd);
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 	return (0);
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4007c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_killbackword(mdb_cmdbuf_t * cmd,int c)4017c478bd9Sstevel@tonic-gate mdb_cmdbuf_killbackword(mdb_cmdbuf_t *cmd, int c)
4027c478bd9Sstevel@tonic-gate {
4037c478bd9Sstevel@tonic-gate 	size_t i;
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	if (cmd->cmd_bufidx == 0)
4067c478bd9Sstevel@tonic-gate 		return (-1);
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	i = backword_index(cmd);
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	bcopy(&cmd->cmd_buf[cmd->cmd_bufidx], &cmd->cmd_buf[i],
4117c478bd9Sstevel@tonic-gate 	    cmd->cmd_buflen - cmd->cmd_bufidx);
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate 	cmd->cmd_buflen -= cmd->cmd_bufidx - i;
4147c478bd9Sstevel@tonic-gate 	cmd->cmd_bufidx = i;
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 	return (0);
4177c478bd9Sstevel@tonic-gate }
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4207c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_kill(mdb_cmdbuf_t * cmd,int c)4217c478bd9Sstevel@tonic-gate mdb_cmdbuf_kill(mdb_cmdbuf_t *cmd, int c)
4227c478bd9Sstevel@tonic-gate {
4237c478bd9Sstevel@tonic-gate 	cmd->cmd_buflen = cmd->cmd_bufidx;
4247c478bd9Sstevel@tonic-gate 	return (0);
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4287c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_reset(mdb_cmdbuf_t * cmd,int c)4297c478bd9Sstevel@tonic-gate mdb_cmdbuf_reset(mdb_cmdbuf_t *cmd, int c)
4307c478bd9Sstevel@tonic-gate {
4317c478bd9Sstevel@tonic-gate 	cmd->cmd_buflen = 0;
4327c478bd9Sstevel@tonic-gate 	cmd->cmd_bufidx = 0;
4337c478bd9Sstevel@tonic-gate 	return (0);
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4377c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_prevhist(mdb_cmdbuf_t * cmd,int c)4387c478bd9Sstevel@tonic-gate mdb_cmdbuf_prevhist(mdb_cmdbuf_t *cmd, int c)
4397c478bd9Sstevel@tonic-gate {
4407c478bd9Sstevel@tonic-gate 	if (cmd->cmd_hcur != cmd->cmd_hold) {
4417c478bd9Sstevel@tonic-gate 		if (cmd->cmd_hcur-- == cmd->cmd_hnew) {
4427c478bd9Sstevel@tonic-gate 			cmd->cmd_buf[cmd->cmd_buflen] = 0;
4437c478bd9Sstevel@tonic-gate 			(void) strcpy(cmd->cmd_linebuf, cmd->cmd_buf);
4447c478bd9Sstevel@tonic-gate 		}
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 		if (cmd->cmd_hcur < 0)
447b2a1c443Svb160487 			cmd->cmd_hcur = cmd->cmd_halloc - 1;
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 		(void) strcpy(cmd->cmd_buf, cmd->cmd_history[cmd->cmd_hcur]);
4507c478bd9Sstevel@tonic-gate 		cmd->cmd_bufidx = strlen(cmd->cmd_buf);
4517c478bd9Sstevel@tonic-gate 		cmd->cmd_buflen = cmd->cmd_bufidx;
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 		return (0);
4547c478bd9Sstevel@tonic-gate 	}
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	return (-1);
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4607c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_nexthist(mdb_cmdbuf_t * cmd,int c)4617c478bd9Sstevel@tonic-gate mdb_cmdbuf_nexthist(mdb_cmdbuf_t *cmd, int c)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate 	if (cmd->cmd_hcur != cmd->cmd_hnew) {
464b2a1c443Svb160487 		cmd->cmd_hcur = (cmd->cmd_hcur + 1) % cmd->cmd_halloc;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 		if (cmd->cmd_hcur == cmd->cmd_hnew) {
4677c478bd9Sstevel@tonic-gate 			(void) strcpy(cmd->cmd_buf, cmd->cmd_linebuf);
4687c478bd9Sstevel@tonic-gate 		} else {
4697c478bd9Sstevel@tonic-gate 			(void) strcpy(cmd->cmd_buf,
4707c478bd9Sstevel@tonic-gate 			    cmd->cmd_history[cmd->cmd_hcur]);
4717c478bd9Sstevel@tonic-gate 		}
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate 		cmd->cmd_bufidx = strlen(cmd->cmd_buf);
4747c478bd9Sstevel@tonic-gate 		cmd->cmd_buflen = cmd->cmd_bufidx;
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate 		return (0);
4777c478bd9Sstevel@tonic-gate 	}
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate 	return (-1);
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4837c478bd9Sstevel@tonic-gate int
mdb_cmdbuf_findhist(mdb_cmdbuf_t * cmd,int c)4847c478bd9Sstevel@tonic-gate mdb_cmdbuf_findhist(mdb_cmdbuf_t *cmd, int c)
4857c478bd9Sstevel@tonic-gate {
4867c478bd9Sstevel@tonic-gate 	ssize_t i, n;
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate 	if (cmd->cmd_buflen != 0) {
4897c478bd9Sstevel@tonic-gate 		cmd->cmd_hcur = cmd->cmd_hnew;
4907c478bd9Sstevel@tonic-gate 		cmd->cmd_buf[cmd->cmd_buflen] = 0;
4917c478bd9Sstevel@tonic-gate 		(void) strcpy(cmd->cmd_linebuf, cmd->cmd_buf);
4927c478bd9Sstevel@tonic-gate 	}
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate 	for (i = cmd->cmd_hcur, n = 0; n < cmd->cmd_hlen; n++) {
4957c478bd9Sstevel@tonic-gate 		if (--i < 0)
496b2a1c443Svb160487 			i = cmd->cmd_halloc - 1;
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 		if (strstr(cmd->cmd_history[i], cmd->cmd_linebuf) != NULL) {
4997c478bd9Sstevel@tonic-gate 			(void) strcpy(cmd->cmd_buf, cmd->cmd_history[i]);
5007c478bd9Sstevel@tonic-gate 			cmd->cmd_bufidx = strlen(cmd->cmd_buf);
5017c478bd9Sstevel@tonic-gate 			cmd->cmd_buflen = cmd->cmd_bufidx;
5027c478bd9Sstevel@tonic-gate 			cmd->cmd_hcur = i;
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate 			return (0);
5057c478bd9Sstevel@tonic-gate 		}
5067c478bd9Sstevel@tonic-gate 	}
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	cmd->cmd_hcur = cmd->cmd_hnew;
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	cmd->cmd_bufidx = 0;
5117c478bd9Sstevel@tonic-gate 	cmd->cmd_buflen = 0;
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	return (-1);
5147c478bd9Sstevel@tonic-gate }
515