3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2013 by Delphix. All rights reserved.
23 * Copyright (c) 2012 Joyent, Inc. All rights reserved.
24 * Copyright (c) 2013 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
25 */
26 /*
27 * This file contains all of the interfaces for mdb's tab completion engine.
28 * Currently some interfaces are private to mdb and its internal implementation,
29 * those are in mdb_tab.h. Other pieces are public interfaces. Those are in
30 * mdb_modapi.h.
31 *
32 * Memory allocations in tab completion context have to be done very carefully.
33 * We need to think of ourselves as the same as any other command that is being
34 * executed by the user, which means we must use UM_GC to handle being
35 * interrupted.
36 */
37
38 #include <mdb/mdb_modapi.h>
39 #include <mdb/mdb_ctf.h>
40 #include <mdb/mdb_ctf_impl.h>
41 #include <mdb/mdb_string.h>
42 #include <mdb/mdb_module.h>
43 #include <mdb/mdb_debug.h>
386 mdb_tab_size(mdb_tab_cookie_t *mcp)
387 {
388 return (mdb_nv_size(&mcp->mtc_nv));
389 }
390
391 /*
392 * Determine whether the specified name is a valid tab completion for
393 * the given command. If the name is a valid tab completion then
394 * it will be saved in the mdb_tab_cookie_t.
395 */
396 void
397 mdb_tab_insert(mdb_tab_cookie_t *mcp, const char *name)
398 {
399 size_t matches, index;
400 mdb_var_t *v;
401
402 /*
403 * If we have a match set, then we want to verify that we actually match
404 * it.
405 */
406 if (mcp->mtc_base != NULL &&
407 strncmp(name, mcp->mtc_base, strlen(mcp->mtc_base)) != 0)
408 return;
409
410 v = mdb_nv_lookup(&mcp->mtc_nv, name);
411 if (v != NULL)
412 return;
413
414 (void) mdb_nv_insert(&mcp->mtc_nv, name, NULL, 0, MDB_NV_RDONLY);
415
416 matches = mdb_tab_size(mcp);
417 if (matches == 1) {
418 (void) strlcpy(mcp->mtc_match, name, MDB_SYM_NAMLEN);
419 } else {
420 index = 0;
421 while (mcp->mtc_match[index] &&
422 mcp->mtc_match[index] == name[index])
423 index++;
424
425 mcp->mtc_match[index] = '\0';
426 }
427 }
428
429 /*ARGSUSED*/
430 static int
431 tab_print_cb(mdb_var_t *v, void *ignored)
432 {
433 mdb_printf("%s\n", mdb_nv_get_name(v));
434 return (0);
435 }
436
437 void
438 mdb_tab_print(mdb_tab_cookie_t *mcp)
439 {
440 mdb_nv_sort_iter(&mcp->mtc_nv, tab_print_cb, NULL, UM_SLEEP | UM_GC);
441 }
442
443 const char *
444 mdb_tab_match(mdb_tab_cookie_t *mcp)
445 {
446 size_t blen;
447
448 if (mcp->mtc_base == NULL)
449 blen = 0;
450 else
451 blen = strlen(mcp->mtc_base);
452 return (mcp->mtc_match + blen);
453 }
454
455 void
456 mdb_tab_setmbase(mdb_tab_cookie_t *mcp, const char *base)
457 {
458 (void) strlcpy(mcp->mtc_base, base, MDB_SYM_NAMLEN);
459 }
460
461 /*
462 * This function is currently a no-op due to the fact that we have to GC because
463 * we're in command context.
464 */
465 /*ARGSUSED*/
466 void
467 mdb_tab_fini(mdb_tab_cookie_t *mcp)
468 {
469 }
470
471 /*ARGSUSED*/
472 static int
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2013 by Delphix. All rights reserved.
23 * Copyright (c) 2018, Joyent, Inc.
24 * Copyright (c) 2013 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
25 */
26 /*
27 * This file contains all of the interfaces for mdb's tab completion engine.
28 * Currently some interfaces are private to mdb and its internal implementation,
29 * those are in mdb_tab.h. Other pieces are public interfaces. Those are in
30 * mdb_modapi.h.
31 *
32 * Memory allocations in tab completion context have to be done very carefully.
33 * We need to think of ourselves as the same as any other command that is being
34 * executed by the user, which means we must use UM_GC to handle being
35 * interrupted.
36 */
37
38 #include <mdb/mdb_modapi.h>
39 #include <mdb/mdb_ctf.h>
40 #include <mdb/mdb_ctf_impl.h>
41 #include <mdb/mdb_string.h>
42 #include <mdb/mdb_module.h>
43 #include <mdb/mdb_debug.h>
386 mdb_tab_size(mdb_tab_cookie_t *mcp)
387 {
388 return (mdb_nv_size(&mcp->mtc_nv));
389 }
390
391 /*
392 * Determine whether the specified name is a valid tab completion for
393 * the given command. If the name is a valid tab completion then
394 * it will be saved in the mdb_tab_cookie_t.
395 */
396 void
397 mdb_tab_insert(mdb_tab_cookie_t *mcp, const char *name)
398 {
399 size_t matches, index;
400 mdb_var_t *v;
401
402 /*
403 * If we have a match set, then we want to verify that we actually match
404 * it.
405 */
406 if (strncmp(name, mcp->mtc_base, strlen(mcp->mtc_base)) != 0)
407 return;
408
409 v = mdb_nv_lookup(&mcp->mtc_nv, name);
410 if (v != NULL)
411 return;
412
413 (void) mdb_nv_insert(&mcp->mtc_nv, name, NULL, 0, MDB_NV_RDONLY);
414
415 matches = mdb_tab_size(mcp);
416 if (matches == 1) {
417 (void) strlcpy(mcp->mtc_match, name, MDB_SYM_NAMLEN);
418 } else {
419 index = 0;
420 while (mcp->mtc_match[index] &&
421 mcp->mtc_match[index] == name[index])
422 index++;
423
424 mcp->mtc_match[index] = '\0';
425 }
426 }
427
428 /*ARGSUSED*/
429 static int
430 tab_print_cb(mdb_var_t *v, void *ignored)
431 {
432 mdb_printf("%s\n", mdb_nv_get_name(v));
433 return (0);
434 }
435
436 void
437 mdb_tab_print(mdb_tab_cookie_t *mcp)
438 {
439 mdb_nv_sort_iter(&mcp->mtc_nv, tab_print_cb, NULL, UM_SLEEP | UM_GC);
440 }
441
442 const char *
443 mdb_tab_match(mdb_tab_cookie_t *mcp)
444 {
445 return (mcp->mtc_match + strlen(mcp->mtc_base));
446 }
447
448 void
449 mdb_tab_setmbase(mdb_tab_cookie_t *mcp, const char *base)
450 {
451 (void) strlcpy(mcp->mtc_base, base, MDB_SYM_NAMLEN);
452 }
453
454 /*
455 * This function is currently a no-op due to the fact that we have to GC because
456 * we're in command context.
457 */
458 /*ARGSUSED*/
459 void
460 mdb_tab_fini(mdb_tab_cookie_t *mcp)
461 {
462 }
463
464 /*ARGSUSED*/
465 static int
|