poldek: poldek/ask.c, poldek/lib_init.c, poldek/poldek.h, poldek/p...

mis mis at pld-linux.org
Sat Feb 2 16:38:41 CET 2008


Author: mis                          Date: Sat Feb  2 15:38:41 2008 GMT
Module: poldek                        Tag: HEAD
---- Log message:
- new choose_suggests() callback (fixes #38, #81), based on poldek-suggests-one-package patch by megabajt at pld

---- Files affected:
poldek/poldek:
   ask.c (1.11 -> 1.12) , lib_init.c (1.92 -> 1.93) , poldek.h (1.38 -> 1.39) , poldek_intern.h (1.14 -> 1.15) 
poldek/poldek/install:
   misc.c (1.14 -> 1.15) 
poldek/poldek/install3:
   conflicts.c (1.4 -> 1.5) , ictx.h (1.2 -> 1.3) , misc.c (1.4 -> 1.5) , preinstall.c (1.2 -> 1.3) , requirements.c (1.3 -> 1.4) 

---- Diffs:

================================================================
Index: poldek/poldek/ask.c
diff -u poldek/poldek/ask.c:1.11 poldek/poldek/ask.c:1.12
--- poldek/poldek/ask.c:1.11	Sun Jul  8 18:48:11 2007
+++ poldek/poldek/ask.c	Sat Feb  2 16:38:36 2008
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2000 - 2007 Pawel A. Gajda <mis at pld-linux.org>
+  Copyright (C) 2000 - 2008 Pawel A. Gajda <mis at pld-linux.org>
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 as
@@ -25,7 +25,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <trurl/nassert.h>
+#include <trurl/trurl.h>
 
 #include "i18n.h"
 #include "log.h"
@@ -33,6 +33,7 @@
 #include "poldek_ts.h"
 #include "poldek_intern.h"
 #include "pkg.h"
+#include "capreq.h"
 
 #define msg_ask(fmt, args...) poldek_log(LOGTTY|LOGINFO, fmt, ## args)
 
@@ -62,8 +63,7 @@
         default:
             n_assert(0);
     }
-    
-    msg_ask("_\n");
+    msg_ask("_ %c\n", a ? 'y' : 'n');
     return a;
 }
 
@@ -87,8 +87,9 @@
     return answer;
 }
 
