1204433Sraj#ifndef _UTIL_H 2204433Sraj#define _UTIL_H 3204433Sraj 4238742Simp#include <stdarg.h> 5261215Simp#include <stdbool.h> 6261215Simp#include <getopt.h> 7238742Simp 8204433Sraj/* 9238742Simp * Copyright 2011 The Chromium Authors, All Rights Reserved. 10204433Sraj * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. 11204433Sraj * 12204433Sraj * This program is free software; you can redistribute it and/or 13204433Sraj * modify it under the terms of the GNU General Public License as 14204433Sraj * published by the Free Software Foundation; either version 2 of the 15204433Sraj * License, or (at your option) any later version. 16204433Sraj * 17204433Sraj * This program is distributed in the hope that it will be useful, 18204433Sraj * but WITHOUT ANY WARRANTY; without even the implied warranty of 19204433Sraj * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20204433Sraj * General Public License for more details. 21204433Sraj * 22204433Sraj * You should have received a copy of the GNU General Public License 23204433Sraj * along with this program; if not, write to the Free Software 24204433Sraj * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 25204433Sraj * USA 26204433Sraj */ 27204433Sraj 28261215Simp#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 29261215Simp 30318102Sgonzo#ifdef __GNUC__ 31318102Sgonzostatic inline void 32318102Sgonzo__attribute__((noreturn)) __attribute__((format (printf, 1, 2))) 33318102Sgonzodie(const char *str, ...) 34318102Sgonzo#else 35318102Sgonzostatic inline void die(const char *str, ...) 36318102Sgonzo#endif 37204433Sraj{ 38204433Sraj va_list ap; 39204433Sraj 40204433Sraj va_start(ap, str); 41204433Sraj fprintf(stderr, "FATAL ERROR: "); 42204433Sraj vfprintf(stderr, str, ap); 43318102Sgonzo va_end(ap); 44204433Sraj exit(1); 45204433Sraj} 46204433Sraj 47204433Srajstatic inline void *xmalloc(size_t len) 48204433Sraj{ 49204433Sraj void *new = malloc(len); 50204433Sraj 51204433Sraj if (!new) 52204433Sraj die("malloc() failed\n"); 53204433Sraj 54204433Sraj return new; 55204433Sraj} 56204433Sraj 57204433Srajstatic inline void *xrealloc(void *p, size_t len) 58204433Sraj{ 59204433Sraj void *new = realloc(p, len); 60204433Sraj 61204433Sraj if (!new) 62318102Sgonzo die("realloc() failed (len=%zd)\n", len); 63204433Sraj 64204433Sraj return new; 65204433Sraj} 66204433Sraj 67204433Srajextern char *xstrdup(const char *s); 68318102Sgonzo 69318102Sgonzo#ifdef __GNUC__ 70318102Sgonzoextern int __attribute__((format (printf, 2, 3))) 71318102Sgonzoxasprintf(char **strp, const char *fmt, ...); 72318102Sgonzo#else 73318102Sgonzoextern int xasprintf(char **strp, const char *fmt, ...); 74318102Sgonzo#endif 75238742Simpextern char *join_path(const char *path, const char *name); 76204433Sraj 77238742Simp/** 78261215Simp * Check a property of a given length to see if it is all printable and 79261215Simp * has a valid terminator. The property can contain either a single string, 80261215Simp * or multiple strings each of non-zero length. 81238742Simp * 82238742Simp * @param data The string to check 83238742Simp * @param len The string length including terminator 84261215Simp * @return 1 if a valid printable string, 0 if not 85261215Simp */ 86261215Simpbool util_is_printable_string(const void *data, int len); 87238742Simp 88238742Simp/* 89238742Simp * Parse an escaped character starting at index i in string s. The resulting 90238742Simp * character will be returned and the index i will be updated to point at the 91238742Simp * character directly after the end of the encoding, this may be the '\0' 92238742Simp * terminator of the string. 93238742Simp */ 94238742Simpchar get_escape_char(const char *s, int *i); 95238742Simp 96238742Simp/** 97238742Simp * Read a device tree file into a buffer. This will report any errors on 98238742Simp * stderr. 99238742Simp * 100238742Simp * @param filename The filename to read, or - for stdin 101238742Simp * @return Pointer to allocated buffer containing fdt, or NULL on error 102238742Simp */ 103238742Simpchar *utilfdt_read(const char *filename); 104238742Simp 105238742Simp/** 106261215Simp * Like utilfdt_read(), but also passes back the size of the file read. 107261215Simp * 108261215Simp * @param len If non-NULL, the amount of data we managed to read 109261215Simp */ 110261215Simpchar *utilfdt_read_len(const char *filename, off_t *len); 111261215Simp 112261215Simp/** 113238742Simp * Read a device tree file into a buffer. Does not report errors, but only 114238742Simp * returns them. The value returned can be passed to strerror() to obtain 115238742Simp * an error message for the user. 116238742Simp * 117238742Simp * @param filename The filename to read, or - for stdin 118238742Simp * @param buffp Returns pointer to buffer containing fdt 119238742Simp * @return 0 if ok, else an errno value representing the error 120238742Simp */ 121238742Simpint utilfdt_read_err(const char *filename, char **buffp); 122238742Simp 123261215Simp/** 124261215Simp * Like utilfdt_read_err(), but also passes back the size of the file read. 125261215Simp * 126261215Simp * @param len If non-NULL, the amount of data we managed to read 127261215Simp */ 128261215Simpint utilfdt_read_err_len(const char *filename, char **buffp, off_t *len); 129238742Simp 130238742Simp/** 131238742Simp * Write a device tree buffer to a file. This will report any errors on 132238742Simp * stderr. 133238742Simp * 134238742Simp * @param filename The filename to write, or - for stdout 135238742Simp * @param blob Poiner to buffer containing fdt 136238742Simp * @return 0 if ok, -1 on error 137238742Simp */ 138238742Simpint utilfdt_write(const char *filename, const void *blob); 139238742Simp 140238742Simp/** 141238742Simp * Write a device tree buffer to a file. Does not report errors, but only 142238742Simp * returns them. The value returned can be passed to strerror() to obtain 143238742Simp * an error message for the user. 144238742Simp * 145238742Simp * @param filename The filename to write, or - for stdout 146238742Simp * @param blob Poiner to buffer containing fdt 147238742Simp * @return 0 if ok, else an errno value representing the error 148238742Simp */ 149238742Simpint utilfdt_write_err(const char *filename, const void *blob); 150238742Simp 151238742Simp/** 152238742Simp * Decode a data type string. The purpose of this string 153238742Simp * 154238742Simp * The string consists of an optional character followed by the type: 155238742Simp * Modifier characters: 156238742Simp * hh or b 1 byte 157238742Simp * h 2 byte 158238742Simp * l 4 byte, default 159238742Simp * 160238742Simp * Type character: 161238742Simp * s string 162238742Simp * i signed integer 163238742Simp * u unsigned integer 164238742Simp * x hex 165238742Simp * 166238742Simp * TODO: Implement ll modifier (8 bytes) 167238742Simp * TODO: Implement o type (octal) 168238742Simp * 169238742Simp * @param fmt Format string to process 170238742Simp * @param type Returns type found(s/d/u/x), or 0 if none 171238742Simp * @param size Returns size found(1,2,4,8) or 4 if none 172238742Simp * @return 0 if ok, -1 on error (no type given, or other invalid format) 173238742Simp */ 174238742Simpint utilfdt_decode_type(const char *fmt, int *type, int *size); 175238742Simp 176238742Simp/* 177238742Simp * This is a usage message fragment for the -t option. It is the format 178238742Simp * supported by utilfdt_decode_type. 179238742Simp */ 180238742Simp 181238742Simp#define USAGE_TYPE_MSG \ 182238742Simp "<type>\ts=string, i=int, u=unsigned, x=hex\n" \ 183238742Simp "\tOptional modifier prefix:\n" \ 184261215Simp "\t\thh or b=byte, h=2 byte, l=4 byte (default)"; 185238742Simp 186261215Simp/** 187261215Simp * Print property data in a readable format to stdout 188261215Simp * 189261215Simp * Properties that look like strings will be printed as strings. Otherwise 190261215Simp * the data will be displayed either as cells (if len is a multiple of 4 191261215Simp * bytes) or bytes. 192261215Simp * 193261215Simp * If len is 0 then this function does nothing. 194261215Simp * 195261215Simp * @param data Pointers to property data 196261215Simp * @param len Length of property data 197261215Simp */ 198261215Simpvoid utilfdt_print_data(const char *data, int len); 199261215Simp 200261215Simp/** 201261215Simp * Show source version and exit 202261215Simp */ 203261215Simpvoid util_version(void) __attribute__((noreturn)); 204261215Simp 205261215Simp/** 206261215Simp * Show usage and exit 207261215Simp * 208261215Simp * This helps standardize the output of various utils. You most likely want 209261215Simp * to use the usage() helper below rather than call this. 210261215Simp * 211261215Simp * @param errmsg If non-NULL, an error message to display 212261215Simp * @param synopsis The initial example usage text (and possible examples) 213261215Simp * @param short_opts The string of short options 214261215Simp * @param long_opts The structure of long options 215261215Simp * @param opts_help An array of help strings (should align with long_opts) 216261215Simp */ 217261215Simpvoid util_usage(const char *errmsg, const char *synopsis, 218261215Simp const char *short_opts, struct option const long_opts[], 219261215Simp const char * const opts_help[]) __attribute__((noreturn)); 220261215Simp 221261215Simp/** 222261215Simp * Show usage and exit 223261215Simp * 224261215Simp * If you name all your usage variables with usage_xxx, then you can call this 225261215Simp * help macro rather than expanding all arguments yourself. 226261215Simp * 227261215Simp * @param errmsg If non-NULL, an error message to display 228261215Simp */ 229261215Simp#define usage(errmsg) \ 230261215Simp util_usage(errmsg, usage_synopsis, usage_short_opts, \ 231261215Simp usage_long_opts, usage_opts_help) 232261215Simp 233261215Simp/** 234261215Simp * Call getopt_long() with standard options 235261215Simp * 236261215Simp * Since all util code runs getopt in the same way, provide a helper. 237261215Simp */ 238261215Simp#define util_getopt_long() getopt_long(argc, argv, usage_short_opts, \ 239261215Simp usage_long_opts, NULL) 240261215Simp 241261215Simp/* Helper for aligning long_opts array */ 242261215Simp#define a_argument required_argument 243261215Simp 244261215Simp/* Helper for usage_short_opts string constant */ 245261215Simp#define USAGE_COMMON_SHORT_OPTS "hV" 246261215Simp 247261215Simp/* Helper for usage_long_opts option array */ 248261215Simp#define USAGE_COMMON_LONG_OPTS \ 249261215Simp {"help", no_argument, NULL, 'h'}, \ 250261215Simp {"version", no_argument, NULL, 'V'}, \ 251261215Simp {NULL, no_argument, NULL, 0x0} 252261215Simp 253261215Simp/* Helper for usage_opts_help array */ 254261215Simp#define USAGE_COMMON_OPTS_HELP \ 255261215Simp "Print this help and exit", \ 256261215Simp "Print version and exit", \ 257261215Simp NULL 258261215Simp 259261215Simp/* Helper for getopt case statements */ 260261215Simp#define case_USAGE_COMMON_FLAGS \ 261261215Simp case 'h': usage(NULL); \ 262261215Simp case 'V': util_version(); \ 263261215Simp case '?': usage("unknown option"); 264261215Simp 265204433Sraj#endif /* _UTIL_H */ 266