help_index_t * /* O - Search index */ helpSearchIndex(help_index_t *hi, /* I - Index */ const char *query, /* I - Query string */ const char *section, /* I - Limit search to this section */ const char *filename) /* I - Limit search to this file */ { help_index_t *search; /* Search index */ help_node_t *node; /* Current node */ help_word_t *word; /* Current word */ void *sc; /* Search context */ int matches; /* Number of matches */ DEBUG_printf(("helpSearchIndex(hi=%p, query=\"%s\", filename=\"%s\")", hi, query, filename)); /* * Range check... */ if (!hi || !query) return (NULL); /* * Reset the scores of all nodes to 0... */ for (node = (help_node_t *)cupsArrayFirst(hi->nodes); node; node = (help_node_t *)cupsArrayNext(hi->nodes)) node->score = 0; /* * Find the first node to search in... */ if (filename) { node = helpFindNode(hi, filename, NULL); if (!node) return (NULL); } else node = (help_node_t *)cupsArrayFirst(hi->nodes); /* * Convert the query into a regular expression... */ sc = cgiCompileSearch(query); if (!sc) return (NULL); /* * Allocate a search index... */ search = calloc(1, sizeof(help_index_t)); if (!search) { cgiFreeSearch(sc); return (NULL); } search->nodes = cupsArrayNew((cups_array_func_t)help_sort_by_name, NULL); search->sorted = cupsArrayNew((cups_array_func_t)help_sort_by_score, NULL); if (!search->nodes || !search->sorted) { cupsArrayDelete(search->nodes); cupsArrayDelete(search->sorted); free(search); cgiFreeSearch(sc); return (NULL); } search->search = 1; /* * Check each node in the index, adding matching nodes to the * search index... */ for (; node; node = (help_node_t *)cupsArrayNext(hi->nodes)) if (section && strcmp(node->section, section)) continue; else if (filename && strcmp(node->filename, filename)) continue; else { matches = cgiDoSearch(sc, node->text); for (word = (help_word_t *)cupsArrayFirst(node->words); word; word = (help_word_t *)cupsArrayNext(node->words)) if (cgiDoSearch(sc, word->text) > 0) matches += word->count; if (matches > 0) { /* * Found a match, add the node to the search index... */ node->score = matches; cupsArrayAdd(search->nodes, node); cupsArrayAdd(search->sorted, node); } } /* * Free the search context... */ cgiFreeSearch(sc); /* * Return the results... */ return (search); }
cups_array_t * /* O - Array of objects */ cgiGetIPPObjects(ipp_t *response, /* I - IPP response */ void *search) /* I - Search filter */ { int i; /* Looping var */ cups_array_t *objs; /* Array of objects */ ipp_attribute_t *attr, /* Current attribute */ *first; /* First attribute for object */ ipp_tag_t group; /* Current group tag */ int add; /* Add this object to the array? */ if (!response) return (0); for (add = 0, first = NULL, objs = cupsArrayNew(NULL, NULL), group = IPP_TAG_ZERO, attr = response->attrs; attr; attr = attr->next) { if (attr->group_tag != group) { group = attr->group_tag; if (group != IPP_TAG_ZERO && group != IPP_TAG_OPERATION) { first = attr; add = 0; } else if (add && first) { cupsArrayAdd(objs, first); add = 0; first = NULL; } } if (attr->name && attr->group_tag != IPP_TAG_OPERATION && !add) { if (!search) { /* * Add all objects if there is no search... */ add = 1; } else { /* * Check the search string against the string and integer values. */ switch (attr->value_tag) { case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : case IPP_TAG_TEXT : case IPP_TAG_NAME : case IPP_TAG_KEYWORD : case IPP_TAG_URI : case IPP_TAG_MIMETYPE : for (i = 0; !add && i < attr->num_values; i ++) if (cgiDoSearch(search, attr->values[i].string.text)) add = 1; break; case IPP_TAG_INTEGER : for (i = 0; !add && i < attr->num_values; i ++) { char buf[255]; /* Number buffer */ sprintf(buf, "%d", attr->values[i].integer); if (cgiDoSearch(search, buf)) add = 1; } break; default : break; } } } } if (add && first) cupsArrayAdd(objs, first); return (objs); }