Author: matz
Date: Sun Nov 11 21:18:58 2007
New Revision: 7781
URL: http://svn.opensuse.org/viewcvs/zypp?rev=7781&view=rev
Log:
Interface to search for strings in attributes.
Modified:
trunk/sat-solver/tools/attr_store.c
trunk/sat-solver/tools/attr_store.h
trunk/sat-solver/tools/dumpattr.c
Modified: trunk/sat-solver/tools/attr_store.c
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/tools/attr_store.c?rev=7781&r1=7780&r2=7781&view=diff
==============================================================================
--- trunk/sat-solver/tools/attr_store.c (original)
+++ trunk/sat-solver/tools/attr_store.c Sun Nov 11 21:18:58 2007
@@ -5,6 +5,11 @@
* for further information
*/
+/* We need FNM_CASEFOLD and strcasestr. */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
#include
#include
#include
@@ -13,6 +18,8 @@
#include
#include
#include
+#include
+#include
#include "attr_store.h"
#include "pool.h"
@@ -23,6 +30,8 @@
#include "fastlz.c"
+/*#define DEBUG_PAGING*/
+
#define NAME_WIDTH 12
#define TYPE_WIDTH (16-NAME_WIDTH)
@@ -397,7 +406,9 @@
s->mapped = xrealloc (s->mapped, s->ncanmap * sizeof (s->mapped[0]));
memset (s->mapped + oldcan, 0, (s->ncanmap - oldcan) * sizeof (s->mapped[0]));
s->blob_store = xrealloc (s->blob_store, s->ncanmap * BLOB_PAGESIZE);
+#ifdef DEBUG_PAGING
fprintf (stderr, "PAGE: can map %d pages\n", s->ncanmap);
+#endif
}
/* Now search for "cheap" space in our store. Space is cheap if it's either
@@ -452,7 +463,9 @@
&& pnum != pstart + i - best)
{
/* Evict this page. */
+#ifdef DEBUG_PAGING
fprintf (stderr, "PAGE: evict page %d from %d\n", pnum, i);
+#endif
cost[i] = 0;
s->mapped[i] = 0;
s->pages[pnum].mapped_at = -1;
@@ -469,7 +482,9 @@
{
if (p->mapped_at != pnum * BLOB_PAGESIZE)
{
+#ifdef DEBUG_PAGING
fprintf (stderr, "PAGECOPY: %d to %d\n", i, pnum);
+#endif
/* Still mapped somewhere else, so just copy it from there. */
memcpy (dest, s->blob_store + p->mapped_at, BLOB_PAGESIZE);
s->mapped[p->mapped_at / BLOB_PAGESIZE] = 0;
@@ -480,7 +495,9 @@
unsigned int in_len = p->file_size;
unsigned int compressed = in_len & 1;
in_len >>= 1;
+#ifdef DEBUG_PAGING
fprintf (stderr, "PAGEIN: %d to %d", i, pnum);
+#endif
/* Not mapped, so read in this page. */
if (fseek (s->file, p->file_offset, SEEK_SET) < 0)
{
@@ -503,9 +520,13 @@
fprintf (stderr, "can't decompress\n");
exit (1);
}
+#ifdef DEBUG_PAGING
fprintf (stderr, " (expand %d to %d)", in_len, out_len);
+#endif
}
+#ifdef DEBUG_PAGING
fprintf (stderr, "\n");
+#endif
}
p->mapped_at = pnum * BLOB_PAGESIZE;
s->mapped[pnum] = i + 1;
@@ -885,7 +906,9 @@
}
else
out_len = 0;
+#ifdef DEBUG_PAGING
fprintf (stderr, "page %d: %d -> %d\n", i, in_len, out_len);
+#endif
write_u32 (fp, out_len * 2 + (out_len != in_len));
if (out_len
&& fwrite (buf, out_len, 1, fp) != 1)
@@ -1064,8 +1087,10 @@
unsigned int compressed = in_len & 1;
Attrblobpage *p = s->pages + i;
in_len >>= 1;
+#ifdef DEBUG_PAGING
fprintf (stderr, "page %d: len %d (%scompressed)\n",
i, in_len, compressed ? "" : "not ");
+#endif
if (can_seek)
{
cur_file_ofs += 4;
@@ -1252,6 +1277,104 @@
return s;
}
+void
+attr_store_search_s (Attrstore *s, const char *pattern, int flags, NameId name, cb_attr_search_s cb)
+{
+ unsigned int i;
+ attr_iterator ai;
+ regex_t regex;
+ /* If we search for a glob, but we don't have a wildcard pattern, make this
+ an exact string search. */
+ if ((flags & 7) == SEARCH_GLOB
+ && !strpbrk (pattern, "?*["))
+ flags = SEARCH_STRING | (flags & ~7);
+ if ((flags & 7) == SEARCH_REGEX)
+ {
+ /* We feed multiple lines eventually (e.g. authors or descriptions),
+ so set REG_NEWLINE. */
+ if (regcomp (®ex, pattern,
+ REG_EXTENDED | REG_NOSUB | REG_NEWLINE
+ | ((flags & SEARCH_NOCASE) ? REG_ICASE : 0)) != 0)
+ return;
+ }
+ for (i = 0; i < s->entries; i++)
+ FOR_ATTRS (s, i, &ai)
+ {
+ const char *str;
+ if (name && name != ai.name)
+ continue;
+ str = 0;
+ switch (ai.type)
+ {
+ case ATTR_INT:
+ case ATTR_INTLIST:
+ continue;
+ case ATTR_ID:
+ if (!(flags & SEARCH_IDS))
+ continue;
+ str = id2str (s->pool, ai.as_id);
+ break;
+ case ATTR_CHUNK:
+ if (!(flags & SEARCH_BLOBS))
+ continue;
+ str = attr_retrieve_blob (s, ai.as_chunk[0], ai.as_chunk[1]);
+ break;
+ case ATTR_STRING:
+ str = ai.as_string;
+ break;
+ case ATTR_LOCALIDS:
+ {
+ Id val;
+ get_num (ai.as_numlist, val);
+ if (val)
+ str = localid2str (s, val);
+ break;
+ }
+ default:
+ break;
+ }
+ while (str)
+ {
+ unsigned int match = 0;
+ switch (flags & 7)
+ {
+ case SEARCH_SUBSTRING:
+ if (flags & SEARCH_NOCASE)
+ match = !! strcasestr (str, pattern);
+ else
+ match = !! strstr (str, pattern);
+ break;
+ case SEARCH_STRING:
+ if (flags & SEARCH_NOCASE)
+ match = ! strcasecmp (str, pattern);
+ else
+ match = ! strcmp (str, pattern);
+ break;
+ case SEARCH_GLOB:
+ match = ! fnmatch (pattern, str,
+ (flags & SEARCH_NOCASE) ? FNM_CASEFOLD : 0);
+ break;
+ case SEARCH_REGEX:
+ match = ! regexec (®ex, str, 0, NULL, 0);
+ break;
+ default:
+ break;
+ }
+ if (match)
+ cb (s, i, s->nameids[ai.name], str);
+ if (ai.type != ATTR_LOCALIDS)
+ break;
+ Id val;
+ get_num (ai.as_numlist, val);
+ if (!val)
+ break;
+ str = localid2str (s, val);
+ }
+ }
+ if ((flags & 7) == SEARCH_REGEX)
+ regfree (®ex);
+}
+
#ifdef MAIN
int
main (void)
Modified: trunk/sat-solver/tools/attr_store.h
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/tools/attr_store.h?rev=7781&r1=7780&r2=7781&view=diff
==============================================================================
--- trunk/sat-solver/tools/attr_store.h (original)
+++ trunk/sat-solver/tools/attr_store.h Sun Nov 11 21:18:58 2007
@@ -40,6 +40,16 @@
void add_attr_localids_id (Attrstore *s, unsigned int entry, NameId name, LocalId id);
const void * attr_retrieve_blob (Attrstore *s, unsigned int ofs, unsigned int len);
+
+#define SEARCH_SUBSTRING 1
+#define SEARCH_STRING 2
+#define SEARCH_GLOB 3
+#define SEARCH_REGEX 4
+#define SEARCH_NOCASE 8
+#define SEARCH_BLOBS 16
+#define SEARCH_IDS 32
+typedef int (*cb_attr_search_s) (Attrstore *s, unsigned entry, Id name, const char *str);
+void attr_store_search_s (Attrstore *s, const char *pattern, int flags, NameId name, cb_attr_search_s cb);
#ifdef __cplusplus
}
#endif
Modified: trunk/sat-solver/tools/dumpattr.c
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/sat-solver/tools/dumpattr.c?rev=7781&r1=7780&r2=7781&view=diff
==============================================================================
--- trunk/sat-solver/tools/dumpattr.c (original)
+++ trunk/sat-solver/tools/dumpattr.c Sun Nov 11 21:18:58 2007
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include "attr_store.h"
#include "pool.h"
@@ -78,8 +79,15 @@
}
}
+static int
+callback (Attrstore *s, unsigned entry, Id name, const char *str)
+{
+ fprintf (stdout, "%d:%s:%s\n", entry, id2str (s->pool, name), str);
+ return 1;
+}
+
int
-main (void)
+main (int argc, char *argv[])
{
unsigned int i;
Pool *pool = pool_create ();
@@ -88,10 +96,37 @@
attr_store_unpack (s);
attr_store_pack (s);
fprintf (stdout, "attribute store contains %d entities\n", s->entries);
- for (i = 0; i < s->entries; i++)
+ if (argc == 1)
+ for (i = 0; i < s->entries; i++)
+ {
+ fprintf (stdout, "\nentity %u:\n", i);
+ dump_attrs (s, i);
+ }
+ else
{
- fprintf (stdout, "\nentity %u:\n", i);
- dump_attrs (s, i);
+ int g;
+ unsigned flags;
+ unsigned search_type;
+ NameId name;
+ name = 0;
+ flags = SEARCH_IDS;
+ search_type = SEARCH_SUBSTRING;
+ while ((g = getopt (argc, argv, "-n:bgeri")) >= 0)
+ switch (g)
+ {
+ case 'n': name = str2nameid (s, optarg); break;
+ case 'b': flags |= SEARCH_BLOBS; break;
+ case 'g': search_type = SEARCH_GLOB; break;
+ case 'e': search_type = SEARCH_STRING; break;
+ case 'r': search_type = SEARCH_REGEX; break;
+ case 'i': flags |= SEARCH_NOCASE; break;
+ case 1:
+ attr_store_search_s (s, optarg, search_type | flags, name, callback);
+ flags = SEARCH_IDS;
+ name = 0;
+ search_type = SEARCH_SUBSTRING;
+ break;
+ }
}
return 0;
}
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org