Adding ARGBEGIN for flexible parameter handling and fixing the manpage. - tthingmenu - A simple graphical menu launcher for X11.
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit e54f54c03160ab7e6615e15f9ee0984ab5d2e9dc
 (DIR) parent 0255257e75f6f3820d695394eb80cd20dcf78e78
 (HTM) Author: Christoph Lohmann <20h@r-36.net>
       Date:   Sat,  4 Aug 2012 22:30:22 +0200
       
       Adding ARGBEGIN for flexible parameter handling and fixing the manpage.
       
       Diffstat:
         arg.h                               |      41 +++++++++++++++++++++++++++++++
         thingmenu.1                         |      11 ++++-------
         thingmenu.c                         |     113 +++++++++++++------------------
       
       3 files changed, 91 insertions(+), 74 deletions(-)
       ---
 (DIR) diff --git a/arg.h b/arg.h
       @@ -0,0 +1,41 @@
       +/*
       + * Copy me if you can.
       + * by 20h
       + */
       +
       +#ifndef __ARG_H__
       +#define __ARG_H__
       +
       +extern char *argv0;
       +
       +#define USED(x) ((void)(x))
       +
       +#define ARGBEGIN        for (argv0 = *argv, argv++, argc--;\
       +                                        argv[0] && argv[0][1]\
       +                                        && argv[0][0] == '-';\
       +                                        argc--, argv++) {\
       +                                char _argc;\
       +                                char **_argv;\
       +                                if (argv[0][1] == '-' && argv[0][2] == '\0') {\
       +                                        argv++;\
       +                                        argc--;\
       +                                        break;\
       +                                }\
       +                                for (argv[0]++, _argv = argv; argv[0][0];\
       +                                                argv[0]++) {\
       +                                        if (_argv != argv)\
       +                                                break;\
       +                                        _argc = argv[0][0];\
       +                                        switch (_argc)
       +
       +#define ARGEND                        }\
       +                                USED(_argc);\
       +                        }\
       +                        USED(argv);\
       +                        USED(argc);
       +
       +#define EARGF(x)        ((argv[1] == NULL)? ((x), abort(), (char *)0) :\
       +                        (argc--, argv++, argv[0]))
       +
       +#endif
       +
 (DIR) diff --git a/thingmenu.1 b/thingmenu.1
       @@ -13,8 +13,8 @@
        .Op Fl s
        .Op Fl o
        .Op Fl g Ar geometry
       -.Op Fl ws Ar widthscaling
       -.Op Fl hs Ar heightscaling
       +.Op Fl w Ar widthscaling
       +.Op Fl e Ar heightscaling
        .Op Fl -
        .Ar label0 cmd0 [label1 cmd1 ...]
        .Ek
       @@ -49,7 +49,6 @@ options and default settings.
        Do not append a
        .Qq "Cancel"
        menu item.
       -.
        .Bd -filled
        .It Fl s
        Disable the oneshot behaviour. After one button click
       @@ -66,10 +65,10 @@ Use the horizontal layout.
        .It Fl g
        Define the X11 geometry string, which is to be used.
        .
       -.It Fl ws
       +.It Fl w
        Define the width scaling.
        .
       -.It Fl hs
       +.It Fl e
        Define the height scaling.
        .
        .El
       @@ -91,7 +90,6 @@ After that the menu will not exit (-s).
        .Ed
        .Bd -literal
                % thingmenu -s -ww 300 -- "Reboot now" reboot
       -
        .Ed
        .Bd -filled
        This will create a centered menu, which is aligned based on the length of the
       @@ -99,7 +97,6 @@ label texts. After the first clicked entry it will exit.
        .Ed
        .Bd -literal
                % thingmenu "Force reboot" "reboot -f" Shutdown shutdown
       -
        .Ed
        .Bd -filled
        An example how to create multi-level menus is shown in the thingmenu-menu.sh
 (DIR) diff --git a/thingmenu.c b/thingmenu.c
       @@ -106,6 +106,10 @@ int nentries = 0;
        int oneshot = 1;
        Bool ispressing = 0;
        
       +char *argv0;
       +
       +#include "arg.h"
       +
        /* configuration, allows nested code to access above variables */
        #include "config.h"
        
       @@ -594,10 +598,10 @@ updateentries(void)
        }
        
        void
       -usage(char *argv0)
       +usage(void)
        {
       -        fprintf(stderr, "usage: %s [-hxso] [-g geometry] [-ws widthscaling] "
       -                        "[-hs heightscaling] [--] "
       +        fprintf(stderr, "usage: %s [-hxso] [-g geometry] [-w widthscaling] "
       +                        "[-e heightscaling] [--] "
                                "label0 cmd0 [label1 cmd1 ...]\n", argv0);
                exit(1);
        }
       @@ -610,74 +614,49 @@ main(int argc, char *argv[])
                int i, xr, yr, bitm;
                unsigned int wr, hr;
        
       +        argv0 = argv[0];
        
                addexit = True;
        
                if (argc < 2)
       -                usage(argv[0]);
       -        i = 1;
       -        for (; argv[i]; i++) {
       -                if (argv[i][0] != '-')
       -                        break;
       -                if (argv[i][1] == '-') {
       -                        i++;
       -                        break;
       -                }
       -
       -                switch (argv[i][1]) {
       -                case 'g':
       -                        if (i >= argc - 1)
       -                                break;
       -                        bitm = XParseGeometry(argv[i+1], &xr, &yr, &wr, &hr);
       -                        if (bitm & XValue)
       -                                wx = xr;
       -                        if (bitm & YValue)
       -                                wy = yr;
       -                        if (bitm & WidthValue)
       -                                ww = (int)wr;
       -                        if (bitm & HeightValue)
       -                                wh = (int)hr;
       -                        if (bitm & XNegative && wx == 0)
       -                                wx = -1;
       -                        if (bitm & YNegative && wy == 0)
       -                                wy = -1;
       -                        i++;
       -                        break;
       -                case 'h':
       -                        switch ((i >= argc - 1)? 0 : argv[i][2]) {
       -                        case 's':
       -                                heightscaling = atof(argv[i+1]);
       -                                i++;
       -                                break;
       -                        default:
       -                                usage(argv[0]);
       -                        }
       -                        break;
       -                case 'o':
       -                        horizontal = True;
       -                        break;
       -                case 's':
       -                        oneshot = 0;
       -                        break;
       -                case 'w':
       -                        switch ((i >= argc - 1)? 0 : argv[i][2]) {
       -                        case 's':
       -                                widthscaling = atof(argv[i+1]);
       -                                i++;
       -                                break;
       -                        default:
       -                                usage(argv[0]);
       -                        }
       -                        break;
       -                case 'x':
       -                        addexit = False;
       -                        break;
       -                default:
       -                        usage(argv[0]);
       -                }
       -        }
       +                usage();
       +
       +        ARGBEGIN {
       +        case 'g':
       +                bitm = XParseGeometry(EARGF(usage()), &xr, &yr, &wr, &hr);
       +                if (bitm & XValue)
       +                        wx = xr;
       +                if (bitm & YValue)
       +                        wy = yr;
       +                if (bitm & WidthValue)
       +                        ww = (int)wr;
       +                if (bitm & HeightValue)
       +                        wh = (int)hr;
       +                if (bitm & XNegative && wx == 0)
       +                        wx = -1;
       +                if (bitm & YNegative && wy == 0)
       +                        wy = -1;
       +                break;
       +        case 'e':
       +                heightscaling = atof(EARGF(usage()));
       +                break;
       +        case 'o':
       +                horizontal = True;
       +                break;
       +        case 's':
       +                oneshot = 0;
       +                break;
       +        case 'w':
       +                widthscaling = atof(EARGF(usage()));
       +                break;
       +        case 'x':
       +                addexit = False;
       +                break;
       +        default:
       +                usage();
       +        } ARGEND;
        
       -        for (; argv[i]; i++) {
       +        for (i = 0; argv[i]; i++) {
                        label = argv[i];
                        if (!argv[i+1])
                                break;
       @@ -696,7 +675,7 @@ main(int argc, char *argv[])
                                die("strdup returned NULL\n");
                }
                if (nentries < 1)
       -                usage(argv[0]);
       +                usage();
        
                if (addexit) {
                        entries = realloc(entries, sizeof(entries[0])*(++nentries));