utils.c 14.1 KB
Newer Older
Chris Allegretta's avatar
Chris Allegretta committed
1
/* $Id$ */
Chris Allegretta's avatar
Chris Allegretta committed
2
3
4
/**************************************************************************
 *   utils.c                                                              *
 *                                                                        *
5
 *   Copyright (C) 1999-2004 Chris Allegretta                             *
Chris Allegretta's avatar
Chris Allegretta committed
6
7
 *   This program is free software; you can redistribute it and/or modify *
 *   it under the terms of the GNU General Public License as published by *
8
 *   the Free Software Foundation; either version 2, or (at your option)  *
Chris Allegretta's avatar
Chris Allegretta committed
9
10
11
12
13
14
15
16
17
18
19
20
21
 *   any later version.                                                   *
 *                                                                        *
 *   This program is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of       *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
 *   GNU General Public License for more details.                         *
 *                                                                        *
 *   You should have received a copy of the GNU General Public License    *
 *   along with this program; if not, write to the Free Software          *
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            *
 *                                                                        *
 **************************************************************************/

22
23
#include "config.h"

Chris Allegretta's avatar
Chris Allegretta committed
24
25
#include <stdlib.h>
#include <string.h>
26
27
#include <stdio.h>
#include <unistd.h>
Chris Allegretta's avatar
Chris Allegretta committed
28
#include <ctype.h>
29
#include <errno.h>
Chris Allegretta's avatar
Chris Allegretta committed
30
#include <assert.h>
Chris Allegretta's avatar
Chris Allegretta committed
31
#include "proto.h"
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
32
#include "nano.h"
Chris Allegretta's avatar
Chris Allegretta committed
33

34
#ifdef HAVE_REGEX_H
35
36
37
38
39
40
41
42
43
44
#ifdef BROKEN_REGEXEC
#undef regexec
int regexec_safe(const regex_t *preg, const char *string, size_t nmatch,
	regmatch_t pmatch[], int eflags)
{
    if (string != NULL && *string != '\0')
	return regexec(preg, string, nmatch, pmatch, eflags);
    return REG_NOMATCH;
}
#define regexec(preg, string, nmatch, pmatch, eflags) regexec_safe(preg, string, nmatch, pmatch, eflags)
45
46
47
#endif /* BROKEN_REGEXEC */

/* Assume that string will be found by regexec() if the REG_NOTBOL and
48
 * REG_NOTEOL flags are not set. */
49
50
51
52
53
54
int regexp_bol_or_eol(const regex_t *preg, const char *string)
{
    return (regexec(preg, string, 0, NULL, REG_NOTBOL | REG_NOTEOL) ==
	REG_NOMATCH);
}
#endif /* HAVE_REGEX_H */
55

56
57
58
59
60
61
62
63
64
65
#ifndef HAVE_ISBLANK
/* This function is equivalent to isblank(). */
int is_blank_char(int c)
{
    return (c == '\t' || c == ' ');
}
#endif

/* This function is equivalent to iscntrl(), except in that it also
 * handles control characters with their high bits set. */
Chris Allegretta's avatar
Chris Allegretta committed
66
67
int is_cntrl_char(int c)
{
68
    return (-128 <= c && c < -96) || (0 <= c && c < 32) ||
69
	(127 <= c && c < 160);
Chris Allegretta's avatar
Chris Allegretta committed
70
71
}

72
73
74
75
76
int num_of_digits(int n)
{
    int i = 1;

    if (n < 0)
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
77
	n = -n;
78
79
80
81
82
83
84
85
86

    while (n > 10) {
	n /= 10;
	i++;
    }

    return i;
}

87
/* Read an int from str, and store it in *val (if val is not NULL).  On
88
89
90
 * error, we return FALSE and don't change *val.  Otherwise, we return 
 * TRUE. */
