lj_strfmt.h (4750B)
1 /* 2 ** String formatting. 3 ** Copyright (C) 2005-2016 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 #if LJ_53 26 STRFMT_UTF8 27 #else 28 STRFMT_UTF8=0 29 #endif 30 } FormatType; 31 32 /* Format subtypes (bits are reused). */ 33 #define STRFMT_T_HEX 0x0010 /* STRFMT_UINT */ 34 #define STRFMT_T_OCT 0x0020 /* STRFMT_UINT */ 35 #define STRFMT_T_FP_A 0x0000 /* STRFMT_NUM */ 36 #define STRFMT_T_FP_E 0x0010 /* STRFMT_NUM */ 37 #define STRFMT_T_FP_F 0x0020 /* STRFMT_NUM */ 38 #define STRFMT_T_FP_G 0x0030 /* STRFMT_NUM */ 39 #define STRFMT_T_QUOTED 0x0010 /* STRFMT_STR */ 40 41 /* Format flags. */ 42 #define STRFMT_F_LEFT 0x0100 43 #define STRFMT_F_PLUS 0x0200 44 #define STRFMT_F_ZERO 0x0400 45 #define STRFMT_F_SPACE 0x0800 46 #define STRFMT_F_ALT 0x1000 47 #define STRFMT_F_UPPER 0x2000 48 49 /* Format indicator fields. */ 50 #define STRFMT_SH_WIDTH 16 51 #define STRFMT_SH_PREC 24 52 53 #define STRFMT_TYPE(sf) ((FormatType)((sf) & 15)) 54 #define STRFMT_WIDTH(sf) (((sf) >> STRFMT_SH_WIDTH) & 255u) 55 #define STRFMT_PREC(sf) ((((sf) >> STRFMT_SH_PREC) & 255u) - 1u) 56 #define STRFMT_FP(sf) (((sf) >> 4) & 3) 57 58 /* Formats for conversion characters. */ 59 #define STRFMT_A (STRFMT_NUM|STRFMT_T_FP_A) 60 #define STRFMT_C (STRFMT_CHAR) 61 #define STRFMT_D (STRFMT_INT) 62 #define STRFMT_E (STRFMT_NUM|STRFMT_T_FP_E) 63 #define STRFMT_F (STRFMT_NUM|STRFMT_T_FP_F) 64 #define STRFMT_G (STRFMT_NUM|STRFMT_T_FP_G) 65 #define STRFMT_I STRFMT_D 66 #define STRFMT_O (STRFMT_UINT|STRFMT_T_OCT) 67 #define STRFMT_P (STRFMT_PTR) 68 #define STRFMT_Q (STRFMT_STR|STRFMT_T_QUOTED) 69 #define STRFMT_S (STRFMT_STR) 70 #define STRFMT_U (STRFMT_UINT) 71 #define STRFMT_X (STRFMT_UINT|STRFMT_T_HEX) 72 #define STRFMT_G14 (STRFMT_G | ((14+1) << STRFMT_SH_PREC)) 73 74 /* Maximum buffer sizes for conversions. */ 75 #define STRFMT_MAXBUF_XINT (1+22) /* '0' prefix + uint64_t in octal. */ 76 #define STRFMT_MAXBUF_INT (1+10) /* Sign + int32_t in decimal. */ 77 #define STRFMT_MAXBUF_NUM 32 /* Must correspond with STRFMT_G14. */ 78 #define STRFMT_MAXBUF_PTR (2+2*sizeof(ptrdiff_t)) /* "0x" + hex ptr. */ 79 #define STRFMT_MAXBUF_UTF8 8 80 81 /* Format parser. */ 82 LJ_FUNC SFormat LJ_FASTCALL lj_strfmt_parse(FormatState *fs); 83 84 static LJ_AINLINE void lj_strfmt_init(FormatState *fs, const char *p, MSize len) 85 { 86 fs->p = (const uint8_t *)p; 87 fs->e = (const uint8_t *)p + len; 88 lua_assert(*fs->e == 0); /* Must be NUL-terminated (may have NULs inside). */ 89 } 90 91 /* Raw conversions. */ 92 LJ_FUNC char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k); 93 LJ_FUNC char * LJ_FASTCALL lj_strfmt_wptr(char *p, const void *v); 94 LJ_FUNC char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v); 95 LJ_FUNC const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp); 96 LJ_FUNC MSize LJ_FASTCALL lj_strfmt_utf8(char *buff, unsigned long x); 97 98 /* Unformatted conversions to buffer. */ 99 LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k); 100 #if LJ_HASJIT 101 LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putnum(SBuf *sb, cTValue *o); 102 #endif 103 LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putptr(SBuf *sb, const void *v); 104 LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putquoted(SBuf *sb, GCstr *str); 105 LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_pututf8(SBuf *sb, long n); 106 107 /* Formatted conversions to buffer. */ 108 LJ_FUNC SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k); 109 LJ_FUNC SBuf *lj_strfmt_putfnum_int(SBuf *sb, SFormat sf, lua_Number n); 110 LJ_FUNC SBuf *lj_strfmt_putfnum_uint(SBuf *sb, SFormat sf, lua_Number n); 111 LJ_FUNC SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat, lua_Number n); 112 LJ_FUNC SBuf *lj_strfmt_putfchar(SBuf *sb, SFormat, int32_t c); 113 LJ_FUNC SBuf *lj_strfmt_putfstr(SBuf *sb, SFormat, GCstr *str); 114 115 /* Conversions to strings. */ 116 LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_int(lua_State *L, int32_t k); 117 LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o); 118 LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_number(lua_State *L, cTValue *o); 119 #if LJ_HASJIT 120 LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_char(lua_State *L, int c); 121 #endif 122 LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_obj(lua_State *L, cTValue *o); 123 124 /* Internal string formatting. */ 125 LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, 126 va_list argp); 127 LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...) 128 #ifdef __GNUC__ 129 __attribute__ ((format (printf, 2, 3))) 130 #endif 131 ; 132 133 #endif