kulp / tenyr
 1 ```#ifndef COMMON_H_ ``` 2 ```#define COMMON_H_ ``` 3 4 ```#include ``` 5 ```#include ``` 6 ```#include ``` 7 ```#include ``` 8 9 ```#include "ops.h" ``` 10 11 ```#define countof(X) (sizeof (X) / sizeof (X)[0]) ``` 12 ```#define STR(X) STR_(X) ``` 13 ```#define STR_(X) #X ``` 14 ```#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) ``` 15 16 1 ```static inline int32_t SEXTEND32(unsigned int bits, int32_t val) ``` 17 ```{ ``` 18 1 ``` if (bits >= 32) ``` 19 1 ``` return val; ``` 20 21 1 ``` const int32_t msb = (int32_t)(1L << (bits - 1)) & val; ``` 22 1 ``` const uint32_t mask = msb ? 0xffffffff : 0; ``` 23 1 ``` const int32_t ext = (int32_t)(mask << bits); ``` 24 1 ``` return ext | (val & ((1L << bits) - 1)); ``` 25 ```} ``` 26 27 ```#define NORETURN __attribute__((noreturn)) ``` 28 29 ```#define CONCAT_(X,Y) X ## Y ``` 30 ```#define CONCAT(X,Y) CONCAT_(X,Y) ``` 31 ```#define LINE(X) CONCAT(X,__LINE__) ``` 32 33 ```#define list_foreach(Tag,Node,Object) \ ``` 34 ``` for (struct Tag *LINE(Next) = (Object), *Node = LINE(Next); \ ``` 35 ``` (void)(Node && (LINE(Next) = Node->next)), Node; \ ``` 36 ``` Node = LINE(Next)) \ ``` 37 ``` // ``` 38 39 ```#define SYMBOL_LEN_V1 32 /* only applies in object version 1 and before */ ``` 40 ```#define SYMBOL_LEN_V2 2048 /* arbitrary large limit to avoid bad behavior with extreme values */ ``` 41 ```// TODO document fixed lengths or remove the limitations ``` 42 ```#define LINE_LEN 512 ``` 43 44 ```#define PRINT_ERRNO 0x80 ``` 45 46 ```enum errcode { /* 0 impossible, 1 reserved for default */ DISPLAY_USAGE=2 }; ``` 47 ```extern jmp_buf errbuf; ``` 48 ```#define fatal(Code,...) \ ``` 49 ``` fatal_(Code,__FILE__,__LINE__,__func__,__VA_ARGS__) ``` 50 51 ```#define debug(Level,...) \ ``` 52 ``` debug_(Level,__FILE__,__LINE__,__func__,__VA_ARGS__) ``` 53 54 ```// use function pointers to support plugin architecture ``` 55 ```extern void (* NORETURN fatal_)(int code, const char *file, int line, const char ``` 56 ``` *func, const char *fmt, ...); ``` 57 58 ```extern void (*debug_)(int level, const char *file, int line, const char *func, ``` 59 ``` const char *fmt, ...); ``` 60 61 ```struct element { ``` 62 ``` struct insn_or_data insn; ``` 63 64 ``` struct reloc_node *reloc; ``` 65 66 ``` struct symbol { ``` 67 ``` struct const_expr *ce; ``` 68 ``` struct symbol *next; ``` 69 70 ``` char *name; ``` 71 ``` int column; ``` 72 ``` int lineno; ``` 73 ``` int32_t reladdr; ``` 74 ``` uint32_t size; ``` 75 76 ``` unsigned char resolved:1; ``` 77 ``` unsigned char global:1; ``` 78 ``` unsigned char unique:1; ///< if this symbol comes from a label ``` 79 ``` unsigned :(CHAR_BIT-3); ``` 80 ``` } *symbol; ``` 81 ```}; ``` 82 83 ```typedef int cmp(const void *, const void*); ``` 84 85 1 ```static inline char *strcopy(char *dest, const char *src, size_t sz) ``` 86 ```{ ``` 87 ``` // Use memcpy() to copy past embedded NUL characters, but force NUL term ``` 88 ``` // Explicit cast to (char*) because this function is included in C++ code ``` 89 1 ``` char *result = (char*)memcpy(dest, src, sz); ``` 90 1 ``` dest[sz - 1] = '\0'; ``` 91 1 ``` return result; ``` 92 ```} ``` 93 94 ```long long numberise(char *str, int base); ``` 95 96 ```// build_path expects a path to a file, or else a path to a directory including ``` 97 ```// a trailing slash. It returns a string whose ownership passes to the caller ``` 98 ```// and which must be deallocated with free(). ``` 99 ```char *build_path(const char *base, const char *fmt, ...); ``` 100 101 ```#define ALIASING_CAST(Type,Expr) \ ``` 102 ``` *(Type * __attribute__((__may_alias__)) *)&(Expr) ``` 103 104 ```#endif ``` 105 106 ```/* vi: set ts=4 sw=4 et: */ ```

Read our documentation on viewing source code .