bool parse_num(const char *str, ssize_t *val)
91
92
93
94
95
96
97
{
    char *first_error;
    ssize_t j;

    assert(str != NULL);
    j = (ssize_t)strtol(str, &first_error, 10);
    if (errno == ERANGE || *str == '\0' || *first_error != '\0')
98
	return FALSE;
99
100
    if (val != NULL)
	*val = j;
101
    return TRUE;
102
103
}

Chris Allegretta's avatar
Chris Allegretta committed
104
105
/* Fix the memory allocation for a string. */
void align(char **strp)
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
106
{
David Lawrence Ramsey's avatar
   
David Lawrence Ramsey committed
107
108
109
    assert(strp != NULL);
    if (*strp != NULL)
	*strp = charealloc(*strp, strlen(*strp) + 1);
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
110
111
}

Chris Allegretta's avatar
Chris Allegretta committed
112
113
/* Null a string at a certain index and align it. */
void null_at(char **data, size_t index)
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
114
{
Chris Allegretta's avatar
Chris Allegretta committed
115
    assert(data != NULL);
Chris Allegretta's avatar
Chris Allegretta committed
116
    *data = charealloc(*data, index + 1);
Chris Allegretta's avatar
Chris Allegretta committed
117
    (*data)[index] = '\0';
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
118
119
}

Chris Allegretta's avatar
Chris Allegretta committed
120
121
122
/* For non-null-terminated lines.  A line, by definition, shouldn't
 * normally have newlines in it, so encode its nulls as newlines. */
void unsunder(char *str, size_t true_len)
Chris Allegretta's avatar
Chris Allegretta committed
123
{
Chris Allegretta's avatar
Chris Allegretta committed
124
    assert(str != NULL);
125
    for (; true_len > 0; true_len--, str++) {
Chris Allegretta's avatar
Chris Allegretta committed
126
127
	if (*str == '\0')
	    *str = '\n';
128
    }
Chris Allegretta's avatar
Chris Allegretta committed
129
}
Chris Allegretta's avatar
Chris Allegretta committed
130

Chris Allegretta's avatar
Chris Allegretta committed
131
132
133
134
135
/* For non-null-terminated lines.  A line, by definition, shouldn't
 * normally have newlines in it, so decode its newlines into nulls. */
void sunder(char *str)
{
    assert(str != NULL);
136
    for (; *str != '\0'; str++) {
Chris Allegretta's avatar
Chris Allegretta committed
137
138
	if (*str == '\n')
	    *str = '\0';
139
    }
Chris Allegretta's avatar
Chris Allegretta committed
140
141
}

142
143
144
145
146
#ifndef HAVE_STRCASECMP
/* This function is equivalent to strcasecmp(). */
int nstricmp(const char *s1, const char *s2)
{
    assert(s1 != NULL && s2 != NULL);
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
147

148
149
150
151
    for (; *s1 != '\0' && *s2 != '\0'; s1++, s2++) {
	if (tolower(*s1) != tolower(*s2))
	    break;
    }
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
152

153
154
155
156
157
158
159
160
161
    return (tolower(*s1) - tolower(*s2));
}
#endif

#ifndef HAVE_STRNCASECMP
/* This function is equivalent to strncasecmp(). */
int nstrnicmp(const char *s1, const char *s2, size_t n)
{
    assert(s1 != NULL && s2 != NULL);
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
162

163
164
165
166
    for (; n > 0 && *s1 != '\0' && *s2 != '\0'; n--, s1++, s2++) {
	if (tolower(*s1) != tolower(*s2))
	    break;
    }
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
167

168
169
    if (n > 0)
	return (tolower(*s1) - tolower(*s2));
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
170
    else
171
	return 0;
172
173
174
}
#endif

175
#ifndef HAVE_STRCASESTR
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/* This function is equivalent to strcasestr().  It was adapted from
 * mutt's mutt_stristr() function. */
