tstest: get rid of getopt, use suckless arg.h - dmenu - Dmenu fork with xft fonts.
 (HTM) git clone git://r-36.net/dmenu
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d6742ef8a6ce03f28ee9431ef51901ef712ffd76
 (DIR) parent 5feb0c689dd815a31d48e2007b364057f6fec773
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Sun, 19 Jul 2015 21:34:51 +0200
       
       stest: get rid of getopt, use suckless arg.h
       
       ... also some style improvements.
       
       Diffstat:
         Makefile                            |       6 +++---
         arg.h                               |      63 +++++++++++++++++++++++++++++++
         stest.c                             |     125 +++++++++++++++++++-------------
       
       3 files changed, 141 insertions(+), 53 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       t@@ -22,7 +22,7 @@ config.h:
                @echo creating $@ from config.def.h
                @cp config.def.h $@
        
       -${OBJ}: config.h config.mk drw.h
       +${OBJ}: arg.h config.h config.mk drw.h
        
        dmenu: dmenu.o drw.o util.o
                @echo CC -o $@
       t@@ -39,8 +39,8 @@ clean:
        dist: clean
                @echo creating dist tarball
                @mkdir -p dmenu-${VERSION}
       -        @cp LICENSE Makefile README config.mk dmenu.1 drw.h util.h dmenu_path \
       -                dmenu_run stest.1 ${SRC} dmenu-${VERSION}
       +        @cp LICENSE Makefile README arg.h config.mk dmenu.1 drw.h util.h \
       +                dmenu_path dmenu_run stest.1 ${SRC} dmenu-${VERSION}
                @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION}
                @gzip dmenu-${VERSION}.tar
                @rm -rf dmenu-${VERSION}
 (DIR) diff --git a/arg.h b/arg.h
       t@@ -0,0 +1,63 @@
       +/*
       + * Copy me if you can.
       + * by 20h
       + */
       +
       +#ifndef ARG_H__
       +#define ARG_H__
       +
       +extern char *argv0;
       +
       +/* use main(int argc, char *argv[]) */
       +#define ARGBEGIN        for (argv0 = *argv, argv++, argc--;\
       +                                        argv[0] && argv[0][1]\
       +                                        && argv[0][0] == '-';\
       +                                        argc--, argv++) {\
       +                                char argc_;\
       +                                char **argv_;\
       +                                int brk_;\
       +                                if (argv[0][1] == '-' && argv[0][2] == '\0') {\
       +                                        argv++;\
       +                                        argc--;\
       +                                        break;\
       +                                }\
       +                                for (brk_ = 0, argv[0]++, argv_ = argv;\
       +                                                argv[0][0] && !brk_;\
       +                                                argv[0]++) {\
       +                                        if (argv_ != argv)\
       +                                                break;\
       +                                        argc_ = argv[0][0];\
       +                                        switch (argc_)
       +
       +/* Handles obsolete -NUM syntax */
       +#define ARGNUM                                case '0':\
       +                                        case '1':\
       +                                        case '2':\
       +                                        case '3':\
       +                                        case '4':\
       +                                        case '5':\
       +                                        case '6':\
       +                                        case '7':\
       +                                        case '8':\
       +                                        case '9'
       +
       +#define ARGEND                        }\
       +                        }
       +
       +#define ARGC()                argc_
       +
       +#define ARGNUMF(base)        (brk_ = 1, estrtol(argv[0], (base)))
       +
       +#define EARGF(x)        ((argv[0][1] == '\0' && argv[1] == NULL)?\
       +                                ((x), abort(), (char *)0) :\
       +                                (brk_ = 1, (argv[0][1] != '\0')?\
       +                                        (&argv[0][1]) :\
       +                                        (argc--, argv++, argv[0])))
       +
       +#define ARGF()                ((argv[0][1] == '\0' && argv[1] == NULL)?\
       +                                (char *)0 :\
       +                                (brk_ = 1, (argv[0][1] != '\0')?\
       +                                        (&argv[0][1]) :\
       +                                        (argc--, argv++, argv[0])))
       +
       +#endif
 (DIR) diff --git a/stest.c b/stest.c
       t@@ -1,66 +1,31 @@
        /* See LICENSE file for copyright and license details. */
       +#include <sys/stat.h>
       +
        #include <dirent.h>
       -#include <stdbool.h>
       +#include <limits.h>
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <unistd.h>
       -#include <sys/stat.h>
       +
       +#include "arg.h"
       +char *argv0;
        
        #define FLAG(x)  (flag[(x)-'a'])
        
        static void test(const char *, const char *);
       +static void usage(void);
        
       -static bool match = false;
       -static bool flag[26];
       +static int match = 0;
       +static int flag[26];
        static struct stat old, new;
        
       -int
       -main(int argc, char *argv[]) {
       -        struct dirent *d;
       -        char buf[BUFSIZ], *p;
       -        DIR *dir;
       -        int opt;
       -
       -        while((opt = getopt(argc, argv, "abcdefghln:o:pqrsuvwx")) != -1)
       -                switch(opt) {
       -                case 'n': /* newer than file */
       -                case 'o': /* older than file */
       -                        if(!(FLAG(opt) = !stat(optarg, (opt == 'n' ? &new : &old))))
       -                                perror(optarg);
       -                        break;
       -                default:  /* miscellaneous operators */
       -                        FLAG(opt) = true;
       -                        break;
       -                case '?': /* error: unknown flag */
       -                        fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] [-n file] [-o file] [file...]\n", argv[0]);
       -                        exit(2);
       -                }
       -        if(optind == argc)
       -                while(fgets(buf, sizeof buf, stdin)) {
       -                        if((p = strchr(buf, '\n')))
       -                                *p = '\0';
       -                        test(buf, buf);
       -                }
       -        for(; optind < argc; optind++)
       -                if(FLAG('l') && (dir = opendir(argv[optind]))) {
       -                        /* test directory contents */
       -                        while((d = readdir(dir)))
       -                                if(snprintf(buf, sizeof buf, "%s/%s", argv[optind], d->d_name) < sizeof buf)
       -                                        test(buf, d->d_name);
       -                        closedir(dir);
       -                }
       -                else
       -                        test(argv[optind], argv[optind]);
       -
       -        return match ? 0 : 1;
       -}
       -
       -void
       -test(const char *path, const char *name) {
       +static void
       +test(const char *path, const char *name)
       +{
                struct stat st, ln;
        
       -        if((!stat(path, &st) && (FLAG('a') || name[0] != '.')         /* hidden files      */
       +        if ((!stat(path, &st) && (FLAG('a') || name[0] != '.')        /* hidden files      */
                && (!FLAG('b') || S_ISBLK(st.st_mode))                        /* block special     */
                && (!FLAG('c') || S_ISCHR(st.st_mode))                        /* character special */
                && (!FLAG('d') || S_ISDIR(st.st_mode))                        /* directory         */
       t@@ -76,9 +41,69 @@ test(const char *path, const char *name) {
                && (!FLAG('u') || st.st_mode & S_ISUID)                       /* set-user-id flag  */
                && (!FLAG('w') || access(path, W_OK) == 0)                    /* writable          */
                && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) {   /* executable        */
       -                if(FLAG('q'))
       +                if (FLAG('q'))
                                exit(0);
       -                match = true;
       +                match = 1;
                        puts(name);
                }
        }
       +
       +static void
       +usage(void)
       +{
       +        fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
       +                "[-n file] [-o file] [file...]\n", argv0);
       +        exit(2); /* like test(1) return > 1 on error */
       +}
       +
       +int
       +main(int argc, char *argv[])
       +{
       +        struct dirent *d;
       +        char path[PATH_MAX], *line = NULL, *file;
       +        size_t linesiz = 0;
       +        ssize_t n;
       +        DIR *dir;
       +        int r;
       +
       +        ARGBEGIN {
       +        case 'n': /* newer than file */
       +        case 'o': /* older than file */
       +                file = EARGF(usage());
       +                if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old))))
       +                        perror(file);
       +                break;
       +        default:
       +                /* miscellaneous operators */
       +                if (strchr("abcdefghlpqrsuvwx", ARGC()))
       +                        FLAG(ARGC()) = 1;
       +                else
       +                        usage(); /* unknown flag */
       +        } ARGEND;
       +
       +        if (!argc) {
       +                /* read list from stdin */
       +                while ((n = getline(&line, &linesiz, stdin)) > 0) {
       +                        if (n && line[n - 1] == '\n')
       +                                line[n - 1] = '\0';
       +                        test(line, line);
       +                }
       +                free(line);
       +        } else {
       +                for (; argc; argc--, argv++) {
       +                        if (FLAG('l') && (dir = opendir(*argv))) {
       +                                /* test directory contents */
       +                                while ((d = readdir(dir))) {
       +                                        r = snprintf(path, sizeof path, "%s/%s",
       +                                                     *argv, d->d_name);
       +                                        if (r >= 0 && (size_t)r < sizeof path)
       +                                                test(path, d->d_name);
       +                                }
       +                                closedir(dir);
       +                        } else {
       +                                test(*argv, *argv);
       +                        }
       +                }
       +        }
       +        return match ? 0 : 1;
       +}