[pacman-dev] [PATCH] Sort short options before long options in --help

2010-10-14 Thread Xavier Chantry
$ pacman -Uh
options:
  -b, --dbpath path  set an alternate database location
  -d, --nodeps skip dependency checks
  -f, --force  force install, overwrite conflicting files
  -k, --dbonly only modify database entries, not package files
  -r, --root pathset an alternate installation root
  -v, --verbosebe verbose
  --arch archset an alternate architecture
  --asdeps install packages as non-explicitly installed
  --asexplicit install packages as explicitly installed
  --cachedir dir set an alternate package cache location
  --config path  set an alternate configuration file
  --debug  display debug messages
  --ignore pkg   ignore a package upgrade (can be used more than once)
  --ignoregroup grp
   ignore a group upgrade (can be used more than once)
  --logfile path set an alternate log file
  --noconfirm  do not ask for any confirmation
  --noprogressbar  do not show a progress bar when downloading files
  --noscriptletdo not execute the install scriptlet if one exists
  --print  only print the targets instead of performing the 
operation
  --print-format string
   specify how the targets should be printed

Signed-off-by: Xavier Chantry chantry.xav...@gmail.com
---
 src/pacman/pacman.c |   27 ++-
 1 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 7d51124..3bfe6ef 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -28,6 +28,7 @@
 
 #include stdlib.h /* atoi */
 #include stdio.h
+#include ctype.h /* isspace */
 #include limits.h
 #include getopt.h
 #include string.h
@@ -59,6 +60,30 @@ pmdb_t *db_local;
 /* list of targets specified on command line */
 static alpm_list_t *pm_targets;
 
+/* Used to sort the options in --help */
+static int options_cmp(const void *p1, const void *p2)
+{
+   const char *s1 = p1;
+   const char *s2 = p2;
+   int ret = 0;
+
+   /* First skip all spaces in both strings */
+   while(isspace((unsigned char)*s1))
+   s1++;
+   while(isspace((unsigned char)*s2))
+   s2++;
+   /* If we compare a long option (--abcd) and a short one (-a),
+* the short one always wins */
+   if (*(s1+1) != '-'  *(s2+1) == '-') {
+   ret = -1;
+   } else if (*(s2+1) != '-'  *(s1+1) == '-') {
+   ret = 1;
+   } else {
+   ret = strcmp(s1, s2);
+   }
+   return(ret);
+}
+
 /** Display usage/syntax for the specified operation.
  * @param op the operation code requested
  * @param myname basename(argv[0])
@@ -166,7 +191,7 @@ static void usage(int op, const char * const myname)
addlist(_(  --logfile path set an alternate log 
file\n));
addlist(_(  --noconfirm  do not ask for any 
confirmation\n));
}
-   list = alpm_list_msort(list, alpm_list_count(list), str_cmp);
+   list = alpm_list_msort(list, alpm_list_count(list), options_cmp);
for (i = list; i; i = alpm_list_next(i)) {
printf(%s, (char *)alpm_list_getdata(i));
}
-- 
1.7.3.1




Re: [pacman-dev] [PATCH] Sort short options before long options in --help

2010-10-14 Thread Nagy Gabor
 $ pacman -Uh
 options:
   -b, --dbpath path  set an alternate database location
   -d, --nodeps skip dependency checks
   -f, --force  force install, overwrite conflicting files
   -k, --dbonly only modify database entries, not package files
   -r, --root pathset an alternate installation root
   -v, --verbosebe verbose
   --arch archset an alternate architecture
   --asdeps install packages as non-explicitly installed
   --asexplicit install packages as explicitly installed
   --cachedir dir set an alternate package cache location
   --config path  set an alternate configuration file
   --debug  display debug messages
   --ignore pkg   ignore a package upgrade (can be used more than once)
   --ignoregroup grp
ignore a group upgrade (can be used more than once)
   --logfile path set an alternate log file
   --noconfirm  do not ask for any confirmation
   --noprogressbar  do not show a progress bar when downloading files
   --noscriptletdo not execute the install scriptlet if one exists
   --print  only print the targets instead of performing the 
 operation
   --print-format string
specify how the targets should be printed
 
 Signed-off-by: Xavier Chantry chantry.xav...@gmail.com

I like this.

 +/* Used to sort the options in --help */
 +static int options_cmp(const void *p1, const void *p2)
 +{
 + const char *s1 = p1;
 + const char *s2 = p2;
 + int ret = 0;
 +
 + /* First skip all spaces in both strings */
 + while(isspace((unsigned char)*s1))
 + s1++;
 + while(isspace((unsigned char)*s2))
 + s2++;
 + /* If we compare a long option (--abcd) and a short one (-a),
 +  * the short one always wins */
 + if (*(s1+1) != '-'  *(s2+1) == '-') {
 + ret = -1;

I hope you don't pass invalid string arguments (e.g. empty string),
otherwise we can get a segfault here.

 + } else if (*(s2+1) != '-'  *(s1+1) == '-') {
 + ret = 1;
 + } else {
 + ret = strcmp(s1, s2);
 + }
 + return(ret);
 +}

