bb_mkdep: Rewroted. removed problem "include name must uniq", speed up * 3.
authorvodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277>
Mon, 10 Oct 2005 11:35:17 +0000 (11:35 +0000)
committervodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277>
Mon, 10 Oct 2005 11:35:17 +0000 (11:35 +0000)
e2fsprogs: remove confuse bb_mkdep. Use internal e2fsprogs includes only.
other: remove confuse bb_mkdep.

git-svn-id: svn://busybox.net/trunk/busybox@11822 69ca8d6d-28ef-0310-b511-8ec308f3f277

19 files changed:
archival/gzip.c
e2fsprogs/Makefile.in
e2fsprogs/blkid/blkidP.h
e2fsprogs/blkid/probe.c
e2fsprogs/blkid/read.c
e2fsprogs/blkid/version.c
e2fsprogs/chattr.c
e2fsprogs/e2p/e2p.h
e2fsprogs/e2p/uuid.c
e2fsprogs/ext2fs/bmove.c
e2fsprogs/ext2fs/ext2_fs.h
e2fsprogs/ext2fs/ext2fs.h
e2fsprogs/ext2fs/ext2fs_inline.c
e2fsprogs/ext2fs/mkjournal.c
e2fsprogs/ext2fs/swapfs.c
e2fsprogs/lsattr.c
e2fsprogs/uuid/uuidP.h
libbb/interface.c
scripts/bb_mkdep.c

index a527f0e..3aa077f 100644 (file)
@@ -234,10 +234,6 @@ static void flush_outbuf(void);
  * terms of the GNU General Public License, see the file COPYING.
  */
 
-#if !defined(OF) && defined(lint)
-#  include "gzip.h"
-#endif
-
 #ifndef BITS
 #  define BITS 16
 #endif
index 546cc83..419b2c6 100644 (file)
@@ -9,7 +9,7 @@ E2FSPROGS_AR:=e2fsprogs.a
 E2FSPROGS_DIR:=$(top_builddir)/e2fsprogs
 E2FSPROGS_SRC:=$(top_srcdir)/e2fsprogs
 
-E2FSPROGS_CFLAGS := -I$(E2FSPROGS_SRC) -include $(E2FSPROGS_SRC)/e2fsbb.h
+E2FSPROGS_CFLAGS := -include $(E2FSPROGS_SRC)/e2fsbb.h
 
 BLKID_SRC   := cache.c dev.c devname.c devno.c blkid_getsize.c \
               probe.c read.c resolve.c save.c tag.c
index 43b4f0f..759dfcd 100644 (file)
@@ -16,9 +16,8 @@
 #include <sys/types.h>
 #include <stdio.h>
 
-#include <blkid/blkid.h>
-
-#include <blkid/list.h>
+#include "blkid.h"
+#include "list.h"
 
 #ifdef __GNUC__
 #define __BLKID_ATTR(x) __attribute__(x)
index 5ae88b1..9008dc8 100644 (file)
@@ -28,7 +28,7 @@
 #include <errno.h>
 #endif
 #include "blkidP.h"
-#include "uuid/uuid.h"
+#include "../uuid/uuid.h"
 #include "probe.h"
 
 /*
index 358554c..36292ab 100644 (file)
@@ -23,7 +23,7 @@
 #endif
 
 #include "blkidP.h"
-#include "uuid/uuid.h"
+#include "../uuid/uuid.h"
 
 #ifdef HAVE_STRTOULL
 #define __USE_ISOC9X
index 7722916..ea30d0c 100644 (file)
@@ -17,7 +17,6 @@
 #include <ctype.h>
 
 #include "blkid.h"
-#include "../../version.h"
 
 static const char *lib_version = E2FSPROGS_VERSION;
 static const char *lib_date = E2FSPROGS_DATE;
index 1471c85..66838e6 100644 (file)
@@ -28,7 +28,7 @@
 #include <errno.h>
 #include <sys/param.h>
 #include <sys/stat.h>
-#include <ext2fs/ext2_fs.h>
+#include "ext2fs/ext2_fs.h"
 
 #ifdef __GNUC__
 # define EXT2FS_ATTR(x) __attribute__(x)
index 57bcec3..d4a8c0e 100644 (file)
@@ -3,12 +3,14 @@
 #include <stdio.h>
 #include <dirent.h>
 
-#include <ext2fs/ext2_fs.h>
+#include "../ext2fs/ext2_fs.h"
 
 #define E2P_FEATURE_COMPAT     0
 #define E2P_FEATURE_INCOMPAT   1
 #define E2P_FEATURE_RO_INCOMPAT        2
-
+#ifndef EXT3_FEATURE_INCOMPAT_EXTENTS
+#define EXT3_FEATURE_INCOMPAT_EXTENTS           0x0040
+#endif
 
 /* `options' for print_flags() */
 
index c16a768..9feca4c 100644 (file)
@@ -4,7 +4,7 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <ext2fs/ext2_types.h>
+#include "../ext2fs/ext2_types.h"
 
 #include "e2p.h"
 
index 7fc85a2..0b2ebb1 100644 (file)
@@ -18,8 +18,8 @@
 #include <sys/time.h>
 #endif
 
