diff options
Diffstat (limited to 'src/lj_strfmt.h')
-rw-r--r-- | src/lj_strfmt.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/lj_strfmt.h b/src/lj_strfmt.h new file mode 100644 index 00000000..339f8e15 --- /dev/null +++ b/src/lj_strfmt.h | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | ** String formatting. | ||
3 | ** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #ifndef _LJ_STRFMT_H | ||
7 | #define _LJ_STRFMT_H | ||
8 | |||
9 | #include "lj_obj.h" | ||
10 | |||
11 | typedef uint32_t SFormat; /* Format indicator. */ | ||
12 | |||
13 | /* Format parser state. */ | ||
14 | typedef struct FormatState { | ||
15 | const uint8_t *p; /* Current format string pointer. */ | ||
16 | const uint8_t *e; /* End of format string. */ | ||
17 | const char *str; /* Returned literal string. */ | ||
18 | MSize len; /* Size of literal string. */ | ||
19 | } FormatState; | ||
20 | |||
21 | /* Format types (max. 16). */ | ||
22 | typedef enum FormatType { | ||
23 | STRFMT_EOF, STRFMT_ERR, STRFMT_LIT, | ||
24 | STRFMT_INT, STRFMT_UINT, STRFMT_NUM, STRFMT_STR, STRFMT_CHAR, STRFMT_PTR | ||
25 | } FormatType; | ||
26 | |||
27 | /* Format subtypes (bits are reused). */ | ||
28 | #define STRFMT_T_HEX 0x0010 /* STRFMT_UINT */ | ||
29 | #define STRFMT_T_OCT 0x0020 /* STRFMT_UINT */ | ||
30 | #define STRFMT_T_FP_A 0x0000 /* STRFMT_NUM */ | ||
31 | #define STRFMT_T_FP_E 0x0010 /* STRFMT_NUM */ | ||
32 | #define STRFMT_T_FP_F 0x0020 /* STRFMT_NUM */ | ||
33 | #define STRFMT_T_FP_G 0x0030 /* STRFMT_NUM */ | ||
34 | #define STRFMT_T_QUOTED 0x0010 /* STRFMT_STR */ | ||
35 | |||
36 | /* Format flags. */ | ||
37 | #define STRFMT_F_LEFT 0x0100 | ||
38 | #define STRFMT_F_PLUS 0x0200 | ||
39 | #define STRFMT_F_ZERO 0x0400 | ||
40 | #define STRFMT_F_SPACE 0x0800 | ||
41 | #define STRFMT_F_ALT 0x1000 | ||
42 | #define STRFMT_F_UPPER 0x2000 | ||
43 | |||
44 | /* Format indicator fields. */ | ||
45 | #define STRFMT_SH_WIDTH 16 | ||
46 | #define STRFMT_SH_PREC 24 | ||
47 | |||
48 | #define STRFMT_TYPE(sf) ((FormatType)((sf) & 15)) | ||
49 | #define STRFMT_WIDTH(sf) (((sf) >> STRFMT_SH_WIDTH) & 255u) | ||
50 | #define STRFMT_PREC(sf) ((((sf) >> STRFMT_SH_PREC) & 255u) - 1u) | ||
51 | #define STRFMT_FP(sf) (((sf) >> 4) & 3) | ||
52 | |||
53 | /* Formats for conversion characters. */ | ||
54 | #define STRFMT_A (STRFMT_NUM|STRFMT_T_FP_A) | ||
55 | #define STRFMT_C (STRFMT_CHAR) | ||
56 | #define STRFMT_D (STRFMT_INT) | ||
57 | #define STRFMT_E (STRFMT_NUM|STRFMT_T_FP_E) | ||
58 | #define STRFMT_F (STRFMT_NUM|STRFMT_T_FP_F) | ||
59 | #define STRFMT_G (STRFMT_NUM|STRFMT_T_FP_G) | ||
60 | #define STRFMT_I STRFMT_D | ||
61 | #define STRFMT_O (STRFMT_UINT|STRFMT_T_OCT) | ||
62 | #define STRFMT_P (STRFMT_PTR) | ||
63 | #define STRFMT_Q (STRFMT_STR|STRFMT_T_QUOTED) | ||
64 | #define STRFMT_S (STRFMT_STR) | ||
65 | #define STRFMT_U (STRFMT_UINT) | ||
66 | #define STRFMT_X (STRFMT_UINT|STRFMT_T_HEX) | ||
67 | #define STRFMT_G14 (STRFMT_G | ((14+1) << STRFMT_SH_PREC)) | ||
68 | |||
69 | /* Maximum buffer sizes for conversions. */ | ||
70 | #define STRFMT_MAXBUF_XINT (1+22) /* '0' prefix + uint64_t in octal. */ | ||
71 | #define STRFMT_MAXBUF_INT (1+10) /* Sign + int32_t in decimal. */ | ||
72 | #define STRFMT_MAXBUF_NUM 32 /* Must correspond with STRFMT_G14. */ | ||
73 | #define STRFMT_MAXBUF_PTR (2+2*sizeof(ptrdiff_t)) /* "0x" + hex ptr. */ | ||
74 | |||
75 | /* Format parser. */ | ||
76 | LJ_FUNC SFormat LJ_FASTCALL lj_strfmt_parse(FormatState *fs); | ||
77 | |||
78 | static LJ_AINLINE void lj_strfmt_init(FormatState *fs, const char *p, MSize len) | ||
79 | { | ||
80 | fs->p = (const uint8_t *)p; | ||
81 | fs->e = (const uint8_t *)p + len; | ||
82 | lua_assert(*fs->e == 0); /* Must be NUL-terminated (may have NULs inside). */ | ||
83 | } | ||
84 | |||
85 | /* Raw conversions. */ | ||
86 | LJ_FUNC char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k); | ||
87 | LJ_FUNC char * LJ_FASTCALL lj_strfmt_wptr(char *p, const void *v); | ||
88 | LJ_FUNC char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v); | ||
89 | LJ_FUNC const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp); | ||
90 | |||
91 | /* Unformatted conversions to buffer. */ | ||
92 | LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k); | ||
93 | #if LJ_HASJIT | ||
94 | LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putnum(SBuf *sb, cTValue *o); | ||
95 | #endif | ||
96 | LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putptr(SBuf *sb, const void *v); | ||
97 | LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putquoted(SBuf *sb, GCstr *str); | ||
98 | |||
99 | /* Formatted conversions to buffer. */ | ||
100 | LJ_FUNC SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k); | ||
101 | LJ_FUNC SBuf *lj_strfmt_putfnum_int(SBuf *sb, SFormat sf, lua_Number n); | ||
102 | LJ_FUNC SBuf *lj_strfmt_putfnum_uint(SBuf *sb, SFormat sf, lua_Number n); | ||
103 | LJ_FUNC SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat, lua_Number n); | ||
104 | LJ_FUNC SBuf *lj_strfmt_putfchar(SBuf *sb, SFormat, int32_t c); | ||
105 | LJ_FUNC SBuf *lj_strfmt_putfstr(SBuf *sb, SFormat, GCstr *str); | ||
106 | |||
107 | /* Conversions to strings. */ | ||
108 | LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_int(lua_State *L, int32_t k); | ||
109 | LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o); | ||
110 | LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_number(lua_State *L, cTValue *o); | ||
111 | #if LJ_HASJIT | ||
112 | LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_char(lua_State *L, int c); | ||
113 | #endif | ||
114 | LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_obj(lua_State *L, cTValue *o); | ||
115 | |||
116 | /* Internal string formatting. */ | ||
117 | LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, | ||
118 | va_list argp); | ||
119 | LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...) | ||
120 | #ifdef __GNUC__ | ||
121 | __attribute__ ((format (printf, 2, 3))) | ||
122 | #endif | ||
123 | ; | ||
124 | |||
125 | #endif | ||