]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
hexdump: use list.h queues and rewrite redundant for cycles
authorOndrej Oprala <ooprala@redhat.com>
Mon, 23 Sep 2013 13:39:09 +0000 (15:39 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 8 Nov 2013 11:54:52 +0000 (12:54 +0100)
Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
text-utils/display.c
text-utils/hexdump.c
text-utils/hexdump.h
text-utils/hexsyntax.c
text-utils/parse.c

index 11303667ed89fa9b1dc9d3dc74233488e52f5ac5..1800f2a10569f842a825a7b2b39599e16103c53b 100644 (file)
@@ -169,35 +169,47 @@ static void bpad(PR *pr)
 
 void display(void)
 {
-       register FS *fs;
+       struct list_head *fs;
+       register FS *fss;
        register FU *fu;
        register PR *pr;
        register int cnt;
        register unsigned char *bp;
        off_t saveaddress;
        unsigned char savech = 0, *savebp;
+       struct list_head *p, *q, *r;
 
-       while ((bp = get()) != NULL)
-           for (fs = fshead, savebp = bp, saveaddress = address; fs;
-               fs = fs->nextfs, bp = savebp, address = saveaddress)
-                   for (fu = fs->nextfu; fu; fu = fu->nextfu) {
-                       if (fu->flags&F_IGNORE)
-                               break;
-                       for (cnt = fu->reps; cnt; --cnt)
-                           for (pr = fu->nextpr; pr; address += pr->bcnt,
-                               bp += pr->bcnt, pr = pr->nextpr) {
-                                   if (eaddress && address >= eaddress &&
-                                       !(pr->flags&(F_TEXT|F_BPAD)))
-                                           bpad(pr);
-                                   if (cnt == 1 && pr->nospace) {
-                                       savech = *pr->nospace;
-                                       *pr->nospace = '\0';
-                                   }
-                                   print(pr, bp);
-                                   if (cnt == 1 && pr->nospace)
-                                       *pr->nospace = savech;
-                           }
-                   }
+       while ((bp = get()) != NULL) {
+               fs = &fshead; savebp = bp; saveaddress = address;
+               list_for_each(p, fs) {
+                       fss = list_entry(p, FS, nextfs);
+                       list_for_each(q, &fss->nextfu) {
+                               fu = list_entry(q, FU, nextfu);
+                               if (fu->flags&F_IGNORE)
+                                       break;
+                               cnt = fu->reps;
+                               while (cnt) {
+                                       list_for_each(r, &fu->nextpr) {
+                                               pr = list_entry(r, PR, nextpr);
+                                           if (eaddress && address >= eaddress &&
+                                               !(pr->flags&(F_TEXT|F_BPAD)))
+                                                   bpad(pr);
+                                           if (cnt == 1 && pr->nospace) {
+                                               savech = *pr->nospace;
+                                               *pr->nospace = '\0';
+                                           }
+                                           print(pr, bp);
+                                           if (cnt == 1 && pr->nospace)
+                                               *pr->nospace = savech;
+                                           address += pr->bcnt;
+                                           bp += pr->bcnt;
+                                       }
+                                       --cnt;
+                               }
+                       }
+                       bp = savebp; address = saveaddress;
+               }
+       }
        if (endfu) {
                /*
                 * if eaddress not set, error or file size was multiple of
@@ -208,15 +220,17 @@ void display(void)
                                return;
                        eaddress = address;
                }
-               for (pr = endfu->nextpr; pr; pr = pr->nextpr)
+               list_for_each (p, &endfu->nextpr) {
+                       pr = list_entry(p, PR, nextpr);
                        switch(pr->flags) {
                        case F_ADDRESS:
-                               (void)printf(pr->fmt, (int64_t)eaddress);
+                               printf(pr->fmt, (int64_t)eaddress);
                                break;
                        case F_TEXT:
-                               (void)printf("%s", pr->fmt);
+                               printf("%s", pr->fmt);
                                break;
                        }
+               }
        }
 }
 
index e966cc313241224448c152a8d2ce42eb62ade6b1..18b3ec23fa278825dc9882b1570d9d836026b75d 100644 (file)
 #include <stdlib.h>
 #include "hexdump.h"
 
+#include "list.h"
 #include "nls.h"
 #include "c.h"
 #include "closestream.h"
 
-FS *fshead;                            /* head of format strings */
+struct list_head fshead;                               /* head of format strings */
 ssize_t blocksize;                     /* data block size */
 int exitval;                           /* final exit value */
 ssize_t length = -1;                   /* max bytes to read */
 
 int main(int argc, char **argv)
 {
+       struct list_head *p;
        FS *tfs;
-       char *p;
+       char *c;
+       INIT_LIST_HEAD(&fshead);
 
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
        atexit(close_stdout);
 
-       if (!(p = strrchr(argv[0], 'o')) || strcmp(p, "od")) {
+       if (!(c = strrchr(argv[0], 'o')) || strcmp(c, "od")) {
                newsyntax(argc, &argv);
        } else
                errx(EXIT_FAILURE, _("calling hexdump as od has been deprecated "
                                     "in favour to GNU coreutils od."));
 
        /* figure out the data block size */
-       for (blocksize = 0, tfs = fshead; tfs; tfs = tfs->nextfs) {
-               tfs->bcnt = block_size(tfs);
-               if (blocksize < tfs->bcnt)
+       blocksize = 0;
+       list_for_each(p, &fshead) {
+               tfs = list_entry(p, FS, nextfs);
+               if ((tfs->bcnt = block_size(tfs)) > blocksize)
                        blocksize = tfs->bcnt;
        }
+
        /* rewrite the rules, do syntax checking */
-       for (tfs = fshead; tfs; tfs = tfs->nextfs)
+       list_for_each(p, &fshead) {
+               tfs = list_entry(p, FS, nextfs);
                rewrite(tfs);
+       }
 
        (void)next(argv);
        display();
index fa8f632c1f65fd149d3e3d0b2ea3978a6db2e2b8..c9fc4a009ef4294cadc2d9a04c24bec9b00ca18a 100644 (file)
  *
  *     @(#)hexdump.h   5.4 (Berkeley) 6/1/90
  */
+#include "c.h"
+#include "list.h"
 
 typedef struct _pr {
-       struct _pr *nextpr;             /* next print unit */
+       struct list_head nextpr;                /* next print unit */
 #define        F_ADDRESS       0x001           /* print offset */
 #define        F_BPAD          0x002           /* blank pad */
 #define        F_C             0x004           /* %_c */
@@ -54,8 +56,8 @@ typedef struct _pr {
 } PR;
 
 typedef struct _fu {
-       struct _fu *nextfu;             /* next format unit */
-       struct _pr *nextpr;             /* next print unit */
+       struct list_head nextfu;                /* next format unit */
+       struct list_head nextpr;                /* next print unit */
 #define        F_IGNORE        0x01            /* %_A */
 #define        F_SETREP        0x02            /* rep count set, not default */
        unsigned int flags;             /* flag values */
@@ -65,13 +67,13 @@ typedef struct _fu {
 } FU;
 
 typedef struct _fs {                   /* format strings */
-       struct _fs *nextfs;             /* linked list of format strings */
-       struct _fu *nextfu;             /* linked list of format units */
+       struct list_head nextfs;                /* linked list of format strings */
+       struct list_head nextfu;                /* linked list of format units */
        int bcnt;
 } FS;
 
 extern FU *endfu;
-extern FS *fshead;                     /* head of format strings list */
+extern struct list_head fshead;                        /* head of format strings list */
 extern ssize_t blocksize;              /* data block size */
 extern int exitval;                    /* final exit value */
 extern ssize_t length;                 /* max bytes to read */
index b37e46e0d32160fb4076e2fe52acd974ba05844a..9b6a1e2fcb23301bce77d26fd27201512f895d85 100644 (file)
@@ -128,7 +128,7 @@ newsyntax(int argc, char ***argvp)
                }
        }
 
-       if (!fshead) {
+       if (list_empty(&fshead)) {
                add("\"%07.7_Ax\n\"");
                add("\"%07.7_ax \" 8/2 \"%04x \" \"\\n\"");
        }
index 26925d9711f6f87a5d1af48ccae6072fc0d613a9..0584e022ca759386d6404e5c1cd57be84b10c2a8 100644 (file)
@@ -55,7 +55,7 @@ FU *endfu;                                    /* format at end-of-data */
 
 void addfile(char *name)
 {
-       char *p;
+       unsigned char *p;
        FILE *fp;
        int ch;
        char buf[2048 + 1];
@@ -63,85 +63,93 @@ void addfile(char *name)
        if ((fp = fopen(name, "r")) == NULL)
                err(EXIT_FAILURE, _("can't read %s"), name);
        while (fgets(buf, sizeof(buf), fp)) {
-               if ((p = strchr(buf, '\n')) == NULL) {
+               if ((p = (unsigned char *)strchr(buf, '\n')) == NULL) {
                        warnx(_("line too long"));
                        while ((ch = getchar()) != '\n' && ch != EOF);
                        continue;
                }
                *p = '\0';
-               for (p = buf; *p && isspace((unsigned char)*p); ++p);
+               for (p = (unsigned char *)buf; *p && isspace(*p); ++p);
                if (!*p || *p == '#')
                        continue;
-               add(p);
+               add((char *)p);
        }
-       (void)fclose(fp);
+       fclose(fp);
 }
 
 void add(const char *fmt)
 {
-       const char *p;
-       static FS **nextfs = NULL;
+       const unsigned char *p;
        FS *tfs;
-       FU *tfu, **nextfu;
-       const char *savep;
+       FU *tfu;
+       const unsigned char *savep;
 
        /* Start new linked list of format units. */
        tfs = xcalloc(1, sizeof(FS));
-       if (!fshead)
-               fshead = tfs;
-       else if (nextfs)
-               *nextfs = tfs;
+       INIT_LIST_HEAD(&tfs->nextfs);
+       INIT_LIST_HEAD(&tfs->nextfu);
+       list_add_tail(&tfs->nextfs, &fshead);
 
-       nextfs = &tfs->nextfs;
-       nextfu = &tfs->nextfu;
+       //entry_list here
 
        /* Take the format string and break it up into format units. */
-       for (p = fmt;;) {
+       p = (unsigned char *)fmt;
+       while (TRUE) {
                /* Skip leading white space. */
-               for (; isspace((unsigned char)*p); ++p);
+               while (isspace(*p) && ++p)
+                       ;
                if (!*p)
                        break;
 
                /* Allocate a new format unit and link it in. */
                tfu = xcalloc(1, sizeof(FU));
-               *nextfu = tfu;
-               nextfu = &tfu->nextfu;
+               INIT_LIST_HEAD(&tfu->nextfu);
+               INIT_LIST_HEAD(&tfu->nextpr);
+               list_add_tail(&tfu->nextfu, &tfs->nextfu);
                tfu->reps = 1;
 
                /* If leading digit, repetition count. */
-               if (isdigit((unsigned char)*p)) {
-                       for (savep = p; isdigit((unsigned char)*p); ++p);
-                       if (!isspace((unsigned char)*p) && *p != '/')
+               if (isdigit(*p)) {
+                       savep = p;
+                       while (isdigit(*p) && ++p)
+                               ;
+                       if (!isspace(*p) && *p != '/')
                                badfmt(fmt);
                        /* may overwrite either white space or slash */
-                       tfu->reps = atoi(savep);
+                       tfu->reps = atoi((char *)savep);
                        tfu->flags = F_SETREP;
                        /* skip trailing white space */
-                       for (++p; isspace((unsigned char)*p); ++p);
+                       while (++p && isspace(*p)) //correct?
+                               ;
                }
 
                /* Skip slash and trailing white space. */
                if (*p == '/')
-                       while (isspace((unsigned char)*++p));
+                       while (isspace(*++p))
+                               ;
 
                /* byte count */
-               if (isdigit((unsigned char)*p)) {
-                       for (savep = p; isdigit((unsigned char)*p); ++p);
-                       if (!isspace((unsigned char)*p))
+               if (isdigit(*p)) {
+                       savep = p;
+                       while (isdigit(*p) && ++p)
+                               ;
+                       if (!isspace(*p))
                                badfmt(fmt);
-                       tfu->bcnt = atoi(savep);
+                       tfu->bcnt = atoi((char *)savep);
                        /* skip trailing white space */
-                       for (++p; isspace((unsigned char)*p); ++p);
+                       while (++p && isspace(*p)) //correct?
+                               ;
                }
 
                /* format */
                if (*p != '"')
                        badfmt(fmt);
-               for (savep = ++p; *p != '"';)
+               savep = ++p;
+               while (*p != '"')
                        if (*p++ == 0)
                                badfmt(fmt);
                tfu->fmt = xmalloc(p - savep + 1);
-               (void) strncpy(tfu->fmt, savep, p - savep);
+               strncpy(tfu->fmt, (char *)savep, p - savep);
                tfu->fmt[p - savep] = '\0';
                escape(tfu->fmt);
                p++;
@@ -153,27 +161,34 @@ static const char *spec = ".#-+ 0123456789";
 int block_size(FS *fs)
 {
        FU *fu;
-       int bcnt, cursize;
-       char *fmt;
+       int bcnt, cursize = 0;
+       unsigned char *fmt;
+       struct list_head *p;
        int prec;
 
        /* figure out the data block size needed for each format unit */
-       for (cursize = 0, fu = fs->nextfu; fu; fu = fu->nextfu) {
+       list_for_each (p, &fs->nextfu) {
+               fu = list_entry(p, FU, nextfu);
                if (fu->bcnt) {
                        cursize += fu->bcnt * fu->reps;
                        continue;
                }
-               for (bcnt = prec = 0, fmt = fu->fmt; *fmt; ++fmt) {
-                       if (*fmt != '%')
+               bcnt = prec = 0;
+               fmt = (unsigned char *)fu->fmt;
+               while (*fmt) {
+                       if (*fmt != '%') {
+                               ++fmt;
                                continue;
+                       }
                        /*
                         * skip any special chars -- save precision in
                         * case it's a %s format.
                         */
                        while (strchr(spec + 1, *++fmt));
-                       if (*fmt == '.' && isdigit((unsigned char)*++fmt)) {
-                               prec = atoi(fmt);
-                               while (isdigit((unsigned char)*++fmt));
+                       if (*fmt == '.' && isdigit(*++fmt)) {
+                               prec = atoi((char *)fmt);
+                               while (isdigit(*++fmt))
+                                       ;
                        }
                        switch(*fmt) {
                        case 'c':
@@ -196,6 +211,7 @@ int block_size(FS *fs)
                                        break;
                                }
                        }
+                       ++fmt;
                }
                cursize += bcnt * fu->reps;
        }
@@ -205,26 +221,27 @@ int block_size(FS *fs)
 void rewrite(FS *fs)
 {
        enum { NOTOKAY, USEBCNT, USEPREC } sokay;
-       PR *pr, **nextpr;
+       PR *pr;
        FU *fu;
+       struct list_head *p, *q;
        char *p1, *p2;
        char savech, *fmtp, cs[3];
        int nconv, prec;
 
-       nextpr = NULL;
        prec = 0;
 
-       for (fu = fs->nextfu; fu; fu = fu->nextfu) {
+       list_for_each (p, &fs->nextfu) {
+               fu = list_entry(p, FU, nextfu);
                /*
                 * Break each format unit into print units; each
                 * conversion character gets its own.
                 */
-               for (nconv = 0, fmtp = fu->fmt; *fmtp; nextpr = &pr->nextpr) {
+               nconv = 0;
+               fmtp = fu->fmt;
+               while (*fmtp) {
                        pr = xcalloc(1, sizeof(PR));
-                       if (!fu->nextpr)
-                               fu->nextpr = pr;
-                       else if (nextpr)
-                               *nextpr = pr;
+                       INIT_LIST_HEAD(&pr->nextpr);
+                       list_add_tail(&pr->nextpr, &fu->nextpr);
 
                        /* Skip preceding text and up to the next % sign. */
                        for (p1 = fmtp; *p1 && *p1 != '%'; ++p1);
@@ -286,17 +303,14 @@ isint:                            cs[2] = '\0';
                                cs[1] = cs[0];
                                cs[0] = 'q';
                                switch(fu->bcnt) {
-                               case 0: case 4:
+                               case 0:
                                        pr->bcnt = 4;
                                        break;
                                case 1:
-                                       pr->bcnt = 1;
-                                       break;
                                case 2:
-                                       pr->bcnt = 2;
-                                       break;
+                               case 4:
                                case 8:
-                                       pr->bcnt = 8;
+                                       pr->bcnt = fu->bcnt;
                                        break;
                                default:
                                        p1[1] = '\0';
@@ -306,11 +320,12 @@ isint:                            cs[2] = '\0';
                        case 'e': case 'E': case 'f': case 'g': case 'G':
                                pr->flags = F_DBL;
                                switch(fu->bcnt) {
-                               case 0: case 8:
+                               case 0:
                                        pr->bcnt = 8;
                                        break;
                                case 4:
-                                       pr->bcnt = 4;
+                               case 8:
+                                       pr->bcnt = fu->bcnt;
                                        break;
                                default:
                                        p1[1] = '\0';
@@ -404,8 +419,8 @@ isint2:                                     switch(fu->bcnt) {
                 * so can adjust rep count later.
                 */
                if (!fu->bcnt)
-                       for (pr = fu->nextpr; pr; pr = pr->nextpr)
-                               fu->bcnt += pr->bcnt;
+                       list_for_each(q, &fu->nextpr)
+                               fu->bcnt += (list_entry(q, PR, nextpr))->bcnt;
        }
        /*
         * If the format string interprets any data at all, and it's
@@ -416,17 +431,16 @@ isint2:                                   switch(fu->bcnt) {
         * If rep count is greater than 1, no trailing whitespace
         * gets output from the last iteration of the format unit.
         */
-       for (fu = fs->nextfu; fu; fu = fu->nextfu) {
-               if (!fu->nextfu && fs->bcnt < blocksize &&
+       list_for_each (p, &fs->nextfu) {
+               fu = list_entry(p, FU, nextfu);
+               if (list_entry_is_last(&fu->nextfu, &fs->nextfu) && fs->bcnt < blocksize &&
                    !(fu->flags&F_SETREP) && fu->bcnt)
                        fu->reps += (blocksize - fs->bcnt) / fu->bcnt;
                if (fu->reps > 1) {
-                       if (fu->nextpr) {
-                               for (pr = fu->nextpr; ; pr = pr->nextpr)
-                                       if (!pr->nextpr)
-                                               break;
+                       if (!list_empty(&fu->nextpr)) {
+                               pr = list_last_entry(&fu->nextpr, PR, nextpr);
                                for (p1 = pr->fmt, p2 = NULL; *p1; ++p1)
-                                       p2 = isspace((unsigned char)*p1) ? p1 : NULL;
+                                       p2 = isspace(*p1) ? p1 : NULL;
                                if (p2)
                                        pr->nospace = p2;
                        }