File indexing completed on 2025-03-09 04:09:53
0001 /* Generic support functions for Xcftools 0002 * 0003 * This file was written by Henning Makholm <henning@makholm.net> 0004 * It is hereby in the public domain. 0005 * 0006 * In jurisdictions that do not recognise grants of copyright to the 0007 * public domain: I, the author and (presumably, in those jurisdictions) 0008 * copyright holder, hereby permit anyone to distribute and use this code, 0009 * in source code or binary form, with or without modifications. This 0010 * permission is world-wide and irrevocable. 0011 * 0012 * Of course, I will not be liable for any errors or shortcomings in the 0013 * code, since I give it away without asking any compenstations. 0014 * 0015 * If you use or distribute this code, I would appreciate receiving 0016 * credit for writing it, in whichever way you find proper and customary. 0017 */ 0018 0019 #include "xcftools.h" 0020 #include <string.h> 0021 #include <stdarg.h> 0022 #include <stdlib.h> 0023 #include <errno.h> 0024 0025 const char *progname = "$0" ; 0026 int verboseFlag = 0 ; 0027 0028 static void 0029 vFatalGeneric(int status,const char *format, va_list args) 0030 { 0031 (void) status; /* mark as unused */ 0032 if( format ) { 0033 if( *format == '!' ) { 0034 vfprintf(stderr,format+1,args); 0035 fprintf(stderr,": %s\n",strerror(errno)); 0036 } else { 0037 vfprintf(stderr,format,args); 0038 fputc('\n',stderr); 0039 } 0040 } 0041 /* don't exit here - Krita can't handle errors otherwise */ 0042 /* exit(status); */ 0043 } 0044 0045 void 0046 FatalGeneric(int status,const char* format,...) 0047 { 0048 va_list v; 0049 va_start(v,format); 0050 if( format ) fprintf(stderr,"%s: ",progname); 0051 vFatalGeneric(status,format,v); 0052 va_end(v); 0053 } 0054 0055 void 0056 FatalUnexpected(const char* format,...) 0057 { 0058 va_list v; 0059 va_start(v, format); 0060 fprintf(stderr,"%s: ",progname); 0061 vFatalGeneric(127, format, v); 0062 va_end(v); 0063 } 0064 0065 void 0066 FatalBadXCF(const char* format,...) 0067 { 0068 va_list v; va_start(v,format); 0069 fprintf(stderr,"%s: %s:\n ",progname,_("Corrupted or malformed XCF file")); 0070 vFatalGeneric(125,format,v) ; 0071 va_end(v); 0072 } 0073 0074 int 0075 xcfCheckspace(uint32_t addr,int spaceafter,const char *format,...) 0076 { 0077 if( xcf_length < spaceafter || addr > xcf_length - spaceafter ) { 0078 va_list v; 0079 va_start(v,format); 0080 fprintf(stderr,"%s: %s\n ",progname,_("Corrupted or truncated XCF file")); 0081 fprintf(stderr,"(0x%" PRIXPTR " bytes): ",(uintptr_t)xcf_length); 0082 vFatalGeneric(125,format,v) ; 0083 va_end(v); 0084 return XCF_ERROR; 0085 } 0086 return XCF_OK; 0087 } 0088 0089 0090 void 0091 FatalUnsupportedXCF(const char* format,...) 0092 { 0093 va_list v; 0094 va_start(v,format); 0095 fprintf(stderr,"%s: %s\n ",progname, 0096 _("The image contains features not understood by this program:")); 0097 vFatalGeneric(123,format,v) ; 0098 va_end(v); 0099 } 0100 0101 void 0102 gpl_blurb(void) 0103 { 0104 fprintf(stderr,PACKAGE_STRING "\n"); 0105 fprintf(stderr, 0106 _("Type \"%s -h\" to get an option summary.\n"),progname); 0107 /* don't exit here - Krita will close otherwise */ 0108 /* exit(1) ; */ 0109 } 0110 0111 /* ******************************************************* */ 0112 0113 void * 0114 xcfmalloc(size_t size) 0115 { 0116 void *ptr = malloc(size); 0117 if( !ptr ) { 0118 FatalUnexpected(_("Out of memory")); 0119 return XCF_PTR_EMPTY; 0120 } 0121 return ptr ; 0122 } 0123 0124 void 0125 xcffree(void *block) 0126 { 0127 if( xcf_file && 0128 (uint8_t*)block >= xcf_file && 0129 (uint8_t*)block < xcf_file + xcf_length ) 0130 ; 0131 else 0132 free(block); 0133 } 0134 0135 /* ******************************************************* */ 0136 0137 FILE * 0138 openout(const char *name) 0139 { 0140 FILE *newfile ; 0141 if( strcmp(name,"-") == 0 ) 0142 return stdout ; 0143 newfile = fopen(name,"wb") ; 0144 if( newfile == NULL ) { 0145 FatalUnexpected(_("!Cannot create file %s"),name); 0146 return XCF_PTR_EMPTY; 0147 } 0148 return newfile ; 0149 } 0150 0151 int 0152 closeout(FILE *f,const char *name) 0153 { 0154 if( f == NULL ) 0155 return XCF_OK; 0156 if( fflush(f) == 0 ) { 0157 errno = 0 ; 0158 if( !ferror(f) ) { 0159 if( fclose(f) == 0 ) 0160 return XCF_OK; 0161 } else if( errno == 0 ) { 0162 /* Attempt to coax a valid errno out of the standard library, 0163 * following an idea by Bruno Haible 0164 * https://lists.gnu.org/archive/html/bug-gnulib/2003-09/msg00157.html 0165 */ 0166 if( fputc('\0', f) != EOF && 0167 fflush(f) == 0 ) 0168 errno = EIO ; /* Argh, everything succedes. Just call it an I/O error */ 0169 } 0170 } 0171 FatalUnexpected(_("!Error writing file %s"),name); 0172 return XCF_ERROR; 0173 }