comparison src/buffer.h @ 440:8de8e3f6228a r21-2-28

Import from CVS: tag r21-2-28
author cvs
date Mon, 13 Aug 2007 11:33:38 +0200
parents 9d177e8d4150
children abe6d1db359e
comparison
equal deleted inserted replaced
439:357dd071b03c 440:8de8e3f6228a
27 FSF: long ago. 27 FSF: long ago.
28 JWZ: separated out bufslots.h, early in Lemacs. 28 JWZ: separated out bufslots.h, early in Lemacs.
29 Ben Wing: almost completely rewritten for Mule, 19.12. 29 Ben Wing: almost completely rewritten for Mule, 19.12.
30 */ 30 */
31 31
32 #ifndef _XEMACS_BUFFER_H_ 32 #ifndef INCLUDED_buffer_h_
33 #define _XEMACS_BUFFER_H_ 33 #define INCLUDED_buffer_h_
34 34
35 #ifdef MULE 35 #ifdef MULE
36 #include "mule-charset.h" 36 #include "mule-charset.h"
37 #endif 37 #endif
38 38
164 #endif /* REGION_CACHE_NEEDS_WORK */ 164 #endif /* REGION_CACHE_NEEDS_WORK */
165 165
166 /* The markers that refer to this buffer. This is actually a single 166 /* The markers that refer to this buffer. This is actually a single
167 marker -- successive elements in its marker `chain' are the other 167 marker -- successive elements in its marker `chain' are the other
168 markers referring to this buffer */ 168 markers referring to this buffer */
169 struct Lisp_Marker *markers; 169 Lisp_Marker *markers;
170 170
171 /* The buffer's extent info. This is its own type, an extent-info 171 /* The buffer's extent info. This is its own type, an extent-info
172 object (done this way for ease in marking / finalizing). */ 172 object (done this way for ease in marking / finalizing). */
173 Lisp_Object extent_info; 173 Lisp_Object extent_info;
174 174
1036 # define BI_BUF_CHARPTR_COPY_CHAR(buf, pos, str) \ 1036 # define BI_BUF_CHARPTR_COPY_CHAR(buf, pos, str) \
1037 charptr_copy_char (BI_BUF_BYTE_ADDRESS (buf, pos), str) 1037 charptr_copy_char (BI_BUF_BYTE_ADDRESS (buf, pos), str)
1038 #define BUF_CHARPTR_COPY_CHAR(buf, pos, str) \ 1038 #define BUF_CHARPTR_COPY_CHAR(buf, pos, str) \
1039 BI_BUF_CHARPTR_COPY_CHAR (buf, bufpos_to_bytind (buf, pos), str) 1039 BI_BUF_CHARPTR_COPY_CHAR (buf, bufpos_to_bytind (buf, pos), str)
1040 1040
1041
1042
1043 1041
1044 /************************************************************************/ 1042 /************************************************************************/
1045 /* */ 1043 /* */
1046 /* working with externally-formatted data */ 1044 /* Converting between internal and external format */
1047 /* */ 1045 /* */
1048 /************************************************************************/ 1046 /************************************************************************/
1049 1047 /*
1050 /* Sometimes strings need to be converted into one or another 1048 All client code should use only the two macros
1051 external format, for passing to a library function. (Note 1049
1052 that we encapsulate and automatically convert the arguments 1050 TO_EXTERNAL_FORMAT (source_type, source, sink_type, sink, coding_system)
1053 of some functions, but not others.) At times this conversion 1051 TO_INTERNAL_FORMAT (source_type, source, sink_type, sink, coding_system)
1054 also has to go the other way -- i.e. when we get external- 1052
1055 format strings back from a library function. 1053 Typical use is
1056 */ 1054
1055 TO_EXTERNAL_FORMAT (DATA, (ptr, len),
1056 LISP_BUFFER, buffer,
1057 Qfile_name);
1058
1059 The source or sink can be specified in one of these ways:
1060
1061 DATA, (ptr, len), // input data is a fixed buffer of size len
1062 ALLOCA, (ptr, len), // output data is in a alloca()ed buffer of size len
1063 MALLOC, (ptr, len), // output data is in a malloc()ed buffer of size len
1064 C_STRING_ALLOCA, ptr, // equivalent to ALLOCA (ptr, len_ignored) on output.
1065 C_STRING_MALLOC, ptr, // equivalent to MALLOC (ptr, len_ignored) on output.
1066 C_STRING, ptr, // equivalent to DATA, (ptr, strlen (ptr) + 1) on input
1067 LISP_STRING, string, // input or output is a Lisp_Object of type string
1068 LISP_BUFFER, buffer, // output is written to (point) in lisp buffer
1069 LISP_LSTREAM, lstream, // input or output is a Lisp_Object of type lstream
1070 LISP_OPAQUE, object, // input or output is a Lisp_Object of type opaque
1071
1072 When specifying the sink, use lvalues, since the macro will assign to them,
1073 except when the sink is an lstream or a lisp buffer.
1074
1075 The macros accept the kinds of sources and sinks appropriate for
1076 internal and external data representation. See the type_checking_assert
1077 macros below for the actual allowed types.
1078
1079 Since some sources and sinks use one argument (a Lisp_Object) to
1080 specify them, while others take a (pointer, length) pair, we use
1081 some C preprocessor trickery to allow pair arguments to be specified
1082 by parenthesizing them, as in the examples above.
1083
1084 Anything prefixed by dfc_ (`data format conversion') is private.
1085 They are only used to implement these macros.
1086
1087 Using C_STRING* is appropriate for using with external APIs that take
1088 null-terminated strings. For internal data, we should try to be
1089 '\0'-clean - i.e. allow arbitrary data to contain embedded '\0'.
1090
1091 Sometime in the future we might allow output to C_STRING_ALLOCA or
1092 C_STRING_MALLOC _only_ with TO_EXTERNAL_FORMAT(), not
1093 TO_INTERNAL_FORMAT(). */
1094
1095 #define TO_EXTERNAL_FORMAT(source_type, source, sink_type, sink, coding_system) \
1096 do { \
1097 dfc_conversion_type dfc_simplified_source_type; \
1098 dfc_conversion_type dfc_simplified_sink_type; \
1099 dfc_conversion_data dfc_source; \
1100 dfc_conversion_data dfc_sink; \
1101 \
1102 type_checking_assert \
1103 ((DFC_TYPE_##source_type == DFC_TYPE_DATA || \
1104 DFC_TYPE_##source_type == DFC_TYPE_C_STRING || \
1105 DFC_TYPE_##source_type == DFC_TYPE_LISP_STRING || \
1106 DFC_TYPE_##source_type == DFC_TYPE_LISP_OPAQUE || \
1107 DFC_TYPE_##source_type == DFC_TYPE_LISP_LSTREAM) \
1108 && \
1109 (DFC_TYPE_##sink_type == DFC_TYPE_ALLOCA || \
1110 DFC_TYPE_##sink_type == DFC_TYPE_MALLOC || \
1111 DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_ALLOCA || \
1112 DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_MALLOC || \
1113 DFC_TYPE_##sink_type == DFC_TYPE_LISP_LSTREAM || \
1114 DFC_TYPE_##sink_type == DFC_TYPE_LISP_OPAQUE)); \
1115 \
1116 DFC_SOURCE_##source_type##_TO_ARGS (source); \
1117 DFC_SINK_##sink_type##_TO_ARGS (sink); \
1118 \
1119 DFC_CONVERT_TO_EXTERNAL_FORMAT (dfc_simplified_source_type, &dfc_source, \
1120 coding_system, \
1121 dfc_simplified_sink_type, &dfc_sink); \
1122 \
1123 DFC_##sink_type##_USE_CONVERTED_DATA (sink); \
1124 } while (0)
1125
1126 #define TO_INTERNAL_FORMAT(source_type, source, sink_type, sink, coding_system) \
1127 do { \
1128 dfc_conversion_type dfc_simplified_source_type; \
1129 dfc_conversion_type dfc_simplified_sink_type; \
1130 dfc_conversion_data dfc_source; \
1131 dfc_conversion_data dfc_sink; \
1132 \
1133 type_checking_assert \
1134 ((DFC_TYPE_##source_type == DFC_TYPE_DATA || \
1135 DFC_TYPE_##source_type == DFC_TYPE_C_STRING || \
1136 DFC_TYPE_##source_type == DFC_TYPE_LISP_OPAQUE || \
1137 DFC_TYPE_##source_type == DFC_TYPE_LISP_LSTREAM) \
1138 && \
1139 (DFC_TYPE_##sink_type == DFC_TYPE_ALLOCA || \
1140 DFC_TYPE_##sink_type == DFC_TYPE_MALLOC || \
1141 DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_ALLOCA || \
1142 DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_MALLOC || \
1143 DFC_TYPE_##sink_type == DFC_TYPE_LISP_STRING || \
1144 DFC_TYPE_##sink_type == DFC_TYPE_LISP_LSTREAM || \
1145 DFC_TYPE_##sink_type == DFC_TYPE_LISP_BUFFER)); \
1146 \
1147 DFC_SOURCE_##source_type##_TO_ARGS (source); \
1148 DFC_SINK_##sink_type##_TO_ARGS (sink); \
1149 \
1150 DFC_CONVERT_TO_INTERNAL_FORMAT (dfc_simplified_source_type, &dfc_source, \
1151 coding_system, \
1152 dfc_simplified_sink_type, &dfc_sink); \
1153 \
1154 DFC_##sink_type##_USE_CONVERTED_DATA (sink); \
1155 } while (0)
1057 1156
1058 #ifdef FILE_CODING 1157 #ifdef FILE_CODING
1158 #define DFC_CONVERT_TO_EXTERNAL_FORMAT dfc_convert_to_external_format
1159 #define DFC_CONVERT_TO_INTERNAL_FORMAT dfc_convert_to_internal_format
1160 #else
1161 /* ignore coding_system argument */
1162 #define DFC_CONVERT_TO_EXTERNAL_FORMAT(a, b, coding_system, c, d) \
1163 dfc_convert_to_external_format (a, b, c, d)
1164 #define DFC_CONVERT_TO_INTERNAL_FORMAT(a, b, coding_system, c, d) \
1165 dfc_convert_to_internal_format (a, b, c, d)
1166 #endif
1167
1168 typedef union
1169 {
1170 struct { const void *ptr; size_t len; } data;
1171 Lisp_Object lisp_object;
1172 } dfc_conversion_data;
1173
1174 enum dfc_conversion_type
1175 {
1176 DFC_TYPE_DATA,
1177 DFC_TYPE_ALLOCA,
1178 DFC_TYPE_MALLOC,
1179 DFC_TYPE_C_STRING,
1180 DFC_TYPE_C_STRING_ALLOCA,
1181 DFC_TYPE_C_STRING_MALLOC,
1182 DFC_TYPE_LISP_STRING,
1183 DFC_TYPE_LISP_LSTREAM,
1184 DFC_TYPE_LISP_OPAQUE,
1185 DFC_TYPE_LISP_BUFFER
1186 };
1187 typedef enum dfc_conversion_type dfc_conversion_type;
1059 1188
1060 /* WARNING: These use a static buffer. This can lead to disaster if 1189 /* WARNING: These use a static buffer. This can lead to disaster if
1061 these functions are not used *very* carefully. Under normal 1190 these functions are not used *very* carefully. Another reason to only use
1062 circumstances, do not call these functions; call the front ends 1191 TO_EXTERNAL_FORMATf() and TO_INTERNAL_FORMAT(). */
1063 below. */ 1192 void
1064 1193 dfc_convert_to_external_format (dfc_conversion_type source_type,
1065 Extbyte *convert_to_external_format (CONST Bufbyte *ptr, 1194 dfc_conversion_data *source,
1066 Bytecount len, 1195 #ifdef FILE_CODING
1067 Extcount *len_out, 1196 Lisp_Object coding_system,
1068 enum external_data_format fmt); 1197 #endif
1069 Bufbyte *convert_from_external_format (CONST Extbyte *ptr, 1198 dfc_conversion_type sink_type,
1070 Extcount len, 1199 dfc_conversion_data *sink);
1071 Bytecount *len_out, 1200 void
1072 enum external_data_format fmt); 1201 dfc_convert_to_internal_format (dfc_conversion_type source_type,
1073 1202 dfc_conversion_data *source,
1074 #else /* ! MULE */ 1203 #ifdef FILE_CODING
1075 1204 Lisp_Object coding_system,
1076 #define convert_to_external_format(ptr, len, len_out, fmt) \ 1205 #endif
1077 (*(len_out) = (int) (len), (Extbyte *) (ptr)) 1206 dfc_conversion_type sink_type,
1078 #define convert_from_external_format(ptr, len, len_out, fmt) \ 1207 dfc_conversion_data *sink);
1079 (*(len_out) = (Bytecount) (len), (Bufbyte *) (ptr)) 1208 /* CPP Trickery */
1080 1209 #define DFC_CPP_CAR(x,y) (x)
1081 #endif /* ! MULE */ 1210 #define DFC_CPP_CDR(x,y) (y)
1082 1211
1083 /* In all of the following macros we use the following general principles: 1212 /* Convert `source' to args for dfc_convert_to_*_format() */
1084 1213 #define DFC_SOURCE_DATA_TO_ARGS(val) do { \
1085 -- Functions that work with charptr's accept two sorts of charptr's: 1214 dfc_source.data.ptr = DFC_CPP_CAR val; \
1086 1215 dfc_source.data.len = DFC_CPP_CDR val; \
1087 a) Pointers to memory with a length specified. The pointer will be 1216 dfc_simplified_source_type = DFC_TYPE_DATA; \
1088 fundamentally of type `unsigned char *' (although labelled 1217 } while (0)
1089 as `Bufbyte *' for internal-format data and `Extbyte *' for 1218 #define DFC_SOURCE_C_STRING_TO_ARGS(val) do { \
1090 external-format data) and the length will be fundamentally of 1219 dfc_source.data.len = \
1091 type `int' (although labelled as `Bytecount' for internal-format 1220 strlen ((char *) (dfc_source.data.ptr = (val))); \
1092 data and `Extcount' for external-format data). The length is 1221 dfc_simplified_source_type = DFC_TYPE_DATA; \
1093 always a count in bytes. 1222 } while (0)
1094 b) Zero-terminated pointers; no length specified. The pointer 1223 #define DFC_SOURCE_LISP_STRING_TO_ARGS(val) do { \
1095 is of type `char *', whether the data pointed to is internal-format 1224 Lisp_Object dfc_slsta = (val); \
1096 or external-format. These sorts of pointers are available for 1225 type_checking_assert (STRINGP (dfc_slsta)); \
1097 convenience in working with C library functions and literal 1226 dfc_source.lisp_object = dfc_slsta; \
1098 strings. In general you should use these sorts of pointers only 1227 dfc_simplified_source_type = DFC_TYPE_LISP_STRING; \
1099 to interface to library routines and not for general manipulation, 1228 } while (0)
1100 as you are liable to lose embedded nulls and such. This could 1229 #define DFC_SOURCE_LISP_LSTREAM_TO_ARGS(val) do { \
1101 be a big problem for routines that want Unicode-formatted data, 1230 Lisp_Object dfc_sllta = (val); \
1102 which is likely to have lots of embedded nulls in it. 1231 type_checking_assert (LSTREAMP (dfc_sllta)); \
1103 (In the real world, though, external Unicode data will be UTF-8, 1232 dfc_source.lisp_object = dfc_sllta; \
1104 which will not have embedded nulls and is ASCII-compatible - martin) 1233 dfc_simplified_source_type = DFC_TYPE_LISP_LSTREAM; \
1105 1234 } while (0)
1106 -- Functions that work with Lisp strings accept strings as Lisp Objects 1235 #define DFC_SOURCE_LISP_OPAQUE_TO_ARGS(val) do { \
1107 (as opposed to the `struct Lisp_String *' for some of the other 1236 Lisp_Opaque *dfc_slota = XOPAQUE (val); \
1108 string accessors). This is for convenience in working with the 1237 dfc_source.data.ptr = OPAQUE_DATA (dfc_slota); \
1109 functions, as otherwise you will almost always have to call 1238 dfc_source.data.len = OPAQUE_SIZE (dfc_slota); \
1110 XSTRING() on the object. 1239 dfc_simplified_source_type = DFC_TYPE_DATA; \
1111 1240 } while (0)
1112 -- Functions that work with charptr's are not guaranteed to copy 1241
1113 their data into alloca()ed space. Functions that work with 1242 /* Convert `sink' to args for dfc_convert_to_*_format() */
1114 Lisp strings are, however. The reason is that Lisp strings can 1243 #define DFC_SINK_ALLOCA_TO_ARGS(val) \
1115 be relocated any time a GC happens, and it could happen at some 1244 dfc_simplified_sink_type = DFC_TYPE_DATA
1116 rather unexpected times. The internal-external conversion is 1245 #define DFC_SINK_C_STRING_ALLOCA_TO_ARGS(val) \
1117 rarely done in time-critical functions, and so the slight 1246 dfc_simplified_sink_type = DFC_TYPE_DATA
1118 extra time required for alloca() and copy is well-worth the 1247 #define DFC_SINK_MALLOC_TO_ARGS(val) \
1119 safety of knowing your string data won't be relocated out from 1248 dfc_simplified_sink_type = DFC_TYPE_DATA
1120 under you. 1249 #define DFC_SINK_C_STRING_MALLOC_TO_ARGS(val) \
1121 */ 1250 dfc_simplified_sink_type = DFC_TYPE_DATA
1122 1251 #define DFC_SINK_LISP_STRING_TO_ARGS(val) \
1123 1252 dfc_simplified_sink_type = DFC_TYPE_DATA
1124 /* Maybe convert charptr's data into ext-format and store the result in 1253 #define DFC_SINK_LISP_OPAQUE_TO_ARGS(val) \
1125 alloca()'ed space. 1254 dfc_simplified_sink_type = DFC_TYPE_DATA
1126 1255 #define DFC_SINK_LISP_LSTREAM_TO_ARGS(val) do { \
1127 You may wonder why this is written in this fashion and not as a 1256 Lisp_Object dfc_sllta = (val); \
1128 function call. With a little trickery it could certainly be 1257 type_checking_assert (LSTREAMP (dfc_sllta)); \
1129 written this way, but it won't work because of those DAMN GCC WANKERS 1258 dfc_sink.lisp_object = dfc_sllta; \
1130 who couldn't be bothered to handle alloca() properly on the x86 1259 dfc_simplified_sink_type = DFC_TYPE_LISP_LSTREAM; \
1131 architecture. (If you put a call to alloca() in the argument to 1260 } while (0)
1132 a function call, the stack space gets allocated right in the 1261 #define DFC_SINK_LISP_BUFFER_TO_ARGS(val) do { \
1133 middle of the arguments to the function call and you are unbelievably 1262 struct buffer *dfc_slbta = XBUFFER (val); \
1134 hosed.) */ 1263 dfc_sink.lisp_object = \
1135 1264 make_lisp_buffer_output_stream \
1136 #ifdef MULE 1265 (dfc_slbta, BUF_PT (dfc_slbta), 0); \
1137 1266 dfc_simplified_sink_type = DFC_TYPE_LISP_LSTREAM; \
1138 #define GET_CHARPTR_EXT_DATA_ALLOCA(ptr, len, fmt, ptr_out, len_out) do \ 1267 } while (0)
1139 { \ 1268
1140 Bytecount gceda_len_in = (Bytecount) (len); \ 1269 /* Assign to the `sink' lvalue(s) using the converted data. */
1141 Extcount gceda_len_out; \ 1270 #define DFC_ALLOCA_USE_CONVERTED_DATA(sink) do { \
1142 CONST Bufbyte *gceda_ptr_in = (ptr); \ 1271 void * dfc_sink_ret = alloca (dfc_sink.data.len + 1); \
1143 Extbyte *gceda_ptr_out = \ 1272 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \
1144 convert_to_external_format (gceda_ptr_in, gceda_len_in, \ 1273 (DFC_CPP_CAR sink) = (unsigned char *) dfc_sink_ret; \
1145 &gceda_len_out, fmt); \ 1274 (DFC_CPP_CDR sink) = dfc_sink.data.len; \
1146 /* If the new string is identical to the old (will be the case most \ 1275 } while (0)
1147 of the time), just return the same string back. This saves \ 1276 #define DFC_MALLOC_USE_CONVERTED_DATA(sink) do { \
1148 on alloca()ing, which can be useful on C alloca() machines and \ 1277 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 1); \
1149 on stack-space-challenged environments. */ \ 1278 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \
1150 \ 1279 (DFC_CPP_CAR sink) = (unsigned char *) dfc_sink_ret; \
1151 if (gceda_len_in == gceda_len_out && \ 1280 (DFC_CPP_CDR sink) = dfc_sink.data.len; \
1152 !memcmp (gceda_ptr_in, gceda_ptr_out, gceda_len_out)) \ 1281 } while (0)
1153 { \ 1282 #define DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA(sink) do { \
1154 (ptr_out) = (Extbyte *) gceda_ptr_in; \ 1283 void * dfc_sink_ret = alloca (dfc_sink.data.len + 1); \
1155 } \ 1284 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \
1156 else \ 1285 (sink) = (char *) dfc_sink_ret; \
1157 { \ 1286 } while (0)
1158 (ptr_out) = (Extbyte *) alloca (1 + gceda_len_out); \ 1287 #define DFC_C_STRING_MALLOC_USE_CONVERTED_DATA(sink) do { \
1159 memcpy ((void *) ptr_out, gceda_ptr_out, 1 + gceda_len_out); \ 1288 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 1); \
1160 } \ 1289 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \
1161 (len_out) = gceda_len_out; \ 1290 (sink) = (char *) dfc_sink_ret; \
1162 } while (0) 1291 } while (0)
1163 1292 #define DFC_LISP_STRING_USE_CONVERTED_DATA(sink) \
1164 #else /* ! MULE */ 1293 sink = make_string ((Bufbyte *) dfc_sink.data.ptr, dfc_sink.data.len)
1165 1294 #define DFC_LISP_OPAQUE_USE_CONVERTED_DATA(sink) \
1166 #define GET_CHARPTR_EXT_DATA_ALLOCA(ptr, len, fmt, ptr_out, len_out) do \ 1295 sink = make_opaque (dfc_sink.data.ptr, dfc_sink.data.len)
1167 { \ 1296 #define DFC_LISP_LSTREAM_USE_CONVERTED_DATA(sink) /* data already used */
1168 (ptr_out) = (Extbyte *) (ptr); \ 1297 #define DFC_LISP_BUFFER_USE_CONVERTED_DATA(sink) \
1169 (len_out) = (Extcount) (len); \ 1298 Lstream_delete (XLSTREAM (dfc_sink.lisp_object))
1170 } while (0) 1299
1171 1300 /* Someday we might want to distinguish between Qnative and Qfile_name
1172 #endif /* ! MULE */ 1301 by using coding-system aliases, but for now it suffices to have
1173 1302 these be identical. Qnative can be used as the coding_system
1174 #define GET_C_CHARPTR_EXT_DATA_ALLOCA(ptr, fmt, ptr_out) do \ 1303 argument to TO_EXTERNAL_FORMAT() and TO_INTERNAL_FORMAT(). */
1175 { \ 1304 #define Qnative Qfile_name
1176 Extcount gcceda_ignored_len; \
1177 CONST Bufbyte *gcceda_ptr_in = (CONST Bufbyte *) (ptr); \
1178 Extbyte *gcceda_ptr_out; \
1179 \
1180 GET_CHARPTR_EXT_DATA_ALLOCA (gcceda_ptr_in, \
1181 strlen ((char *) gcceda_ptr_in), \
1182 fmt, \
1183 gcceda_ptr_out, \
1184 gcceda_ignored_len); \
1185 (ptr_out) = (char *) gcceda_ptr_out; \
1186 } while (0)
1187
1188 #define GET_C_CHARPTR_EXT_BINARY_DATA_ALLOCA(ptr, ptr_out) \
1189 GET_C_CHARPTR_EXT_DATA_ALLOCA (ptr, FORMAT_BINARY, ptr_out)
1190 #define GET_CHARPTR_EXT_BINARY_DATA_ALLOCA(ptr, len, ptr_out, len_out) \
1191 GET_CHARPTR_EXT_DATA_ALLOCA (ptr, len, FORMAT_BINARY, ptr_out, len_out)
1192
1193 #define GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA(ptr, ptr_out) \
1194 GET_C_CHARPTR_EXT_DATA_ALLOCA (ptr, FORMAT_FILENAME, ptr_out)
1195 #define GET_CHARPTR_EXT_FILENAME_DATA_ALLOCA(ptr, len, ptr_out, len_out) \
1196 GET_CHARPTR_EXT_DATA_ALLOCA (ptr, len, FORMAT_FILENAME, ptr_out, len_out)
1197
1198 #define GET_C_CHARPTR_EXT_CTEXT_DATA_ALLOCA(ptr, ptr_out) \
1199 GET_C_CHARPTR_EXT_DATA_ALLOCA (ptr, FORMAT_CTEXT, ptr_out)
1200 #define GET_CHARPTR_EXT_CTEXT_DATA_ALLOCA(ptr, len, ptr_out, len_out) \
1201 GET_CHARPTR_EXT_DATA_ALLOCA (ptr, len, FORMAT_CTEXT, ptr_out, len_out)
1202
1203 /* Maybe convert external charptr's data into internal format and store
1204 the result in alloca()'ed space.
1205
1206 You may wonder why this is written in this fashion and not as a
1207 function call. With a little trickery it could certainly be
1208 written this way, but it won't work because of those DAMN GCC WANKERS
1209 who couldn't be bothered to handle alloca() properly on the x86
1210 architecture. (If you put a call to alloca() in the argument to
1211 a function call, the stack space gets allocated right in the
1212 middle of the arguments to the function call and you are unbelievably
1213 hosed.) */
1214
1215 #ifdef MULE
1216
1217 #define GET_CHARPTR_INT_DATA_ALLOCA(ptr, len, fmt, ptr_out, len_out) do \
1218 { \
1219 Extcount gcida_len_in = (Extcount) (len); \
1220 Bytecount gcida_len_out; \
1221 CONST Extbyte *gcida_ptr_in = (ptr); \
1222 Bufbyte *gcida_ptr_out = \
1223 convert_from_external_format (gcida_ptr_in, gcida_len_in, \
1224 &gcida_len_out, fmt); \
1225 /* If the new string is identical to the old (will be the case most \
1226 of the time), just return the same string back. This saves \
1227 on alloca()ing, which can be useful on C alloca() machines and \
1228 on stack-space-challenged environments. */ \
1229 \
1230 if (gcida_len_in == gcida_len_out && \
1231 !memcmp (gcida_ptr_in, gcida_ptr_out, gcida_len_out)) \
1232 { \
1233 (ptr_out) = (Bufbyte *) gcida_ptr_in; \
1234 } \
1235 else \
1236 { \
1237 (ptr_out) = (Extbyte *) alloca (1 + gcida_len_out); \
1238 memcpy ((void *) ptr_out, gcida_ptr_out, 1 + gcida_len_out); \
1239 } \
1240 (len_out) = gcida_len_out; \
1241 } while (0)
1242
1243 #else /* ! MULE */
1244
1245 #define GET_CHARPTR_INT_DATA_ALLOCA(ptr, len, fmt, ptr_out, len_out) do \
1246 { \
1247 (ptr_out) = (Bufbyte *) (ptr); \
1248 (len_out) = (Bytecount) (len); \
1249 } while (0)
1250
1251 #endif /* ! MULE */
1252
1253 #define GET_C_CHARPTR_INT_DATA_ALLOCA(ptr, fmt, ptr_out) do \
1254 { \
1255 Bytecount gccida_ignored_len; \
1256 CONST Extbyte *gccida_ptr_in = (CONST Extbyte *) (ptr); \
1257 Bufbyte *gccida_ptr_out; \
1258 \
1259 GET_CHARPTR_INT_DATA_ALLOCA (gccida_ptr_in, \
1260 strlen ((char *) gccida_ptr_in), \
1261 fmt, \
1262 gccida_ptr_out, \
1263 gccida_ignored_len); \
1264 (ptr_out) = gccida_ptr_out; \
1265 } while (0)
1266
1267 #define GET_C_CHARPTR_INT_BINARY_DATA_ALLOCA(ptr, ptr_out) \
1268 GET_C_CHARPTR_INT_DATA_ALLOCA (ptr, FORMAT_BINARY, ptr_out)
1269 #define GET_CHARPTR_INT_BINARY_DATA_ALLOCA(ptr, len, ptr_out, len_out) \
1270 GET_CHARPTR_INT_DATA_ALLOCA (ptr, len, FORMAT_BINARY, ptr_out, len_out)
1271
1272 #define GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA(ptr, ptr_out) \
1273 GET_C_CHARPTR_INT_DATA_ALLOCA (ptr, FORMAT_FILENAME, ptr_out)
1274 #define GET_CHARPTR_INT_FILENAME_DATA_ALLOCA(ptr, len, ptr_out, len_out) \
1275 GET_CHARPTR_INT_DATA_ALLOCA (ptr, len, FORMAT_FILENAME, ptr_out, len_out)
1276
1277 #define GET_C_CHARPTR_INT_CTEXT_DATA_ALLOCA(ptr, ptr_out) \
1278 GET_C_CHARPTR_INT_DATA_ALLOCA (ptr, FORMAT_CTEXT, ptr_out)
1279 #define GET_CHARPTR_INT_CTEXT_DATA_ALLOCA(ptr, len, ptr_out, len_out) \
1280 GET_CHARPTR_INT_DATA_ALLOCA (ptr, len, FORMAT_CTEXT, ptr_out, len_out)
1281
1282
1283 /* Maybe convert Lisp string's data into ext-format and store the result in
1284 alloca()'ed space.
1285
1286 You may wonder why this is written in this fashion and not as a
1287 function call. With a little trickery it could certainly be
1288 written this way, but it won't work because of those DAMN GCC WANKERS
1289 who couldn't be bothered to handle alloca() properly on the x86
1290 architecture. (If you put a call to alloca() in the argument to
1291 a function call, the stack space gets allocated right in the
1292 middle of the arguments to the function call and you are unbelievably
1293 hosed.) */
1294
1295 #define GET_STRING_EXT_DATA_ALLOCA(s, fmt, ptr_out, len_out) do \
1296 { \
1297 Extcount gseda_len_out; \
1298 struct Lisp_String *gseda_s = XSTRING (s); \
1299 Extbyte * gseda_ptr_out = \
1300 convert_to_external_format (string_data (gseda_s), \
1301 string_length (gseda_s), \
1302 &gseda_len_out, fmt); \
1303 (ptr_out) = (Extbyte *) alloca (1 + gseda_len_out); \
1304 memcpy ((void *) ptr_out, gseda_ptr_out, 1 + gseda_len_out); \
1305 (len_out) = gseda_len_out; \
1306 } while (0)
1307
1308
1309 #define GET_C_STRING_EXT_DATA_ALLOCA(s, fmt, ptr_out) do \
1310 { \
1311 Extcount gcseda_ignored_len; \
1312 Extbyte *gcseda_ptr_out; \
1313 \
1314 GET_STRING_EXT_DATA_ALLOCA (s, fmt, gcseda_ptr_out, \
1315 gcseda_ignored_len); \
1316 (ptr_out) = (char *) gcseda_ptr_out; \
1317 } while (0)
1318
1319 #define GET_STRING_BINARY_DATA_ALLOCA(s, ptr_out, len_out) \
1320 GET_STRING_EXT_DATA_ALLOCA (s, FORMAT_BINARY, ptr_out, len_out)
1321 #define GET_C_STRING_BINARY_DATA_ALLOCA(s, ptr_out) \
1322 GET_C_STRING_EXT_DATA_ALLOCA (s, FORMAT_BINARY, ptr_out)
1323
1324 #define GET_STRING_FILENAME_DATA_ALLOCA(s, ptr_out, len_out) \
1325 GET_STRING_EXT_DATA_ALLOCA (s, FORMAT_FILENAME, ptr_out, len_out)
1326 #define GET_C_STRING_FILENAME_DATA_ALLOCA(s, ptr_out) \
1327 GET_C_STRING_EXT_DATA_ALLOCA (s, FORMAT_FILENAME, ptr_out)
1328
1329 #define GET_STRING_OS_DATA_ALLOCA(s, ptr_out, len_out) \
1330 GET_STRING_EXT_DATA_ALLOCA (s, FORMAT_OS, ptr_out, len_out)
1331 #define GET_C_STRING_OS_DATA_ALLOCA(s, ptr_out) \
1332 GET_C_STRING_EXT_DATA_ALLOCA (s, FORMAT_OS, ptr_out)
1333
1334 #define GET_STRING_CTEXT_DATA_ALLOCA(s, ptr_out, len_out) \
1335 GET_STRING_EXT_DATA_ALLOCA (s, FORMAT_CTEXT, ptr_out, len_out)
1336 #define GET_C_STRING_CTEXT_DATA_ALLOCA(s, ptr_out) \
1337 GET_C_STRING_EXT_DATA_ALLOCA (s, FORMAT_CTEXT, ptr_out)
1338
1339 1305
1340 1306
1341 /************************************************************************/ 1307 /************************************************************************/
1342 /* */ 1308 /* */
1343 /* fake charset functions */ 1309 /* fake charset functions */
1566 1532
1567 /* Allocation of buffer data. */ 1533 /* Allocation of buffer data. */
1568 1534
1569 #ifdef REL_ALLOC 1535 #ifdef REL_ALLOC
1570 1536
1571 char *r_alloc (unsigned char **, unsigned long); 1537 char *r_alloc (unsigned char **, size_t);
1572 char *r_re_alloc (unsigned char **, unsigned long); 1538 char *r_re_alloc (unsigned char **, size_t);
1573 void r_alloc_free (unsigned char **); 1539 void r_alloc_free (unsigned char **);
1574 1540
1575 #define BUFFER_ALLOC(data, size) \ 1541 #define BUFFER_ALLOC(data, size) \
1576 ((Bufbyte *) r_alloc ((unsigned char **) &data, (size) * sizeof(Bufbyte))) 1542 ((Bufbyte *) r_alloc ((unsigned char **) &data, (size) * sizeof(Bufbyte)))
1577 #define BUFFER_REALLOC(data, size) \ 1543 #define BUFFER_REALLOC(data, size) \
1706 string_char (XSTRING (table), (Charcount) ch) 1672 string_char (XSTRING (table), (Charcount) ch)
1707 # define SET_TRT_TABLE_CHAR_1(table, ch1, ch2) \ 1673 # define SET_TRT_TABLE_CHAR_1(table, ch1, ch2) \
1708 set_string_char (XSTRING (table), (Charcount) ch1, ch2) 1674 set_string_char (XSTRING (table), (Charcount) ch1, ch2)
1709 1675
1710 #ifdef MULE 1676 #ifdef MULE
1711 # define MAKE_MIRROR_TRT_TABLE() make_opaque (256, 0) 1677 # define MAKE_MIRROR_TRT_TABLE() make_opaque (OPAQUE_CLEAR, 256)
1712 # define MIRROR_TRT_TABLE_AS_STRING(table) ((Bufbyte *) XOPAQUE_DATA (table)) 1678 # define MIRROR_TRT_TABLE_AS_STRING(table) ((Bufbyte *) XOPAQUE_DATA (table))
1713 # define MIRROR_TRT_TABLE_CHAR_1(table, ch) \ 1679 # define MIRROR_TRT_TABLE_CHAR_1(table, ch) \
1714 ((Emchar) (MIRROR_TRT_TABLE_AS_STRING (table)[ch])) 1680 ((Emchar) (MIRROR_TRT_TABLE_AS_STRING (table)[ch]))
1715 # define SET_MIRROR_TRT_TABLE_CHAR_1(table, ch1, ch2) \ 1681 # define SET_MIRROR_TRT_TABLE_CHAR_1(table, ch1, ch2) \
1716 (MIRROR_TRT_TABLE_AS_STRING (table)[ch1] = (Bufbyte) (ch2)) 1682 (MIRROR_TRT_TABLE_AS_STRING (table)[ch1] = (Bufbyte) (ch2))
1792 1758
1793 /* Downcase a character, or make no change if that cannot be done. */ 1759 /* Downcase a character, or make no change if that cannot be done. */
1794 1760
1795 #define DOWNCASE(buf, ch) DOWNCASE_TABLE_OF (buf, ch) 1761 #define DOWNCASE(buf, ch) DOWNCASE_TABLE_OF (buf, ch)
1796 1762
1797 #endif /* _XEMACS_BUFFER_H_ */ 1763 #endif /* INCLUDED_buffer_h_ */