const char *nstristr(const char *haystack, const char *needle)
{
    assert(haystack != NULL && needle != NULL);

    for (; *haystack != '\0'; haystack++) {
	const char *p = haystack;
	const char *q = needle;

	for (; tolower(*p) == tolower(*q) && *q != '\0'; p++, q++)
	    ;

	if (*q == '\0')
	    return haystack;
    }

    return NULL;
}
195
#endif
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
196

197
198
/* None of this is needed if we're using NANO_SMALL! */
#ifndef NANO_SMALL
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
199
200
const char *revstrstr(const char *haystack, const char *needle, const
	char *rev_start)
Chris Allegretta's avatar
Chris Allegretta committed
201
{
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
202
    for (; rev_start >= haystack; rev_start--) {
Chris Allegretta's avatar
Chris Allegretta committed
203
	const char *r, *q;
Chris Allegretta's avatar
Chris Allegretta committed
204

Chris Allegretta's avatar
Chris Allegretta committed
205
	for (r = rev_start, q = needle ; *q == *r && *q != '\0'; r++, q++)
Chris Allegretta's avatar
Chris Allegretta committed
206
207
	    ;
	if (*q == '\0')
Chris Allegretta's avatar
Chris Allegretta committed
208
	    return rev_start;
Chris Allegretta's avatar
Chris Allegretta committed
209
    }
Chris Allegretta's avatar
Chris Allegretta committed
210
    return NULL;
Chris Allegretta's avatar
Chris Allegretta committed
211
212
}

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
213
214
const char *revstristr(const char *haystack, const char *needle, const
	char *rev_start)
Chris Allegretta's avatar
Chris Allegretta committed
215
{
Chris Allegretta's avatar
Chris Allegretta committed
216
217
    for (; rev_start >= haystack; rev_start--) {
	const char *r = rev_start, *q = needle;
Chris Allegretta's avatar
Chris Allegretta committed
218

Chris Allegretta's avatar
Chris Allegretta committed
219
	for (; (tolower(*q) == tolower(*r)) && (*q != '\0') ; r++, q++)
Chris Allegretta's avatar
Chris Allegretta committed
220
221
	    ;
	if (*q == '\0')
Chris Allegretta's avatar
Chris Allegretta committed
222
	    return rev_start;
Chris Allegretta's avatar
Chris Allegretta committed
223
    }
Chris Allegretta's avatar
Chris Allegretta committed
224
    return NULL;
Chris Allegretta's avatar
Chris Allegretta committed
225
}
Chris Allegretta's avatar
Chris Allegretta committed
226
#endif /* !NANO_SMALL */
Chris Allegretta's avatar
Chris Allegretta committed
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#ifndef HAVE_STRNLEN
/* This function is equivalent to strnlen(). */
size_t nstrnlen(const char *s, size_t maxlen)
{
    size_t n = 0;

    assert(s != NULL);

    for (; maxlen > 0 && *s != '\0'; maxlen--, n++, s++)
	;

    return n;
}
#endif

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
243
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#ifndef HAVE_GETLINE
/* This function is equivalent to getline().  It was adapted from
 * GNU mailutils' getline() function. */
ssize_t ngetline(char **lineptr, size_t *n, FILE *stream)
{
    return getdelim(lineptr, n, '\n', stream);
}
#endif

#ifndef HAVE_GETDELIM
/* This function is equivalent to getdelim().  It was adapted from
 * GNU mailutils' getdelim() function. */
