1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright (c) 1997, by Sun Mircrosystems, Inc.
28 * All rights reserved.
29 */
30
31 /*LINTLIBRARY*/
32
33 #include <sys/types.h>
34 #include <ctype.h>
35 #include "private.h"
36
37 static int
substr(MENU * m,char * s1,char * s2)38 substr(MENU *m, char *s1, char *s2)
39 {
40 if (IgnoreCase(m)) {
41 while (*s1 && *s2) {
42 if (toupper(*s1++) != toupper(*s2++)) {
43 return (FALSE);
44 }
45 }
46 } else {
47 while (*s1 && *s2) {
48 if (*s1++ != *s2++) {
49 return (FALSE);
50 }
51 }
52 }
53 if (*s1) {
54 return (FALSE);
55 }
56 return (TRUE);
57 }
58
59 int
_match(MENU * m,char c,ITEM ** current)60 _match(MENU *m, char c, ITEM **current)
61 {
62 int i, j;
63 int found;
64 /*
65 * Indicates search has cycled past the current item. If the current
66 * item is matched after cycled is true then NO_MATCH results.
67 */
68 int cycled;
69
70 /* If a backspace is encountered then search backward from the */
71 /* current item. Otherwise, search forward from the current item. */
72
73 i = Index(*current);
74 if (c && c != '\b') { /* c could be null */
75 if (Pindex(m)+1 > MaxName(m)) {
76 return (E_NO_MATCH);
77 }
78 IthPattern(m, Pindex(m)) = c;
79 IthPattern(m, ++Pindex(m)) = '\0';
80 if (--i < 0) {
81 i = Nitems(m)-1;
82 }
83 }
84
85 j = i;
86 found = FALSE;
87 cycled = FALSE;
88
89 do {
90 if (c == '\b') {
91 if (--i < 0) {
92 i = Nitems(m)-1;
93 }
94 } else {
95 if (++i >= Nitems(m)) {
96 i = 0;
97 }
98 }
99 if (substr(m, Pattern(m), Name(IthItem(m, i)))) {
100 found = TRUE;
101 break;
102 }
103 cycled = TRUE;
104 } while (i != j);
105
106 if (found) {
107 if (i == Index(*current) && cycled) {
108 return (E_NO_MATCH);
109 }
110 *current = IthItem(m, i);
111 } else {
112 if (c && c != '\b') {
113 Pindex(m) -= 1;
114 IthPattern(m, Pindex(m)) = '\0';
115 }
116 return (E_NO_MATCH);
117 }
118 return (E_OK);
119 }
120
121 char *
menu_pattern(MENU * m)122 menu_pattern(MENU *m)
123 {
124 if (m) {
125 if (Pattern(m)) {
126 return (Pattern(m));
127 } else {
128 return ("");
129 }
130 } else {
131 return (NULL);
132 }
133 }
134
135 int
set_menu_pattern(MENU * m,char * s)136 set_menu_pattern(MENU *m, char *s)
137 {
138 int top;
139 ITEM *current;
140
141 if (!m || !s) {
142 return (E_BAD_ARGUMENT);
143 }
144 if (!Items(m)) {
145 return (E_NOT_CONNECTED);
146 }
147 if (Indriver(m)) {
148 return (E_BAD_STATE);
149 }
150
151 IthPattern(m, 0) = '\0';
152 Pindex(m) = 0;
153
154 if (*s == '\0') {
155 _position_cursor(m);
156 return (E_OK);
157 }
158 if (LinkNeeded(m)) {
159 _link_items(m);
160 }
161
162 top = Top(m);
163 current = Current(m);
164
165 for (; *s; s++) {
166 if (_match(m, *s, ¤t) != E_OK) {
167 IthPattern(m, 0) = '\0';
168 Pindex(m) = 0;
169 _position_cursor(m);
170 return (E_NO_MATCH);
171 }
172 }
173 _chk_current(m, &top, current);
174 _affect_change(m, top, current);
175 return (E_OK);
176 }
177