]>
git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/search.c
2 * "$Id: search.c 4859 2005-11-30 23:45:24Z mike $"
4 * Search routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2005 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * cgiCompileSearch() - Compile a search string.
27 * cgiDoSearch() - Do a search of some text.
28 * cgiFreeSearch() - Free a compiled search context.
32 * Include necessary headers...
35 #include "cgi-private.h"
40 * 'cgiCompileSearch()' - Compile a search string.
43 void * /* O - Search context */
44 cgiCompileSearch(const char *query
) /* I - Query string */
46 regex_t
*re
; /* Regular expression */
47 char *s
, /* Regular expression string */
48 *sptr
, /* Pointer into RE string */
49 *sword
; /* Pointer to start of word */
50 int slen
; /* Allocated size of RE string */
51 const char *qptr
, /* Pointer into query string */
52 *qend
; /* End of current word */
53 const char *prefix
; /* Prefix to add to next word */
54 int quoted
; /* Word is quoted */
55 int wlen
; /* Word length */
56 char *lword
; /* Last word in query */
59 DEBUG_printf(("help_compile_search(query=\"%s\")\n", query
? query
: "(nil)"));
62 * Allocate a regular expression storage structure...
65 re
= (regex_t
*)calloc(1, sizeof(regex_t
));
68 * Allocate a buffer to hold the regular expression string, starting
69 * at 1024 bytes or 3 times the length of the query string, whichever
70 * is greater. We'll expand the string as needed...
73 slen
= strlen(query
) * 3;
77 s
= (char *)malloc(slen
);
80 * Copy the query string to the regular expression, handling basic
92 * Skip leading whitespace...
95 while (isspace(*qptr
& 255))
102 * Find the end of the current word...
105 if (*qptr
== '\"' || *qptr
== '\'')
108 * Scan quoted string...
112 for (qend
= qptr
; *qend
&& *qend
!= quoted
; qend
++);
117 * No closing quote, error out!
132 * Scan whitespace-delimited string...
136 for (qend
= qptr
+ 1; *qend
&& !isspace(*qend
); qend
++);
142 * Look for logic words: AND, OR
145 if (wlen
== 3 && !strncasecmp(qptr
, "AND", 3))
148 * Logical AND with the following text...
156 else if (wlen
== 2 && !strncasecmp(qptr
, "OR", 2))
159 * Logical OR with the following text...
170 * Add a search word, making sure we have enough room for the
171 * string + RE overhead...
174 wlen
= (sptr
- s
) + 4 * wlen
+ 2 * strlen(prefix
) + 4;
179 * Expand the RE string buffer...
182 char *temp
; /* Temporary string pointer */
186 temp
= (char *)realloc(s
, slen
);
198 sptr
= temp
+ (sptr
- s
);
203 * Add the prefix string...
206 strcpy(sptr
, prefix
);
207 sptr
+= strlen(sptr
);
210 * Then quote the remaining word characters as needed for the
219 * Quote: ^ . [ $ ( ) | * + ? { \
222 if (strchr("^.[$()|*+?{\\", *qptr
))
229 * For "word1 AND word2", add reciprocal "word2 AND word1"...
232 if (!strcmp(prefix
, ".*") && lword
)
234 char *lword2
; /* New "last word" */
237 lword2
= strdup(sword
);
239 strcpy(sptr
, ".*|.*");
242 strcpy(sptr
, lword2
);
243 sptr
+= strlen(sptr
);
249 sptr
+= strlen(sptr
);
259 lword
= strdup(sword
);
266 * Advance to the next string...
281 * No query data, return NULL...
291 * Compile the regular expression...
294 DEBUG_printf((" s=\"%s\"\n", s
));
296 if (regcomp(re
, s
, REG_EXTENDED
| REG_ICASE
))
305 * Free the RE string and return the new regular expression we compiled...
315 * 'cgiDoSearch()' - Do a search of some text.
318 int /* O - Number of matches */
319 cgiDoSearch(void *search
, /* I - Search context */
320 const char *text
) /* I - Text to search */
322 int i
; /* Looping var */
323 regmatch_t matches
[100]; /* RE matches */
330 if (!search
|| !text
)
337 if (!regexec((regex_t
*)search
, text
, sizeof(matches
) / sizeof(matches
[0]),
341 * Figure out the number of matches in the string...
344 for (i
= 0; i
< (int)(sizeof(matches
) / sizeof(matches
[0])); i
++)
345 if (matches
[i
].rm_so
< 0)
356 * 'cgiFreeSearch()' - Free a compiled search context.
360 cgiFreeSearch(void *search
) /* I - Search context */
362 regfree((regex_t
*)search
);
367 * End of "$Id: search.c 4859 2005-11-30 23:45:24Z mike $".