ssize_t ngetdelim(char **lineptr, size_t *n, int delim, FILE *stream)
{
    size_t indx = 0;
    int c;

    /* Sanity checks. */
    if (lineptr == NULL || n == NULL || stream == NULL)
	return -1;

    /* Allocate the line the first time. */
    if (*lineptr == NULL) {
267
268
	*lineptr = charalloc(128);
	*n = 128;
269
270
271
272
273
    }

    while ((c = getc(stream)) != EOF) {
	/* Check if more memory is needed. */
	if (indx >= *n) {
274
275
	    *lineptr = charealloc(*lineptr, *n + 128);
	    *n += 128;
276
277
278
279
280
281
282
283
284
285
286
287
	}

	/* Push the result in the line. */
	(*lineptr)[indx++] = (char)c;

	/* Bail out. */
	if (c == delim)
	    break;
    }

    /* Make room for the null character. */
    if (indx >= *n) {
288
289
	*lineptr = charealloc(*lineptr, *n + 128);
	*n += 128;
290
291
292
    }

    /* Null terminate the buffer. */
293
    null_at(lineptr, indx++);
294
    *n = indx;
295
296
297
298
299
300

    /* The last line may not have the delimiter, we have to return what
     * we got and the error will be seen on the next iteration. */
    return (c == EOF && (indx - 1) == 0) ? -1 : indx - 1;
}
#endif
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
301
#endif /* !NANO_SMALL && ENABLE_NANORC */
302

303
304
305
306
307
308
/* If we are searching backwards, we will find the last match that
 * starts no later than start.  Otherwise we find the first match
 * starting no earlier than start.  If we are doing a regexp search, we
 * fill in the global variable regmatches with at most 9 subexpression
 * matches.  Also, all .rm_so elements are relative to the start of the
 * whole match, so regmatches[0].rm_so == 0. */
Chris Allegretta's avatar
Chris Allegretta committed
309
const char *strstrwrapper(const char *haystack, const char *needle,
310
	const char *start)
Chris Allegretta's avatar
Chris Allegretta committed
311
{
312
    /* start can be 1 character before the start or after the end of the
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
313
     * line.  In either case, we just say no match was found. */
314
315
316
    if ((start > haystack && *(start - 1) == '\0') || start < haystack)
	return NULL;
    assert(haystack != NULL && needle != NULL && start != NULL);
317
#ifdef HAVE_REGEX_H
318
    if (ISSET(USE_REGEXP)) {
319
#ifndef NANO_SMALL
320
	if (ISSET(REVERSE_SEARCH)) {
321
322
	    if (regexec(&search_regexp, haystack, 1, regmatches, 0) == 0
		&& haystack + regmatches[0].rm_so <= start) {
323
324
		const char *retval = haystack + regmatches[0].rm_so;

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
325
		/* Search forward until there are no more matches. */
326
		while (regexec(&search_regexp, retval + 1, 1, regmatches,
327
328
			REG_NOTBOL) == 0 && retval + 1 +
			regmatches[0].rm_so <= start)
329
330
331
332
333
334
		    retval += 1 + regmatches[0].rm_so;
		/* Finally, put the subexpression matches in global
		 * variable regmatches.  The REG_NOTBOL flag doesn't
		 * matter now. */
		regexec(&search_regexp, retval, 10, regmatches, 0);
		return retval;
Chris Allegretta's avatar
Chris Allegretta committed
335
	    }
336
337
	} else
#endif /* !NANO_SMALL */
338
339
340
	if (regexec(&search_regexp, start, 10, regmatches,
		start > haystack ? REG_NOTBOL : 0) == 0) {
	    const char *retval = start + regmatches[0].rm_so;
341
342
343

	    regexec(&search_regexp, retval, 10, regmatches, 0);
	    return retval;
344
	}
345
	return NULL;
346
    }
347
#endif /* HAVE_REGEX_H */
348
#if !defined(DISABLE_SPELLER) || !defined(NANO_SMALL)
349
    if (ISSET(CASE_SENSITIVE)) {
350
#ifndef NANO_SMALL
351
	if (ISSET(REVERSE_SEARCH))
352
	    return revstrstr(haystack, needle, start);
353
	else
354
#endif
355
	    return strstr(start, needle);
356
357
358
359
360
    }
#endif /* !DISABLE_SPELLER || !NANO_SMALL */
#ifndef NANO_SMALL
    else if (ISSET(REVERSE_SEARCH))
	return revstristr(haystack, needle, start);
361
#endif
362
    return strcasestr(start, needle);
Chris Allegretta's avatar
Chris Allegretta committed
363
}
Chris Allegretta's avatar
Chris Allegretta committed
364

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
365
366
367
/* This is a wrapper for the perror() function.  The wrapper takes care
 * of ncurses, calls perror (which writes to stderr), then refreshes the
 * screen.  Note that nperror() causes the window to flicker once. */
