linux-old/scripts/mkdep.c
<<
>>
Prefs
   1#include <stdio.h>
   2#include <stdlib.h>
   3
   4#include <errno.h>
   5#include <string.h>
   6#include <sys/types.h>
   7#include <sys/stat.h>
   8#include <unistd.h>
   9#include <sys/fcntl.h>
  10#include <sys/mman.h>
  11
  12char *filename, *command, __depname[256] = "\n\t@touch ";
  13int needsconfig, hasconfig, hasmodules, hasdep;
  14
  15#define depname (__depname+9)
  16
  17struct path_struct {
  18        int len;
  19        char buffer[256-sizeof(int)];
  20} path_array[2] = {
  21        { 23, "/usr/src/linux/include/" },
  22        {  0, "" }
  23};
  24
  25static void handle_include(int type, char *name, int len)
  26{
  27        int plen;
  28        struct path_struct *path = path_array+type;
  29
  30        if (len == 14)
  31                if (!memcmp(name, "linux/config.h", len))
  32                        hasconfig = 1;
  33                else if (!memcmp(name, "linux/module.h", len))
  34                        hasmodules = 1;
  35
  36        plen = path->len;
  37        memcpy(path->buffer+plen, name, len);
  38        len += plen;
  39        path->buffer[len] = '\0';
  40        if (access(path->buffer, F_OK))
  41                return;
  42
  43        if (!hasdep) {
  44                hasdep = 1;
  45                printf("%s:", depname);
  46        }
  47        printf(" \\\n   %s", path->buffer);
  48}
  49
  50static void handle_config(void)
  51{
  52        needsconfig = 1;
  53        if (!hasconfig)
  54                fprintf(stderr,
  55                        "%s needs config but has not included config file\n",
  56                        filename);
  57}
  58
  59#if defined(__alpha__) || defined(__i386__)
  60#define LE_MACHINE
  61#endif
  62
  63#ifdef LE_MACHINE
  64#define next_byte(x) (x >>= 8)
  65#define current ((unsigned char) __buf)
  66#else
  67#define next_byte(x) (x <<= 8)
  68#define current (__buf >> 8*(sizeof(unsigned long)-1))
  69#endif
  70
  71#define GETNEXT { \
  72next_byte(__buf); \
  73if (!__nrbuf) { \
  74        __buf = *(unsigned long *) next; \
  75        __nrbuf = sizeof(unsigned long); \
  76        if (!__buf) \
  77                break; \
  78} next++; __nrbuf--; }
  79#define CASE(c,label) if (current == c) goto label
  80#define NOTCASE(c,label) if (current != c) goto label
  81
  82static void state_machine(register char *next)
  83{
  84        for(;;) {
  85        register unsigned long __buf = 0;
  86        register unsigned long __nrbuf = 0;
  87
  88normal:
  89        GETNEXT
  90__normal:
  91        CASE('/',slash);
  92        CASE('"',string);
  93        CASE('\'',char_const);
  94        CASE('#',preproc);
  95        goto normal;
  96
  97slash:
  98        GETNEXT
  99        CASE('*',comment);
 100        goto __normal;
 101
 102string:
 103        GETNEXT
 104        CASE('"',normal);
 105        NOTCASE('\\',string);
 106        GETNEXT
 107        goto string;
 108
 109char_const:
 110        GETNEXT
 111        CASE('\'',normal);
 112        NOTCASE('\\',char_const);
 113        GETNEXT
 114        goto char_const;
 115
 116comment:
 117        GETNEXT
 118__comment:
 119        NOTCASE('*',comment);
 120        GETNEXT
 121        CASE('/',normal);
 122        goto __comment;
 123
 124preproc:
 125        GETNEXT
 126        CASE('\n',normal);
 127        CASE(' ',preproc);
 128        CASE('\t',preproc);
 129        CASE('i',i_preproc);
 130        CASE('e',e_preproc);
 131        GETNEXT
 132
 133skippreproc:
 134        CASE('\n',normal);
 135        CASE('\\',skippreprocslash);
 136        GETNEXT
 137        goto skippreproc;
 138
 139skippreprocslash:
 140        GETNEXT;
 141        GETNEXT;
 142        goto skippreproc;
 143
 144e_preproc:
 145        GETNEXT
 146        NOTCASE('l',skippreproc);
 147        GETNEXT
 148        NOTCASE('i',skippreproc);
 149        GETNEXT
 150        CASE('f',if_line);
 151        goto skippreproc;
 152
 153i_preproc:
 154        GETNEXT
 155        CASE('f',if_line);
 156        NOTCASE('n',skippreproc);
 157        GETNEXT
 158        NOTCASE('c',skippreproc);
 159        GETNEXT
 160        NOTCASE('l',skippreproc);
 161        GETNEXT
 162        NOTCASE('u',skippreproc);
 163        GETNEXT
 164        NOTCASE('d',skippreproc);
 165        GETNEXT
 166        NOTCASE('e',skippreproc);
 167
 168/* "# include" found */
 169include_line:
 170        GETNEXT
 171        CASE('\n',normal);
 172        CASE('<', std_include_file);
 173        NOTCASE('"', include_line);
 174
 175/* "local" include file */
 176{
 177        char *incname = next;
 178local_include_name:
 179        GETNEXT
 180        CASE('\n',normal);
 181        NOTCASE('"', local_include_name);
 182        handle_include(1, incname, next-incname-1);
 183        goto skippreproc;
 184}
 185
 186/* <std> include file */
 187std_include_file:
 188{
 189        char *incname = next;
 190std_include_name:
 191        GETNEXT
 192        CASE('\n',normal);
 193        NOTCASE('>', std_include_name);
 194        handle_include(0, incname, next-incname-1);
 195        goto skippreproc;
 196}
 197
 198if_line:
 199        if (needsconfig)
 200                goto skippreproc;
 201if_start:
 202        GETNEXT
 203        CASE('C', config);
 204        CASE('\n', normal);
 205        CASE('_', if_middle);
 206        if (current >= 'a' && current <= 'z')
 207                goto if_middle;
 208        if (current < 'A' || current > 'Z')
 209                goto if_start;
 210config:
 211        GETNEXT
 212        NOTCASE('O', __if_middle);
 213        GETNEXT
 214        NOTCASE('N', __if_middle);
 215        GETNEXT
 216        NOTCASE('F', __if_middle);
 217        GETNEXT
 218        NOTCASE('I', __if_middle);
 219        GETNEXT
 220        NOTCASE('G', __if_middle);
 221        GETNEXT
 222        NOTCASE('_', __if_middle);
 223        handle_config();
 224        goto skippreproc;
 225
 226if_middle:
 227        GETNEXT
 228__if_middle:
 229        CASE('\n', normal);
 230        CASE('_', if_middle);
 231        if (current >= 'a' && current <= 'z')
 232                goto if_middle;
 233        if (current < 'A' || current > 'Z')
 234                goto if_start;
 235        goto if_middle;
 236        }
 237}
 238
 239static void do_depend(void)
 240{
 241        char *map;
 242        int mapsize;
 243        int pagesizem1 = getpagesize()-1;
 244        int fd = open(filename, O_RDONLY);
 245        struct stat st;
 246
 247        if (fd < 0) {
 248                if (errno != ENOENT)
 249                        perror(filename);
 250                return;
 251        }
 252        fstat(fd, &st);
 253        if (st.st_size == 0) {
 254                fprintf(stderr,"%s is empty\n",filename);
 255                return;
 256        }
 257        mapsize = st.st_size + 2*sizeof(unsigned long);
 258        mapsize = (mapsize+pagesizem1) & ~pagesizem1;
 259        map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
 260        if (-1 == (long)map) {
 261                perror("mkdep: mmap");
 262                close(fd);
 263                return;
 264        }
 265        close(fd);
 266        state_machine(map);
 267        munmap(map, mapsize);
 268        if (hasdep)
 269                puts(command);
 270}
 271
 272int main(int argc, char **argv)
 273{
 274        int len;
 275        char * hpath;
 276
 277        hpath = getenv("HPATH");
 278        if (!hpath)
 279                hpath = "/usr/src/linux/include";
 280        len = strlen(hpath);
 281        memcpy(path_array[0].buffer, hpath, len);
 282        if (len && hpath[len-1] != '/') {
 283                path_array[0].buffer[len] = '/';
 284                len++;
 285        }
 286        path_array[0].buffer[len] = '\0';
 287        path_array[0].len = len;
 288
 289        while (--argc > 0) {
 290                int len;
 291                char *name = *++argv;
 292
 293                filename = name;
 294                len = strlen(name);
 295                memcpy(depname, name, len+1);
 296                command = __depname;
 297                if (len > 2 && name[len-2] == '.') {
 298                        switch (name[len-1]) {
 299                                case 'c':
 300                                case 'S':
 301                                        depname[len-1] = 'o';
 302                                        command = "";
 303                        }
 304                }
 305                needsconfig = hasconfig = hasmodules = hasdep = 0;
 306                do_depend();
 307                if (hasconfig && !hasmodules && !needsconfig)
 308                        fprintf(stderr, "%s doesn't need config\n", filename);
 309        }
 310        return 0;
 311}
 312
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.