43#ifdef FREECIV_HAVE_LIBZ
69#define PLAIN_FILE_BUF_SIZE (8096*1024)
71#ifdef FREECIV_HAVE_LIBBZ2
81#ifdef FREECIV_HAVE_LIBLZMA
83#define PLAIN_FILE_BUF_SIZE_XZ PLAIN_FILE_BUF_SIZE
84#define XZ_DECODER_TEST_SIZE (4*1024)
88#define XZ_DECODER_MEMLIMIT (65*1024*1024)
89#define XZ_DECODER_MEMLIMIT_STEP (25*1024*1024)
90#define XZ_DECODER_MEMLIMIT_FINAL (100*1024*1024)
119static bool xz_outbuffer_to_file(
fz_FILE *fp, lzma_action
action);
124#ifdef FREECIV_HAVE_LIBZSTD
126#define PLAIN_FILE_BUF_SIZE_ZSTD PLAIN_FILE_BUF_SIZE
129 ZSTD_DStream *dstream;
130 ZSTD_CStream *cstream;
133 ZSTD_inBuffer in_buf;
134 ZSTD_outBuffer out_buf;
156#ifdef FREECIV_HAVE_LIBZ
159#ifdef FREECIV_HAVE_LIBBZ2
160 struct bzip2_struct bz2;
162#ifdef FREECIV_HAVE_LIBLZMA
165#ifdef FREECIV_HAVE_LIBZSTD
166 struct zstd_struct zstd;
178#ifdef FREECIV_HAVE_LIBZ
181#ifdef FREECIV_HAVE_LIBBZ2
184#ifdef FREECIV_HAVE_LIBLZMA
187#ifdef FREECIV_HAVE_LIBZSTD
195#define fz_method_validate(method) \
196 (fz_method_is_valid(method) ? method \
197 : (fc_assert_msg(fz_method_is_valid(method), \
198 "Unsupported compress method %d, reverting to plain.",\
231 enum fz_method method,
int compress_level)
244 if (mode[0] ==
'w') {
248#if defined(FREECIV_HAVE_LIBBZ2) || defined(FREECIV_HAVE_LIBLZMA) || defined (FREECIV_HAVE_LIBZSTD)
258#ifdef FREECIV_HAVE_LIBBZ2
263 fp->
u.bz2.file = BZ2_bzReadOpen(&fp->
u.bz2.error, fp->
u.bz2.
plain, 1, 0,
267 fp->
u.bz2.file = NULL;
269 if (!fp->
u.bz2.file) {
287 read_len = BZ2_bzRead(&fp->
u.bz2.error, fp->
u.bz2.file, &tmp, 1);
288 if (fp->
u.bz2.error != BZ_DATA_ERROR_MAGIC) {
290 if (fp->
u.bz2.error == BZ_STREAM_END) {
294 fp->
u.bz2.firstbyte = -1;
296 fp->
u.bz2.firstbyte = tmp;
298 fp->
u.bz2.eof =
TRUE;
299 }
else if (fp->
u.bz2.error != BZ_OK) {
301 BZ2_bzReadClose(&tmp_err, fp->
u.bz2.file);
307 fp->
u.bz2.firstbyte = tmp;
315 BZ2_bzReadClose(&tmp_err, fp->
u.bz2.file);
320#ifdef FREECIV_HAVE_LIBLZMA
322 fp->
u.xz.memlimit = XZ_DECODER_MEMLIMIT;
323 memset(&fp->
u.xz.stream, 0,
sizeof(lzma_stream));
324 fp->
u.xz.error = lzma_stream_decoder(&fp->
u.xz.stream,
327 if (fp->
u.xz.error != LZMA_OK) {
335 fp->
u.xz.in_buf =
fc_malloc(PLAIN_FILE_BUF_SIZE_XZ);
337 len = fread(fp->
u.xz.in_buf, 1, XZ_DECODER_TEST_SIZE,
342 fp->
u.xz.stream.next_in = fp->
u.xz.in_buf;
343 fp->
u.xz.stream.avail_in =
len;
344 fp->
u.xz.out_buf =
fc_malloc(PLAIN_FILE_BUF_SIZE_XZ);
345 fp->
u.xz.stream.next_out = fp->
u.xz.out_buf;
346 fp->
u.xz.stream.avail_out = PLAIN_FILE_BUF_SIZE_XZ;
347 len = fread(&fp->
u.xz.hack_byte, 1, 1, fp->
u.xz.
plain);
349 fp->
u.xz.hack_byte_used =
TRUE;
352 fp->
u.xz.hack_byte_used =
FALSE;
356 if (fp->
u.xz.error == LZMA_OK || fp->
u.xz.error == LZMA_STREAM_END) {
358 fp->
u.xz.out_index = 0;
359 fp->
u.xz.total_read = 0;
360 fp->
u.xz.out_avail = fp->
u.xz.stream.total_out;
364 free(fp->
u.xz.out_buf);
367 lzma_end(&fp->
u.xz.stream);
368 free(fp->
u.xz.in_buf);
375#ifdef FREECIV_HAVE_LIBZSTD
377 fp->
u.zstd.dstream = ZSTD_createDStream();
383 fp->
u.zstd.in_buf.size = ZSTD_initDStream(fp->
u.zstd.dstream);
384 fp->
u.zstd.nonconst_in =
fc_malloc(fp->
u.zstd.in_buf.size);
385 fp->
u.zstd.in_buf.src = fp->
u.zstd.nonconst_in;
387 len = fread(fp->
u.zstd.nonconst_in, 1, fp->
u.zstd.in_buf.size,
390 if (len < fp->u.zstd.in_buf.size) {
391 fp->
u.zstd.in_buf.size =
len;
393 fp->
u.zstd.out_buf.size = ZSTD_DStreamOutSize();
394 fp->
u.zstd.out_buf.dst =
fc_malloc(fp->
u.zstd.out_buf.size);
396 fp->
u.zstd.out_buf.pos = 0;
397 fp->
u.zstd.in_buf.pos = 0;
399 fp->
u.zstd.error = ZSTD_decompressStream(fp->
u.zstd.dstream,
403 if (!ZSTD_isError(fp->
u.zstd.error)) {
405 fp->
u.zstd.outbuf_pos = 0;
409 free(fp->
u.zstd.out_buf.dst);
412 free(fp->
u.zstd.nonconst_in);
416 ZSTD_freeDStream(fp->
u.zstd.dstream);
419#ifdef FREECIV_HAVE_LIBZ
429#ifdef FREECIV_HAVE_LIBLZMA
436 memset(&fp->
u.xz.stream, 0,
sizeof(lzma_stream));
437 ret = lzma_easy_encoder(&fp->
u.xz.stream, compress_level, LZMA_CHECK_CRC32);
438 fp->
u.xz.error = ret;
439 if (ret != LZMA_OK) {
443 fp->
u.xz.in_buf =
fc_malloc(PLAIN_FILE_BUF_SIZE_XZ);
444 fp->
u.xz.stream.next_in = fp->
u.xz.in_buf;
445 fp->
u.xz.out_buf =
fc_malloc(PLAIN_FILE_BUF_SIZE_XZ);
446 fp->
u.xz.stream.next_out = fp->
u.xz.out_buf;
447 fp->
u.xz.stream.avail_out = PLAIN_FILE_BUF_SIZE_XZ;
448 fp->
u.xz.out_index = 0;
449 fp->
u.xz.total_read = 0;
458#ifdef FREECIV_HAVE_LIBZSTD
470 fp->
u.zstd.cstream = ZSTD_createCStream();
474 ZSTD_initCStream(fp->
u.zstd.cstream, compress_level * 2);
476 fp->
u.zstd.in_buf.size = PLAIN_FILE_BUF_SIZE_ZSTD;
477 fp->
u.zstd.nonconst_in =
fc_malloc(fp->
u.zstd.in_buf.size);
478 fp->
u.zstd.in_buf.src = fp->
u.zstd.nonconst_in;
479 fp->
u.zstd.out_buf.size = ZSTD_CStreamOutSize();
480 fp->
u.zstd.out_buf.dst =
fc_malloc(fp->
u.zstd.out_buf.size);
481 fp->
u.zstd.in_buf.pos = 0;
482 fp->
u.zstd.out_buf.pos = 0;
486#ifdef FREECIV_HAVE_LIBBZ2
494 fp->
u.bz2.file = BZ2_bzWriteOpen(&fp->
u.bz2.error, fp->
u.bz2.
plain,
495 compress_level, 1, 15);
496 if (fp->
u.bz2.error != BZ_OK) {
500 BZ2_bzWriteClose(&tmp_err, fp->
u.bz2.file, 0, NULL, NULL);
501 fp->
u.bz2.file = NULL;
504 fp->
u.bz2.file = NULL;
506 if (!fp->
u.bz2.file) {
515#ifdef FREECIV_HAVE_LIBZ
519 if (mode[0] ==
'w') {
522 fp->
u.zlib = fc_gzopen(filename, mode);
540 __FUNCTION__, fp->
method);
587#ifdef FREECIV_HAVE_LIBLZMA
589 if (fp->
mode ==
'w' && !xz_outbuffer_to_file(fp, LZMA_FINISH)) {
592 lzma_end(&fp->
u.xz.stream);
593 free(fp->
u.xz.in_buf);
594 free(fp->
u.xz.out_buf);
599#ifdef FREECIV_HAVE_LIBZSTD
601 if (fp->
mode ==
'w') {
602 fp->
u.zstd.error = ZSTD_endStream(fp->
u.zstd.cstream, &fp->
u.zstd.out_buf);
603 while (fp->
u.zstd.out_buf.pos > 0) {
604 fwrite(fp->
u.zstd.out_buf.dst, 1,
605 fp->
u.zstd.out_buf.pos, fp->
u.zstd.
plain);
606 fp->
u.zstd.out_buf.pos = 0;
607 fp->
u.zstd.error = ZSTD_flushStream(fp->
u.zstd.cstream, &fp->
u.zstd.out_buf);
609 ZSTD_freeCStream(fp->
u.zstd.cstream);
611 ZSTD_freeDStream(fp->
u.zstd.dstream);
613 free(fp->
u.zstd.nonconst_in);
614 free(fp->
u.zstd.out_buf.dst);
619#ifdef FREECIV_HAVE_LIBBZ2
621 if (
'w' == fp->
mode) {
622 BZ2_bzWriteClose(&fp->
u.bz2.error, fp->
u.bz2.file, 0, NULL, NULL);
624 BZ2_bzReadClose(&fp->
u.bz2.error, fp->
u.bz2.file);
626 error = fp->
u.bz2.error;
629 return BZ_OK == error ? 0 : 1;
631#ifdef FREECIV_HAVE_LIBZ
633 error = gzclose(fp->
u.zlib);
635 return 0 > error ? error : 0;
638 error = fclose(fp->
u.
plain);
645 __FUNCTION__, fp->
method);
678 }
else if (i < fp->u.mem.size
696#ifdef FREECIV_HAVE_LIBLZMA
701 for (i = 0; i <
size - 1; i += j) {
705 for (j = 0, line_end =
FALSE; fp->
u.xz.out_avail > 0
708 j++, fp->
u.xz.out_avail--) {
709 buffer[i + j] = fp->
u.xz.out_buf[fp->
u.xz.out_index++];
710 fp->
u.xz.total_read++;
711 if (buffer[i + j] ==
'\n') {
716 if (line_end ||
size <= j + i + 1) {
717 buffer[i + j] =
'\0';
721 if (fp->
u.xz.hack_byte_used) {
724 fp->
u.xz.in_buf[0] = fp->
u.xz.hack_byte;
725 len = fread(fp->
u.xz.in_buf + 1, 1, PLAIN_FILE_BUF_SIZE_XZ - 1,
730 hblen = fread(&fp->
u.xz.hack_byte, 1, 1, fp->
u.xz.
plain);
733 fp->
u.xz.hack_byte_used =
FALSE;
737 if (fp->
u.xz.error == LZMA_STREAM_END) {
743 buffer[i + j] =
'\0';
746 fp->
u.xz.stream.next_out = fp->
u.xz.out_buf;
747 fp->
u.xz.stream.avail_out = PLAIN_FILE_BUF_SIZE_XZ;
748 xz_action(fp, LZMA_FINISH);
749 fp->
u.xz.out_index = 0;
751 fp->
u.xz.stream.total_out - fp->
u.xz.total_read;
752 if (fp->
u.xz.error != LZMA_OK
753 && fp->
u.xz.error != LZMA_STREAM_END) {
760 fp->
u.xz.stream.next_in = fp->
u.xz.in_buf;
761 fp->
u.xz.stream.avail_in =
len;
762 fp->
u.xz.stream.next_out = fp->
u.xz.out_buf;
763 fp->
u.xz.stream.avail_out = PLAIN_FILE_BUF_SIZE_XZ;
764 if (fp->
u.xz.hack_byte_used) {
771 fp->
u.xz.stream.total_out - fp->
u.xz.total_read;
772 fp->
u.xz.out_index = 0;
773 if (fp->
u.xz.error != LZMA_OK && fp->
u.xz.error != LZMA_STREAM_END) {
784#ifdef FREECIV_HAVE_LIBZSTD
789 for (i = 0; i <
size - 1;) {
793 while (fp->
u.zstd.outbuf_pos < fp->
u.zstd.out_buf.pos) {
794 buffer[i] = ((
char *)fp->
u.zstd.out_buf.dst)[fp->
u.zstd.outbuf_pos++];
795 if (buffer[i] ==
'\n' || i ==
size - 2) {
796 buffer[i + 1] =
'\0';
803 fp->
u.zstd.outbuf_pos = 0;
805 if (fp->
u.zstd.in_buf.pos != 0) {
807 for (j = 0; j < fp->
u.zstd.in_buf.size - fp->
u.zstd.in_buf.pos; j++) {
808 fp->
u.zstd.nonconst_in[j] = fp->
u.zstd.nonconst_in[j + fp->
u.zstd.in_buf.pos];
812 len = fread(fp->
u.zstd.nonconst_in + j, 1, fp->
u.zstd.in_buf.size - j,
815 if (
len + j < fp->u.zstd.in_buf.size) {
816 fp->
u.zstd.in_buf.size =
len + j;
820 fp->
u.zstd.out_buf.pos = 0;
821 fp->
u.zstd.in_buf.pos = 0;
823 fp->
u.zstd.error = ZSTD_decompressStream(fp->
u.zstd.dstream,
826 if (ZSTD_isError(fp->
u.zstd.error)) {
831 if (fp->
u.zstd.out_buf.pos == 0 &&
len == 0) {
847#ifdef FREECIV_HAVE_LIBBZ2
855 if (fp->
u.bz2.firstbyte >= 0) {
856 buffer[0] = fp->
u.bz2.firstbyte;
857 fp->
u.bz2.firstbyte = -1;
860 if (!fp->
u.bz2.eof) {
861 last_read = BZ2_bzRead(&fp->
u.bz2.error, fp->
u.bz2.file, buffer + i, 1);
865 if (!fp->
u.bz2.eof) {
868 && fp->
u.bz2.error == BZ_OK && buffer[i - 1] !=
'\n' ;
870 last_read = BZ2_bzRead(&fp->
u.bz2.error, fp->
u.bz2.file,
873 if (fp->
u.bz2.error != BZ_OK
874 && (fp->
u.bz2.error != BZ_STREAM_END
880 if (fp->
u.bz2.error == BZ_STREAM_END) {
882 fp->
u.bz2.eof =
TRUE;
889#ifdef FREECIV_HAVE_LIBZ
891 return gzgets(fp->
u.zlib, buffer,
size);
899 __FUNCTION__, fp->
method);
903#ifdef FREECIV_HAVE_LIBLZMA
909static bool xz_outbuffer_to_file(
fz_FILE *fp, lzma_action
action)
915 fp->
u.xz.error = lzma_code(&fp->
u.xz.stream,
action);
917 if (fp->
u.xz.error != LZMA_OK && fp->
u.xz.error != LZMA_STREAM_END) {
921 while (total < PLAIN_FILE_BUF_SIZE_XZ - fp->u.xz.stream.avail_out) {
922 len = fwrite(fp->
u.xz.out_buf, 1,
923 PLAIN_FILE_BUF_SIZE_XZ - fp->
u.xz.stream.avail_out - total,
930 fp->
u.xz.stream.avail_out = PLAIN_FILE_BUF_SIZE_XZ;
931 fp->
u.xz.stream.next_out = fp->
u.xz.out_buf;
932 }
while (fp->
u.xz.stream.avail_in > 0);
942 fp->
u.xz.error = lzma_code(&fp->
u.xz.stream,
action);
943 if (fp->
u.xz.error != LZMA_MEMLIMIT_ERROR) {
947 while (fp->
u.xz.error == LZMA_MEMLIMIT_ERROR
948 && fp->
u.xz.memlimit < XZ_DECODER_MEMLIMIT_FINAL) {
949 fp->
u.xz.memlimit += XZ_DECODER_MEMLIMIT_STEP;
950 if (fp->
u.xz.memlimit > XZ_DECODER_MEMLIMIT_FINAL) {
951 fp->
u.xz.memlimit = XZ_DECODER_MEMLIMIT_FINAL;
953 fp->
u.xz.error = lzma_memlimit_set(&fp->
u.xz.stream, fp->
u.xz.memlimit);
956 fp->
u.xz.error = lzma_code(&fp->
u.xz.stream,
action);
980#ifdef FREECIV_HAVE_LIBLZMA
983 va_start(ap, format);
984 num =
fc_vsnprintf((
char *)fp->
u.xz.in_buf, PLAIN_FILE_BUF_SIZE_XZ,
989 log_error(
"Too much data: truncated in fz_fprintf (%u)",
990 PLAIN_FILE_BUF_SIZE_XZ);
991 num = PLAIN_FILE_BUF_SIZE_XZ;
993 fp->
u.xz.stream.next_in = fp->
u.xz.in_buf;
994 fp->
u.xz.stream.avail_in = num;
996 if (!xz_outbuffer_to_file(fp, LZMA_RUN)) {
999 return strlen((
char *)fp->
u.xz.in_buf);
1004#ifdef FREECIV_HAVE_LIBZSTD
1007 va_start(ap, format);
1009 PLAIN_FILE_BUF_SIZE_ZSTD, format, ap);
1013 log_error(
"Too much data: truncated in fz_fprintf (%u)",
1014 PLAIN_FILE_BUF_SIZE_ZSTD);
1015 num = PLAIN_FILE_BUF_SIZE_ZSTD;
1018 fp->
u.zstd.in_buf.pos = 0;
1019 fp->
u.zstd.in_buf.size = num;
1021 while (fp->
u.zstd.in_buf.pos < fp->
u.zstd.in_buf.size) {
1024 fp->
u.zstd.error = ZSTD_compressStream(fp->
u.zstd.cstream,
1025 &fp->
u.zstd.out_buf,
1026 &fp->
u.zstd.in_buf);
1027 if (ZSTD_isError(fp->
u.zstd.error)) {
1031 if (fp->
u.zstd.out_buf.pos > 0) {
1032 len = fwrite(fp->
u.zstd.out_buf.dst, 1,
1033 fp->
u.zstd.out_buf.pos, fp->
u.zstd.
plain);
1039 fp->
u.zstd.out_buf.pos = 0;
1047#ifdef FREECIV_HAVE_LIBBZ2
1052 va_start(ap, format);
1053 num =
fc_vsnprintf(buffer,
sizeof(buffer), format, ap);
1056 log_error(
"Too much data: truncated in fz_fprintf (%lu)",
1057 (
unsigned long)
sizeof(buffer));
1059 BZ2_bzWrite(&fp->
u.bz2.error, fp->
u.bz2.file, buffer, strlen(buffer));
1060 if (fp->
u.bz2.error != BZ_OK) {
1063 return strlen(buffer);
1067#ifdef FREECIV_HAVE_LIBZ
1072 va_start(ap, format);
1073 num =
fc_vsnprintf(buffer,
sizeof(buffer), format, ap);
1076 log_error(
"Too much data: truncated in fz_fprintf (%lu)",
1077 (
unsigned long)
sizeof(buffer));
1079 return gzwrite(fp->
u.zlib, buffer, (
unsigned int)strlen(buffer));
1083 va_start(ap, format);
1084 num = vfprintf(fp->
u.
plain, format, ap);
1091 __FUNCTION__, fp->
method);
1108#ifdef FREECIV_HAVE_LIBLZMA
1110 if (fp->
u.xz.error != LZMA_OK
1111 && fp->
u.xz.error != LZMA_STREAM_END) {
1117#ifdef FREECIV_HAVE_LIBZSTD
1119 if (ZSTD_isError(fp->
u.zstd.error)) {
1124#ifdef FREECIV_HAVE_LIBBZ2
1126 return (BZ_OK != fp->
u.bz2.error
1127 && BZ_STREAM_END != fp->
u.bz2.error);
1129#ifdef FREECIV_HAVE_LIBZ
1134 (void) gzerror(fp->
u.zlib, &error);
1135 return 0 > error ? error : 0;
1139 return ferror(fp->
u.
plain);
1145 __FUNCTION__, fp->
method);
1163#ifdef FREECIV_HAVE_LIBLZMA
1166 static char xzerror[50];
1167 char *cleartext = NULL;
1169 switch (fp->
u.xz.error) {
1173 case LZMA_STREAM_END:
1174 cleartext =
"Stream end";
1177 cleartext =
"No integrity check";
1179 case LZMA_UNSUPPORTED_CHECK:
1180 cleartext =
"Cannot calculate the integrity check";
1182 case LZMA_MEM_ERROR:
1183 cleartext =
"Mem error";
1185 case LZMA_MEMLIMIT_ERROR:
1186 cleartext =
"Memory limit reached";
1188 case LZMA_FORMAT_ERROR:
1189 cleartext =
"Unrecognized file format";
1191 case LZMA_OPTIONS_ERROR:
1192 cleartext =
"Unsupported options";
1194 case LZMA_DATA_ERROR:
1195 cleartext =
"Data error";
1197 case LZMA_BUF_ERROR:
1198 cleartext =
"Progress not possible";
1204 if (NULL != cleartext) {
1205 fc_snprintf(xzerror,
sizeof(xzerror),
"XZ: \"%s\" (%d)",
1206 cleartext, fp->
u.xz.error);
1208 fc_snprintf(xzerror,
sizeof(xzerror),
"XZ error %d",
1215#ifdef FREECIV_HAVE_LIBZSTD
1218 static char zstderror[50];
1219 char *cleartext = NULL;
1221 if (ZSTD_isError(fp->
u.zstd.error)) {
1222 cleartext =
"error";
1225 if (NULL != cleartext) {
1227 "ZSTD: \"%s\" (" SIZE_T_PRINTF
")",
1228 cleartext, fp->
u.zstd.error);
1231 "ZSTD error " SIZE_T_PRINTF,
1238#ifdef FREECIV_HAVE_LIBBZ2
1241 static char bzip2error[50];
1242 const char *cleartext = NULL;
1248 switch (fp->
u.bz2.error) {
1253 cleartext =
"Run ok";
1256 cleartext =
"Flush ok";
1259 cleartext =
"Finish ok";
1262 cleartext =
"Stream end";
1264 case BZ_CONFIG_ERROR:
1265 cleartext =
"Config error";
1267 case BZ_SEQUENCE_ERROR:
1268 cleartext =
"Sequence error";
1270 case BZ_PARAM_ERROR:
1271 cleartext =
"Parameter error";
1274 cleartext =
"Mem error";
1277 cleartext =
"Data error";
1279 case BZ_DATA_ERROR_MAGIC:
1280 cleartext =
"Not bzip2 file";
1283 cleartext =
"IO error";
1285 case BZ_UNEXPECTED_EOF:
1286 cleartext =
"Unexpected EOF";
1288 case BZ_OUTBUFF_FULL:
1289 cleartext =
"Output buffer full";
1295 if (cleartext != NULL) {
1296 fc_snprintf(bzip2error,
sizeof(bzip2error),
"Bz2: \"%s\" (%d)",
1297 cleartext, fp->
u.bz2.error);
1299 fc_snprintf(bzip2error,
sizeof(bzip2error),
"Bz2 error %d",
1305#ifdef FREECIV_HAVE_LIBZ
1309 const char *estr = gzerror(fp->
u.zlib, &errnum);
1320 __FUNCTION__, fp->
method);
#define fz_method_validate(method)
char * fz_fgets(char *buffer, int size, fz_FILE *fp)
int fz_fprintf(fz_FILE *fp, const char *format,...)
fz_FILE * fz_from_stream(FILE *stream)
fz_FILE * fz_from_memory(char *buffer, int size, bool control)
fz_FILE * fz_from_file(const char *filename, const char *in_mode, enum fz_method method, int compress_level)
const char * fz_strerror(fz_FILE *fp)
static bool fz_method_is_valid(enum fz_method method)
int fz_fclose(fz_FILE *fp)
int fz_ferror(fz_FILE *fp)
#define fc_assert_msg(condition, message,...)
#define fc_assert_ret_val(condition, val)
#define log_error(message,...)
int fc_snprintf(char *str, size_t n, const char *format,...)
const char * fc_strerror(fc_errno err)
int cat_snprintf(char *str, size_t n, const char *format,...)
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
FILE * fc_fopen(const char *filename, const char *opentype)
fc_errno fc_get_errno(void)
bool is_reg_file_for_access(const char *name, bool write_access)
#define sz_strlcpy(dest, src)
#define sz_strlcat(dest, src)