-static int term_choose_pkg(void *foo, const struct poldek_ts *ts,
-                           const char *capname, tn_array *pkgs, int hint)
+static int term_choose_equiv(void *foo, const struct poldek_ts *ts,
+                             const struct pkg *pkg, const char *capname,
+                             tn_array *candidates, int hint)
 {
     char *validchrs, *p;
     int i, a;
@@ -100,16 +101,23 @@
     
     if (!isatty(STDIN_FILENO))
         return hint;
+
+    if (pkg) {
+        msg_ask(_("%s: required \"%s\" is provided by folowing packages:"),
+                pkg_id(pkg), capname);
+    } else {
+        msg_ask(_("Required \"%s\" is provided by folowing packages:"),
+                capname);
+    }
     
-    msg_ask(_("There are more than one package which provide \"%s\":"), capname);
     msg_ask("_\n");
     validchrs = alloca(64);
     p = validchrs;
     *p++ = '\n';
 
     i = 0;
-    for (i=0; i < n_array_size(pkgs); i++) {
-        msgn(-1, "%c) %s", 'a' + i, pkg_id(n_array_nth(pkgs, i)));
+    for (i=0; i < n_array_size(candidates); i++) {
+        msgn(-1, "%c) %s", 'a' + i, pkg_id(n_array_nth(candidates, i)));
         *p++ = 'a' + i;
 
         if (i > 24)
@@ -136,6 +144,72 @@
     return hint;
 }
 
+static int term_choose_suggests(void *foo, const struct poldek_ts *ts, 
+                                const struct pkg *pkg, tn_array *caps,
+                                tn_array *choices, int hint)
+{
+    char message[512], *question;
+    char *yns = "N/y/s", *yn = "N/y";
+    int i, a, ac;
+    
+    foo = foo; ts = ts;
+    
+    if (!isatty(STDIN_FILENO))
+        return hint;
+
+    if (hint) {
+        yns = "Y/n/s";
+        yn = "N/y";
+    }
+
+    n_snprintf(message, sizeof(message),
+               "Package %s suggests installation of:", pkg_id(pkg));
+
+    question = ngettext("Try to install it?", "Try to install them?",
+                        n_array_size(caps));    
+
+    msg_ask("%s\n", message);
+    
+    for (i=0; i < n_array_size(caps); i++) {
+        struct capreq *cap = n_array_nth(caps, i);
+        msgn(-1, "%d. %s", i + 1, capreq_stra(cap));
+    }
+
+    if (n_array_size(caps) > 1) {
+        msg_ask("%s ", question);
+        msg_ask(_("(y - all, n - nothing, s - select some of)? [%s]"),
+                yns);
+    } else {
+        msg_ask("%s? [%s]", question, yn);
+    }
+        
+    a = poldek_term_ask(STDIN_FILENO, "QqYyNnSs\n", NULL);
+    a = toupper(a);
+    switch(a) {
+        case 'Y': a = 1; ac = 'y'; break;
+        case 'N': a = 0; ac = 'n'; break;
+        case 'S': a = 2; ac = 's'; break;
+        case 'Q': a = -1; ac = 'q'; break;
+        case '\n': a = hint; ac = hint ? 'y':'n'; break;
+        default:
+            n_assert(0);
+    }
+    msg_ask("_ %c\n", ac);
+    
+    if (a == 2) {
+        for (i=0; i < n_array_size(caps); i++) {
+            struct capreq *cap = n_array_nth(caps, i);
+            char q[512];
+            n_snprintf(q, sizeof(q), _("Try to install %s?"), capreq_stra(cap));
+            
+            if (term_confirm(NULL, NULL, 1, q))
+                n_array_push(choices, cap);
+        }
+    }
+
+    return a;
+}
+
 int poldek__confirm(const struct poldek_ts *ts, int hint, const char *message)
 {
     if (ts->ctx->confirm_fn == NULL)
@@ -153,7 +227,8 @@
 }
 
 int poldek__choose_equiv(const struct poldek_ts *ts,
-                         const char *capname, tn_array *pkgs, struct pkg *hint)
+                         const struct pkg *pkg, const char *capname,
+                         tn_array *pkgs, struct pkg *hint)
 {
     int i, inthint = 0;
     
@@ -170,9 +245,21 @@
         return inthint;
     
     return ts->ctx->choose_equiv_fn(ts->ctx->data_choose_equiv_fn,
-                                    ts, capname, pkgs, inthint);
+                                    ts, pkg, capname, pkgs, inthint);
+}
+
+int poldek__choose_suggests(const struct poldek_ts *ts,
+                            const struct pkg *pkg, tn_array *caps,
+                            tn_array *choices, int hint)
+{
+    if (ts->ctx->choose_suggests_fn == NULL)
+        return hint;
+
+    return ts->ctx->choose_suggests_fn(ts->ctx->data_choose_suggests_fn,
+                                       ts, pkg, caps, choices, hint);
 }
 
+
 void poldek__setup_default_ask_callbacks(struct poldek_ctx *ctx)
 {
     ctx->data_confirm_fn = NULL;
@@ -182,5 +269,8 @@
     ctx->ts_confirm_fn = term_ts_confirm;
 
     ctx->data_choose_equiv_fn = NULL;
-    ctx->choose_equiv_fn = term_choose_pkg;
+    ctx->choose_equiv_fn = term_choose_equiv;
+
+    ctx->data_choose_suggests_fn = NULL;
+    ctx->choose_suggests_fn = term_choose_suggests;
 }

================================================================
Index: poldek/poldek/lib_init.c
diff -u poldek/poldek/lib_init.c:1.92 poldek/poldek/lib_init.c:1.93
--- poldek/poldek/lib_init.c:1.92	Sun Jan 27 17:01:55 2008
+++ poldek/poldek/lib_init.c	Sat Feb  2 16:38:36 2008
@@ -675,7 +675,7 @@
     struct default_op_map_ent *ent;
     struct default_op_map_ent addon[] = {
         { 0, "(!no)hold", POLDEK_OP_HOLD,   1,  1, CONF_TYPE_BOOLEAN  },
-        { 0, "(!no)ingore", POLDEK_OP_IGNORE, 1, 1, CONF_TYPE_BOOLEAN  }, 
+        { 0, "(!no)ingore", POLDEK_OP_IGNORE, 1, 1, CONF_TYPE_BOOLEAN  },
         { 0, NULL, 0, 0, 0, 0 }
     };
     
@@ -1232,6 +1232,15 @@
                 ctx->data_choose_equiv_fn = vv;
             break;
 
