linux/scripts/dtc/srcpos.c
<<
>>
Prefs
   1/*
   2 * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License as
   6 * published by the Free Software Foundation; either version 2 of the
   7 * License, or (at your option) any later version.
   8 *
   9 *  This program is distributed in the hope that it will be useful,
  10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12 *  General Public License for more details.
  13 *
  14 *  You should have received a copy of the GNU General Public License
  15 *  along with this program; if not, write to the Free Software
  16 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  17 *                                                                   USA
  18 */
  19
  20#include "dtc.h"
  21#include "srcpos.h"
  22
  23/*
  24 * Like yylineno, this is the current open file pos.
  25 */
  26
  27struct dtc_file *srcpos_file;
  28
  29static int dtc_open_one(struct dtc_file *file,
  30                        const char *search,
  31                        const char *fname)
  32{
  33        char *fullname;
  34
  35        if (search) {
  36                fullname = xmalloc(strlen(search) + strlen(fname) + 2);
  37
  38                strcpy(fullname, search);
  39                strcat(fullname, "/");
  40                strcat(fullname, fname);
  41        } else {
  42                fullname = strdup(fname);
  43        }
  44
  45        file->file = fopen(fullname, "r");
  46        if (!file->file) {
  47                free(fullname);
  48                return 0;
  49        }
  50
  51        file->name = fullname;
  52        return 1;
  53}
  54
  55
  56struct dtc_file *dtc_open_file(const char *fname,
  57                               const struct search_path *search)
  58{
  59        static const struct search_path default_search = { NULL, NULL, NULL };
  60
  61        struct dtc_file *file;
  62        const char *slash;
  63
  64        file = xmalloc(sizeof(struct dtc_file));
  65
  66        slash = strrchr(fname, '/');
  67        if (slash) {
  68                char *dir = xmalloc(slash - fname + 1);
  69
  70                memcpy(dir, fname, slash - fname);
  71                dir[slash - fname] = 0;
  72                file->dir = dir;
  73        } else {
  74                file->dir = NULL;
  75        }
  76
  77        if (streq(fname, "-")) {
  78                file->name = "stdin";
  79                file->file = stdin;
  80                return file;
  81        }
  82
  83        if (fname[0] == '/') {
  84                file->file = fopen(fname, "r");
  85                if (!file->file)
  86                        goto fail;
  87
  88                file->name = strdup(fname);
  89                return file;
  90        }
  91
  92        if (!search)
  93                search = &default_search;
  94
  95        while (search) {
  96                if (dtc_open_one(file, search->dir, fname))
  97                        return file;
  98
  99                if (errno != ENOENT)
 100                        goto fail;
 101
 102                search = search->next;
 103        }
 104
 105fail:
 106        die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
 107}
 108
 109void dtc_close_file(struct dtc_file *file)
 110{
 111        if (fclose(file->file))
 112                die("Error closing \"%s\": %s\n", file->name, strerror(errno));
 113
 114        free(file->dir);
 115        free(file);
 116}
 117