xref: /linux-6.15/scripts/dtc/util.h (revision 12d638f4)
112869ecdSRob Herring /* SPDX-License-Identifier: GPL-2.0-or-later */
29130ba88SRob Herring #ifndef UTIL_H
39130ba88SRob Herring #define UTIL_H
4658f29a5SJohn Bonesio 
56e9c9686SRob Herring #include <stdlib.h>
6cd296721SStephen Warren #include <stdarg.h>
747605971SRob Herring #include <stdbool.h>
873ab39b1SGrant Likely #include <getopt.h>
9cd296721SStephen Warren 
10658f29a5SJohn Bonesio /*
11cd296721SStephen Warren  * Copyright 2011 The Chromium Authors, All Rights Reserved.
12658f29a5SJohn Bonesio  * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
13658f29a5SJohn Bonesio  */
14658f29a5SJohn Bonesio 
1589d12310SRob Herring #ifdef __GNUC__
16*12d638f4SRob Herring (Arm) #ifdef __MINGW_PRINTF_FORMAT
17*12d638f4SRob Herring (Arm) #define PRINTF(i, j)	__attribute__((format (__MINGW_PRINTF_FORMAT, i, j)))
18*12d638f4SRob Herring (Arm) #elif __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
190cec114eSRob Herring #define PRINTF(i, j)	__attribute__((format (gnu_printf, i, j)))
20a77725a9SRob Herring #else
21a77725a9SRob Herring #define PRINTF(i, j)	__attribute__((format (printf, i, j)))
220cec114eSRob Herring #endif
2389d12310SRob Herring #define NORETURN	__attribute__((noreturn))
2489d12310SRob Herring #else
2589d12310SRob Herring #define PRINTF(i, j)
2689d12310SRob Herring #define NORETURN
2789d12310SRob Herring #endif
2889d12310SRob Herring 
2973ab39b1SGrant Likely #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3073ab39b1SGrant Likely 
319130ba88SRob Herring #define stringify(s)	stringify_(s)
329130ba88SRob Herring #define stringify_(s)	#s
339130ba88SRob Herring 
die(const char * str,...)3489d12310SRob Herring static inline void NORETURN PRINTF(1, 2) die(const char *str, ...)
35658f29a5SJohn Bonesio {
36658f29a5SJohn Bonesio 	va_list ap;
37658f29a5SJohn Bonesio 
38658f29a5SJohn Bonesio 	va_start(ap, str);
39658f29a5SJohn Bonesio 	fprintf(stderr, "FATAL ERROR: ");
40658f29a5SJohn Bonesio 	vfprintf(stderr, str, ap);
4147605971SRob Herring 	va_end(ap);
42658f29a5SJohn Bonesio 	exit(1);
43658f29a5SJohn Bonesio }
44658f29a5SJohn Bonesio 
xmalloc(size_t len)45658f29a5SJohn Bonesio static inline void *xmalloc(size_t len)
46658f29a5SJohn Bonesio {
47658f29a5SJohn Bonesio 	void *new = malloc(len);
48658f29a5SJohn Bonesio 
49658f29a5SJohn Bonesio 	if (!new)
50658f29a5SJohn Bonesio 		die("malloc() failed\n");
51658f29a5SJohn Bonesio 
52658f29a5SJohn Bonesio 	return new;
53658f29a5SJohn Bonesio }
54658f29a5SJohn Bonesio 
xrealloc(void * p,size_t len)55658f29a5SJohn Bonesio static inline void *xrealloc(void *p, size_t len)
56658f29a5SJohn Bonesio {
57658f29a5SJohn Bonesio 	void *new = realloc(p, len);
58658f29a5SJohn Bonesio 
59658f29a5SJohn Bonesio 	if (!new)
6089d12310SRob Herring 		die("realloc() failed (len=%zd)\n", len);
61658f29a5SJohn Bonesio 
62658f29a5SJohn Bonesio 	return new;
63658f29a5SJohn Bonesio }
64658f29a5SJohn Bonesio 
65658f29a5SJohn Bonesio extern char *xstrdup(const char *s);
66ea3723a5SRob Herring extern char *xstrndup(const char *s, size_t len);
6789d12310SRob Herring 
6889d12310SRob Herring extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);
69c2e7075cSRob Herring extern int PRINTF(2, 3) xasprintf_append(char **strp, const char *fmt, ...);
70*12d638f4SRob Herring (Arm) extern int PRINTF(2, 0) xavsprintf_append(char **strp, const char *fmt, va_list ap);
71658f29a5SJohn Bonesio extern char *join_path(const char *path, const char *name);
72658f29a5SJohn Bonesio 
73cd296721SStephen Warren /**
7473ab39b1SGrant Likely  * Check a property of a given length to see if it is all printable and
7573ab39b1SGrant Likely  * has a valid terminator. The property can contain either a single string,
7673ab39b1SGrant Likely  * or multiple strings each of non-zero length.
77cd296721SStephen Warren  *
78cd296721SStephen Warren  * @param data	The string to check
79cd296721SStephen Warren  * @param len	The string length including terminator
8073ab39b1SGrant Likely  * @return 1 if a valid printable string, 0 if not
8173ab39b1SGrant Likely  */
8247605971SRob Herring bool util_is_printable_string(const void *data, int len);
83cd296721SStephen Warren 
84cd296721SStephen Warren /*
85cd296721SStephen Warren  * Parse an escaped character starting at index i in string s.  The resulting
86cd296721SStephen Warren  * character will be returned and the index i will be updated to point at the
87cd296721SStephen Warren  * character directly after the end of the encoding, this may be the '\0'
88cd296721SStephen Warren  * terminator of the string.
89cd296721SStephen Warren  */
90cd296721SStephen Warren char get_escape_char(const char *s, int *i);
91cd296721SStephen Warren 
92cd296721SStephen Warren /**
93cd296721SStephen Warren  * Read a device tree file into a buffer. This will report any errors on
94cd296721SStephen Warren  * stderr.
95cd296721SStephen Warren  *
96cd296721SStephen Warren  * @param filename	The filename to read, or - for stdin
97f858927fSRob Herring  * @param len		If non-NULL, the amount of data we managed to read
98cd296721SStephen Warren  * @return Pointer to allocated buffer containing fdt, or NULL on error
99cd296721SStephen Warren  */
100f858927fSRob Herring char *utilfdt_read(const char *filename, size_t *len);
10173ab39b1SGrant Likely 
10273ab39b1SGrant Likely /**
103cd296721SStephen Warren  * Read a device tree file into a buffer. Does not report errors, but only
104cd296721SStephen Warren  * returns them. The value returned can be passed to strerror() to obtain
105cd296721SStephen Warren  * an error message for the user.
106cd296721SStephen Warren  *
107cd296721SStephen Warren  * @param filename	The filename to read, or - for stdin
108cd296721SStephen Warren  * @param buffp		Returns pointer to buffer containing fdt
109f858927fSRob Herring  * @param len		If non-NULL, the amount of data we managed to read
110cd296721SStephen Warren  * @return 0 if ok, else an errno value representing the error
111cd296721SStephen Warren  */
112f858927fSRob Herring int utilfdt_read_err(const char *filename, char **buffp, size_t *len);
113cd296721SStephen Warren 
114cd296721SStephen Warren /**
115cd296721SStephen Warren  * Write a device tree buffer to a file. This will report any errors on
116cd296721SStephen Warren  * stderr.
117cd296721SStephen Warren  *
118cd296721SStephen Warren  * @param filename	The filename to write, or - for stdout
1199bb9c6a1SRob Herring  * @param blob		Pointer to buffer containing fdt
120cd296721SStephen Warren  * @return 0 if ok, -1 on error
121cd296721SStephen Warren  */
122cd296721SStephen Warren int utilfdt_write(const char *filename, const void *blob);
123cd296721SStephen Warren 
124cd296721SStephen Warren /**
125cd296721SStephen Warren  * Write a device tree buffer to a file. Does not report errors, but only
126cd296721SStephen Warren  * returns them. The value returned can be passed to strerror() to obtain
127cd296721SStephen Warren  * an error message for the user.
128cd296721SStephen Warren  *
129cd296721SStephen Warren  * @param filename	The filename to write, or - for stdout
1309bb9c6a1SRob Herring  * @param blob		Pointer to buffer containing fdt
131cd296721SStephen Warren  * @return 0 if ok, else an errno value representing the error
132cd296721SStephen Warren  */
133cd296721SStephen Warren int utilfdt_write_err(const char *filename, const void *blob);
134cd296721SStephen Warren 
135cd296721SStephen Warren /**
136cd296721SStephen Warren  * Decode a data type string. The purpose of this string
137cd296721SStephen Warren  *
138cd296721SStephen Warren  * The string consists of an optional character followed by the type:
139cd296721SStephen Warren  *	Modifier characters:
140cd296721SStephen Warren  *		hh or b	1 byte
141cd296721SStephen Warren  *		h	2 byte
142cd296721SStephen Warren  *		l	4 byte, default
143cd296721SStephen Warren  *
144cd296721SStephen Warren  *	Type character:
145cd296721SStephen Warren  *		s	string
146cd296721SStephen Warren  *		i	signed integer
147cd296721SStephen Warren  *		u	unsigned integer
148cd296721SStephen Warren  *		x	hex
149ea3723a5SRob Herring  *		r	raw
150cd296721SStephen Warren  *
151cd296721SStephen Warren  * TODO: Implement ll modifier (8 bytes)
152cd296721SStephen Warren  * TODO: Implement o type (octal)
153cd296721SStephen Warren  *
154cd296721SStephen Warren  * @param fmt		Format string to process
155cd296721SStephen Warren  * @param type		Returns type found(s/d/u/x), or 0 if none
156cd296721SStephen Warren  * @param size		Returns size found(1,2,4,8) or 4 if none
157cd296721SStephen Warren  * @return 0 if ok, -1 on error (no type given, or other invalid format)
158cd296721SStephen Warren  */
159cd296721SStephen Warren int utilfdt_decode_type(const char *fmt, int *type, int *size);
160cd296721SStephen Warren 
161cd296721SStephen Warren /*
162cd296721SStephen Warren  * This is a usage message fragment for the -t option. It is the format
163cd296721SStephen Warren  * supported by utilfdt_decode_type.
164cd296721SStephen Warren  */
165cd296721SStephen Warren 
166cd296721SStephen Warren #define USAGE_TYPE_MSG \
167ea3723a5SRob Herring 	"<type>\ts=string, i=int, u=unsigned, x=hex, r=raw\n" \
168cd296721SStephen Warren 	"\tOptional modifier prefix:\n" \
16973ab39b1SGrant Likely 	"\t\thh or b=byte, h=2 byte, l=4 byte (default)";
17073ab39b1SGrant Likely 
17173ab39b1SGrant Likely /**
17273ab39b1SGrant Likely  * Print property data in a readable format to stdout
17373ab39b1SGrant Likely  *
17473ab39b1SGrant Likely  * Properties that look like strings will be printed as strings. Otherwise
17573ab39b1SGrant Likely  * the data will be displayed either as cells (if len is a multiple of 4
17673ab39b1SGrant Likely  * bytes) or bytes.
17773ab39b1SGrant Likely  *
17873ab39b1SGrant Likely  * If len is 0 then this function does nothing.
17973ab39b1SGrant Likely  *
18073ab39b1SGrant Likely  * @param data	Pointers to property data
18173ab39b1SGrant Likely  * @param len	Length of property data
18273ab39b1SGrant Likely  */
18373ab39b1SGrant Likely void utilfdt_print_data(const char *data, int len);
18473ab39b1SGrant Likely 
18573ab39b1SGrant Likely /**
18673ab39b1SGrant Likely  * Show source version and exit
18773ab39b1SGrant Likely  */
18889d12310SRob Herring void NORETURN util_version(void);
18973ab39b1SGrant Likely 
19073ab39b1SGrant Likely /**
19173ab39b1SGrant Likely  * Show usage and exit
19273ab39b1SGrant Likely  *
19373ab39b1SGrant Likely  * This helps standardize the output of various utils.  You most likely want
19473ab39b1SGrant Likely  * to use the usage() helper below rather than call this.
19573ab39b1SGrant Likely  *
19673ab39b1SGrant Likely  * @param errmsg	If non-NULL, an error message to display
19773ab39b1SGrant Likely  * @param synopsis	The initial example usage text (and possible examples)
19873ab39b1SGrant Likely  * @param short_opts	The string of short options
19973ab39b1SGrant Likely  * @param long_opts	The structure of long options
20073ab39b1SGrant Likely  * @param opts_help	An array of help strings (should align with long_opts)
20173ab39b1SGrant Likely  */
20289d12310SRob Herring void NORETURN util_usage(const char *errmsg, const char *synopsis,
20389d12310SRob Herring 			 const char *short_opts,
20489d12310SRob Herring 			 struct option const long_opts[],
20589d12310SRob Herring 			 const char * const opts_help[]);
20673ab39b1SGrant Likely 
20773ab39b1SGrant Likely /**
20873ab39b1SGrant Likely  * Show usage and exit
20973ab39b1SGrant Likely  *
21073ab39b1SGrant Likely  * If you name all your usage variables with usage_xxx, then you can call this
21173ab39b1SGrant Likely  * help macro rather than expanding all arguments yourself.
21273ab39b1SGrant Likely  *
21373ab39b1SGrant Likely  * @param errmsg	If non-NULL, an error message to display
21473ab39b1SGrant Likely  */
21573ab39b1SGrant Likely #define usage(errmsg) \
21673ab39b1SGrant Likely 	util_usage(errmsg, usage_synopsis, usage_short_opts, \
21773ab39b1SGrant Likely 		   usage_long_opts, usage_opts_help)
21873ab39b1SGrant Likely 
21973ab39b1SGrant Likely /**
22073ab39b1SGrant Likely  * Call getopt_long() with standard options
22173ab39b1SGrant Likely  *
22273ab39b1SGrant Likely  * Since all util code runs getopt in the same way, provide a helper.
22373ab39b1SGrant Likely  */
22473ab39b1SGrant Likely #define util_getopt_long() getopt_long(argc, argv, usage_short_opts, \
22573ab39b1SGrant Likely 				       usage_long_opts, NULL)
22673ab39b1SGrant Likely 
22773ab39b1SGrant Likely /* Helper for aligning long_opts array */
22873ab39b1SGrant Likely #define a_argument required_argument
22973ab39b1SGrant Likely 
23073ab39b1SGrant Likely /* Helper for usage_short_opts string constant */
23173ab39b1SGrant Likely #define USAGE_COMMON_SHORT_OPTS "hV"
23273ab39b1SGrant Likely 
23373ab39b1SGrant Likely /* Helper for usage_long_opts option array */
23473ab39b1SGrant Likely #define USAGE_COMMON_LONG_OPTS \
23573ab39b1SGrant Likely 	{"help",      no_argument, NULL, 'h'}, \
23673ab39b1SGrant Likely 	{"version",   no_argument, NULL, 'V'}, \
23773ab39b1SGrant Likely 	{NULL,        no_argument, NULL, 0x0}
23873ab39b1SGrant Likely 
23973ab39b1SGrant Likely /* Helper for usage_opts_help array */
24073ab39b1SGrant Likely #define USAGE_COMMON_OPTS_HELP \
24173ab39b1SGrant Likely 	"Print this help and exit", \
24273ab39b1SGrant Likely 	"Print version and exit", \
24373ab39b1SGrant Likely 	NULL
24473ab39b1SGrant Likely 
24573ab39b1SGrant Likely /* Helper for getopt case statements */
24673ab39b1SGrant Likely #define case_USAGE_COMMON_FLAGS \
24773ab39b1SGrant Likely 	case 'h': usage(NULL); \
24873ab39b1SGrant Likely 	case 'V': util_version(); \
24973ab39b1SGrant Likely 	case '?': usage("unknown option");
250cd296721SStephen Warren 
2519130ba88SRob Herring #endif /* UTIL_H */
252