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