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 */
25 /*
26 * This file contains all of the interfaces for mdb's tab completion engine.
27 * Currently some interfaces are private to mdb and its internal implementation,
28 * those are in mdb_tab.h. Other pieces are public interfaces. Those are in
29 * mdb_modapi.h.
30 *
31 * Memory allocations in tab completion context have to be done very carefully.
32 * We need to think of ourselves as the same as any other command that is being
33 * executed by the user, which means we must use UM_GC to handle being
34 * interrupted.
35 */
36
37 #include <mdb/mdb_modapi.h>
38 #include <mdb/mdb_ctf.h>
39 #include <mdb/mdb_ctf_impl.h>
40 #include <mdb/mdb_string.h>
41 #include <mdb/mdb_module.h>
42 #include <mdb/mdb_debug.h>
43 #include <mdb/mdb_print.h>
377 mcp = mdb_zalloc(sizeof (mdb_tab_cookie_t), UM_SLEEP | UM_GC);
378 (void) mdb_nv_create(&mcp->mtc_nv, UM_SLEEP | UM_GC);
379
380 return (mcp);
381 }
382
383 size_t
384 mdb_tab_size(mdb_tab_cookie_t *mcp)
385 {
386 return (mdb_nv_size(&mcp->mtc_nv));
387 }
388
389 /*
390 * Determine whether the specified name is a valid tab completion for
391 * the given command. If the name is a valid tab completion then
392 * it will be saved in the mdb_tab_cookie_t.
393 */
394 void
395 mdb_tab_insert(mdb_tab_cookie_t *mcp, const char *name)
396 {
397 size_t len, matches, index;
398 uint_t flags;
399 mdb_var_t *v;
400 char *n;
401 const char *nvn;
402
403 /*
404 * If we have a match set, then we want to verify that we actually match
405 * it.
406 */
407 if (mcp->mtc_base != NULL &&
408 strncmp(name, mcp->mtc_base, strlen(mcp->mtc_base)) != 0)
409 return;
410
411 v = mdb_nv_lookup(&mcp->mtc_nv, name);
412 if (v != NULL)
413 return;
414
415 /*
416 * Names that we get passed in may be longer than MDB_NV_NAMELEN which
417 * is currently 31 including the null terminator. If that is the case,
418 * then we're going to take care of allocating a string and holding it
419 * for our caller. Note that we don't need to free it, because we're
420 * allocating this with UM_GC.
421 */
422 flags = 0;
423 len = strlen(name);
424 if (len > MDB_NV_NAMELEN - 1) {
425 n = mdb_alloc(len + 1, UM_SLEEP | UM_GC);
426 (void) strcpy(n, name);
427 nvn = n;
428 flags |= MDB_NV_EXTNAME;
429 } else {
430 nvn = name;
431 }
432 flags |= MDB_NV_RDONLY;
433
434 (void) mdb_nv_insert(&mcp->mtc_nv, nvn, NULL, 0, flags);
435
436 matches = mdb_tab_size(mcp);
437 if (matches == 1) {
438 (void) strlcpy(mcp->mtc_match, nvn, MDB_SYM_NAMLEN);
439 } else {
440 index = 0;
441 while (mcp->mtc_match[index] &&
442 mcp->mtc_match[index] == nvn[index])
443 index++;
444
445 mcp->mtc_match[index] = '\0';
446 }
447 }
448
449 /*ARGSUSED*/
450 static int
451 tab_print_cb(mdb_var_t *v, void *ignored)
452 {
453 mdb_printf("%s\n", mdb_nv_get_name(v));
454 return (0);
455 }
456
457 void
458 mdb_tab_print(mdb_tab_cookie_t *mcp)
459 {
460 mdb_nv_sort_iter(&mcp->mtc_nv, tab_print_cb, NULL, UM_SLEEP | UM_GC);
461 }
462
|
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>
44 #include <mdb/mdb_print.h>
378 mcp = mdb_zalloc(sizeof (mdb_tab_cookie_t), UM_SLEEP | UM_GC);
379 (void) mdb_nv_create(&mcp->mtc_nv, UM_SLEEP | UM_GC);
380
381 return (mcp);
382 }
383
384 size_t
385 mdb_tab_size(mdb_tab_cookie_t *mcp)
386 {
387 return (mdb_nv_size(&mcp->mtc_nv));
388 }
389
390 /*
391 * Determine whether the specified name is a valid tab completion for
392 * the given command. If the name is a valid tab completion then
393 * it will be saved in the mdb_tab_cookie_t.
394 */
395 void
396 mdb_tab_insert(mdb_tab_cookie_t *mcp, const char *name)
397 {
398 size_t matches, index;
399 mdb_var_t *v;
400
401 /*
402 * If we have a match set, then we want to verify that we actually match
403 * it.
404 */
405 if (mcp->mtc_base != NULL &&
406 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
|