Home | History | Annotate | Download | only in dtc
      1 #ifndef _UTIL_H
      2 #define _UTIL_H
      3 
      4 #include <stdarg.h>
      5 #include <stdbool.h>
      6 #include <getopt.h>
      7 
      8 /*
      9  * Copyright 2011 The Chromium Authors, All Rights Reserved.
     10  * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
     11  *
     12  * This program is free software; you can redistribute it and/or
     13  * modify it under the terms of the GNU General Public License as
     14  * published by the Free Software Foundation; either version 2 of the
     15  * License, or (at your option) any later version.
     16  *
     17  *  This program is distributed in the hope that it will be useful,
     18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     20  *  General Public License for more details.
     21  *
     22  *  You should have received a copy of the GNU General Public License
     23  *  along with this program; if not, write to the Free Software
     24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
     25  *                                                                   USA
     26  */
     27 
     28 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
     29 
     30 static inline void __attribute__((noreturn)) die(const char *str, ...)
     31 {
     32 	va_list ap;
     33 
     34 	va_start(ap, str);
     35 	fprintf(stderr, "FATAL ERROR: ");
     36 	vfprintf(stderr, str, ap);
     37 	va_end(ap);
     38 	exit(1);
     39 }
     40 
     41 static inline void *xmalloc(size_t len)
     42 {
     43 	void *new = malloc(len);
     44 
     45 	if (!new)
     46 		die("malloc() failed\n");
     47 
     48 	return new;
     49 }
     50 
     51 static inline void *xrealloc(void *p, size_t len)
     52 {
     53 	void *new = realloc(p, len);
     54 
     55 	if (!new)
     56 		die("realloc() failed (len=%d)\n", len);
     57 
     58 	return new;
     59 }
     60 
     61 extern char *xstrdup(const char *s);
     62 extern int xasprintf(char **strp, const char *fmt, ...);
     63 extern char *join_path(const char *path, const char *name);
     64 
     65 /**
     66  * Check a property of a given length to see if it is all printable and
     67  * has a valid terminator. The property can contain either a single string,
     68  * or multiple strings each of non-zero length.
     69  *
     70  * @param data	The string to check
     71  * @param len	The string length including terminator
     72  * @return 1 if a valid printable string, 0 if not
     73  */
     74 bool util_is_printable_string(const void *data, int len);
     75 
     76 /*
     77  * Parse an escaped character starting at index i in string s.  The resulting
     78  * character will be returned and the index i will be updated to point at the
     79  * character directly after the end of the encoding, this may be the '\0'
     80  * terminator of the string.
     81  */
     82 char get_escape_char(const char *s, int *i);
     83 
     84 /**
     85  * Read a device tree file into a buffer. This will report any errors on
     86  * stderr.
     87  *
     88  * @param filename	The filename to read, or - for stdin
     89  * @return Pointer to allocated buffer containing fdt, or NULL on error
     90  */
     91 char *utilfdt_read(const char *filename);
     92 
     93 /**
     94  * Like utilfdt_read(), but also passes back the size of the file read.
     95  *
     96  * @param len		If non-NULL, the amount of data we managed to read
     97  */
     98 char *utilfdt_read_len(const char *filename, off_t *len);
     99 
    100 /**
    101  * Read a device tree file into a buffer. Does not report errors, but only
    102  * returns them. The value returned can be passed to strerror() to obtain
    103  * an error message for the user.
    104  *
    105  * @param filename	The filename to read, or - for stdin
    106  * @param buffp		Returns pointer to buffer containing fdt
    107  * @return 0 if ok, else an errno value representing the error
    108  */
    109 int utilfdt_read_err(const char *filename, char **buffp);
    110 
    111 /**
    112  * Like utilfdt_read_err(), but also passes back the size of the file read.
    113  *
    114  * @param len		If non-NULL, the amount of data we managed to read
    115  */
    116 int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len);
    117 
    118 /**
    119  * Write a device tree buffer to a file. This will report any errors on
    120  * stderr.
    121  *
    122  * @param filename	The filename to write, or - for stdout
    123  * @param blob		Poiner to buffer containing fdt
    124  * @return 0 if ok, -1 on error
    125  */
    126 int utilfdt_write(const char *filename, const void *blob);
    127 
    128 /**
    129  * Write a device tree buffer to a file. Does not report errors, but only
    130  * returns them. The value returned can be passed to strerror() to obtain
    131  * an error message for the user.
    132  *
    133  * @param filename	The filename to write, or - for stdout
    134  * @param blob		Poiner to buffer containing fdt
    135  * @return 0 if ok, else an errno value representing the error
    136  */
    137 int utilfdt_write_err(const char *filename, const void *blob);
    138 
    139 /**
    140  * Decode a data type string. The purpose of this string
    141  *
    142  * The string consists of an optional character followed by the type:
    143  *	Modifier characters:
    144  *		hh or b	1 byte
    145  *		h	2 byte
    146  *		l	4 byte, default
    147  *
    148  *	Type character:
    149  *		s	string
    150  *		i	signed integer
    151  *		u	unsigned integer
    152  *		x	hex
    153  *
    154  * TODO: Implement ll modifier (8 bytes)
    155  * TODO: Implement o type (octal)
    156  *
    157  * @param fmt		Format string to process
    158  * @param type		Returns type found(s/d/u/x), or 0 if none
    159  * @param size		Returns size found(1,2,4,8) or 4 if none
    160  * @return 0 if ok, -1 on error (no type given, or other invalid format)
    161  */
    162 int utilfdt_decode_type(const char *fmt, int *type, int *size);
    163 
    164 /*
    165  * This is a usage message fragment for the -t option. It is the format
    166  * supported by utilfdt_decode_type.
    167  */
    168 
    169 #define USAGE_TYPE_MSG \
    170 	"<type>\ts=string, i=int, u=unsigned, x=hex\n" \
    171 	"\tOptional modifier prefix:\n" \
    172 	"\t\thh or b=byte, h=2 byte, l=4 byte (default)";
    173 
    174 /**
    175  * Print property data in a readable format to stdout
    176  *
    177  * Properties that look like strings will be printed as strings. Otherwise
    178  * the data will be displayed either as cells (if len is a multiple of 4
    179  * bytes) or bytes.
    180  *
    181  * If len is 0 then this function does nothing.
    182  *
    183  * @param data	Pointers to property data
    184  * @param len	Length of property data
    185  */
    186 void utilfdt_print_data(const char *data, int len);
    187 
    188 /**
    189  * Show source version and exit
    190  */
    191 void util_version(void) __attribute__((noreturn));
    192 
    193 /**
    194  * Show usage and exit
    195  *
    196  * This helps standardize the output of various utils.  You most likely want
    197  * to use the usage() helper below rather than call this.
    198  *
    199  * @param errmsg	If non-NULL, an error message to display
    200  * @param synopsis	The initial example usage text (and possible examples)
    201  * @param short_opts	The string of short options
    202  * @param long_opts	The structure of long options
    203  * @param opts_help	An array of help strings (should align with long_opts)
    204  */
    205 void util_usage(const char *errmsg, const char *synopsis,
    206 		const char *short_opts, struct option const long_opts[],
    207 		const char * const opts_help[]) __attribute__((noreturn));
    208 
    209 /**
    210  * Show usage and exit
    211  *
    212  * If you name all your usage variables with usage_xxx, then you can call this
    213  * help macro rather than expanding all arguments yourself.
    214  *
    215  * @param errmsg	If non-NULL, an error message to display
    216  */
    217 #define usage(errmsg) \
    218 	util_usage(errmsg, usage_synopsis, usage_short_opts, \
    219 		   usage_long_opts, usage_opts_help)
    220 
    221 /**
    222  * Call getopt_long() with standard options
    223  *
    224  * Since all util code runs getopt in the same way, provide a helper.
    225  */
    226 #define util_getopt_long() getopt_long(argc, argv, usage_short_opts, \
    227 				       usage_long_opts, NULL)
    228 
    229 /* Helper for aligning long_opts array */
    230 #define a_argument required_argument
    231 
    232 /* Helper for usage_short_opts string constant */
    233 #define USAGE_COMMON_SHORT_OPTS "hV"
    234 
    235 /* Helper for usage_long_opts option array */
    236 #define USAGE_COMMON_LONG_OPTS \
    237 	{"help",      no_argument, NULL, 'h'}, \
    238 	{"version",   no_argument, NULL, 'V'}, \
    239 	{NULL,        no_argument, NULL, 0x0}
    240 
    241 /* Helper for usage_opts_help array */
    242 #define USAGE_COMMON_OPTS_HELP \
    243 	"Print this help and exit", \
    244 	"Print version and exit", \
    245 	NULL
    246 
    247 /* Helper for getopt case statements */
    248 #define case_USAGE_COMMON_FLAGS \
    249 	case 'h': usage(NULL); \
    250 	case 'V': util_version(); \
    251 	case '?': usage("unknown option");
    252 
    253 #endif /* _UTIL_H */
    254