-#include "ext2fs/ext2_fs.h"
-#include "ext2fs/ext2fsP.h"
+#include "ext2_fs.h"
+#include "ext2fsP.h"
 
 struct process_block_struct {
        ext2_ino_t              ino;
index ff615c4..7a98903 100644 (file)
@@ -16,7 +16,7 @@
 #ifndef _LINUX_EXT2_FS_H
 #define _LINUX_EXT2_FS_H
 
-#include <ext2fs/ext2_types.h>         /* Changed from linux/types.h */
+#include "ext2_types.h"                /* Changed from linux/types.h */
 
 /*
  * The second extended filesystem constants/structures
index bad2f9e..eda9622 100644 (file)
@@ -61,13 +61,8 @@ extern "C" {
 #include <stdio.h>
 #include <stdlib.h>
 
-#if EXT2_FLAT_INCLUDES
-#include "e2_types.h"
+#include "ext2_types.h"
 #include "ext2_fs.h"
-#else
-#include <ext2fs/ext2_types.h>
-#include <ext2fs/ext2_fs.h>
-#endif /* EXT2_FLAT_INCLUDES */
 
 typedef __u32          ext2_ino_t;
 typedef __u32          blk_t;
@@ -76,13 +71,8 @@ typedef __u32                ext2_off_t;
 typedef __s64          e2_blkcnt_t;
 typedef __u32          ext2_dirhash_t;
 
-#if EXT2_FLAT_INCLUDES
 #include "ext2_io.h"
 #include "ext2_err.h"
-#else
-#include <ext2fs/ext2_io.h>
-#include <ext2fs/ext2_err.h>
-#endif
 
 /*
  * Portability help for Microsoft Visual C++
@@ -243,11 +233,7 @@ struct struct_ext2_filsys {
        io_channel                      image_io;
 };
 
-#if EXT2_FLAT_INCLUDES
-#include "e2_bitops.h"
-#else
-#include <ext2fs/bitops.h>
-#endif
+#include "bitops.h"
 
 /*
  * Return flags for the block iterator functions
index d1d1b83..f14e7b2 100644 (file)
@@ -9,8 +9,8 @@
  * %End-Header%
  */
 
-#include "ext2fs/ext2fs.h"
-#include "ext2fs/bitops.h"
+#include "ext2fs.h"
+#include "bitops.h"
 
 /*
  *  Allocate memory
index 427a08e..b748918 100644 (file)
@@ -33,7 +33,7 @@
 #endif
 
 #include "ext2_fs.h"
-#include "e2p/e2p.h"
+#include "../e2p/e2p.h"
 #include "ext2fs.h"
 #include "jfs_user.h"
 
index 9081701..8a08995 100644 (file)
@@ -18,7 +18,7 @@
 
 #include "ext2_fs.h"
 #include "ext2fs.h"
-#include <ext2fs/ext2_ext_attr.h>
+#include "ext2_ext_attr.h"
 
 #ifdef EXT2FS_ENABLE_SWAPFS
 void ext2fs_swap_super(struct ext2_super_block * sb)
index 475a66f..e25f36d 100644 (file)
@@ -29,7 +29,7 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 
-#include <ext2fs/ext2_fs.h>
+#include "ext2fs/ext2_fs.h"
 #include "e2fsbb.h"
 #include "e2p/e2p.h"
 
index adf233d..d2e1a45 100644 (file)
  * %End-Header%
  */
 
-#ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
-#else
-#include <uuid/uuid_types.h>
-#endif
 #include <sys/types.h>
 
 #include "uuid.h"
index 65d7c4e..7b7d9de 100644 (file)
@@ -111,8 +111,6 @@ struct in6_ifreq {
 #if HAVE_AFIPX
 #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
 #include <netipx/ipx.h>
-#else
-#include "ipx.h"
 #endif
 #endif
 
index 76db960..758b78c 100644 (file)
@@ -1,9 +1,20 @@
 /*
- * Another fast dependencies generator for Makefiles, Version 2.5
+ * Another fast dependencies generator for Makefiles, Version 3.0
  *
  * Copyright (C) 2005 by Vladimir Oleynik <dzo@simtreas.ru>
+ *
  * mmaping file may be originally by Linus Torvalds.
  *
+ * bb_simplify_path()
+ *      Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * xmalloc() bb_xstrdup() bb_error_d():
+ *      Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * llist routine
+ *      Copyright (C) 2003 Glenn McGrath
+ *      Copyright (C) Vladimir Oleynik <dzo@simtreas.ru>
+ *
  * (c) 2005 Bernhard Fischer:
  *  - commentary typos,
  *  - move "memory exhausted" into msg_enomem,
  *
  * This program does:
  * 1) find #define KEY VALUE or #undef KEY from include/config.h
- * 2) save include/config/key*.h if changed after previous usage
- * 3) recursive find and scan *.[ch] files, but skips scan of include/config/
- * 4) find #include "*.h" and KEYs using, if not as #define and #undef
- * 5) generate dependencies to stdout
+ * 2) recursive find and scan *.[ch] files, but skips scan of include/config/
+ * 3) find #include "*.h" and KEYs using, if not as #define and #undef
+ * 4) generate dependencies to stdout
  *    pwd/file.o: include/config/key*.h found_include_*.h
  *    path/inc.h: include/config/key*.h found_included_include_*.h
+ * 5) save include/config/key*.h if changed after previous usage
  * This program does not generate dependencies for #include <...>
- * BUG: all includes name must unique
  */
 
 #define LOCAL_INCLUDE_PATH          "include"
 #include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 
 
-typedef struct BB_KEYS {
-       char *keyname;
-       size_t key_sz;
-       const char *value;
-       char *stored_path;
-       char *checked;
-       struct BB_KEYS *next;
-} bb_key_t;
-
-static bb_key_t *check_key(bb_key_t *k, const char *nk, size_t key_sz);
-static bb_key_t *make_new_key(bb_key_t *k, const char *nk, size_t key_sz);
-
 /* partial and simplified libbb routine */
 static void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
 static char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
+static char *bb_simplify_path(const char *path);
 
 /* stolen from libbb as is */
 typedef struct llist_s {
        char *data;
        struct llist_s *link;
 } llist_t;
-static void *xrealloc(void *p, size_t size);
-static void *xmalloc(size_t size);
-static char *bb_xstrdup(const char *s);
-static char *bb_simplify_path(const char *path);
-/* error messages */
+
 static const char msg_enomem[] = "memory exhausted";
 
-/* for lexical analyser */
-static bb_key_t *key_top;
-static llist_t *configs;
+/* inline realization for fast works */
+static inline void *xmalloc(size_t size)
+{
+       void *p = malloc(size);
 
-static int mode;
-#define CONFIG_MODE  0
-#define SOURCES_MODE 1
+       if(p == NULL)
+               bb_error_d(msg_enomem);
+       return p;
+}
+
+static inline char *bb_xstrdup(const char *s)
+{
+       char *r = strdup(s);
 
-static void parse_inc(const char *include, const char *fname, size_t key_sz);
-static void parse_conf_opt(const char *opt, const char *val,
-                               size_t rsz, size_t key_sz);
+       if(r == NULL)
+           bb_error_d(msg_enomem);
+       return r;
+}
+
+
+static int dontgenerate_dep;    /* flag -d usaged */
+static int noiwarning;          /* flag -w usaged */
+static llist_t *configs;    /* list of -c usaged and them stat() after parsed */
+static llist_t *Iop;        /* list of -I include usaged */
+
+static char *pwd;           /* current work directory */
+static size_t replace;      /* replace current work derectory to build dir */
+
+static const char *kp;      /* KEY path, argument of -k usaged */
+static size_t kp_len;
+static struct stat st_kp;   /* stat(kp) */
+
+typedef struct BB_KEYS {
+       char *keyname;
+       size_t key_sz;
+       const char *value;
+       const char *checked;
+       char *stored_path;
+       const char *src_have_this_key;
+       struct BB_KEYS *next;
+} bb_key_t;
+
+static bb_key_t *key_top;   /* list of found KEYs */
+static bb_key_t *Ifound;    /* list of parsed includes */
+
+
+static void parse_conf_opt(const char *opt, const char *val, size_t key_sz);
+static void parse_inc(const char *include, const char *fname);
+
+static inline bb_key_t *check_key(bb_key_t *k, const char *nk, size_t key_sz)
+{
+    bb_key_t *cur;
+
+    for(cur = k; cur; cur = cur->next) {
+       if(key_sz == cur->key_sz && memcmp(cur->keyname, nk, key_sz) == 0) {
+           cur->checked = cur->stored_path;
+           return cur;
+       }
+    }
+    return NULL;
+}
+
+/* for lexical analyser */
+static int pagesizem1;      /* padding mask = getpagesize() - 1 */
 
 /* for speed tricks */
-static char first_chars[257];  /* + L_EOF */
-static char isalnums[257];     /* + L_EOF */
+static char first_chars[1+UCHAR_MAX];               /* + L_EOF */
+static char isalnums[1+UCHAR_MAX];                  /* + L_EOF */
 /* trick for fast find "define", "include", "undef" */
-static char first_chars_diu[256] = {
-       [(int)'d'] = (char)5,           /* strlen("define") - 1;  */
+static const char first_chars_diu[UCHAR_MAX] = {
+       [(int)'d'] = (char)5,           /* strlen("define")  - 1; */
        [(int)'i'] = (char)6,           /* strlen("include") - 1; */
-       [(int)'u'] = (char)4,           /* strlen("undef") - 1;   */
+       [(int)'u'] = (char)4,           /* strlen("undef")   - 1; */
 };
 
-static int pagesizem1;
-static size_t mema_id = 128;   /* first allocated for id */
-static char *id_s;
-
+#define CONFIG_MODE  0
+#define SOURCES_MODE 1
+static int mode;
 
 #define yy_error_d(s) bb_error_d("%s:%d hmm, %s", fname, line, s)
 
@@ -117,44 +165,40 @@ static char *id_s;
 #define REM    '/'      /* block comment */
 #define BS     '\\'     /* back slash */
 #define POUND  '#'      /* # */
-#define I      'i'      /* #include preprocessor's directive */
-#define D      'd'      /* #define preprocessor's directive */
-#define U      'u'      /* #undef preprocessor's directive */
-#define LI     'I'      /* #include "... */
+#define D      '5'      /* #define preprocessor's directive */
+#define I      '6'      /* #include preprocessor's directive */
+#define U      '4'      /* #undef preprocessor's directive */
 #define DK     'K'      /* #define KEY... (config mode) */
-#define DV     'V'      /* #define KEY "VALUE or #define KEY 'VALUE */
-#define NLC    'n'      /* \ and \n */
 #define ANY    '*'      /* any unparsed chars */
 
-#define L_EOF  256
 /* [A-Z_a-z] */
 #define ID(c) ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')
 /* [A-Z_a-z0-9] */
 #define ISALNUM(c)  (ID(c) || (c >= '0' && c <= '9'))
 
-#define getc1()     do { c = (optr >= oend) ? L_EOF : *optr++; } while(0)
-#define ungetc1()   optr--
+#define L_EOF  (1+UCHAR_MAX)
 
-#define put_id(c)   do {    if(id_len == local_mema_id)                 \
-                               id = xrealloc(id, local_mema_id += 16); \
-                           id[id_len++] = c; } while(0)
+#define getc0()     do { c = (optr >= oend) ? L_EOF : *optr++; } while(0)
+
+#define getc1()     do { getc0(); if(c == BS) { getc0(); \
+                                   if(c == '\n') { line++; continue; } \
+                                   else { optr--; c = BS; } \
+                                 } break; } while(1)
+
+static char id_s[4096];
+#define put_id(ic)  do {    if(id_len == sizeof(id_s)) goto too_long; \
+                               id[id_len++] = ic; } while(0)
 
 
 /* stupid C lexical analyser */
 static void c_lex(const char *fname, long fsize)
 {
-  int c = L_EOF;                     /* stupid initialize */
-  int prev_state = L_EOF;
-  int called;
+  int c;
   int state;
   int line;
   char *id = id_s;
-  size_t local_mema_id = mema_id;
   size_t id_len = 0;                /* stupid initialize */
-  char *val = NULL;
   unsigned char *optr, *oend;
-  unsigned char *start = NULL;      /* stupid initialize */
-  size_t opt_len = 0;               /* stupid initialize */
 
   int fd;
   char *map;
@@ -178,30 +222,15 @@ static void c_lex(const char *fname, long fsize)
   oend = optr + fsize;
 
   line = 1;
-  called = state = S;
+  state = S;
 
   for(;;) {
-       if(prev_state != state) {
-           prev_state = state;
-           getc1();
-       }
-
+    getc1();
+    for(;;) {
        /* [ \t]+ eat first space */
        while(c == ' ' || c == '\t')
            getc1();
 
-       if(c == BS) {
-               getc1();
-               if(c == '\n') {
-                       /* \\\n eat continued */
-                       line++;
-                       prev_state = NLC;
-                       continue;
-               }
-               ungetc1();
-               c = BS;
-       }
-
        if(state == S) {
                while(first_chars[c] == ANY) {
                    /* <S>unparsed */
@@ -211,33 +240,44 @@ static void c_lex(const char *fname, long fsize)
                }
                if(c == L_EOF) {
                        /* <S><<EOF>> */
-                       id_s = id;
-                       mema_id = local_mema_id;
                        munmap(map, mapsize);
                        close(fd);
                        return;
                }
                if(c == REM) {
                        /* <S>/ */
-                       getc1();    /* eat <S>/ */
+                       getc0();
                        if(c == REM) {
                                /* <S>"//"[^\n]* */
-                               do getc1(); while(c != '\n' && c != L_EOF);
+                               do getc0(); while(c != '\n' && c != L_EOF);
                        } else if(c == '*') {
-                               /* <S>[/][*] */
-                               called = S;
-                               state = REM;
+                               /* <S>[/][*] goto parse block comments */
+                               break;
                        }
                } else if(c == POUND) {
                        /* <S># */
-                       start = optr - 1;
                        state = c;
+                       getc1();
                } else if(c == STR || c == CHR) {
                        /* <S>\"|\' */
-                       val = NULL;
-                       called = S;
-                       state = c;
-               } else if(c != BS) {
+                       int qc = c;
+
+                       for(;;) {
+                           /* <STR,CHR>. */
+                           getc1();
+                           if(c == qc) {
+                               /* <STR>\" or <CHR>\' */
+                               break;
+                           }
+                           if(c == BS) {
+                               /* <STR,CHR>\\ but is not <STR,CHR>\\\n */
+                               getc0();
+                           }
+                           if(c == '\n' || c == L_EOF)
+                               yy_error_d("unterminated");
+                       }
+                       getc1();
+               } else {
                        /* <S>[A-Z_a-z0-9] */
 
                        /* trick for fast drop id
@@ -254,90 +294,20 @@ static void c_lex(const char *fname, long fsize)
                            } while(isalnums[c]);
                            check_key(key_top, id, id_len);
                        }
-               } else {
-                   /* <S>\\ */
-                   prev_state = c;
                }
                continue;
        }
-       if(state == REM) {
-         for(;;) {
-               /* <REM>[^*]+ */
-               while(c != '*') {
-                       if(c == '\n') {
-                               /* <REM>\n */
-                               if(called != S)
-                                   yy_error_d("unexpected newline");
-                               line++;
-                       } else if(c == L_EOF)
-                               yy_error_d("unexpected EOF");
-                       getc1();
-               }
-               /* <REM>[*] */
-               getc1();
-               if(c == REM) {
-                       /* <REM>[*][/] */
-                       state = called;
-                       break;
-               }
-         }
-         continue;
-       }
-       if(state == STR || state == CHR) {
-           for(;;) {
-               /* <STR,CHR>\n|<<EOF>> */
-               if(c == '\n' || c == L_EOF)
-                       yy_error_d("unterminated");
-               if(c == BS) {
-                       /* <STR,CHR>\\ */
-                       getc1();
-                       if(c != BS && c != '\n' && c != state) {
-                           /* another usage \ in str or char */
-                           if(c == L_EOF)
-                               yy_error_d("unexpected EOF");
-                           if(val)
-                               put_id(c);
-                           continue;
-                       }
-                       /* <STR,CHR>\\[\\\n] or <STR>\\\" or <CHR>\\\' */
-                       /* eat 2 char */
-                       if(c == '\n')
-                           line++;
-                       else if(val)
-                           put_id(c);
-               } else if(c == state) {
-                       /* <STR>\" or <CHR>\' */
-                       if(called == LI) {
-                           /* store "include.h" */
-                           parse_inc(id, fname, id_len);
-                       } else if(called == DV) {
-                           put_id(c);  /* config mode #define KEY "VAL"<- */
-                           put_id(0);
-                           parse_conf_opt(id, val, (optr - start), opt_len);
-                       }
-                       state = S;
-                       break;
-               } else if(val)
-                       put_id(c);
-               /* <STR,CHR>. */
-               getc1();
-           }
-           continue;
-       }
-
        /* begin preprocessor states */
        if(c == L_EOF)
            yy_error_d("unexpected EOF");
        if(c == REM) {
                /* <#.*>/ */
-               getc1();
+               getc0();
                if(c == REM)
                        yy_error_d("detected // in preprocessor line");
                if(c == '*') {
-                       /* <#.*>[/][*] */
-                       called = state;
-                       state = REM;
-                       continue;
+                       /* <#.*>[/][*] goto parse block comments */
+                       break;
                }
                /* hmm, #.*[/] */
                yy_error_d("strange preprocessor line");
@@ -345,43 +315,49 @@ static void c_lex(const char *fname, long fsize)
        if(state == POUND) {
            /* tricks */
            static const char * const preproc[] = {
-                   /* 0-3 */
-                   "", "", "", "",
-                   /* 4 */ /* 5 */   /* 6 */
-                   "ndef", "efine", "nclude",
+                   /* 0 1   2  3     4        5        6 */
+                   "", "", "", "", "ndef", "efine", "nclude"
            };
            size_t diu = first_chars_diu[c];   /* strlen and preproc ptr */
-           const unsigned char *p = optr;
 
-           while(isalnums[c]) getc1();
-           /* have str begined with c, readed == strlen key and compared */
-           if(diu != S && diu == (optr-p-1) && !memcmp(p, preproc[diu], diu)) {
-               state = p[-1];
-               id_len = 0; /* common for save */
+           state = S;
+           if(diu != S) {
+               getc1();
+               id_len = 0;
+               while(isalnums[c]) {
+                   put_id(c);
+                   getc1();
+               }
+               /* have str begined with c, readed == strlen key and compared */
+               if(diu == id_len && !memcmp(id, preproc[diu], diu)) {
+                   state = diu + '0';
+                   id_len = 0; /* common for save */
+               }
            } else {
-               state = S;
+               while(isalnums[c]) getc1();
            }
-           ungetc1();
-           continue;
-       }
-       if(state == I) {
+       } else if(state == I) {
                if(c == STR) {
                        /* <I>\" */
-                       val = id;
-                       called = LI;
-                       state = STR;
-               } else {
-                   /* another (may be wrong) #include ... */
-                   ungetc1();
-                   state = S;
+                       for(;;) {
+                           getc1();
+                           if(c == STR)
+                               break;
+                           if(c == L_EOF)
+                               yy_error_d("unexpected EOF");
+                           put_id(c);
+                       }
+                       put_id(0);
+                       /* store "include.h" */
+                       parse_inc(id, fname);
+                       getc1();
                }
-               continue;
-       }
-       if(state == D || state == U) {
+               /* else another (may be wrong) #include ... */
+               state = S;
+       } else if(state == D || state == U) {
            if(mode == SOURCES_MODE) {
                /* ignore depend with #define or #undef KEY */
-               while(isalnums[c])
-                   getc1();
+               while(isalnums[c]) getc1();
                state = S;
            } else {
                /* save KEY from #"define"|"undef" ... */
@@ -392,145 +368,164 @@ static void c_lex(const char *fname, long fsize)
                if(!id_len)
                    yy_error_d("expected identifier");
                if(state == U) {
-                   parse_conf_opt(id, NULL, (optr - start), id_len);
+                   parse_conf_opt(id, NULL, id_len);
                    state = S;
                } else {
                    /* D -> DK */
-                   opt_len = id_len;
+                   if(c == '(')
+                       yy_error_d("unexpected function macro");
                    state = DK;
                }
            }
-           ungetc1();
-           continue;
-       }
-       if(state == DK) {
-           /* #define KEY[ ] (config mode) */
-           val = id + id_len;
-           if(c == STR || c == CHR) {
-               /* define KEY "... or define KEY '... */
-               put_id(c);
-               called = DV;
-               state = c;
-               continue;
-           }
-           while(isalnums[c]) {
-               /* VALUE */
+       } else {
+           /* state==<DK> #define KEY[ ] (config mode) */
+           size_t opt_len = id_len;
+           char *val = id + opt_len;
+           char *sp;
+
+           for(;;) {
+               if(c == L_EOF || c == '\n')
+                   break;
                put_id(c);
                getc1();
            }
+           sp = id + id_len;
            put_id(0);
-           parse_conf_opt(id, val, (optr - start), opt_len);
+           /* trim tail spaces */
+           while(--sp >= val && (*sp == ' ' || *sp == '\t'
+                               || *sp == '\f' || *sp == '\v'))
+               *sp = '\0';
+           parse_conf_opt(id, val, opt_len);
            state = S;
-           ungetc1();
-           continue;
        }
     }
+
+    /* <REM> */
+    getc0();
+    for(;;) {
+         /* <REM>[^*]+ */
+         while(c != '*') {
+               if(c == '\n') {
+                   /* <REM>\n */
+                   if(state != S)
+                       yy_error_d("unexpected newline");
+                   line++;
+               } else if(c == L_EOF)
+                   yy_error_d("unexpected EOF");
+               getc0();
+         }
+         /* <REM>[*] */
+         getc0();
+         if(c == REM) {
+               /* <REM>[*][/] */
+               break;
+         }
+    }
+  }
+too_long:
+  yy_error_d("phrase too long");
 }
 
 
-static void show_usage(void) __attribute__ ((noreturn));
-static void show_usage(void)
+/* bb_simplify_path special variant for apsolute pathname */
+static size_t bb_qa_simplify_path(char *path)
 {
-       bb_error_d("%s\n%s\n", bb_mkdep_terse_options, bb_mkdep_full_options);
-}
+       char *s, *p;
 
-static const char *kp;
-static size_t kp_len;
-static llist_t *Iop;
-static bb_key_t *Ifound;
-static int noiwarning;
+       p = s = path;
 
-static bb_key_t *check_key(bb_key_t *k, const char *nk, size_t key_sz)
-{
-    bb_key_t *cur;
+       do {
+           if (*p == '/') {
+               if (*s == '/') {    /* skip duplicate (or initial) slash */
+                   continue;
+               } else if (*s == '.') {
+                   if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */
+                       continue;
+                   } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) {
+                       ++s;
+                       if (p > path) {
+                           while (*--p != '/');    /* omit previous dir */
+                       }
+                       continue;
+                   }
+               }
+           }
+           *++p = *s;
+       } while (*++s);
 
-    for(cur = k; cur; cur = cur->next) {
-       if(key_sz == cur->key_sz && memcmp(cur->keyname, nk, key_sz) == 0) {
-           cur->checked = cur->stored_path;
-           return cur;
+       if ((p == path) || (*p != '/')) {  /* not a trailing slash */
+           ++p;                            /* so keep last character */
        }
-    }
-    return NULL;
-}
-
-static bb_key_t *make_new_key(bb_key_t *k, const char *nk, size_t key_sz)
-{
-       bb_key_t *cur;
+       *p = 0;
 
-       cur = xmalloc(sizeof(bb_key_t) + key_sz + 1);
-       cur->keyname = memcpy(cur + 1, nk, key_sz);
-       cur->keyname[key_sz] = '\0';
-       cur->key_sz = key_sz;
-       cur->checked = NULL;
-       cur->next = k;
-       return cur;
+       return (p - path);
 }
 
-static inline char *store_include_fullpath(char *p_i, bb_key_t *li)
+static void parse_inc(const char *include, const char *fname)
 {
-    char *ok;
-
-    if(access(p_i, F_OK) == 0) {
-       ok = li->stored_path = bb_simplify_path(p_i);
-       li->checked = ok;
+    bb_key_t *cur;
+    const char *p_i;
+    llist_t *lo;
+    char *ap;
+    size_t key_sz;
+
+    if(*include == '/') {
+       lo = NULL;
+       ap = bb_xstrdup(include);
     } else {
-       ok = NULL;
+       int w;
+       const char *p;
+
+       lo = Iop;
+       p = strrchr(fname, '/');    /* fname have absolute pathname */
+       w = (p-fname);
+       /* find from current directory of source file */
+       ap = bb_asprint("%.*s/%s", w, fname, include);
     }
-    free(p_i);
-    return ok;
-}
-
-static void parse_inc(const char *include, const char *fname, size_t key_sz)
-{
-       bb_key_t *li;
-       char *p_i;
-       llist_t *lo;
 
-       li = check_key(Ifound, include, key_sz);
-       if(li)
+    for(;;) {
+       key_sz = bb_qa_simplify_path(ap);
+       cur = check_key(Ifound, ap, key_sz);
+       if(cur) {
+           cur->checked = cur->value;
+           free(ap);
            return;
-       Ifound = li = make_new_key(Ifound, include, key_sz);
-       include = li->keyname;
-       if(include[0] != '/') {
-           /* relative */
-           int w;
-
-           p_i = strrchr(fname, '/');  /* fname have absolute pathname */
-           w = (p_i-fname);
-           /* find from current directory of source file */
-           p_i = bb_asprint("%.*s/%s", w, fname, include);
-           if(store_include_fullpath(p_i, li))
-               return;
-           /* find from "-I include" specified directories */
-           for(lo = Iop; lo; lo = lo->link) {
-               p_i = bb_asprint("%s/%s", lo->data, include);
-               if(store_include_fullpath(p_i, li))
-                   return;
-           }
-       } else {
-           /* absolute include pathname */
-           if(access(include, F_OK) == 0) {
-               li->checked = li->stored_path = bb_xstrdup(include);
-               return;
-           }
        }
-       li->stored_path = NULL;
-       if(noiwarning)
-           fprintf(stderr, "%s: Warning: #include \"%s\" not found in specified paths\n", fname, include);
+       if(access(ap, F_OK) == 0) {
+           /* found */
+           p_i = ap;
+           break;
+       } else if(lo == NULL) {
+           p_i = NULL;
+           break;
+       }
+
+       /* find from "-I include" specified directories */
+       free(ap);
+       /* lo->data have absolute pathname */
+       ap = bb_asprint("%s/%s", lo->data, include);
+       lo = lo->link;
+    }
+
+    cur = xmalloc(sizeof(bb_key_t));
+    cur->keyname = ap;
+    cur->key_sz = key_sz;
+    cur->stored_path = ap;
+    cur->value = cur->checked = p_i;
+    if(p_i == NULL && noiwarning)
+       fprintf(stderr, "%s: Warning: #include \"%s\" not found\n", fname, include);
+    cur->next = Ifound;
+    Ifound = cur;
 }
 
-static void parse_conf_opt(const char *opt, const char *val,
-                          size_t recordsz, size_t key_sz)
+static size_t max_rec_sz;
+
+static void parse_conf_opt(const char *opt, const char *val, size_t key_sz)
 {
        bb_key_t *cur;
        char *k;
-       char *s, *p;
-       struct stat st;
-       int fd;
-       int cmp_ok = 0;
-       static char *record_buf;
-       static size_t r_sz;
-       ssize_t rw_ret;
+       char *p;
+       size_t val_sz = 0;
 
        cur = check_key(key_top, opt, key_sz);
        if(cur != NULL) {
@@ -543,29 +538,33 @@ static void parse_conf_opt(const char *opt, const char *val,
            k = cur->keyname;
            fprintf(stderr, "Warning: redefined %s\n", k);
        } else {
-           key_top = cur = make_new_key(key_top, opt, key_sz);
-           k = cur->keyname;
+           size_t recordsz;
+
+           if(val && *val)
+               val_sz = strlen(val) + 1;
+           recordsz = key_sz + val_sz + 1;
+           if(max_rec_sz < recordsz)
+               max_rec_sz = recordsz;
+           cur = xmalloc(sizeof(bb_key_t) + recordsz);
+           k = cur->keyname = memcpy(cur + 1, opt, key_sz);
+           cur->keyname[key_sz] = '\0';
+           cur->key_sz = key_sz;
+           cur->checked = NULL;
+           cur->src_have_this_key = NULL;
+           cur->next = key_top;
+           key_top = cur;
        }
-       /* do generate record */
-       recordsz += 2;  /* \n\0 */
-       if(recordsz > r_sz)
-           record_buf = xrealloc(record_buf, (r_sz = recordsz) * 2);
-       s = record_buf;
-       /* may be short count " " */
+       /* save VAL */
        if(val) {
            if(*val == '\0') {
                cur->value = "";
-               recordsz = sprintf(s, "#define %s\n", k);
            } else {
-               cur->value = bb_xstrdup(val);
-               recordsz = sprintf(s, "#define %s %s\n", k, val);
+               cur->value = p = cur->keyname + key_sz + 1;
+               memcpy(p, val, val_sz);
            }
        } else {
            cur->value = NULL;
-           recordsz = sprintf(s, "#undef %s\n", k);
        }
-       /* size_t -> ssize_t :( */
-       rw_ret = (ssize_t)recordsz;
        /* trick, save first char KEY for do fast identify id */
        first_chars[(int)*k] = *k;
 
@@ -577,80 +576,118 @@ static void parse_conf_opt(const char *opt, const char *val,
            else if(*p == '_' && p[1] > '9')    /* do not change A_1 to A/1 */
                    *p = '/';
        }
-       /* check kp/key.h if present after previous usage */
-       if(stat(k, &st)) {
-           for(p = k + kp_len + 1; *p; p++) {
-               /* Auto-create directories. */
-               if (*p == '/') {
-                   *p = '\0';
-                   if (access(k, F_OK) != 0 && mkdir(k, 0755) != 0)
-                       bb_error_d("mkdir(%s): %m", k);
-                   *p = '/';
+}
+
+static void store_keys(void)
+{
+    bb_key_t *cur;
+    char *k;
+    struct stat st;
+    int cmp_ok;
+    ssize_t rw_ret;
+    size_t recordsz = max_rec_sz * 2 + 10 * 2 + 16;
+    /* buffer for double "#define KEY VAL\n" */
+    char *record_buf = xmalloc(recordsz);
+
+    for(cur = key_top; cur; cur = cur->next) {
+       if(cur->src_have_this_key) {
+           /* do generate record */
+           k = cur->keyname;
+           if(cur->value == NULL) {
+               recordsz = sprintf(record_buf, "#undef %s\n", k);
+           } else {
+               const char *val = cur->value;
+               if(*val == '\0') {
+                   recordsz = sprintf(record_buf, "#define %s\n", k);
+               } else {
+                   recordsz = sprintf(record_buf, "#define %s %s\n", k, val);
                }
            }
-       } else {
-               /* found */
-               if(st.st_size == (off_t)recordsz) {
-                   char *r_cmp = s + recordsz;
-
-                   fd = open(k, O_RDONLY);
-                   if(fd < 0 || read(fd, r_cmp, recordsz) < rw_ret)
-                       bb_error_d("%s: %m", k);
-                   close(fd);
-                   cmp_ok = memcmp(s, r_cmp, recordsz) == 0;
+           /* size_t -> ssize_t :( */
+           rw_ret = (ssize_t)recordsz;
+           /* check kp/key.h, compare after previous usage */
+           cmp_ok = 0;
+           k = cur->stored_path;
+           if(stat(k, &st)) {
+               char *p;
+               for(p = k + kp_len + 1; *p; p++) {
+                   /* Auto-create directories. */
+                   if (*p == '/') {
+                       *p = '\0';
+                       if (access(k, F_OK) != 0 && mkdir(k, 0755) != 0)
+                           bb_error_d("mkdir(%s): %m", k);
+                       *p = '/';
+                   }
                }
+           } else {
+                   /* found */
+                   if(st.st_size == (off_t)recordsz) {
+                       char *r_cmp;
+                       int fd;
+                       size_t padded = recordsz;
+
+                       /* 16-byte padding for read(2) and memcmp(3) */
+                       padded = (padded+15) & ~15;
+                       r_cmp = record_buf + padded;
+                       fd = open(k, O_RDONLY);
+                       if(fd < 0 || read(fd, r_cmp, recordsz) < rw_ret)
+                           bb_error_d("%s: %m", k);
+                       close(fd);
+                       cmp_ok = memcmp(record_buf, r_cmp, recordsz) == 0;
+                   }
+           }
+           if(!cmp_ok) {
+               int fd = open(k, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+               if(fd < 0 || write(fd, record_buf, recordsz) < rw_ret)
+                   bb_error_d("%s: %m", k);
+               close(fd);
+           }
        }
-       if(!cmp_ok) {
-           fd = open(k, O_WRONLY|O_CREAT|O_TRUNC, 0644);
-           if(fd < 0 || write(fd, s, recordsz) < rw_ret)
-               bb_error_d("%s: %m", k);
-           close(fd);
-       }
+    }
 }
 
-static char *pwd;
-
 static int show_dep(int first, bb_key_t *k, const char *name, const char *f)
 {
     bb_key_t *cur;
 
     for(cur = k; cur; cur = cur->next) {
        if(cur->checked) {
-           if(first) {
-               if(f == NULL)
+           if(first >= 0) {
+               if(first) {
+                   if(f == NULL)
                        printf("\n%s:", name);
-               else
+                   else
                        printf("\n%s/%s:", pwd, name);
-               first = 0;
-           } else {
-               printf(" \\\n  ");
+                   first = 0;
+               } else {
+                   printf(" \\\n  ");
+               }
+               printf(" %s", cur->checked);
            }
-           printf(" %s", cur->checked);
+           cur->src_have_this_key = cur->checked;
+           cur->checked = NULL;
        }
-       cur->checked = NULL;
     }
     return first;
 }
 
-static size_t replace;
-
-static struct stat st_kp;
-static int dontgenerate_dep;
-
 static char *
 parse_chd(const char *fe, const char *p, size_t dirlen)
 {
     struct stat st;
     char *fp;
     size_t df_sz;
-    static char *dir_and_entry;
-    static size_t dir_and_entry_sz;
+    static char dir_and_entry[4096];
+    size_t fe_sz = strlen(fe) + 1;
 
-    df_sz = dirlen + strlen(fe) + 2;     /* dir/file\0 */
-    if(df_sz > dir_and_entry_sz)
-       dir_and_entry = xrealloc(dir_and_entry, dir_and_entry_sz = df_sz);
+    df_sz = dirlen + fe_sz + 1;         /* dir/file\0 */
+    if(df_sz > sizeof(dir_and_entry))
+       bb_error_d("%s: file name too long", fe);
     fp = dir_and_entry;
-    sprintf(fp, "%s/%s", p, fe);
+    /* sprintf(fp, "%s/%s", p, fe); */
+    memcpy(fp, p, dirlen);
+    fp[dirlen] = '/';
+    memcpy(fp + dirlen + 1, fe, fe_sz);
 
     if(stat(fp, &st)) {
        fprintf(stderr, "Warning: stat(%s): %m\n", fp);
@@ -673,17 +710,16 @@ parse_chd(const char *fe, const char *p, size_t dirlen)
            }
        }
        /* direntry is *.[ch] regular file and is not configs */
+       c_lex(fp, st.st_size);
        if(!dontgenerate_dep) {
            int first;
-
-           c_lex(fp, st.st_size);
            if(*e == 'c') {
                /* *.c -> *.o */
                *e = 'o';
                /* /src_dir/path/file.o to path/file.o */
                fp += replace;
                if(*fp == '/')
-                       fp++;
+                   fp++;
            } else {
                e = NULL;
            }
@@ -691,15 +727,15 @@ parse_chd(const char *fe, const char *p, size_t dirlen)
            first = show_dep(first, key_top, fp, e);
            if(first == 0)
                putchar('\n');
+       } else {
+           show_dep(-1, key_top, NULL, NULL);
        }
        return NULL;
     } else if(S_ISDIR(st.st_mode)) {
        if (st.st_dev == st_kp.st_dev && st.st_ino == st_kp.st_ino)
            return NULL;    /* drop scan kp/ directory */
-       /* direntry is directory. buff is returned, begin of zero allocate */
-       dir_and_entry = NULL;
-       dir_and_entry_sz = 0;
-       return fp;
+       /* direntry is directory. buff is returned */
+       return bb_xstrdup(fp);
     }
     /* hmm, direntry is device! */
     return NULL;
@@ -755,6 +791,11 @@ static void scan_dir_find_ch_files(const char *p)
     }
 }
 
+static void show_usage(void) __attribute__ ((noreturn));
+static void show_usage(void)
+{
+       bb_error_d("%s\n%s\n", bb_mkdep_terse_options, bb_mkdep_full_options);
+}
 
 int main(int argc, char **argv)
 {
@@ -763,24 +804,25 @@ int main(int argc, char **argv)
        llist_t *fl;
 
        {
-           /* for bb_simplify_path */
-           /* libbb xgetcwd(), this program have not chdir() */
+           /* for bb_simplify_path, this program have not chdir() */
+           /* libbb-like my xgetcwd() */
            unsigned path_max = 512;
 
            s = xmalloc (path_max);
-#define PATH_INCR 32
            while (getcwd (s, path_max) == NULL) {
                if(errno != ERANGE)
                    bb_error_d("getcwd: %m");
-               s = xrealloc (s, path_max += PATH_INCR);
-               }
+               free(s);
+               s = xmalloc(path_max *= 2);
+           }
            pwd = s;
        }
 
        while ((i = getopt(argc, argv, "I:c:dk:w")) > 0) {
                switch(i) {
                    case 'I':
-                           Iop = llist_add_to(Iop, optarg);
+                           s = bb_simplify_path(optarg);
+                           Iop = llist_add_to(Iop, s);
                            break;
                    case 'c':
                            s = bb_simplify_path(optarg);
@@ -812,19 +854,18 @@ int main(int argc, char **argv)
            bb_error_d("%s is not directory", kp);
        /* defaults */
        if(Iop == NULL)
-           Iop = llist_add_to(Iop, LOCAL_INCLUDE_PATH);
+           Iop = llist_add_to(Iop, bb_simplify_path(LOCAL_INCLUDE_PATH));
        if(configs == NULL) {
            s = bb_simplify_path(INCLUDE_CONFIG_KEYS_PATH);
            configs = llist_add_to(configs, s);
        }
        /* for c_lex */
        pagesizem1 = getpagesize() - 1;
-       id_s = xmalloc(mema_id);
-       for(i = 0; i < 256; i++) {
+       for(i = 0; i < UCHAR_MAX; i++) {
            if(ISALNUM(i))
                isalnums[i] = i;
            /* set unparsed chars for speed up of parser */
-           else if(i != CHR && i != STR && i != POUND && i != REM && i != BS)
+           else if(i != CHR && i != STR && i != POUND && i != REM)
                first_chars[i] = ANY;
        }
        first_chars[i] = '-';   /* L_EOF */
@@ -836,8 +877,9 @@ int main(int argc, char **argv)
            if(stat(fl->data, &st))
                bb_error_d("stat(%s): %m", fl->data);
            c_lex(fl->data, st.st_size);
+           free(fl->data);
            /* trick for fast comparing found files with configs */
-           fl->data = xrealloc(fl->data, sizeof(struct stat));
+           fl->data = xmalloc(sizeof(struct stat));
            memcpy(fl->data, &st, sizeof(struct stat));
        }
 
@@ -850,6 +892,7 @@ int main(int argc, char **argv)
        } else {
                scan_dir_find_ch_files(".");
        }
+       store_keys();
        return 0;
 }
 
@@ -881,30 +924,6 @@ static char *bb_asprint(const char *format, ...)
 }
 
 /* partial libbb routine as is */
-static void *xmalloc(size_t size)
-{
-       void *p = malloc(size);
-
-       if(p == NULL)
-               bb_error_d(msg_enomem);
-       return p;
-}
-
-static void *xrealloc(void *p, size_t size) {
-       p = realloc(p, size);
-       if(p == NULL)
-               bb_error_d(msg_enomem);
-       return p;
-}
-
-static char *bb_xstrdup(const char *s)
-{
-       char *r = strdup(s);
-
-       if(r == NULL)
-           bb_error_d(msg_enomem);
-       return r;
-}
 
 static char *bb_simplify_path(const char *path)
 {