368
369
void nperror(const char *s)
{
370
    /* leave ncurses mode, go to the terminal */
371
372
373
374
375
376
    if (endwin() != ERR) {
	perror(s);		/* print the error */
	total_refresh();	/* return to ncurses and repaint */
    }
}

Chris Allegretta's avatar
Chris Allegretta committed
377
378
/* Thanks BG, many ppl have been asking for this... */
void *nmalloc(size_t howmuch)
Chris Allegretta's avatar
Chris Allegretta committed
379
{
Chris Allegretta's avatar
Chris Allegretta committed
380
    void *r = malloc(howmuch);
Chris Allegretta's avatar
Chris Allegretta committed
381

Chris Allegretta's avatar
Chris Allegretta committed
382
383
    if (r == NULL && howmuch != 0)
	die(_("nano is out of memory!"));
384

Chris Allegretta's avatar
Chris Allegretta committed
385
    return r;
386
387
}

Chris Allegretta's avatar
Chris Allegretta committed
388
void *nrealloc(void *ptr, size_t howmuch)
Chris Allegretta's avatar
Chris Allegretta committed
389
{
Chris Allegretta's avatar
Chris Allegretta committed
390
    void *r = realloc(ptr, howmuch);
Chris Allegretta's avatar
Chris Allegretta committed
391

Chris Allegretta's avatar
Chris Allegretta committed
392
393
    if (r == NULL && howmuch != 0)
	die(_("nano is out of memory!"));
Chris Allegretta's avatar
Chris Allegretta committed
394
395
396

    return r;
}
Robert Siemborski's avatar
Robert Siemborski committed
397

Chris Allegretta's avatar
Chris Allegretta committed
398
/* Copy one malloc()ed string to another pointer.  Should be used as:
399
 * "dest = mallocstrcpy(dest, src);". */
Chris Allegretta's avatar
Chris Allegretta committed
400
char *mallocstrcpy(char *dest, const char *src)
401
{
402
403
    if (src == NULL)
	src = "";
404

405
    if (src != dest)
406
407
	free(dest);

408
    dest = charalloc(strlen(src) + 1);
409
410
411
412
413
    strcpy(dest, src);

    return dest;
}

414
415
416
417
418
419
420
421
422
423
/* Free the malloc()ed string at dest and return the malloc()ed string
 * at src.  Should be used as: "answer = mallocstrassn(answer,
 * real_dir_from_tilde(answer));". */
char *mallocstrassn(char *dest, char *src)
{
    free(dest);
    return src;
}

/* Append a new magicline to filebot. */
424
425
void new_magicline(void)
{
David Lawrence Ramsey's avatar
   
David Lawrence Ramsey committed
426
    filebot->next = (filestruct *)nmalloc(sizeof(filestruct));
427
    filebot->next->data = charalloc(1);
Robert Siemborski's avatar
Robert Siemborski committed
428
429
430
431
432
433
    filebot->next->data[0] = '\0';
    filebot->next->prev = filebot;
    filebot->next->next = NULL;
    filebot->next->lineno = filebot->lineno + 1;
    filebot = filebot->next;
    totlines++;
434
    totsize++;
Robert Siemborski's avatar
Robert Siemborski committed
435
}
Chris Allegretta's avatar
Chris Allegretta committed
436

437
438
439
#ifndef NANO_SMALL
/* Set top_x and bot_x to the top and bottom x-coordinates of the mark,
 * respectively, based on the locations of top and bot. */
