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