NG





Re: [pacman-dev] [PATCH] Sort short options before long options in --help

2010-10-14 Thread Xavier Chantry
On Thu, Oct 14, 2010 at 1:55 PM, Nagy Gabor ng...@bibl.u-szeged.hu wrote:

 I like this.


Cool :)

 +     /* First skip all spaces in both strings */
 +     while(isspace((unsigned char)*s1))
 +             s1++;
 +     while(isspace((unsigned char)*s2))
 +             s2++;
 +     /* If we compare a long option (--abcd) and a short one (-a),
 +      * the short one always wins */
 +     if (*(s1+1) != '-'  *(s2+1) == '-') {
 +             ret = -1;

 I hope you don't pass invalid string arguments (e.g. empty string),
 otherwise we can get a segfault here.


I missed something very important. I thought we had complete controls
on these strings, while in fact we don't have any control at all,
since it's the gettext-ed strings that I sort :P
I will make a safer version, thanks.



[pacman-dev] [PATCH] Sort short options before long options in --help

2010-10-14 Thread Xavier Chantry
$ pacman -Uh
options:
  -b, --dbpath path  set an alternate database location
  -d, --nodeps skip dependency checks
  -f, --force  force install, overwrite conflicting files
  -k, --dbonly only modify database entries, not package files
  -r, --root pathset an alternate installation root
  -v, --verbosebe verbose
  --arch archset an alternate architecture
  --asdeps install packages as non-explicitly installed
  --asexplicit install packages as explicitly installed
  --cachedir dir set an alternate package cache location
  --config path  set an alternate configuration file
  --debug  display debug messages
  --ignore pkg   ignore a package upgrade (can be used more than once)
  --ignoregroup grp
   ignore a group upgrade (can be used more than once)
  --logfile path set an alternate log file
  --noconfirm  do not ask for any confirmation
  --noprogressbar  do not show a progress bar when downloading files
  --noscriptletdo not execute the install scriptlet if one exists
  --print  only print the targets instead of performing the 
operation
  --print-format string
   specify how the targets should be printed

Signed-off-by: Xavier Chantry chantry.xav...@gmail.com
---
 src/pacman/pacman.c |   39 ++-
 1 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 7d51124..38d7f6a 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -26,8 +26,10 @@
 #define PACKAGE_VERSION GIT_VERSION
 #endif
 
+#include assert.h
 #include stdlib.h /* atoi */
 #include stdio.h
+#include ctype.h /* isspace */
 #include limits.h
 #include getopt.h
 #include string.h
@@ -59,6 +61,41 @@ pmdb_t *db_local;
 /* list of targets specified on command line */
 static alpm_list_t *pm_targets;
 
+/* Used to sort the options in --help */
+static int options_cmp(const void *p1, const void *p2)
+{
+   const char *s1 = p1;
+   const char *s2 = p2;
+
+   assert(s1);
+   assert(s2);
+   /* First skip all spaces in both strings */
+   while(isspace((unsigned char)*s1))
+   s1++;
+   while(isspace((unsigned char)*s2))
+   s2++;
+   /* If we compare a long option (--abcd) and a short one (-a),
+* the short one always wins */
+   if(*s1 == '-'  *s2 == '-') {
+   s1++;
+   s2++;
+   if(*s1 == '-'  *s2 == '-') {
+   /* two long - strcmp */
+   s1++;
+   s2++;
+   } else if(*s2 == '-') {
+   /* s1 short, s2 long */
+   return(-1);
+   } else if(*s1 == '-') {
+   /* s1 long, s2 short */
+   return(1);
+   }
+   /* two short - strcmp */
+   }
+
+   return(strcmp(s1, s2));
+}
+
 /** Display usage/syntax for the specified operation.
  * @param op the operation code requested
  * @param myname basename(argv[0])
@@ -166,7 +203,7 @@ static void usage(int op, const char * const myname)
addlist(_(  --logfile path set an alternate log 
file\n));
addlist(_(  --noconfirm  do not ask for any 
confirmation\n));
}
-   list = alpm_list_msort(list, alpm_list_count(list), str_cmp);
+   list = alpm_list_msort(list, alpm_list_count(list), options_cmp);
for (i = list; i; i = alpm_list_next(i)) {
printf(%s, (char *)alpm_list_getdata(i));
}
-- 
1.7.3.1




Re: [pacman-dev] [PATCH] Sort short options before long options in --help

2010-10-14 Thread Dan McGee
On Thu, Oct 14, 2010 at 8:36 AM, Xavier Chantry
chantry.xav...@gmail.com wrote:
 diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
 index 7d51124..38d7f6a 100644
 --- a/src/pacman/pacman.c
 +++ b/src/pacman/pacman.c
 @@ -26,8 +26,10 @@
  #define PACKAGE_VERSION GIT_VERSION
  #endif

 +#include assert.h
  #include stdlib.h /* atoi */
  #include stdio.h
 +#include ctype.h /* isspace */
  #include limits.h
  #include getopt.h
  #include string.h
 @@ -59,6 +61,41 @@ pmdb_t *db_local;
  /* list of targets specified on command line */
  static alpm_list_t *pm_targets;

 +/* Used to sort the options in --help */
 +static int options_cmp(const void *p1, const void *p2)
 +{
 +       const char *s1 = p1;
 +       const char *s2 = p2;
 +
 +       assert(s1);
 +       assert(s2);

Is the assert stuff you added to be safer? We don't want to use this.
One, they are compiled into nothing if NDEBUG is defined, and two, it
is a bit silly to abort on this condition. cmp(NULL, NULL) ==0, and
then just decide whether to sort NULL first or last.

-Dan



Re: [pacman-dev] [PATCH] Sort short options before long options in --help

2010-10-14 Thread Xavier Chantry
On Thu, Oct 14, 2010 at 3:44 PM, Dan McGee dpmc...@gmail.com wrote:

 Is the assert stuff you added to be safer? We don't want to use this.
 One, they are compiled into nothing if NDEBUG is defined, and two, it
 is a bit silly to abort on this condition. cmp(NULL, NULL) ==0, and
 then just decide whether to sort NULL first or last.


It was not supposed to be safer, just to explicitly state that this
case should not happen.
If gettext returns NULL, our --help output is going to look awesome :
(null)(null)(null)..
It's not perfectly clear to me that an assert is worse. In the
unlikely case that this could be triggered, at least an assert would
fail gracefully telling us where it failed and possibly giving a core
dump that would tell us more about what happened.

Anyway we could debate over and over about assert usage. Maybe it's
more interesting for an expensive check in a hot-path that you do not
want to keep in a release build, but you want to make sure that the
assert is indeed not triggered while developing / testing.

I updated the patch with an explicit check (I actually already did
this before choosing to use assert) :
http://code.toofishes.net/cgit/xavier/pacman.git/log/?h=parseargs