Rizin
unix-like reverse engineering framework and cli tools
util.h File Reference

Miscellaneous utility functions. More...

Go to the source code of this file.

Macros

#define xmalloc(size)   xrealloc(NULL, size)
 Safe malloc() that never returns NULL. More...
 

Enumerations

enum  nicestr_unit {
  NICESTR_B , NICESTR_KIB , NICESTR_MIB , NICESTR_GIB ,
  NICESTR_TIB
}
 

Functions

void * xrealloc (void *ptr, size_t size) lzma_attribute((__malloc__)) lzma_attr_alloc_size(2)
 Safe realloc() that never returns NULL. More...
 
char * xstrdup (const char *src) lzma_attribute((__malloc__))
 Safe strdup() that never returns NULL. More...
 
uint64_t str_to_uint64 (const char *name, const char *value, uint64_t min, uint64_t max)
 Fancy version of strtoull() More...
 
uint64_t round_up_to_mib (uint64_t n)
 Round an integer up to the next full MiB and convert to MiB. More...
 
const char * uint64_to_str (uint64_t value, uint32_t slot)
 Convert uint64_t to a string. More...
 
const char * uint64_to_nicestr (uint64_t value, enum nicestr_unit unit_min, enum nicestr_unit unit_max, bool always_also_bytes, uint32_t slot)
 Convert uint64_t to a nice human readable string. More...
 
