/* util.c Copyright (C) 2010-2019 Amf This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #ifdef __WIN32__ #include "windows.h" #include "shlobj.h" #endif #include "chroma.h" #include "level.h" #include "menu.h" #include "display.h" #include "util.h" void display_quit(); void file_readline(FILE *file, char *buffer, size_t size) { char c; size_t pos = 0; int ok = 1; while(ok) { c=fgetc(file); if(!feof(file) && c!=13 && c!=10 && c!=0 && pos<(size-1)) buffer[pos++]=c; else ok=0; } buffer[pos]=0; } int isfile(char *filename) { struct stat fst; if(stat(filename, &fst) == -1) return 0; if(S_ISREG(fst.st_mode)) return 1; return 0; } int isdirectory(char *filename) { struct stat fst; if(stat(filename, &fst) == -1) return 0; if(S_ISDIR(fst.st_mode)) return 1; return 0; } void ensuredirectory(char *directory) { char buffer[FILENAME_MAX + 4096]; if(isdirectory(directory)) return; errno = 0; #ifdef __WIN32__ if(mkdir(directory) && errno != EEXIST) #else if(mkdir(directory, 0755) && errno != EEXIST) #endif { sprintf(buffer, gettext("Unable to create directory '%s': %s"), directory, strerror(errno)); warning(buffer); } } void getfilename(char *filename, char *fullfilename, int create, int location) { char base[FILENAME_MAX]; #ifdef __WIN32__ #ifndef CSIDL_FLAG_CREATE #define CSIDL_FLAG_CREATE 0x8000 #endif #ifndef CSIDL_PERSONAL #define CSIDL_PERSONAL 0x05 #endif #ifndef CSIDL_APPDATA #define CSIDL_APPDATA 0x1A #endif #ifndef SHGFP_TYPE_CURRENT #define SHGFP_TYPE_CURRENT 0 #endif typedef HRESULT (WINAPI *SHGETFOLDERPATH)(HWND, int, HANDLE, DWORD, LPTSTR); HINSTANCE shfolder_dll; SHGETFOLDERPATH SHGetFolderPath ; #endif if(location == LOCATION_SYSTEM) { #ifdef CHROMA_DATA_DIR #ifndef __WIN32__ sprintf(fullfilename, "%s%s", CHROMA_DATA_DIR, filename); #else strcpy(fullfilename, filename); #endif #else strcpy(fullfilename, filename); #endif return; } if(location == LOCATION_DOCUMENTS) { #ifdef __WIN32__ if((shfolder_dll = LoadLibrary("shfolder.dll")) != NULL) { SHGetFolderPath = (void *)GetProcAddress(shfolder_dll, "SHGetFolderPathA"); if(SHGetFolderPath != NULL) { if(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, base) != S_OK) strcpy(base, "."); } FreeLibrary(shfolder_dll); if(create) ensuredirectory(base); } #endif #ifndef __WIN32__ if(getenv("HOME") != NULL) { snprintf(base, FILENAME_MAX, "%s", getenv("HOME")); base[FILENAME_MAX - 1] = 0; if(create) ensuredirectory(base); } else { strcpy(base, "."); } #endif snprintf(fullfilename, FILENAME_MAX, "%s/%s", base, filename); fullfilename[FILENAME_MAX - 1] = 0; if(create) ensuredirectory(fullfilename); } if(location == LOCATION_LOCAL) { #ifdef __WIN32__ if((shfolder_dll = LoadLibrary("shfolder.dll")) != NULL) { SHGetFolderPath = (void *)GetProcAddress(shfolder_dll, "SHGetFolderPathA"); if(SHGetFolderPath != NULL) { if(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, base) == S_OK) strcat(base, "\\chroma"); else strcpy(base, "chroma"); } FreeLibrary(shfolder_dll); if(create) ensuredirectory(base); } #endif #ifndef __WIN32__ if(getenv("HOME") != NULL) { snprintf(base, FILENAME_MAX, "%s/.chroma", getenv("HOME")); base[FILENAME_MAX - 1] = 0; if(create) ensuredirectory(base); } else { strcpy(base, ".chroma"); } #endif snprintf(fullfilename, FILENAME_MAX, "%s/%s", base, filename); fullfilename[FILENAME_MAX - 1] = 0; if(strcmp(filename, "curses.chroma") == 0) create = 0; if(strcmp(filename, "sdl.chroma") == 0) create = 0; if(create) ensuredirectory(fullfilename); } } void warning(char *error) { #ifdef __WIN32__ if(display_type() == DISPLAY_SDL) MessageBox(0,error,"Chroma",MB_OK); else { fprintf(stderr, "chroma: %s\n", error); sleep(5); } #else fprintf(stderr, "chroma: %s\n", error); #endif } void fatal(char *error) { display_quit(); #ifdef __WIN32__ if(display_type() == DISPLAY_SDL) MessageBox(0,error,"Chroma",MB_OK); else { fprintf(stderr, "chroma: %s\n", error); sleep(5); } #else fprintf(stderr, "chroma: %s\n", error); #endif exit(1); } int utf8strlen(char *string) { int i, j; i = 0; j = 0; while(string[i]) { if((string[i] & 0xc0) != 0x80) j ++; i++; } return j; } void utf8strncpy(char *out, char *in, int l) { int i, x; i = 0; x = 0; while(in[i] != 0 && x < l) { out[i] = in[i]; if((out[i] & 0xc0) != 0x80) x ++; i ++; } while(in[i] != 0 && (in[i] & 0xc0) == 0x80) { out[i] = in[i]; i ++; } out[i] = 0; /* unlike the real strncpy! */ }