From 7b0a5daa703117cde2dc0d54d5a39941a1c01ce8 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 11 Dec 1995 09:15:21 +0000 Subject: [PATCH] New set types: sand/sor/snot - ranked versions of and/or/not in ranked/semi-ranked result sets. Note: the snot not finished yet. New rset member: flag. Bug fix: r_delete in rsrel.c did free bad memory block. --- rset/Makefile | 4 +- rset/rsbool.c | 34 +++-- rset/rset.c | 20 ++- rset/rsisam.c | 18 ++- rset/rsnull.c | 17 ++- rset/rsrel.c | 23 +++- rset/rssbool.c | 391 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rset/rstemp.c | 18 ++- 8 files changed, 486 insertions(+), 39 deletions(-) create mode 100644 rset/rssbool.c diff --git a/rset/Makefile b/rset/Makefile index 7644092..3970f4c 100644 --- a/rset/Makefile +++ b/rset/Makefile @@ -1,7 +1,7 @@ # Copyright (C) 1994, Index Data I/S # All rights reserved. # Sebastian Hammer, Adam Dickmeiss -# $Id: Makefile,v 1.9 1995-11-20 11:58:10 adam Exp $ +# $Id: Makefile,v 1.10 1995-12-11 09:15:21 adam Exp $ SHELL=/bin/sh RANLIB=ranlib @@ -14,7 +14,7 @@ INCLUDE=-I../include $(YAZINC) DEFS=$(INCLUDE) LIB=../lib/rset.a PROG= -PO=rset.o rstemp.o rsisam.o rsnull.o rsbool.o rsrel.o +PO=rset.o rstemp.o rsisam.o rsnull.o rsbool.o rssbool.o rsrel.o CPP=$(CC) -E all: $(LIB) diff --git a/rset/rsbool.c b/rset/rsbool.c index d77d259..df2c5e4 100644 --- a/rset/rsbool.c +++ b/rset/rsbool.c @@ -4,7 +4,14 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: rsbool.c,v $ - * Revision 1.8 1995-10-12 12:41:55 adam + * Revision 1.9 1995-12-11 09:15:22 adam + * New set types: sand/sor/snot - ranked versions of and/or/not in + * ranked/semi-ranked result sets. + * Note: the snot not finished yet. + * New rset member: flag. + * Bug fix: r_delete in rsrel.c did free bad memory block. + * + * Revision 1.8 1995/10/12 12:41:55 adam * Private info (buf) moved from struct rset_control to struct rset. * Bug fixes in relevance. * @@ -40,7 +47,8 @@ #include #include -static void *r_create(const struct rset_control *sel, void *parms); +static void *r_create(const struct rset_control *sel, void *parms, + int *flags); static RSFD r_open (RSET ct, int flag); static void r_close (RSFD rfd); static void r_delete (RSET ct); @@ -54,7 +62,7 @@ static int r_score (RSFD rfd, int *score); static const rset_control control_and = { - "AND set type", + "and", r_create, r_open, r_close, @@ -68,7 +76,7 @@ static const rset_control control_and = static const rset_control control_or = { - "OR set type", + "or", r_create, r_open, r_close, @@ -82,7 +90,7 @@ static const rset_control control_or = static const rset_control control_not = { - "NOT set type", + "not", r_create, r_open, r_close, @@ -118,15 +126,18 @@ struct rset_bool_rfd { struct rset_bool_info *info; }; -static void *r_create (const struct rset_control *sel, void *parms) +static void *r_create (const struct rset_control *sel, void *parms, + int *flags) { rset_bool_parms *bool_parms = parms; struct rset_bool_info *info; - info = xmalloc (sizeof(struct rset_bool_info)); + info = xmalloc (sizeof(*info)); info->key_size = bool_parms->key_size; info->rset_l = bool_parms->rset_l; info->rset_r = bool_parms->rset_r; + if (rset_is_volatile(info->rset_l) || rset_is_volatile(info->rset_r)) + *flags |= RSET_FLAG_VOLATILE; info->cmp = bool_parms->cmp; info->rfd_list = NULL; return info; @@ -142,18 +153,17 @@ static RSFD r_open (RSET ct, int flag) logf (LOG_FATAL, "bool set type is read-only"); return NULL; } - flag = 0; rfd = xmalloc (sizeof(*rfd)); rfd->next = info->rfd_list; info->rfd_list = rfd; + rfd->info = info; rfd->buf_l = xmalloc (info->key_size); rfd->buf_r = xmalloc (info->key_size); - rfd->rfd_l = rset_open (info->rset_l, flag); - rfd->rfd_r = rset_open (info->rset_r, flag); + rfd->rfd_l = rset_open (info->rset_l, RSETF_READ|RSETF_SORT_SYSNO); + rfd->rfd_r = rset_open (info->rset_r, RSETF_READ|RSETF_SORT_SYSNO); rfd->more_l = rset_read (info->rset_l, rfd->rfd_l, rfd->buf_l); rfd->more_r = rset_read (info->rset_r, rfd->rfd_r, rfd->buf_r); - rfd->info = info; return rfd; } @@ -182,6 +192,8 @@ static void r_delete (RSET ct) struct rset_bool_info *info = ct->buf; assert (info->rfd_list == NULL); + rset_delete (info->rset_l); + rset_delete (info->rset_r); xfree (info); } diff --git a/rset/rset.c b/rset/rset.c index 5050a1d..d6e2041 100644 --- a/rset/rset.c +++ b/rset/rset.c @@ -4,7 +4,14 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: rset.c,v $ - * Revision 1.7 1995-10-12 12:41:56 adam + * Revision 1.8 1995-12-11 09:15:23 adam + * New set types: sand/sor/snot - ranked versions of and/or/not in + * ranked/semi-ranked result sets. + * Note: the snot not finished yet. + * New rset member: flag. + * Bug fix: r_delete in rsrel.c did free bad memory block. + * + * Revision 1.7 1995/10/12 12:41:56 adam * Private info (buf) moved from struct rset_control to struct rset. * Bug fixes in relevance. * @@ -37,13 +44,14 @@ RSET rset_create(const rset_control *sel, void *parms) { - RSET new; + RSET rnew; logf (LOG_DEBUG, "rs_create(%s)", sel->desc); - new = xmalloc(sizeof(*new)); - new->control = sel; - new->buf = (*sel->f_create)(sel, parms); - return new; + rnew = xmalloc(sizeof(*rnew)); + rnew->control = sel; + rnew->flags = 0; + rnew->buf = (*sel->f_create)(sel, parms, &rnew->flags); + return rnew; } void rset_delete (RSET rs) diff --git a/rset/rsisam.c b/rset/rsisam.c index 249a763..2bdd745 100644 --- a/rset/rsisam.c +++ b/rset/rsisam.c @@ -4,7 +4,14 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: rsisam.c,v $ - * Revision 1.13 1995-10-12 12:41:56 adam + * Revision 1.14 1995-12-11 09:15:24 adam + * New set types: sand/sor/snot - ranked versions of and/or/not in + * ranked/semi-ranked result sets. + * Note: the snot not finished yet. + * New rset member: flag. + * Bug fix: r_delete in rsrel.c did free bad memory block. + * + * Revision 1.13 1995/10/12 12:41:56 adam * Private info (buf) moved from struct rset_control to struct rset. * Bug fixes in relevance. * @@ -51,7 +58,8 @@ #include #include -static void *r_create(const struct rset_control *sel, void *parms); +static void *r_create(const struct rset_control *sel, void *parms, + int *flags); static RSFD r_open (RSET ct, int flag); static void r_close (RSFD rfd); static void r_delete (RSET ct); @@ -63,7 +71,7 @@ static int r_score (RSFD rfd, int *score); static const rset_control control = { - "ISAM set type", + "isam", r_create, r_open, r_close, @@ -89,11 +97,13 @@ struct rset_isam_info { struct rset_ispt_info *ispt_list; }; -static void *r_create(const struct rset_control *sel, void *parms) +static void *r_create(const struct rset_control *sel, void *parms, + int *flags) { rset_isam_parms *pt = parms; struct rset_isam_info *info; + *flags |= RSET_FLAG_VOLATILE; info = xmalloc (sizeof(struct rset_isam_info)); info->is = pt->is; info->pos = pt->pos; diff --git a/rset/rsnull.c b/rset/rsnull.c index 3cf371f..fd98d30 100644 --- a/rset/rsnull.c +++ b/rset/rsnull.c @@ -4,7 +4,14 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: rsnull.c,v $ - * Revision 1.6 1995-10-12 12:41:57 adam + * Revision 1.7 1995-12-11 09:15:25 adam + * New set types: sand/sor/snot - ranked versions of and/or/not in + * ranked/semi-ranked result sets. + * Note: the snot not finished yet. + * New rset member: flag. + * Bug fix: r_delete in rsrel.c did free bad memory block. + * + * Revision 1.6 1995/10/12 12:41:57 adam * Private info (buf) moved from struct rset_control to struct rset. * Bug fixes in relevance. * @@ -32,7 +39,8 @@ #include #include -static void *r_create(const struct rset_control *sel, void *parms); +static void *r_create(const struct rset_control *sel, void *parms, + int *flags); static RSFD r_open (RSET ct, int flag); static void r_close (RSFD rfd); static void r_delete (RSET ct); @@ -44,7 +52,7 @@ static int r_score (RSFD rfd, int *score); static const rset_control control = { - "NULL set type", + "null", r_create, r_open, r_close, @@ -58,7 +66,8 @@ static const rset_control control = const rset_control *rset_kind_null = &control; -static void *r_create(const struct rset_control *sel, void *parms) +static void *r_create(const struct rset_control *sel, void *parms, + int *flags) { return NULL; } diff --git a/rset/rsrel.c b/rset/rsrel.c index 63736e7..2f7af4c 100644 --- a/rset/rsrel.c +++ b/rset/rsrel.c @@ -4,7 +4,14 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: rsrel.c,v $ - * Revision 1.8 1995-12-05 11:25:45 adam + * Revision 1.9 1995-12-11 09:15:26 adam + * New set types: sand/sor/snot - ranked versions of and/or/not in + * ranked/semi-ranked result sets. + * Note: the snot not finished yet. + * New rset member: flag. + * Bug fix: r_delete in rsrel.c did free bad memory block. + * + * Revision 1.8 1995/12/05 11:25:45 adam * Doesn't include math.h. * * Revision 1.7 1995/10/12 12:41:57 adam @@ -40,7 +47,8 @@ #include #include -static void *r_create(const struct rset_control *sel, void *parms); +static void *r_create(const struct rset_control *sel, void *parms, + int *flags); static RSFD r_open (RSET ct, int flag); static void r_close (RSFD rfd); static void r_delete (RSET ct); @@ -52,7 +60,7 @@ static int r_score (RSFD rfd, int *score); static const rset_control control = { - "relevance set type", + "relevance", r_create, r_open, r_close, @@ -164,7 +172,7 @@ static void relevance (struct rset_rel_info *info, rset_relevance_parms *parms) /* find min with lowest sysno */ for (i = 0; ino_isam_positions; i++) if (isam_r[i] && - (min < 0 || (*parms->cmp)(isam_buf[i], isam_buf[min]) < 1)) + (min < 0 || (*parms->cmp)(isam_buf[i], isam_buf[min]) < 2)) min = i; if (min < 0) break; @@ -197,7 +205,7 @@ static void relevance (struct rset_rel_info *info, rset_relevance_parms *parms) for (i = 0; ino_isam_positions; i++) score += wgt[i]; /* if value is in the top score, then save it - don't emit yet */ - add_rec (info, score, isam_tmp_buf); + add_rec (info, score/parms->no_isam_positions, isam_tmp_buf); } for (i = 0; ino_rec; i++) info->sysno_idx[i] = i; @@ -216,11 +224,13 @@ static void relevance (struct rset_rel_info *info, rset_relevance_parms *parms) xfree (wgt); } -static void *r_create (const struct rset_control *sel, void *parms) +static void *r_create (const struct rset_control *sel, void *parms, + int *flags) { rset_relevance_parms *r_parms = parms; struct rset_rel_info *info; + *flags |= RSET_FLAG_RANKED; info = xmalloc (sizeof(struct rset_rel_info)); info->key_size = r_parms->key_size; assert (info->key_size > 1); @@ -284,7 +294,6 @@ static void r_delete (RSET ct) xfree (info->sort_idx); xfree (info->sysno_idx); xfree (info); - xfree (ct); } static void r_rewind (RSFD rfd) diff --git a/rset/rssbool.c b/rset/rssbool.c new file mode 100644 index 0000000..32855d3 --- /dev/null +++ b/rset/rssbool.c @@ -0,0 +1,391 @@ +/* + * Copyright (C) 1994-1995, Index Data I/S + * All rights reserved. + * Sebastian Hammer, Adam Dickmeiss + * + * $Log: rssbool.c,v $ + * Revision 1.1 1995-12-11 09:15:27 adam + * New set types: sand/sor/snot - ranked versions of and/or/not in + * ranked/semi-ranked result sets. + * Note: the snot not finished yet. + * New rset member: flag. + * Bug fix: r_delete in rsrel.c did free bad memory block. + * + */ + +#include +#include + +#include +#include + +static void *r_create_and(const struct rset_control *sel, void *parms, + int *flags); +static void *r_create_or(const struct rset_control *sel, void *parms, + int *flags); +static void *r_create_not(const struct rset_control *sel, void *parms, + int *flags); +static RSFD r_open (RSET ct, int flag); +static void r_close (RSFD rfd); +static void r_delete (RSET ct); +static void r_rewind (RSFD rfd); +static int r_count (RSET ct); +static int r_read (RSFD rfd, void *buf); +static int r_write (RSFD rfd, const void *buf); +static int r_score (RSFD rfd, int *score); + +static const rset_control control_sand = +{ + "sand", + r_create_and, + r_open, + r_close, + r_delete, + r_rewind, + r_count, + r_read, + r_write, + r_score +}; + +static const rset_control control_sor = +{ + "sor", + r_create_or, + r_open, + r_close, + r_delete, + r_rewind, + r_count, + r_read, + r_write, + r_score +}; + +static const rset_control control_snot = +{ + "snot", + r_create_not, + r_open, + r_close, + r_delete, + r_rewind, + r_count, + r_read, + r_write, + r_score +}; + + +const rset_control *rset_kind_sand = &control_sand; +const rset_control *rset_kind_sor = &control_sor; +const rset_control *rset_kind_snot = &control_snot; + +struct rset_bool_info { + int key_size; + RSET rset_l; + RSET rset_r; + char *key_buf; + int *score_buf; + int key_no; + int key_max; + int (*cmp)(const void *p1, const void *p2); + struct rset_bool_rfd *rfd_list; +}; + +struct rset_bool_rfd { + struct rset_bool_rfd *next; + struct rset_bool_info *info; + int position; + int last_pos; + int open_flag; +}; + +static void *r_create_common (const struct rset_control *sel, + rset_bool_parms *bool_parms, int *flags); + +static void key_add (struct rset_bool_info *info, + char *buf, int score) +{ + if (info->key_no == info->key_max) + return; + memcpy (info->key_buf + info->key_size * info->key_no, + buf, info->key_size); + info->score_buf[info->key_no] = score; + (info->key_no)++; +} + +static void *r_create_and (const struct rset_control *sel, void *parms, + int *flags) +{ + int more_l, more_r; + RSFD fd_l, fd_r; + char *buf_l, *buf_r; + + struct rset_bool_info *info; + info = r_create_common (sel, parms, flags); + + buf_l = xmalloc (info->key_size); + buf_r = xmalloc (info->key_size); + fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ); + fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ); + + more_l = rset_read(info->rset_l, fd_l, buf_l); + more_r = rset_read(info->rset_r, fd_r, buf_r); + + while (more_l || more_r) + { + int cmp; + int score, score_l, score_r; + + if (more_l && more_r) + cmp = (*info->cmp)(buf_l, buf_r); + else if (more_r) + cmp = 2; + else + cmp = -2; + + if (cmp >= -1 && cmp <= 1) + { + rset_score (info->rset_l, fd_l, &score_l); + rset_score (info->rset_r, fd_r, &score_r); + if (score_l == -1) + score = score_r; + else if (score_r == -1) + score = score_l; + else + score = score_l > score_r ? score_r : score_l; + key_add (info, buf_l, score); + + more_l = rset_read (info->rset_l, fd_l, buf_l); + more_r = rset_read (info->rset_r, fd_r, buf_r); + } + else if (cmp > 1) + { + rset_score (info->rset_r, fd_r, &score_r); + if (score_r != -1) + key_add (info, buf_r, 1); + more_r = rset_read (info->rset_r, fd_r, buf_r); + } + else + { + rset_score (info->rset_l, fd_l, &score_l); + if (score_l != -1) + key_add (info, buf_l, 1); + more_l = rset_read (info->rset_l, fd_l, buf_l); + } + } + rset_close (info->rset_l, fd_l); + rset_close (info->rset_r, fd_r); + rset_delete (info->rset_l); + rset_delete (info->rset_r); + xfree (buf_l); + xfree (buf_r); + return info; +} + +static void *r_create_or (const struct rset_control *sel, void *parms, + int *flags) +{ + int more_l, more_r; + RSFD fd_l, fd_r; + char *buf_l, *buf_r; + + struct rset_bool_info *info; + info = r_create_common (sel, parms, flags); + + buf_l = xmalloc (info->key_size); + buf_r = xmalloc (info->key_size); + fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ); + fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ); + + more_l = rset_read(info->rset_l, fd_l, buf_l); + more_r = rset_read(info->rset_r, fd_r, buf_r); + + while (more_l || more_r) + { + int cmp; + int score, score_l, score_r; + + if (more_l && more_r) + cmp = (*info->cmp)(buf_l, buf_r); + else if (more_r) + cmp = 2; + else + cmp = -2; + + if (cmp >= -1 && cmp <= 1) + { + rset_score (info->rset_l, fd_l, &score_l); + rset_score (info->rset_r, fd_r, &score_r); + if (score_l == -1) + score = score_r; + else if (score_r == -1) + score = score_l; + else + score = score_r > score_l ? score_r : score_l; + key_add (info, buf_l, score); + + more_l = rset_read (info->rset_l, fd_l, buf_l); + more_r = rset_read (info->rset_r, fd_r, buf_r); + } + else if (cmp > 1) + { + rset_score (info->rset_r, fd_r, &score_r); + if (score_r != -1) + key_add (info, buf_r, score_r / 2); + more_r = rset_read (info->rset_r, fd_r, buf_r); + } + else + { + rset_score (info->rset_l, fd_l, &score_l); + if (score_l != -1) + key_add (info, buf_l, score_l / 2); + more_l = rset_read (info->rset_l, fd_l, buf_l); + } + } + rset_close (info->rset_l, fd_l); + rset_close (info->rset_r, fd_r); + rset_delete (info->rset_l); + rset_delete (info->rset_r); + xfree (buf_l); + xfree (buf_r); + return info; +} + +static void *r_create_not (const struct rset_control *sel, void *parms, + int *flags) +{ + char *buf_l, *buf_r; + + struct rset_bool_info *info; + info = r_create_common (sel, parms, flags); + + buf_l = xmalloc (info->key_size); + buf_r = xmalloc (info->key_size); + rset_delete (info->rset_l); + rset_delete (info->rset_r); + xfree (buf_l); + xfree (buf_r); + return info; +} + +static void *r_create_common (const struct rset_control *sel, + rset_bool_parms *bool_parms, int *flags) +{ + struct rset_bool_info *info; + + info = xmalloc (sizeof(*info)); + info->key_size = bool_parms->key_size; + info->rset_l = bool_parms->rset_l; + info->rset_r = bool_parms->rset_r; + info->cmp = bool_parms->cmp; + info->rfd_list = NULL; + + if (rset_is_ranked(info->rset_l) || rset_is_ranked(info->rset_r)) + *flags |= RSET_FLAG_RANKED; + + info->key_max = rset_count(bool_parms->rset_l) + +rset_count(bool_parms->rset_r); + if (!info->key_max) + info->key_max = 1; + if (info->key_max > 1000) + info->key_max = 1000; + info->key_buf = xmalloc (info->key_size * info->key_max); + info->score_buf = xmalloc (info->key_max * sizeof(*info->score_buf)); + info->key_no = 0; + + return info; +} + +static RSFD r_open (RSET ct, int flag) +{ + struct rset_bool_info *info = ct->buf; + struct rset_bool_rfd *rfd; + + if (flag & RSETF_WRITE) + { + logf (LOG_FATAL, "sbool set type is read-only"); + return NULL; + } + rfd = xmalloc (sizeof(*rfd)); + rfd->next = info->rfd_list; + info->rfd_list = rfd; + rfd->info = info; + + rfd->position = 0; + rfd->last_pos = 0; + rfd->open_flag = flag; + + return rfd; +} + +static void r_close (RSFD rfd) +{ + struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info; + struct rset_bool_rfd **rfdp; + + for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next) + if (*rfdp == rfd) + { + *rfdp = (*rfdp)->next; + xfree (rfd); + return; + } + logf (LOG_FATAL, "r_close but no rfd match!"); + assert (0); +} + +static void r_delete (RSET ct) +{ + struct rset_bool_info *info = ct->buf; + + assert (info->rfd_list == NULL); + xfree (info->score_buf); + xfree (info->key_buf); + xfree (info); +} + +static void r_rewind (RSFD rfd) +{ + struct rset_bool_rfd *p = rfd; + + logf (LOG_DEBUG, "rsbool_rewind"); + p->position = p->last_pos = 0; +} + +static int r_count (RSET ct) +{ + struct rset_bool_info *info = ct->buf; + + return info->key_no; +} + +static int r_read (RSFD rfd, void *buf) +{ + struct rset_bool_rfd *p = rfd; + struct rset_bool_info *info = p->info; + + if (p->position >= info->key_no) + return 0; + p->last_pos = (p->position)++; + memcpy (buf, info->key_buf + info->key_size * p->last_pos, + info->key_size); + return 1; +} + +static int r_write (RSFD rfd, const void *buf) +{ + logf (LOG_FATAL, "sbool set type is read-only"); + return -1; +} + +static int r_score (RSFD rfd, int *score) +{ + struct rset_bool_rfd *p = rfd; + struct rset_bool_info *info = p->info; + + *score = info->score_buf[p->last_pos]; + return 1; +} + diff --git a/rset/rstemp.c b/rset/rstemp.c index 5eb0db9..f200e8b 100644 --- a/rset/rstemp.c +++ b/rset/rstemp.c @@ -4,7 +4,14 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: rstemp.c,v $ - * Revision 1.16 1995-11-28 14:47:02 adam + * Revision 1.17 1995-12-11 09:15:28 adam + * New set types: sand/sor/snot - ranked versions of and/or/not in + * ranked/semi-ranked result sets. + * Note: the snot not finished yet. + * New rset member: flag. + * Bug fix: r_delete in rsrel.c did free bad memory block. + * + * Revision 1.16 1995/11/28 14:47:02 adam * New setting: tempSetPath. Location of temporary result sets. * * Revision 1.15 1995/10/12 12:41:58 adam @@ -67,7 +74,8 @@ #include #include -static void *r_create(const struct rset_control *sel, void *parms); +static void *r_create(const struct rset_control *sel, void *parms, + int *flags); static RSFD r_open (RSET ct, int flag); static void r_close (RSFD rfd); static void r_delete (RSET ct); @@ -82,7 +90,7 @@ static char *temppath_root = NULL; static const rset_control control = { - "Temporary set", + "temp", r_create, r_open, r_close, @@ -114,11 +122,11 @@ struct rset_temp_rfd { struct rset_temp_rfd *next; }; -static void *r_create(const struct rset_control *sel, void *parms) +static void *r_create(const struct rset_control *sel, void *parms, int *flags) { rset_temp_parms *temp_parms = parms; struct rset_temp_info *info; - + info = xmalloc (sizeof(struct rset_temp_info)); info->fd = -1; info->fname = NULL; -- 1.7.10.4