kulp / tenyr
1
#ifndef COMMON_H_
2
#define COMMON_H_
3

4
#include <setjmp.h>
5
#include <search.h>
6
#include <string.h>
7
#include <limits.h>
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 .

Loading