+        case POLDEK_CONF_CHOOSESUGGESTS_CB:
+            if ((vv = va_arg(ap, void*)))
+                ctx->choose_suggests_fn = vv;
+            
+            if ((vv = va_arg(ap, void*)))
+                ctx->data_choose_suggests_fn = vv;
+            break;
+
+
         case POLDEK_CONF_GOODBYE_CB:
             vv = va_arg(ap, void*);
             if (vv) {

================================================================
Index: poldek/poldek/poldek.h
diff -u poldek/poldek/poldek.h:1.38 poldek/poldek/poldek.h:1.39
--- poldek/poldek/poldek.h:1.38	Wed Jul 11 00:56:17 2007
+++ poldek/poldek/poldek.h	Sat Feb  2 16:38:36 2008
@@ -50,11 +50,12 @@
 #define POLDEK_CONF_LOGFILE         20
 #define POLDEK_CONF_LOGTTY          21
 
-#define POLDEK_CONF_GOODBYE_CB      22
-#define POLDEK_CONF_CONFIRM_CB      23
-#define POLDEK_CONF_TSCONFIRM_CB    24
-#define POLDEK_CONF_CHOOSEEQUIV_CB  25
-#define POLDEK_CONF_VFILEPROGRESS   26
+#define POLDEK_CONF_GOODBYE_CB         22
+#define POLDEK_CONF_CONFIRM_CB         23
+#define POLDEK_CONF_TSCONFIRM_CB       24
+#define POLDEK_CONF_CHOOSEEQUIV_CB     25
+#define POLDEK_CONF_CHOOSESUGGESTS_CB  26
+#define POLDEK_CONF_VFILEPROGRESS      27
 
 int poldek_configure(struct poldek_ctx *ctx, int param, ...);
 

================================================================
Index: poldek/poldek/poldek_intern.h
diff -u poldek/poldek/poldek_intern.h:1.14 poldek/poldek/poldek_intern.h:1.15
--- poldek/poldek/poldek_intern.h:1.14	Sun Jan 27 17:01:55 2008
+++ poldek/poldek/poldek_intern.h	Sat Feb  2 16:38:36 2008
@@ -40,8 +40,13 @@
 
     void *data_choose_equiv_fn;
     int  (*choose_equiv_fn)(void *data, const struct poldek_ts *ts,
-                            const char *cap, tn_array *pkgs, int hint);
+                            const struct pkg *pkg, const char *cap,
+                            tn_array *candidates, int hint);
 
+    void *data_choose_suggests_fn;
+    int  (*choose_suggests_fn)(void *data, const struct poldek_ts *ts,
+                               const struct pkg *pkg, tn_array *caps,
+                               tn_array *choices, int hint);
     
     tn_hash        *_cnf;       /* runtime config */
     unsigned       _iflags;     /* internal flags */
@@ -75,7 +80,12 @@
 int poldek__ts_confirm(const struct poldek_ts *ts);
 
 int poldek__choose_equiv(const struct poldek_ts *ts,
-                         const char *capname, tn_array *pkgs, struct pkg *hint);
+                         const struct pkg *pkg, const char *capname,
+                         tn_array *pkgs, struct pkg *hint);
+
+int poldek__choose_suggests(const struct poldek_ts *ts,
+                            const struct pkg *pkg, tn_array *caps,
+                            tn_array *choices, int hint);
 
 void poldek__setup_default_ask_callbacks(struct poldek_ctx *ctx);
 int poldek__load_sources_internal(struct poldek_ctx *ctx);

================================================================
Index: poldek/poldek/install/misc.c
diff -u poldek/poldek/install/misc.c:1.14 poldek/poldek/install/misc.c:1.15
--- poldek/poldek/install/misc.c:1.14	Mon Jul  9 19:03:02 2007
+++ poldek/poldek/install/misc.c	Sat Feb  2 16:38:36 2008
@@ -638,7 +638,7 @@
         }
     }
     
-    n = poldek__choose_equiv(ts, capreq_snprintf_s(cap), pkgs, hint);
+    n = poldek__choose_equiv(ts, NULL, capreq_snprintf_s(cap), pkgs, hint);
     if (n == -1)
         return NULL;
 

