Bug Summary

File:src/lib/libedit/search.c
Warning:line 457, column 2
Value stored to 'tmplen' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name search.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/lib/libedit/obj -resource-dir /usr/local/lib/clang/13.0.0 -I . -I /usr/src/lib/libedit -I . -I /usr/src/lib/libedit -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libedit/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/lib/libedit/search.c
1/* $OpenBSD: search.c,v 1.27 2016/05/06 13:12:52 schwarze Exp $ */
2/* $NetBSD: search.c,v 1.45 2016/04/18 17:01:19 christos Exp $ */
3
4/*-
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Christos Zoulas of Cornell University.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "config.h"
37
38/*
39 * search.c: History and character search functions
40 */
41#include <stdlib.h>
42#include <string.h>
43#if defined(REGEX)
44#include <regex.h>
45#elif defined(REGEXP)
46#include <regexp.h>
47#endif
48
49#include "el.h"
50#include "common.h"
51#include "fcns.h"
52
53/*
54 * Adjust cursor in vi mode to include the character under it
55 */
56#define EL_CURSOR(el)((el)->el_line.cursor + (((el)->el_map.type == 1) &&
((el)->el_map.current == (el)->el_map.alt)))
\
57 ((el)->el_line.cursor + (((el)->el_map.type == MAP_VI1) && \
58 ((el)->el_map.current == (el)->el_map.alt)))
59
60/* search_init():
61 * Initialize the search stuff
62 */
63protected__attribute__((__visibility__("hidden"))) int
64search_init(EditLine *el)
65{
66
67 el->el_search.patbuf = reallocarray(NULL((void *)0), EL_BUFSIZ1024,
68 sizeof(*el->el_search.patbuf));
69 if (el->el_search.patbuf == NULL((void *)0))
70 return -1;
71 *el->el_search.patbuf = L'\0';
72 el->el_search.patlen = 0;
73 el->el_search.patdir = -1;
74 el->el_search.chacha = '\0';
75 el->el_search.chadir = CHAR_FWD(+1);
76 el->el_search.chatflg = 0;
77 return 0;
78}
79
80
81/* search_end():
82 * Initialize the search stuff
83 */
84protected__attribute__((__visibility__("hidden"))) void
85search_end(EditLine *el)
86{
87
88 free(el->el_search.patbuf);
89 el->el_search.patbuf = NULL((void *)0);
90}
91
92
93#ifdef REGEXP
94/* regerror():
95 * Handle regular expression errors
96 */
97void
98/*ARGSUSED*/
99regerror(const char *msg)
100{
101}
102#endif
103
104
105/* el_match():
106 * Return if string matches pattern
107 */
108protected__attribute__((__visibility__("hidden"))) int
109el_match(const wchar_t *str, const wchar_t *pat)
110{
111 static ct_buffer_t conv;
112#if defined (REGEX)
113 regex_t re;
114 int rv;
115#elif defined (REGEXP)
116 regexp *rp;
117 int rv;
118#else
119 extern char *re_comp(const char *);
120 extern int re_exec(const char *);
121#endif
122
123 if (wcsstr(str, pat) != 0)
124 return 1;
125
126#if defined(REGEX)
127 if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) {
128 rv = regexec(&re, ct_encode_string(str, &conv), 0, NULL((void *)0), 0) == 0;
129 regfree(&re);
130 } else {
131 rv = 0;
132 }
133 return rv;
134#elif defined(REGEXP)
135 if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL((void *)0)) {
136 rv = regexec(re, ct_encode_string(str, &conv));
137 free(re);
138 } else {
139 rv = 0;
140 }
141 return rv;
142#else
143 if (re_comp(ct_encode_string(pat, &conv)) != NULL((void *)0))
144 return 0;
145 else
146 return re_exec(ct_encode_string(str, &conv)) == 1;
147#endif
148}
149
150
151/* c_hmatch():
152 * return True if the pattern matches the prefix
153 */
154protected__attribute__((__visibility__("hidden"))) int
155c_hmatch(EditLine *el, const wchar_t *str)
156{
157#ifdef SDEBUG
158 (void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
159 el->el_search.patbuf, str);
160#endif /* SDEBUG */
161
162 return el_match(str, el->el_search.patbuf);
163}
164
165
166/* c_setpat():
167 * Set the history seatch pattern
168 */
169protected__attribute__((__visibility__("hidden"))) void
170c_setpat(EditLine *el)
171{
172 if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY24 &&
173 el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY23) {
174 el->el_search.patlen = EL_CURSOR(el)((el)->el_line.cursor + (((el)->el_map.type == 1) &&
((el)->el_map.current == (el)->el_map.alt)))
- el->el_line.buffer;
175 if (el->el_search.patlen >= EL_BUFSIZ1024)
176 el->el_search.patlen = EL_BUFSIZ1024 - 1;
177 if (el->el_search.patlen != 0) {
178 (void) wcsncpy(el->el_search.patbuf, el->el_line.buffer,
179 el->el_search.patlen);
180 el->el_search.patbuf[el->el_search.patlen] = '\0';
181 } else
182 el->el_search.patlen = wcslen(el->el_search.patbuf);
183 }
184#ifdef SDEBUG
185 (void) fprintf(el->el_errfile, "\neventno = %d\n",
186 el->el_history.eventno);
187 (void) fprintf(el->el_errfile, "patlen = %d\n", el->el_search.patlen);
188 (void) fprintf(el->el_errfile, "patbuf = \"%s\"\n",
189 el->el_search.patbuf);
190 (void) fprintf(el->el_errfile, "cursor %d lastchar %d\n",
191 EL_CURSOR(el)((el)->el_line.cursor + (((el)->el_map.type == 1) &&
((el)->el_map.current == (el)->el_map.alt)))
- el->el_line.buffer,
192 el->el_line.lastchar - el->el_line.buffer);
193#endif
194}
195
196
197/* ce_inc_search():
198 * Emacs incremental search
199 */
200protected__attribute__((__visibility__("hidden"))) el_action_t
201ce_inc_search(EditLine *el, int dir)
202{
203 static const wchar_t STRfwd[] = L"fwd", STRbck[] = L"bck";
204 static wchar_t pchar = L':'; /* ':' = normal, '?' = failed */
205 static wchar_t endcmd[2] = {'\0', '\0'};
206 wchar_t *ocursor = el->el_line.cursor, oldpchar = pchar, ch;
207 const wchar_t *cp;
208
209 el_action_t ret = CC_NORM0;
210
211 int ohisteventno = el->el_history.eventno;
212 size_t oldpatlen = el->el_search.patlen;
213 int newdir = dir;
214 int done, redo;
215
216 if (el->el_line.lastchar + sizeof(STRfwd) /
217 sizeof(*el->el_line.lastchar) + 2 +
218 el->el_search.patlen >= el->el_line.limit)
219 return CC_ERROR6;
220
221 for (;;) {
222
223 if (el->el_search.patlen == 0) { /* first round */
224 pchar = ':';
225#ifdef ANCHOR
226#define LEN2 2
227 el->el_search.patbuf[el->el_search.patlen++] = '.';
228 el->el_search.patbuf[el->el_search.patlen++] = '*';
229#else
230#define LEN2 0
231#endif
232 }
233 done = redo = 0;
234 *el->el_line.lastchar++ = '\n';
235 for (cp = (newdir == ED_SEARCH_PREV_HISTORY24) ? STRbck : STRfwd;
236 *cp; *el->el_line.lastchar++ = *cp++)
237 continue;
238 *el->el_line.lastchar++ = pchar;
239 for (cp = &el->el_search.patbuf[LEN2];
240 cp < &el->el_search.patbuf[el->el_search.patlen];
241 *el->el_line.lastchar++ = *cp++)
242 continue;
243 *el->el_line.lastchar = '\0';
244 re_refresh(el);
245
246 if (el_wgetc(el, &ch) != 1)
247 return ed_end_of_file(el, 0);
248
249 switch (el->el_map.current[(unsigned char) ch]) {
250 case ED_INSERT9:
251 case ED_DIGIT6:
252 if (el->el_search.patlen >= EL_BUFSIZ1024 - LEN2)
253 terminal_beep(el);
254 else {
255 el->el_search.patbuf[el->el_search.patlen++] =
256 ch;
257 *el->el_line.lastchar++ = ch;
258 *el->el_line.lastchar = '\0';
259 re_refresh(el);
260 }
261 break;
262
263 case EM_INC_SEARCH_NEXT37:
264 newdir = ED_SEARCH_NEXT_HISTORY23;
265 redo++;
266 break;
267
268 case EM_INC_SEARCH_PREV38:
269 newdir = ED_SEARCH_PREV_HISTORY24;
270 redo++;
271 break;
272
273 case EM_DELETE_PREV_CHAR34:
274 case ED_DELETE_PREV_CHAR4:
275 if (el->el_search.patlen > LEN2)
276 done++;
277 else
278 terminal_beep(el);
279 break;
280
281 default:
282 switch (ch) {
283 case 0007: /* ^G: Abort */
284 ret = CC_ERROR6;
285 done++;
286 break;
287
288 case 0027: /* ^W: Append word */
289 /* No can do if globbing characters in pattern */
290 for (cp = &el->el_search.patbuf[LEN2];; cp++)
291 if (cp >= &el->el_search.patbuf[
292 el->el_search.patlen]) {
293 el->el_line.cursor +=
294 el->el_search.patlen - LEN2 - 1;
295 cp = c__next_word(el->el_line.cursor,
296 el->el_line.lastchar, 1,
297 ce__isword);
298 while (el->el_line.cursor < cp &&
299 *el->el_line.cursor != '\n') {
300 if (el->el_search.patlen >=
301 EL_BUFSIZ1024 - LEN2) {
302 terminal_beep(el);
303 break;
304 }
305 el->el_search.patbuf[el->el_search.patlen++] =
306 *el->el_line.cursor;
307 *el->el_line.lastchar++ =
308 *el->el_line.cursor++;
309 }
310 el->el_line.cursor = ocursor;
311 *el->el_line.lastchar = '\0';
312 re_refresh(el);
313 break;
314 } else if (isglob(*cp)(strchr("*[]?", (*cp)) != ((void *)0))) {
315 terminal_beep(el);
316 break;
317 }
318 break;
319
320 default: /* Terminate and execute cmd */
321 endcmd[0] = ch;
322 el_wpush(el, endcmd);
323 /* FALLTHROUGH */
324
325 case 0033: /* ESC: Terminate */
326 ret = CC_REFRESH4;
327 done++;
328 break;
329 }
330 break;
331 }
332
333 while (el->el_line.lastchar > el->el_line.buffer &&
334 *el->el_line.lastchar != '\n')
335 *el->el_line.lastchar-- = '\0';
336 *el->el_line.lastchar = '\0';
337
338 if (!done) {
339
340 /* Can't search if unmatched '[' */
341 for (cp = &el->el_search.patbuf[el->el_search.patlen-1],
342 ch = L']';
343 cp >= &el->el_search.patbuf[LEN2];
344 cp--)
345 if (*cp == '[' || *cp == ']') {
346 ch = *cp;
347 break;
348 }
349 if (el->el_search.patlen > LEN2 && ch != L'[') {
350 if (redo && newdir == dir) {
351 if (pchar == '?') { /* wrap around */
352 el->el_history.eventno =
353 newdir == ED_SEARCH_PREV_HISTORY24 ? 0 : 0x7fffffff;
354 if (hist_get(el) == CC_ERROR6)
355 /* el->el_history.event
356 * no was fixed by
357 * first call */
358 (void) hist_get(el);
359 el->el_line.cursor = newdir ==
360 ED_SEARCH_PREV_HISTORY24 ?
361 el->el_line.lastchar :
362 el->el_line.buffer;
363 } else
364 el->el_line.cursor +=
365 newdir ==
366 ED_SEARCH_PREV_HISTORY24 ?
367 -1 : 1;
368 }
369#ifdef ANCHOR
370 el->el_search.patbuf[el->el_search.patlen++] =
371 '.';
372 el->el_search.patbuf[el->el_search.patlen++] =
373 '*';
374#endif
375 el->el_search.patbuf[el->el_search.patlen] =
376 '\0';
377 if (el->el_line.cursor < el->el_line.buffer ||
378 el->el_line.cursor > el->el_line.lastchar ||
379 (ret = ce_search_line(el, newdir))
380 == CC_ERROR6) {
381 /* avoid c_setpat */
382 el->el_state.lastcmd =
383 (el_action_t) newdir;
384 ret = newdir == ED_SEARCH_PREV_HISTORY24 ?
385 ed_search_prev_history(el, 0) :
386 ed_search_next_history(el, 0);
387 if (ret != CC_ERROR6) {
388 el->el_line.cursor = newdir ==
389 ED_SEARCH_PREV_HISTORY24 ?
390 el->el_line.lastchar :
391 el->el_line.buffer;
392 (void) ce_search_line(el,
393 newdir);
394 }
395 }
396 el->el_search.patlen -= LEN2;
397 el->el_search.patbuf[el->el_search.patlen] =
398 '\0';
399 if (ret == CC_ERROR6) {
400 terminal_beep(el);
401 if (el->el_history.eventno !=
402 ohisteventno) {
403 el->el_history.eventno =
404 ohisteventno;
405 if (hist_get(el) == CC_ERROR6)
406 return CC_ERROR6;
407 }
408 el->el_line.cursor = ocursor;
409 pchar = '?';
410 } else {
411 pchar = ':';
412 }
413 }
414 ret = ce_inc_search(el, newdir);
415
416 if (ret == CC_ERROR6 && pchar == '?' && oldpchar == ':')
417 /*
418 * break abort of failed search at last
419 * non-failed
420 */
421 ret = CC_NORM0;
422
423 }
424 if (ret == CC_NORM0 || (ret == CC_ERROR6 && oldpatlen == 0)) {
425 /* restore on normal return or error exit */
426 pchar = oldpchar;
427 el->el_search.patlen = oldpatlen;
428 if (el->el_history.eventno != ohisteventno) {
429 el->el_history.eventno = ohisteventno;
430 if (hist_get(el) == CC_ERROR6)
431 return CC_ERROR6;
432 }
433 el->el_line.cursor = ocursor;
434 if (ret == CC_ERROR6)
435 re_refresh(el);
436 }
437 if (done || ret != CC_NORM0)
438 return ret;
439 }
440}
441
442
443/* cv_search():
444 * Vi search.
445 */
446protected__attribute__((__visibility__("hidden"))) el_action_t
447cv_search(EditLine *el, int dir)
448{
449 wchar_t ch;
450 wchar_t tmpbuf[EL_BUFSIZ1024];
451 int tmplen;
452
453#ifdef ANCHOR
454 tmpbuf[0] = '.';
455 tmpbuf[1] = '*';
456#endif
457 tmplen = LEN2;
Value stored to 'tmplen' is never read
458
459 el->el_search.patdir = dir;
460
461 tmplen = c_gets(el, &tmpbuf[LEN2],
462 dir == ED_SEARCH_PREV_HISTORY24 ? L"\n/" : L"\n?" );
463 if (tmplen == -1)
464 return CC_REFRESH4;
465
466 tmplen += LEN2;
467 ch = tmpbuf[tmplen];
468 tmpbuf[tmplen] = '\0';
469
470 if (tmplen == LEN2) {
471 /*
472 * Use the old pattern, but wild-card it.
473 */
474 if (el->el_search.patlen == 0) {
475 re_refresh(el);
476 return CC_ERROR6;
477 }
478#ifdef ANCHOR
479 if (el->el_search.patbuf[0] != '.' &&
480 el->el_search.patbuf[0] != '*') {
481 (void) wcsncpy(tmpbuf, el->el_search.patbuf,
482 sizeof(tmpbuf) / sizeof(*tmpbuf) - 1);
483 el->el_search.patbuf[0] = '.';
484 el->el_search.patbuf[1] = '*';
485 (void) wcsncpy(&el->el_search.patbuf[2], tmpbuf,
486 EL_BUFSIZ1024 - 3);
487 el->el_search.patlen++;
488 el->el_search.patbuf[el->el_search.patlen++] = '.';
489 el->el_search.patbuf[el->el_search.patlen++] = '*';
490 el->el_search.patbuf[el->el_search.patlen] = '\0';
491 }
492#endif
493 } else {
494#ifdef ANCHOR
495 tmpbuf[tmplen++] = '.';
496 tmpbuf[tmplen++] = '*';
497#endif
498 tmpbuf[tmplen] = '\0';
499 (void) wcsncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ1024 - 1);
500 el->el_search.patlen = tmplen;
501 }
502 el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
503 el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
504 if ((dir == ED_SEARCH_PREV_HISTORY24 ? ed_search_prev_history(el, 0) :
505 ed_search_next_history(el, 0)) == CC_ERROR6) {
506 re_refresh(el);
507 return CC_ERROR6;
508 }
509 if (ch == 0033) {
510 re_refresh(el);
511 return ed_newline(el, 0);
512 }
513 return CC_REFRESH4;
514}
515
516
517/* ce_search_line():
518 * Look for a pattern inside a line
519 */
520protected__attribute__((__visibility__("hidden"))) el_action_t
521ce_search_line(EditLine *el, int dir)
522{
523 wchar_t *cp = el->el_line.cursor;
524 wchar_t *pattern = el->el_search.patbuf;
525 wchar_t oc, *ocp;
526#ifdef ANCHOR
527 ocp = &pattern[1];
528 oc = *ocp;
529 *ocp = '^';
530#else
531 ocp = pattern;
532 oc = *ocp;
533#endif
534
535 if (dir == ED_SEARCH_PREV_HISTORY24) {
536 for (; cp >= el->el_line.buffer; cp--) {
537 if (el_match(cp, ocp)) {
538 *ocp = oc;
539 el->el_line.cursor = cp;
540 return CC_NORM0;
541 }
542 }
543 *ocp = oc;
544 return CC_ERROR6;
545 } else {
546 for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
547 if (el_match(cp, ocp)) {
548 *ocp = oc;
549 el->el_line.cursor = cp;
550 return CC_NORM0;
551 }
552 }
553 *ocp = oc;
554 return CC_ERROR6;
555 }
556}
557
558
559/* cv_repeat_srch():
560 * Vi repeat search
561 */
562protected__attribute__((__visibility__("hidden"))) el_action_t
563cv_repeat_srch(EditLine *el, wint_t c)
564{
565
566#ifdef SDEBUG
567 (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n",
568 c, el->el_search.patlen, ct_encode_string(el->el_search.patbuf));
569#endif
570
571 el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
572 el->el_line.lastchar = el->el_line.buffer;
573
574 switch (c) {
575 case ED_SEARCH_NEXT_HISTORY23:
576 return ed_search_next_history(el, 0);
577 case ED_SEARCH_PREV_HISTORY24:
578 return ed_search_prev_history(el, 0);
579 default:
580 return CC_ERROR6;
581 }
582}
583
584
585/* cv_csearch():
586 * Vi character search
587 */
588protected__attribute__((__visibility__("hidden"))) el_action_t
589cv_csearch(EditLine *el, int direction, wint_t ch, int count, int tflag)
590{
591 wchar_t *cp;
592
593 if (ch == 0)
594 return CC_ERROR6;
595
596 if (ch == (wint_t)-1) {
597 if (el_wgetc(el, &ch) != 1)
598 return ed_end_of_file(el, 0);
599 }
600
601 /* Save for ';' and ',' commands */
602 el->el_search.chacha = ch;
603 el->el_search.chadir = direction;
604 el->el_search.chatflg = tflag;
605
606 cp = el->el_line.cursor;
607 while (count--) {
608 if ((wint_t)*cp == ch)
609 cp += direction;
610 for (;;cp += direction) {
611 if (cp >= el->el_line.lastchar)
612 return CC_ERROR6;
613 if (cp < el->el_line.buffer)
614 return CC_ERROR6;
615 if ((wint_t)*cp == ch)
616 break;
617 }
618 }
619
620 if (tflag)
621 cp -= direction;
622
623 el->el_line.cursor = cp;
624
625 if (el->el_chared.c_vcmd.action != NOP0x00) {
626 if (direction > 0)
627 el->el_line.cursor++;
628 cv_delfini(el);
629 return CC_REFRESH4;
630 }
631 return CC_CURSOR5;
632}