[Dctrl-tools-devel] [SCM] Debian control file query tools branch, master, updated. 2.18-22-g0705462
Antti-Juhani Kaijanaho
ajk at debian.org
Wed Oct 19 21:25:05 UTC 2011
The following commit has been merged in the master branch:
commit 56a84f637482bcf31f489372b98fa17da4a3c565
Author: Antti-Juhani Kaijanaho <ajk at debian.org>
Date: Wed Oct 19 21:48:06 2011 +0300
Move atom into its own lib module.
Signed-off-by: Antti-Juhani Kaijanaho <ajk at debian.org>
diff --git a/grep-dctrl/grep-dctrl.c b/grep-dctrl/grep-dctrl.c
index f549e24..ca994fc 100644
--- a/grep-dctrl/grep-dctrl.c
+++ b/grep-dctrl/grep-dctrl.c
@@ -29,6 +29,7 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
+#include "atom.h"
#include "fnutil.h"
#include "fsaf.h"
#include "i18n.h"
@@ -261,11 +262,11 @@ static void finish_atom(struct arguments * args)
for (size_t i = 0; i < args->num_search_fields; i++) {
if (i > 0) atom = clone_atom(args);
atom->field_name = args->search_fields[i];
- predicate_finish_atom(&args->p);
+ atom_finish(atom);
}
// If there are no fields, we have not yet run this...
// ... but it must be done (especially with -r/-e atoms)
- if (args->num_search_fields == 0) predicate_finish_atom(&args->p);
+ if (args->num_search_fields == 0) atom_finish(atom);
args->num_search_fields = 0;
}
diff --git a/lib/predicate.c b/lib/atom.c
similarity index 72%
copy from lib/predicate.c
copy to lib/atom.c
index 5c213b2..831620b 100644
--- a/lib/predicate.c
+++ b/lib/atom.c
@@ -1,5 +1,5 @@
/* dctrl-tools - Debian control file inspection tools
- Copyright © 2003, 2004, 2008, 2010 Antti-Juhani Kaijanaho
+ Copyright © 2011 Antti-Juhani Kaijanaho
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
@@ -14,41 +14,19 @@
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
-#include <ctype.h>
-#include <stdlib.h>
#include <regex.h>
-#include <string.h>
-#include "fsaf.h"
+#include <stdlib.h>
+#include "atom.h"
#include "msg.h"
-#include "util.h"
-#include "predicate.h"
-#include "strutil.h"
#include "version.h"
#define RE_PKG_BEGIN "(^| )"
#define RE_PKG_END "([, \\(]|$)"
-void init_predicate(struct predicate * p)
+void atom_finish(struct atom * atom)
{
- p->num_atoms = 0;
- p->proglen = 0;
-}
-
-void addinsn(struct predicate * p, int insn)
-{
- if (insn == I_NOP) return;
- if (p->proglen >= MAX_OPS) {
- message(L_FATAL, 0, _("predicate is too complex"));
- fail();
- }
- p->program[p->proglen++] = insn;
-}
-
-void predicate_finish_atom(struct predicate * p)
-{
- struct atom * atom = get_current_atom(p);
char * regex_pat = NULL;
int regex_patlen = atom->patlen + strlen(RE_PKG_BEGIN)
+ strlen(RE_PKG_END) + 1;
@@ -91,7 +69,7 @@ void predicate_finish_atom(struct predicate * p)
}
-static bool verify_atom(struct atom * atom, para_t * para)
+bool atom_verify(struct atom * atom, para_t * para)
{
size_t start = 0;
size_t end = 0;
@@ -191,67 +169,3 @@ static bool verify_atom(struct atom * atom, para_t * para)
}
assert(0);
}
-
-bool check_predicate(struct predicate * p)
-{
- size_t sp = 0;
- /* Simulate the program. */
- for (size_t i = 0; i < p->proglen; i++) {
- switch (p->program[i]) {
- case I_NOP: break;
- case I_NEG:
- if (sp == 0) return false;
- break;
- case I_AND: case I_OR:
- if (sp < 2) return false;
- --sp;
- break;
- default:
- ++sp;
- }
- }
- if (sp != 1) return false;
- return true;
-}
-
-bool does_para_satisfy(struct predicate * p, para_t * para)
-{
- bool sat_atom[MAX_ATOMS];
- bool stack[MAX_OPS];
- size_t sp = 0;
-
- /* Verify atoms. */
- for (size_t i = 0; i < p->num_atoms; i++) {
- sat_atom[i] = verify_atom(&p->atoms[i], para);
- }
-
- /* Run the program. */
- for (size_t i = 0; i < p->proglen; i++) {
- switch (p->program[i]) {
- case I_NOP: break;
- case I_NEG:
- assert(sp >= 1);
- stack[sp-1] = !stack[sp-1];
- break;
- case I_AND:
- assert(sp >= 2);
- stack[sp-2] = stack[sp-2] && stack[sp-1];
- --sp;
- break;
- case I_OR:
- assert(sp >= 2);
- stack[sp-2] = stack[sp-2] || stack[sp-1];
- --sp;
- break;
- default:
- {
- int atom = p->program[i] - I_PUSH(0);
- assert(atom <= p->num_atoms);
- stack[sp] = sat_atom[atom];
- ++sp;
- }
- }
- }
- assert(sp == 1);
- return stack[0];
-}
diff --git a/lib/predicate.h b/lib/atom.h
similarity index 63%
copy from lib/predicate.h
copy to lib/atom.h
index 82ca63a..5674519 100644
--- a/lib/predicate.h
+++ b/lib/atom.h
@@ -1,5 +1,5 @@
/* dctrl-tools - Debian control file inspection tools
- Copyright © 2003, 2004, 2005 Antti-Juhani Kaijanaho
+ Copyright © 2011 Antti-Juhani Kaijanaho
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
@@ -16,23 +16,12 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef PREDICATE_H
-#define PREDICATE_H
+#ifndef GUARD_LIB_ATOM_H
+#define GUARD_LIB_ATOM_H
-#include <assert.h>
#include <regex.h>
-#include <stdint.h>
-#include "fieldtrie.h"
#include "paragraph.h"
-
-#define MAX_OPS 4096
-#define MAX_ATOMS 4096
-
-#define I_NOP 0
-#define I_NEG 1 /* --not; 1-1 */
-#define I_AND 2 /* --and; 2-1 */
-#define I_OR 3 /* --or; 2-1 */
-#define I_PUSH(n) (4+(n)) /* push result of nth atomic proposition */
+#include "util.h"
/* An atomic predicate. */
struct atom {
@@ -70,35 +59,7 @@ struct atom {
unsigned whole_pkg;
};
-/* A predicate is represented as a set of atomic predicates and a
- * program - a sequence of stack-based "bytecode" instructions - that
- * specifies the structure of the combined predicate. */
-struct predicate {
- /* Number of atomic predicates. */
- size_t num_atoms;
- /* Length of the program */
- size_t proglen;
- /* The program */
- int program[MAX_OPS];
- /* The atomic predicates */
- struct atom atoms[MAX_ATOMS];
-};
-
-void init_predicate(struct predicate * p);
-
-static inline
-struct atom * get_current_atom(struct predicate * p)
-{
- assert(p->num_atoms > 0);
- return &p->atoms[p->num_atoms-1];
-}
-
-void predicate_finish_atom(struct predicate *);
-
-void addinsn(struct predicate * p, int insn);
-
-bool does_para_satisfy(struct predicate * p, para_t *);
-
-bool check_predicate(struct predicate * p);
+void atom_finish(struct atom * atom);
+bool atom_verify(struct atom * atom, para_t * para);
-#endif /* PREDICATE_H */
+#endif /* GUARD_LIB_ATOM_H */
diff --git a/lib/predicate.c b/lib/predicate.c
index 5c213b2..cf78796 100644
--- a/lib/predicate.c
+++ b/lib/predicate.c
@@ -1,5 +1,5 @@
/* dctrl-tools - Debian control file inspection tools
- Copyright © 2003, 2004, 2008, 2010 Antti-Juhani Kaijanaho
+ Copyright © 2003, 2004, 2008, 2010, 2011 Antti-Juhani Kaijanaho
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
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <regex.h>
#include <string.h>
+#include "atom.h"
#include "fsaf.h"
#include "msg.h"
#include "util.h"
@@ -27,13 +28,12 @@
#include "strutil.h"
#include "version.h"
-#define RE_PKG_BEGIN "(^| )"
-#define RE_PKG_END "([, \\(]|$)"
-
void init_predicate(struct predicate * p)
{
p->num_atoms = 0;
p->proglen = 0;
+ p->atoms = malloc(MAX_ATOMS * sizeof p->atoms[0]);
+ if (p->atoms == 0) enomem(0);
}
void addinsn(struct predicate * p, int insn)
@@ -46,151 +46,6 @@ void addinsn(struct predicate * p, int insn)
p->program[p->proglen++] = insn;
}
-void predicate_finish_atom(struct predicate * p)
-{
- struct atom * atom = get_current_atom(p);
- char * regex_pat = NULL;
- int regex_patlen = atom->patlen + strlen(RE_PKG_BEGIN)
- + strlen(RE_PKG_END) + 1;
- debug_message("predicate_finish_atom", 0);
- if (atom->field_name != 0) {
- char * repl = strchr(atom->field_name, ':');
- if (repl != NULL) {
- *repl++ = '\0';
- atom->repl_inx = fieldtrie_insert(repl)->inx;
- } else {
- atom->repl_inx = -1;
- }
- atom->field_inx = fieldtrie_insert(atom->field_name)->inx;
- }
-
- if (atom->mode == M_REGEX || atom->mode == M_EREGEX) {
- regex_pat = calloc(1, regex_patlen); /* rely on mem 0-ing */
- if (regex_pat == 0) fatal_enomem(0);
- if (atom->whole_pkg)
- strncat(regex_pat, RE_PKG_BEGIN, strlen(RE_PKG_BEGIN));
- strncat(regex_pat, atom->pat, atom->patlen);
- if (atom->whole_pkg)
- strncat(regex_pat, RE_PKG_END, strlen(RE_PKG_END));
- debug_message("compiling:", 0);
- debug_message(regex_pat, 0);
- int rerr = regcomp(&atom->regex, regex_pat,
- (atom->mode == M_EREGEX ? REG_EXTENDED : 0)
- | REG_NOSUB
- | (atom->ignore_case ? REG_ICASE : 0));
- free(regex_pat);
- if (rerr != 0) {
- char * s;
- s = get_regerror(rerr, &atom->regex);
- if (s == 0) fatal_enomem(0);
- message(L_FATAL, 0, "%s", s);
- free(s);
- fail();
- }
- }
-
-}
-
-static bool verify_atom(struct atom * atom, para_t * para)
-{
- size_t start = 0;
- size_t end = 0;
- if (atom->field_inx == -1) {
- /* Take the full paragraph */
- start = para->start;
- end = para->end;
- } else {
- /* Take the field */
- struct field_data * fd = find_field_wr(para,
- atom->field_inx,
- atom->repl_inx);
- if (fd != NULL) {
- start = fd->start;
- end = fd->end;
- }
- }
- size_t len = end - start;
- struct fsaf_read_rv r = fsaf_read(para->common->fp, start, len);
- assert(r.len == len);
- switch (atom->mode) {
- case M_EXACT:
- if (len != atom->patlen) return false;
- if (atom->ignore_case) {
- return strncasecmp(atom->pat, r.b, len) == 0;
- } else {
- return strncmp(atom->pat, r.b, len) == 0;
- }
- case M_SUBSTR: {
-#if 0
- if (atom->ignore_case) {
- return strncasestr(r.b, atom->pat, len);
- } else {
- return strnstr(r.b, atom->pat, len);
- }
-#else
- bool rv;
- char * s = strndup(r.b, len);
- if (s == 0) fatal_enomem(0);
- if (atom->ignore_case) {
- rv = strcasestr(s, atom->pat) != 0;
- } else {
- rv = strstr(s, atom->pat) != 0;
- }
- free(s);
- return rv;
-#endif
- }
- case M_REGEX: case M_EREGEX: {
- char * s = strndup(r.b, len);
- if (s == 0) fatal_enomem(0);
- int regex_errcode = regexec(&atom->regex, s, 0, 0, 0);
- free(s);
- if (regex_errcode == 0 || regex_errcode == REG_NOMATCH) {
- return (regex_errcode == 0);
- }
- /* Error handling be here. */
- assert(regex_errcode != 0 && regex_errcode != REG_NOMATCH);
- s = get_regerror (regex_errcode, &atom->regex);
- if (s == 0) { enomem (0); return false; }
- message(L_IMPORTANT, 0, "%s", s);
- free(s);
- return false;
- }
- case M_VER_EQ:case M_VER_LT:case M_VER_LE:case M_VER_GT:case M_VER_GE:
- ;
- char *pats = strndup(atom->pat, atom->patlen);
- char *cands = strndup(r.b, len);
- struct versionrevision pat, cand;
- if (!parse_version(&pat, pats, atom->patlen)) {
- free(pats);
- free(cands);
- return false;
- }
- if (!parse_version(&cand, cands, len)) {
- free(pats);
- free(cands);
- return false;
- }
- int res = versioncompare(&cand, &pat);
- free(pats);
- free(cands);
- switch (atom->mode) {
- case M_VER_EQ:
- return res == 0;
- case M_VER_LT:
- return res < 0;
- case M_VER_LE:
- return res <= 0;
- case M_VER_GT:
- return res > 0;
- case M_VER_GE:
- return res >= 0;
- default:
- assert(0);
- }
- }
- assert(0);
-}
bool check_predicate(struct predicate * p)
{
@@ -222,7 +77,7 @@ bool does_para_satisfy(struct predicate * p, para_t * para)
/* Verify atoms. */
for (size_t i = 0; i < p->num_atoms; i++) {
- sat_atom[i] = verify_atom(&p->atoms[i], para);
+ sat_atom[i] = atom_verify(&p->atoms[i], para);
}
/* Run the program. */
diff --git a/lib/predicate.h b/lib/predicate.h
index 82ca63a..47d700c 100644
--- a/lib/predicate.h
+++ b/lib/predicate.h
@@ -19,10 +19,6 @@
#ifndef PREDICATE_H
#define PREDICATE_H
-#include <assert.h>
-#include <regex.h>
-#include <stdint.h>
-#include "fieldtrie.h"
#include "paragraph.h"
#define MAX_OPS 4096
@@ -34,41 +30,7 @@
#define I_OR 3 /* --or; 2-1 */
#define I_PUSH(n) (4+(n)) /* push result of nth atomic proposition */
-/* An atomic predicate. */
-struct atom {
- /* The name of field to which matching is limited. Empty
- * field_name specifies the whole paragraph (in which case
- * field_inx is -1. */
- char const * field_name; size_t field_inx;
- /* The index to the field whose value is to be used when this
- * field is empty. */
- size_t repl_inx;
- /* Matching mode */
- enum matching_mode {
- M_SUBSTR, /* substring matching */
- M_REGEX, /* POSIX regular expression match */
- M_EREGEX, /* POSIX extended regular expression matching */
- M_EXACT, /* exact string match */
-#define M_FIRST_VERSION M_VER_EQ
- M_VER_EQ, /* numeric equality comparison */
- M_VER_LT, /* numeric < */
- M_VER_LE, /* numeric <= */
- M_VER_GT, /* numeric > */
- M_VER_GE, /* numeric >= */
-#define M_LAST_VERSION M_VER_GE
- } mode;
- /* Flag: should matching ignore case */
- unsigned ignore_case;
- /* The pattern as given on the command line; interpretation
- * depends on matching mode. Must be null-terminated and
- * patlen must equal strlen(pat). */
- char const * pat; size_t patlen;
- /* A compiled version of pat; valid only when mode is M_REGEX
- * or M_EREGEX. */
- regex_t regex;
- /* Flag: (extended) regex should match whole package names */
- unsigned whole_pkg;
-};
+struct atom;
/* A predicate is represented as a set of atomic predicates and a
* program - a sequence of stack-based "bytecode" instructions - that
@@ -81,7 +43,7 @@ struct predicate {
/* The program */
int program[MAX_OPS];
/* The atomic predicates */
- struct atom atoms[MAX_ATOMS];
+ struct atom *atoms;
};
void init_predicate(struct predicate * p);
@@ -93,8 +55,6 @@ struct atom * get_current_atom(struct predicate * p)
return &p->atoms[p->num_atoms-1];
}
-void predicate_finish_atom(struct predicate *);
-
void addinsn(struct predicate * p, int insn);
bool does_para_satisfy(struct predicate * p, para_t *);
--
Debian control file query tools
More information about the Dctrl-tools-devel
mailing list