void my_snprintf (char **pos, size_t *left, const char *fmt,...) lzma_attribute((__format__(__printf__
 Wrapper for snprintf() to help constructing a string in pieces. More...
 
void bool is_empty_filename (const char *filename)
 Check if filename is empty and print an error message. More...
 
bool is_tty_stdin (void)
 Test if stdin is a terminal. More...
 
bool is_tty_stdout (void)
 Test if stdout is a terminal. More...
 

Detailed Description

Miscellaneous utility functions.

Definition in file util.h.

Macro Definition Documentation

◆ xmalloc

#define xmalloc (   size)    xrealloc(NULL, size)

Safe malloc() that never returns NULL.

Note
xmalloc(), xrealloc(), and xstrdup() must not be used when there are files open for writing, that should be cleaned up before exiting.

Definition at line 18 of file util.h.

Enumeration Type Documentation

◆ nicestr_unit

Enumerator
NICESTR_B 
NICESTR_KIB 
NICESTR_MIB 
NICESTR_GIB 
NICESTR_TIB 

Definition at line 64 of file util.h.

64  {
65  NICESTR_B,
70 };
@ NICESTR_MIB
Definition: util.h:67
@ NICESTR_KIB
Definition: util.h:66
@ NICESTR_B
Definition: util.h:65
@ NICESTR_TIB
Definition: util.h:69
@ NICESTR_GIB
Definition: util.h:68

Function Documentation

◆ is_empty_filename()

void bool is_empty_filename ( const char *  filename)

Check if filename is empty and print an error message.

Definition at line 264 of file util.c.

265 {
266  if (filename[0] == '\0') {
267  message_error(_("Empty filename, skipping"));
268  return true;
269  }
270 
271  return false;
272 }
const char * filename
Definition: ioapi.h:137
void message_error(const char *fmt,...)
Definition: message.c:764
#define _(String)
Definition: opintl.h:53

References _, and message_error().

Referenced by io_open_src().

◆ is_tty_stdin()

bool is_tty_stdin ( void  )

Test if stdin is a terminal.

If stdin is a terminal, an error message is printed and exit status set to EXIT_ERROR.

Definition at line 276 of file util.c.

277 {
278  const bool ret = isatty(STDIN_FILENO);
279 
280  if (ret)
281  message_error(_("Compressed data cannot be read from "
282  "a terminal"));
283 
284  return ret;
285 }
#define STDIN_FILENO
Definition: private.h:37

References _, message_error(), and STDIN_FILENO.

Referenced by main().

◆ is_tty_stdout()

bool is_tty_stdout ( void  )

Test if stdout is a terminal.

If stdout is a terminal, an error message is printed and exit status set to EXIT_ERROR.

Definition at line 289 of file util.c.

290 {
291  const bool ret = isatty(STDOUT_FILENO);
292 
293  if (ret)
294  message_error(_("Compressed data cannot be written to "
295  "a terminal"));
296 
297  return ret;
298 }
#define STDOUT_FILENO
Definition: private.h:41

References _, message_error(), and STDOUT_FILENO.

Referenced by main().

◆ my_snprintf()

void my_snprintf ( char **  pos,
size_t left,
const char *  fmt,
  ... 
)

Wrapper for snprintf() to help constructing a string in pieces.

A maximum of *left bytes is written starting from *pos. *pos and *left are updated accordingly.

◆ round_up_to_mib()

uint64_t round_up_to_mib ( uint64_t  n)

Round an integer up to the next full MiB and convert to MiB.

This is used when printing memory usage and limit.

Definition at line 139 of file util.c.

140 {
141  return (n >> 20) + ((n & ((UINT32_C(1) << 20) - 1)) != 0);
142 }
int n
Definition: mipsasm.c:19
#define UINT32_C(val)

References n, and UINT32_C.

Referenced by coder_init(), memlimit_show(), message_mem_needed(), print_info_adv(), and print_totals_adv().

◆ str_to_uint64()

uint64_t str_to_uint64 ( const char *  name,
const char *  value,
uint64_t  min,
uint64_t  max 
)

Fancy version of strtoull()

Parameters
nameName of the option to show in case of an error
valueString containing the number to be parsed; may contain suffixes "k", "M", "G", "Ki", "Mi", or "Gi"
minMinimum valid value
maxMaximum valid value
Returns
Parsed value that is in the range [min, max]. Does not return if an error occurs.

Definition at line 58 of file util.c.

59 {
60  uint64_t result = 0;
61 
62  // Skip blanks.
63  while (*value == ' ' || *value == '\t')
64  ++value;
65 
66  // Accept special value "max". Supporting "min" doesn't seem useful.
67  if (strcmp(value, "max") == 0)
68  return max;
69 
70  if (*value < '0' || *value > '9')
71  message_fatal(_("%s: Value is not a non-negative "
72  "decimal integer"), value);
73 
74  do {
75  // Don't overflow.
76  if (result > UINT64_MAX / 10)
77  goto error;
78 
79  result *= 10;
80 
81  // Another overflow check
82  const uint32_t add = (uint32_t)(*value - '0');
83  if (UINT64_MAX - add < result)
84  goto error;
85 
86  result += add;
87  ++value;
88  } while (*value >= '0' && *value <= '9');
89 
90  if (*value != '\0') {
91  // Look for suffix. Originally this supported both base-2
92  // and base-10, but since there seems to be little need
93  // for base-10 in this program, treat everything as base-2
94  // and also be more relaxed about the case of the first
95  // letter of the suffix.
96  uint64_t multiplier = 0;
97  if (*value == 'k' || *value == 'K')
98  multiplier = UINT64_C(1) << 10;
99  else if (*value == 'm' || *value == 'M')
100  multiplier = UINT64_C(1) << 20;
101  else if (*value == 'g' || *value == 'G')
102  multiplier = UINT64_C(1) << 30;
103 
104  ++value;
105 
106  // Allow also e.g. Ki, KiB, and KB.
107  if (*value != '\0' && strcmp(value, "i") != 0
108  && strcmp(value, "iB") != 0
109  && strcmp(value, "B") != 0)
110  multiplier = 0;
111 
112  if (multiplier == 0) {
113  message(V_ERROR, _("%s: Invalid multiplier suffix"),
114  value - 1);
115  message_fatal(_("Valid suffixes are `KiB' (2^10), "
116  "`MiB' (2^20), and `GiB' (2^30)."));
117  }
118 
119  // Don't overflow here either.
120  if (result > UINT64_MAX / multiplier)
121  goto error;
122 
123  result *= multiplier;
124  }
125 
126  if (result < min || result > max)
127  goto error;
128 
129  return result;
130 
131 error:
132  message_fatal(_("Value of the option `%s' must be in the range "
133  "[%" PRIu64 ", %" PRIu64 "]"),
134  name, min, max);
135 }
static int value
Definition: cmd_api.c:93
int max
Definition: enough.c:225
#define PRIu64
Definition: macros.h:18
void message_fatal(const char *fmt,...)
Definition: message.c:777
@ V_ERROR
Only error messages.
Definition: message.h:16
#define min(a, b)
Definition: qsort.h:83
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
#define UINT64_MAX
#define UINT64_C(val)
Definition: z80asm.h:102
char * message
Definition: main.c:12
void error(const char *msg)
Definition: untgz.c:593
static int add(char *argv[])
Definition: ziptool.c:84

References _, add(), error(), max, message, message_fatal(), min, PRIu64, UINT64_C, UINT64_MAX, V_ERROR, and value.

Referenced by parse_block_list(), parse_memlimit(), parse_options(), and parse_real().

◆ uint64_to_nicestr()

const char* uint64_to_nicestr ( uint64_t  value,
enum nicestr_unit  unit_min,
enum nicestr_unit  unit_max,
bool  always_also_bytes,
uint32_t  slot 
)

Convert uint64_t to a nice human readable string.

This is like uint64_to_str() but uses B, KiB, MiB, GiB, or TiB suffix and optionally includes the exact size in parenthesis.

Parameters
valueValue to be printed
unit_minSmallest unit to use. This and unit_max are used e.g. when showing the progress indicator to force the unit to MiB.
unit_maxBiggest unit to use. assert(unit_min <= unit_max).
always_also_bytesShow also the exact byte value in parenthesis if the nicely formatted string uses bigger unit than bytes.
slotWhich static buffer to use to hold the string. This is shared with uint64_to_str().
Returns
Pointer to statically allocated buffer containing the string.
Note
This uses double_to_str() internally so the static buffer in double_to_str() will be overwritten.

Definition at line 187 of file util.c.

190 {
191  assert(unit_min <= unit_max);
192  assert(unit_max <= NICESTR_TIB);
193  assert(slot < ARRAY_SIZE(bufs));
194 
195  check_thousand_sep(slot);
196 
197  enum nicestr_unit unit = NICESTR_B;
198  char *pos = bufs[slot];
199  size_t left = sizeof(bufs[slot]);
200 
201  if ((unit_min == NICESTR_B && value < 10000)
202  || unit_max == NICESTR_B) {
203  // The value is shown as bytes.
204  if (thousand == WORKS)
205  my_snprintf(&pos, &left, "%'u", (unsigned int)value);
206  else
207  my_snprintf(&pos, &left, "%u", (unsigned int)value);
208  } else {
209  // Scale the value to a nicer unit. Unless unit_min and
210  // unit_max limit us, we will show at most five significant
211  // digits with one decimal place.
212  double d = (double)(value);
213  do {
214  d /= 1024.0;
215  ++unit;
216  } while (unit < unit_min || (d > 9999.9 && unit < unit_max));
217 
218  if (thousand == WORKS)
219  my_snprintf(&pos, &left, "%'.1f", d);
220  else
221  my_snprintf(&pos, &left, "%.1f", d);
222  }
223 
224  static const char suffix[5][4] = { "B", "KiB", "MiB", "GiB", "TiB" };
225  my_snprintf(&pos, &left, " %s", suffix[unit]);
226 
227  if (always_also_bytes && value >= 10000) {
228  if (thousand == WORKS)
229  snprintf(pos, left, " (%'" PRIu64 " B)", value);
230  else
231  snprintf(pos, left, " (%" PRIu64 " B)", value);
232  }
233 
234  return bufs[slot];
235 }
#define ARRAY_SIZE(a)
unsigned char suffix[65536]
Definition: gun.c:164
snprintf
Definition: kernel.h:364
assert(limit<=UINT32_MAX/2)
#define d(i)
Definition: sha256.c:44
int pos
Definition: main.c:11
static enum @663 thousand
Thousand separator support in uint64_to_str() and uint64_to_nicestr()
@ WORKS
Definition: util.c:21
void my_snprintf(char **pos, size_t *left, const char *fmt,...)
Definition: util.c:239
static char bufs[4][128]
Buffers for uint64_to_str() and uint64_to_nicestr()
Definition: util.c:18
static void check_thousand_sep(uint32_t slot)
Definition: util.c:156
nicestr_unit
Definition: util.h:64

References ARRAY_SIZE, assert(), bufs, check_thousand_sep(), d, my_snprintf(), NICESTR_B, NICESTR_TIB, pos, PRIu64, snprintf, suffix, thousand, value, and WORKS.

Referenced by print_adv_helper(), print_info_basic(), print_totals_basic(), and progress_sizes().

◆ uint64_to_str()

const char* uint64_to_str ( uint64_t  value,
uint32_t  slot 
)

Convert uint64_t to a string.

Convert the given value to a string with locale-specific thousand separators, if supported by the snprintf() implementation. The string is stored into an internal static buffer indicated by the slot argument. A pointer to the selected buffer is returned.

This function exists, because non-POSIX systems don't support thousand separator in format strings. Solving the problem in a simple way doesn't work, because it breaks gettext (specifically, the xgettext tool).

Definition at line 171 of file util.c.

172 {
173  assert(slot < ARRAY_SIZE(bufs));
174 
175  check_thousand_sep(slot);
176 
177  if (thousand == WORKS)
178  snprintf(bufs[slot], sizeof(bufs[slot]), "%'" PRIu64, value);
179  else
180  snprintf(bufs[slot], sizeof(bufs[slot]), "%" PRIu64, value);
181 
182  return bufs[slot];
183 }

References ARRAY_SIZE, assert(), bufs, check_thousand_sep(), PRIu64, snprintf, thousand, value, and WORKS.

Referenced by coder_init(), memlimit_show(), message_mem_needed(), print_adv_helper(), print_info_adv(), print_info_basic(), print_totals_adv(), and print_totals_basic().

◆ xrealloc()

void* xrealloc ( void *  ptr,
size_t  size 
)

Safe realloc() that never returns NULL.

Definition at line 25 of file util.c.

26 {
27  assert(size > 0);
28 
29  // Save ptr so that we can free it if realloc fails.
30  // The point is that message_fatal ends up calling stdio functions
31  // which in some libc implementations might allocate memory from
32  // the heap. Freeing ptr improves the chances that there's free
33  // memory for stdio functions if they need it.
34  void *p = ptr;
35  ptr = realloc(ptr, size);
36 
37  if (ptr == NULL) {
38  const int saved_errno = errno;
39  free(p);
40  message_fatal("%s", strerror(saved_errno));
41  }
42 
43  return ptr;
44 }
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
void * p
Definition: libc.cpp:67
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144

◆ xstrdup()

char* xstrdup ( const char *  src)

Safe strdup() that never returns NULL.

Definition at line 48 of file util.c.

49 {
50  assert(src != NULL);
51  const size_t size = strlen(src) + 1;
52  char *dest = xmalloc(size);
53  return memcpy(dest, src, size);
54 }
lzma_index * src
Definition: index.h:567
#define xmalloc
Definition: disas-asm.h:43
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
char * dest
Definition: lz4.h:697