================================================================
Index: poldek/poldek/install3/conflicts.c
diff -u poldek/poldek/install3/conflicts.c:1.4 poldek/poldek/install3/conflicts.c:1.5
--- poldek/poldek/install3/conflicts.c:1.4	Wed Jan 30 23:13:42 2008
+++ poldek/poldek/install3/conflicts.c	Sat Feb  2 16:38:37 2008
@@ -106,7 +106,7 @@
 
         /* tomark == NULL ? req satsfied by already installed set */
         if (tomark && candidates && n_array_size(candidates) > 1) {
-            real_tomark = i3_choose_equiv(ictx->ts, req, candidates, tomark);
+            real_tomark = i3_choose_equiv(ictx->ts, pkg, req, candidates, tomark);
             n_array_cfree(&candidates);
             if (real_tomark == NULL) { /* user aborts */
                 ictx->abort = 1;

================================================================
Index: poldek/poldek/install3/ictx.h
diff -u poldek/poldek/install3/ictx.h:1.2 poldek/poldek/install3/ictx.h:1.3
--- poldek/poldek/install3/ictx.h:1.2	Wed Jan 30 22:29:35 2008
+++ poldek/poldek/install3/ictx.h	Sat Feb  2 16:38:37 2008
@@ -179,7 +179,9 @@
 
 
 int i3_is_user_choosable_equiv(struct poldek_ts *ts);
-struct pkg *i3_choose_equiv(struct poldek_ts *ts, const struct capreq *cap,
+
+struct pkg *i3_choose_equiv(struct poldek_ts *ts,
+                            const struct pkg *pkg, const struct capreq *cap,
                             tn_array *pkgs, struct pkg *hint);
 
 #endif

================================================================
Index: poldek/poldek/install3/misc.c
diff -u poldek/poldek/install3/misc.c:1.4 poldek/poldek/install3/misc.c:1.5
--- poldek/poldek/install3/misc.c:1.4	Wed Jan 30 23:13:42 2008
+++ poldek/poldek/install3/misc.c	Sat Feb  2 16:38:37 2008
@@ -438,7 +438,8 @@
                            iset_packages_by_recno(ictx->unset));
 }
 
-struct pkg *i3_choose_equiv(struct poldek_ts *ts, const struct capreq *cap,
+struct pkg *i3_choose_equiv(struct poldek_ts *ts,
+                            const struct pkg *pkg, const struct capreq *cap,
                             tn_array *pkgs, struct pkg *hint) 
 {
     int n;
@@ -468,7 +469,7 @@
         }
     }
     
-    n = poldek__choose_equiv(ts, capreq_stra(cap), pkgs, hint);
+    n = poldek__choose_equiv(ts, pkg, capreq_stra(cap), pkgs, hint);
     if (n == -1)
         return NULL;
 

================================================================
Index: poldek/poldek/install3/preinstall.c
diff -u poldek/poldek/install3/preinstall.c:1.2 poldek/poldek/install3/preinstall.c:1.3
--- poldek/poldek/install3/preinstall.c:1.2	Fri Jan 25 15:23:10 2008
+++ poldek/poldek/install3/preinstall.c	Sat Feb  2 16:38:37 2008
@@ -83,7 +83,7 @@
             return 0;
 
         if (i3_is_user_choosable_equiv(ts) && n_array_size(pkgs) > 1) {
-            pkg = i3_choose_equiv(ts, cap, pkgs, NULL);
+            pkg = i3_choose_equiv(ts, NULL, cap, pkgs, NULL);
             if (pkg == NULL) { /* user aborts */
                 found = -1;
                 goto l_end;

================================================================
Index: poldek/poldek/install3/requirements.c
diff -u poldek/poldek/install3/requirements.c:1.3 poldek/poldek/install3/requirements.c:1.4
--- poldek/poldek/install3/requirements.c:1.3	Wed Jan 30 22:29:35 2008
+++ poldek/poldek/install3/requirements.c	Sat Feb  2 16:38:37 2008
@@ -239,7 +239,7 @@
     int              rc = 1, giveup = 0, indentt = indent + 1;
 
     strreq = capreq_stra(req);
-    tracef(indent, "%s, req: %s (%s)", pkg_id(pkg), capreq_snprintf_s(req), strreq);
+    tracef(indent, "%s, req: %s (%s)", pkg_id(pkg), capreq_stra(req), strreq);
 
     /* skip foreign (not provided by uninstalled) dependencies */
     if (!iset_provides(ictx->unset, req)) {
@@ -294,7 +294,7 @@
         struct i3pkg *i3tomark;
         
         if (i3_is_user_choosable_equiv(ts) && candidates) {
-            real_tomark = i3_choose_equiv(ts, req, candidates, tomark);
+            real_tomark = i3_choose_equiv(ts, pkg, req, candidates, tomark);
             
             if (real_tomark == NULL) { /* user abort */
                 i3_stop_processing(ictx, 1);
@@ -419,7 +419,7 @@
         int             i3pkg_flag = 0;
         
         if (i3_is_user_choosable_equiv(ts) && candidates) {
-            real_tomark = i3_choose_equiv(ts, req, candidates, tomark);
+            real_tomark = i3_choose_equiv(ts, pkg, req, candidates, tomark);
             
             if (real_tomark == NULL) { /* user abort */
                 ictx->abort = 1;
@@ -469,12 +469,11 @@
     return rc;
 }
 
-static tn_array *with_suggests(struct i3ctx *ictx, struct pkg *pkg) 
+
+static tn_array *with_suggests(int indent, struct i3ctx *ictx, struct pkg *pkg) 
 {
-    char *confirmation, message[2048];
-    tn_array *suggests = capreq_arr_new(4);
-    tn_buf *nbuf;
-    int n, i, autochoice = 0;
+    tn_array *suggests = NULL, *choices = NULL;
+    int i, autochoice = 0;
 
     if (pkg->sugs == NULL)
         return NULL;
@@ -495,15 +494,38 @@
     if (!autochoice && !i3_is_user_choosable_equiv(ictx->ts))
         return NULL;
 
+    tracef(indent, "%s", pkg_id(pkg));
+
+    suggests = capreq_arr_new(4);
     n_array_ctl_set_freefn(suggests, NULL); /* 'weak' ref */
     for (i=0; i < n_array_size(pkg->sugs); i++) {
         struct capreq *req = n_array_nth(pkg->sugs, i);
+        struct pkg *tomark = NULL;
         
-        if (i3_pkgdb_match_req(ictx, req) || iset_provides(ictx->inset, req))
+        if (iset_provides(ictx->inset, req)) {
+            trace(indent, "- %s: already marked", capreq_stra(req));
             continue;
-
+        }
+        
+        if (i3_pkgdb_match_req(ictx, req)) {
+            trace(indent, "- %s: satisfied by db", capreq_stra(req));
+            continue;
+        }
+        
+        if (!i3_find_req(indent, ictx, pkg, req, &tomark, NULL)) {
+            logn(LOGWARN, _("%s: suggested %s not found, skipped"), pkg_id(pkg),
+                 capreq_stra(req));
+            continue;
+            
+        } else if (tomark == NULL) {
+            trace(indent, "- %s: satisfied by being installed set",
+                  capreq_stra(req));
+            continue;
+        }
+        
         if (autochoice > 0 && i != autochoice - 1)
             continue;
+        
         n_array_push(suggests, req);
     }
     
@@ -514,22 +536,25 @@
 
     if (autochoice)
         return suggests;
-    
 
-    nbuf = capreq_arr_join(suggests, NULL, NULL);
-    n = n_snprintf(message, sizeof(message), _("%s suggests installation of: %s"),
-                   pkg_id(pkg), n_buf_ptr(nbuf));
-    n_buf_free(nbuf);
-    
-    confirmation = ngettext("Try to install it?", "Try to install them?",
-                            n_array_size(suggests));    
-    n_snprintf(&message[n], sizeof(message) - n, "\n%s", confirmation);
+    choices = n_array_clone(suggests);
+    n_array_ctl_set_freefn(choices, NULL); /* 'weak' ref */
     
-    if (poldek__confirm(ictx->ts, 0, message)) 
-        return suggests;
+    if (!poldek__choose_suggests(ictx->ts, pkg, suggests, choices, 0)) {
+        n_array_free(choices);
+        n_array_cfree(&suggests);
+        
+    } else {
+        if (!n_array_size(choices))
+            n_array_free(choices);
+        
+        else {
+            n_array_free(suggests);
+            suggests = choices;
+        }
+    }
     
-    n_array_free(suggests);
-    return NULL;
+    return suggests;
 }
 
 static int suggests_contains(tn_array *suggests, const struct capreq *req) 
@@ -565,7 +590,7 @@
     tracef(indent, "%s as NEW", pkg_id(pkg));
 
     if (ts->getop(ts, POLDEK_OP_SUGGESTS)) {
-        suggests = with_suggests(ictx, pkg);
+        suggests = with_suggests(indent + 2, ictx, pkg);
         if (suggests)
             itflags |= PKG_ITER_REQSUG;
     }
================================================================

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/ask.c?r1=1.11&r2=1.12&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/lib_init.c?r1=1.92&r2=1.93&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/poldek.h?r1=1.38&r2=1.39&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/poldek_intern.h?r1=1.14&r2=1.15&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/install/misc.c?r1=1.14&r2=1.15&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/install3/conflicts.c?r1=1.4&r2=1.5&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/install3/ictx.h?r1=1.2&r2=1.3&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/install3/misc.c?r1=1.4&r2=1.5&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/install3/preinstall.c?r1=1.2&r2=1.3&f=u
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/poldek/poldek/install3/requirements.c?r1=1.3&r2=1.4&f=u



More information about the pld-cvs-commit mailing list