master xplshn/aruu / shared / libtcutil / tcutil.h
  1/* toolchain utility library: memory, paths, containers, option parsing */
  2
  3#ifndef ARUU_TCUTIL_H
  4#define ARUU_TCUTIL_H
  5
  6#include <stddef.h>    /* size_t */
  7#include <stdint.h>    /* intptr_t */
  8#include <stdio.h>     /* FILE */
  9#include <sys/types.h> /* ssize_t */
 10
 11/* macros also defined by shared/util.h, undef to avoid redefinition warning */
 12#undef MIN
 13#undef MAX
 14#undef ALIGN
 15
 16#define MIN(a, b)        ((a) < (b) ? (a) : (b))
 17#define MAX(a, b)        ((a) > (b) ? (a) : (b))
 18#define ALIGN(x, align)  (((x) + (align) - 1) & -(align)) /* align must be power of 2 */
 19#define UNUSED(x)        ((void)(x))
 20#define IS_POWER_OF_2(x) ((x) > 0 && ((x) & ((x) - 1)) == 0)
 21#define INT2VOIDP(i)     ((void *)(intptr_t)(i))
 22#define UINT2VOIDP(i)    ((void *)(uintptr_t)(i))
 23#define VOIDP2INT(p)     ((intptr_t)(p))
 24#define VOIDP2UINT(p)    ((uintptr_t)(p))
 25#define ARRAY_SIZE(a)    (sizeof(a) / sizeof(*(a)))
 26
 27struct Name;
 28
 29/* character classification */
 30int isalnum_(int c);
 31int isutf8first(int c);
 32int isutf8follow(int c);
 33int isoctal(int c);
 34int xvalue(char c);
 35
 36/* string and path helpers */
 37int         starts_with(const char *str, const char *prefix);
 38int         is_fullpath(const char *filename);
 39char       *join_paths(const char *paths[]);
 40char       *get_ext(const char *filename);
 41char       *change_ext(const char *path, const char *ext);
 42const char *skip_whitespaces(const char *s);
 43const char *block_comment_start(const char *p);
 44const char *block_comment_end(const char *p);
 45
 46/* file I/O helpers */
 47void   *read_or_die(FILE *fp, void *buf, long offset, size_t size, const char *msg);
 48void    put_padding(FILE *fp, long start);
 49int     is_file(const char *path);
 50ssize_t getline_chomp(char **lineptr, size_t *n, FILE *stream);
 51ssize_t getline_cont(char **lineptr, size_t *n, FILE *stream, int *plineno);
 52
 53/* memory: toolchain-local, same contract as aruu emalloc/ecalloc/erealloc
 54 * kept separate so the toolchain can build standalone without libutil */
 55void *malloc_or_die(size_t size);
 56void *calloc_or_die(size_t size);
 57void *realloc_or_die(void *ptr, size_t size);
 58
 59/* diagnostics */
 60void           show_version(const char *exe, int arch);
 61_Noreturn void error(const char *fmt, ...);
 62void           show_error_line(const char *line, const char *p, int len);
 63
 64/* value range checks for immediate operands */
 65int     is_im8(int64_t x);
 66int     is_im16(int64_t x);
 67int     is_im32(int64_t x);
 68int64_t wrap_value(int64_t value, int size, int is_unsigned);
 69int     most_significant_bit(size_t x);
 70
 71/* name interning (see table.h for struct name) */
 72const struct Name *alloc_label(void);
 73
 74/* container: growable pointer vector */
 75struct Vector {
 76  void **data;
 77  int    capacity;
 78  int    len;
 79};
 80
 81struct Vector *new_vector(void);
 82void           free_vector(struct Vector *vec);
 83void           vec_init(struct Vector *vec);
 84void           vec_clear(struct Vector *vec);
 85void           vec_push(struct Vector *vec, const void *elem);
 86void          *vec_pop(struct Vector *vec);
 87void           vec_insert(struct Vector *vec, int pos, const void *elem);
 88void           vec_remove_at(struct Vector *vec, int index);
 89int            vec_contains(struct Vector *vec, void *elem);
 90void           vec_concat(struct Vector *dst, const struct Vector *src);
 91
 92/* container: growable byte buffer */
 93struct DataStorage {
 94  struct Vector *chunk_stack;
 95  unsigned char *buf;
 96  size_t         capacity;
 97  size_t         len;
 98};
 99
100void data_release(struct DataStorage *data);
101void data_init(struct DataStorage *data);
102void data_reserve(struct DataStorage *data, size_t capacity);
103void data_insert(struct DataStorage *data, ssize_t pos, const void *buf, size_t size);
104void data_append(struct DataStorage *data, const void *buf, size_t size);
105void data_push(struct DataStorage *data, unsigned char c);
106void data_align(struct DataStorage *data, int align);
107void data_concat(struct DataStorage *dst, struct DataStorage *src);
108void data_leb128(struct DataStorage *data, ssize_t pos, int64_t val);
109void data_uleb128(struct DataStorage *data, ssize_t pos, uint64_t val);
110void data_string(struct DataStorage *data, const void *str, size_t len);
111void data_open_chunk(struct DataStorage *data);
112void data_close_chunk(struct DataStorage *data, ssize_t num);
113void data_varint32(struct DataStorage *data, ssize_t pos, int64_t val);
114void data_varuint32(struct DataStorage *data, ssize_t pos, uint64_t val);
115
116/* container: rope-style string builder */
117struct StringBuffer {
118  struct Vector *elems;
119};
120
121void  sb_init(struct StringBuffer *sb);
122void  sb_clear(struct StringBuffer *sb);
123int   sb_empty(struct StringBuffer *sb);
124void  sb_insert(struct StringBuffer *sb, int pos, const char *start, const char *end);
125char *sb_join(struct StringBuffer *sb, const char *separator);
126
127static inline void
128sb_append(struct StringBuffer *sb, const char *start, const char *end)
129{
130  sb_insert(sb, sb->elems->len, start, end);
131}
132
133static inline void
134sb_prepend(struct StringBuffer *sb, const char *start, const char *end)
135{
136  sb_insert(sb, 0, start, end);
137}
138
139static inline char *
140sb_to_string(struct StringBuffer *sb)
141{
142  return sb_join(sb, NULL);
143}
144
145void escape_string(const char *str, size_t size, struct StringBuffer *sb);
146
147/* convenience macro for join_paths */
148#define JOIN_PATHS(...) join_paths((const char *[]){__VA_ARGS__, NULL})
149
150/* option parser: long-option style for toolchain commands
151 * has_arg values: 0 = none, 1 = required, 2 = optional */
152#define no_argument       0
153#define required_argument 1
154#define optional_argument 2
155
156struct option {
157  const char *name;
158  int         has_arg;
159  int         val;
160};
161
162extern int   optind;
163extern int   opterr;
164extern int   optopt;
165extern char *optarg;
166
167int optparse(int argc, char *const argv[], const struct option *opts);
168
169#endif /* ARUU_TCUTIL_H */