1 /********************************************************************/ 2 /* */ 3 /* striutl.h Procedures to work with wide char strings. */ 4 /* Copyright (C) 1989 - 2015 Thomas Mertes */ 5 /* */ 6 /* This file is part of the Seed7 Runtime Library. */ 7 /* */ 8 /* The Seed7 Runtime Library is free software; you can */ 9 /* redistribute it and/or modify it under the terms of the GNU */ 10 /* Lesser General Public License as published by the Free Software */ 11 /* Foundation; either version 2.1 of the License, or (at your */ 12 /* option) any later version. */ 13 /* */ 14 /* The Seed7 Runtime Library is distributed in the hope that it */ 15 /* will be useful, but WITHOUT ANY WARRANTY; without even the */ 16 /* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */ 17 /* PURPOSE. See the GNU Lesser General Public License for more */ 18 /* details. */ 19 /* */ 20 /* You should have received a copy of the GNU Lesser General */ 21 /* Public License along with this program; if not, write to the */ 22 /* Free Software Foundation, Inc., 51 Franklin Street, */ 23 /* Fifth Floor, Boston, MA 02110-1301, USA. */ 24 /* */ 25 /* Module: Seed7 Runtime Library */ 26 /* File: seed7/src/striutl.h */ 27 /* Changes: 1991 - 1994, 2005 - 2015 Thomas Mertes */ 28 /* Content: Procedures to work with wide char strings. */ 29 /* */ 30 /********************************************************************/ 31 32 /** 33 * Compute strlen() for normal or wide strings at compile time. 34 */ 35 #define STRLEN(s) (sizeof(s) / sizeof(s[0]) - 1) 36 37 #define MEMCPY_STRING(dest, src) memcpy(dest, src, STRLEN(src)); 38 39 /* Maximum escape sequence length in string literal: */ 40 #define ESC_SEQUENCE_MAX_LEN STRLEN("\\4294967295;") 41 42 #if STRINGIFY_WORKS 43 #define STRINGIFY(s) STRINGIFY_HELPER(s) 44 #define STRINGIFY_HELPER(s) #s 45 #else 46 #define STRINGIFY(s) stringify((intType) s) 47 #endif 48 49 #define CSTRI_LITERAL_TO_STRI(literal) cstri_buf_to_stri(literal, STRLEN(literal)) 50 51 #define toStri(name) #name 52 53 extern const const_cstriType stri_escape_sequence[]; 54 extern const const_cstriType cstri_escape_sequence[]; 55 56 #define MAX_UTF8_EXPANSION_FACTOR 6 57 #define max_utf8_size(size) (MAX_UTF8_EXPANSION_FACTOR * (size)) 58 #define free_cstri(cstri,stri) UNALLOC_CSTRI(cstri, (stri)->size); 59 #define free_cstri8(cstri,stri) UNALLOC_CSTRI(cstri, max_utf8_size((stri)->size)); 60 #define free_wstri(wstri,stri) free(wstri); 61 62 /** 63 * UTF-16 encodes characters > 0xffff with surrogate pairs. 64 * When converting to UTF-16 it might be necessary to store 65 * every character with surrogate pairs (= two UTF-16 chars). 66 */ 67 #define SURROGATE_PAIR_FACTOR 2 68 69 70 #ifdef OS_STRI_WCHAR 71 typedef wchar_t os_charType; 72 typedef uint16Type os_ucharType; 73 typedef wchar_t *os_striType; 74 typedef const wchar_t *const_os_striType; 75 #define os_stri_strlen wcslen 76 #define os_stri_strcpy wcscpy 77 #define os_stri_strcat wcscat 78 #define os_stri_strchr wcschr 79 #define os_stri_strrchr wcsrchr 80 #define ALLOC_OS_STRI(var,len) ALLOC_HEAP(var, os_striType, SIZ_WSTRI(len)) 81 #define REALLOC_OS_STRI(var,len) ((os_striType) REALLOC_HEAP(var, ustriType, SIZ_WSTRI(len))) 82 #define FREE_OS_STRI free 83 #define SIZ_OS_STRI SIZ_WSTRI 84 #define MAX_OS_STRI_LEN MAX_WSTRI_LEN 85 #define FMT_S_OS "%ls" 86 #else 87 typedef char os_charType; 88 typedef unsigned char os_ucharType; 89 typedef cstriType os_striType; 90 typedef const_cstriType const_os_striType; 91 #define os_stri_strlen strlen 92 #define os_stri_strcpy strcpy 93 #define os_stri_strcat strcat 94 #define os_stri_strchr strchr 95 #define os_stri_strrchr strrchr 96 #define ALLOC_OS_STRI ALLOC_CSTRI 97 #define REALLOC_OS_STRI REALLOC_CSTRI 98 #define FREE_OS_STRI free 99 #define SIZ_OS_STRI SIZ_CSTRI 100 #define MAX_OS_STRI_LEN MAX_CSTRI_LEN 101 #define FMT_S_OS "%s" 102 #endif 103 104 105 #if STACK_LIKE_ALLOC_FOR_OS_STRI 106 typedef struct stackAllocStruct *stackAllocType; 107 108 typedef struct stackAllocStruct { 109 stackAllocType previous; 110 cstriType beyond; 111 cstriType curr_free; 112 char start[1]; 113 } stackAllocRecord; 114 115 #ifdef DO_INIT 116 stackAllocRecord stack_alloc_base = {NULL, NULL, NULL, {' '}}; 117 stackAllocType stack_alloc = &stack_alloc_base; 118 #else 119 EXTERN stackAllocRecord stack_alloc_base; 120 EXTERN stackAllocType stack_alloc; 121 #endif 122 123 #define SIZ_STACK_ALLOC(len) ((sizeof(stackAllocRecord) - sizeof(char)) + \ 124 (len) * sizeof(os_charType)) 125 /* One is subtracted in the macro MAX_STACK_ALLOC to make */ 126 /* sure that stack_alloc->beyond does not wrap around. */ 127 #define MAX_STACK_ALLOC (MAX_MEMSIZETYPE - 1 - \ 128 (sizeof(stackAllocRecord) - sizeof(char)) / sizeof(os_charType)) 129 #define POP_OS_STRI_OK(len) (memSizeType) stack_alloc->beyond >= (len) && \ 130 (memSizeType) (stack_alloc->beyond - (len)) >= \ 131 (memSizeType) stack_alloc->curr_free 132 #define PUSH_OS_STRI_OK(var) (memSizeType) (var) >= (memSizeType) stack_alloc->start && \ 133 (memSizeType) (var) < (memSizeType) stack_alloc->curr_free 134 #define POP_OS_STRI(var,len) (var = (os_striType) stack_alloc->curr_free, \ 135 stack_alloc->curr_free += (len), TRUE) 136 #define PUSH_OS_STRI(var) { stack_alloc->curr_free = (cstriType) (var); } 137 #define os_stri_alloc(var,len) (POP_OS_STRI_OK(SIZ_OS_STRI(len)) ? \ 138 POP_OS_STRI(var, SIZ_OS_STRI(len)) : \ 139 (var = heapAllocOsStri(len)) != NULL) 140 #define os_stri_free(var) if (PUSH_OS_STRI_OK(var)) PUSH_OS_STRI(var) \ 141 else heapFreeOsStri(var); 142 #else 143 #define os_stri_alloc ALLOC_OS_STRI 144 #define os_stri_free FREE_OS_STRI 145 #endif 146 147 148 #if MAP_ABSOLUTE_PATH_TO_DRIVE_LETTERS 149 #if EMULATE_ROOT_CWD 150 /* Assume that drive letters are used only with a backslash as path delimiter. */ 151 #define OS_PATH_DELIMITER '\\' 152 extern const_os_striType current_emulated_cwd; 153 #endif 154 extern const os_charType emulated_root[]; 155 156 #define IS_EMULATED_ROOT(os_path) (os_path == emulated_root) 157 158 #if USE_EXTENDED_LENGTH_PATH 159 #define PATH_PREFIX L"\\\\?\\" 160 #else 161 #define PATH_PREFIX L"" 162 #endif 163 #define PREFIX_LEN STRLEN(PATH_PREFIX) 164 #endif 165 166 #define PATH_IS_NORMAL 0 167 #define PATH_IS_EMULATED_ROOT 1 168 #define PATH_NOT_MAPPED 2 169 170 171 cstriType striAsUnquotedCStri (const const_striType stri); 172 cstriType bstriAsUnquotedCStri (const const_bstriType bstri); 173 #if !STRINGIFY_WORKS 174 cstriType stringify (intType number); 175 #endif 176 void memcpy_to_strelem (register strElemType *const dest, 177 register const const_ustriType src, memSizeType len); 178 void memset_to_strelem (register strElemType *const dest, 179 register const strElemType ch, memSizeType len); 180 boolType memcpy_from_strelem (register const ustriType dest, 181 register const strElemType *const src, 182 memSizeType len); 183 #if HAS_WMEMCHR && WCHAR_T_SIZE == 32 184 #define memchr_strelem(mem, ch, len) \ 185 (const strElemType *) wmemchr((const wchar_t *) mem, (wchar_t) ch, (size_t) len) 186 #else 187 const strElemType *memchr_strelem (register const strElemType *mem, 188 const strElemType ch, memSizeType len); 189 #endif 190 #if STACK_LIKE_ALLOC_FOR_OS_STRI 191 os_striType heapAllocOsStri (memSizeType len); 192 void heapFreeOsStri (const_os_striType var); 193 #endif 194 memSizeType utf8_to_stri (strElemType *const dest_stri, memSizeType *const dest_len, 195 const_ustriType ustri, memSizeType len); 196 memSizeType utf8_bytes_missing (const const_ustriType ustri, const memSizeType len); 197 memSizeType stri_to_utf8 (const ustriType out_stri, 198 const strElemType *strelem, memSizeType len); 199 cstriType conv_to_cstri (cstriType cstri, const const_striType stri); 200 void conv_to_cstri8 (cstriType cstri, const const_striType stri, 201 errInfoType *err_info); 202 memSizeType stri_to_utf16 (const wstriType out_wstri, 203 register const strElemType *strelem, memSizeType len, 204 errInfoType *const err_info); 205 void memcpy_to_wstri (wstriType dest, const char *src, memSizeType len); 206 cstriType stri_to_cstri (const const_striType stri, errInfoType *err_info); 207 cstriType stri_to_cstri8 (const const_striType stri, errInfoType *err_info); 208 cstriType stri_to_cstri8_buf (const const_striType stri, memSizeType *length); 209 bstriType stri_to_bstri (const const_striType stri, errInfoType *err_info); 210 bstriType stri_to_bstri8 (const const_striType stri); 211 #ifdef CONSOLE_WCHAR 212 bstriType stri_to_bstriw (const const_striType stri, errInfoType *err_info); 213 #endif 214 wstriType stri_to_wstri_buf (const const_striType stri, memSizeType *length, 215 errInfoType *err_info); 216 striType cstri_to_stri (const_cstriType cstri); 217 striType cstri_buf_to_stri (const_cstriType cstri, memSizeType length); 218 striType cstri8_to_stri (const_cstriType cstri, errInfoType *err_info); 219 striType cstri8_buf_to_stri (const_cstriType cstri, memSizeType length, 220 errInfoType *err_info); 221 striType cstri8_or_cstri_to_stri (const_cstriType cstri); 222 striType wstri_buf_to_stri (const_wstriType wstri, memSizeType length, 223 errInfoType *err_info); 224 errInfoType conv_wstri_buf_to_cstri (cstriType cstri, const_wstriType wstri, 225 memSizeType length); 226 striType conv_from_os_stri (const const_os_striType os_stri, memSizeType length); 227 os_striType stri_to_os_stri (const_striType stri, errInfoType *err_info); 228 striType os_stri_to_stri (const const_os_striType os_stri, errInfoType *err_info); 229 striType stri_to_standard_path (const striType stri); 230 striType cp_from_os_path (const_os_striType os_path, errInfoType *err_info); 231 #if EMULATE_ROOT_CWD 232 void setEmulatedCwdToRoot (void); 233 void setEmulatedCwd (os_striType os_path, errInfoType *err_info); 234 #endif 235 os_striType cp_to_os_path (const_striType std_path, int *path_info, 236 errInfoType *err_info); 237 os_striType temp_name_in_dir (const const_os_striType path); 238 os_striType cp_to_command (const const_striType command, 239 const const_striType parameters, errInfoType *err_info); 240