440
441
void mark_order(const filestruct **top, size_t *top_x, const filestruct
	**bot, size_t *bot_x)
442
443
{
    assert(top != NULL && top_x != NULL && bot != NULL && bot_x != NULL);
444

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
445
446
    if ((current->lineno == mark_beginbuf->lineno && current_x >
	 mark_beginx) || current->lineno > mark_beginbuf->lineno) {
447
448
449
450
451
452
453
454
455
456
457
458
459
	*top = mark_beginbuf;
	*top_x = mark_beginx;
	*bot = current;
	*bot_x = current_x;
    } else {
	*bot = mark_beginbuf;
	*bot_x = mark_beginx;
	*top = current;
	*top_x = current_x;
    }
}
#endif

460
#ifndef DISABLE_TABCOMP
Chris Allegretta's avatar
Chris Allegretta committed
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
/*
 * Routine to see if a text string is matched by a wildcard pattern.
 * Returns TRUE if the text is matched, or FALSE if it is not matched
 * or if the pattern is invalid.
 *  *		matches zero or more characters
 *  ?		matches a single character
 *  [abc]	matches 'a', 'b' or 'c'
 *  \c		quotes character c
 * Adapted from code written by Ingo Wilken, and
 * then taken from sash, Copyright (c) 1999 by David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 * Permission to distribute this code under the GPL has been granted.
 */
int check_wildcard_match(const char *text, const char *pattern)
{
Chris Allegretta's avatar
Chris Allegretta committed
477
478
    const char *retrypat;
    const char *retrytext;
Chris Allegretta's avatar
Chris Allegretta committed
479
480
481
482
    int ch;
    int found;
    int len;

Chris Allegretta's avatar
Chris Allegretta committed
483
484
    retrypat = NULL;
    retrytext = NULL;
Chris Allegretta's avatar
Chris Allegretta committed
485

486
    while (*text != '\0' || *pattern != '\0') {
Chris Allegretta's avatar
Chris Allegretta committed
487
488
489
490
	ch = *pattern++;

	switch (ch) {
	case '*':
Chris Allegretta's avatar
Chris Allegretta committed
491
492
	    retrypat = pattern;
	    retrytext = text;
Chris Allegretta's avatar
Chris Allegretta committed
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
	    break;

	case '[':
	    found = FALSE;

	    while ((ch = *pattern++) != ']') {
		if (ch == '\\')
		    ch = *pattern++;

		if (ch == '\0')
		    return FALSE;

		if (*text == ch)
		    found = TRUE;
	    }
	    len = strlen(text);
509
	    if (!found && len != 0) {
Chris Allegretta's avatar
Chris Allegretta committed
510
511
		return FALSE;
	    }
512
	    if (found) {
Chris Allegretta's avatar
Chris Allegretta committed
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
		if (strlen(pattern) == 0 && len == 1) {
		    return TRUE;
		}
		if (len != 0) {
		    text++;
		    continue;
		}
	    }

	    /* fall into next case */

	case '?':
	    if (*text++ == '\0')
		return FALSE;

	    break;

	case '\\':
	    ch = *pattern++;

	    if (ch == '\0')
		return FALSE;

	    /* fall into next case */

	default:
	    if (*text == ch) {
540
		if (*text != '\0')
Chris Allegretta's avatar
Chris Allegretta committed
541
542
543
544
		    text++;
		break;
	    }

545
	    if (*text != '\0') {
Chris Allegretta's avatar
Chris Allegretta committed
546
547
		pattern = retrypat;
		text = ++retrytext;
Chris Allegretta's avatar
Chris Allegretta committed
548
549
550
551
552
553
		break;
	    }

	    return FALSE;
	}

554
	if (pattern == NULL)
Chris Allegretta's avatar
Chris Allegretta committed
555
556
557
558
559
	    return FALSE;
    }

    return TRUE;
}
560
#endif