/** * PROJECT: XTchain * LICENSE: See COPYING.md in the top level directory * FILE: tools/xtchain.h * DESCRIPTION: Common header for XTchain tools * DEVELOPERS: Martin Storsjo * Rafal Kupiec */ #ifdef UNICODE #define _UNICODE #endif #include #include #include #include #include #include #define _T(x) x #ifdef _UNICODE #define TS "%ls" #else #define TS "%s" #endif static inline int _tcsicmp(const char *a, const char *b) { while(*a && tolower(*a) == tolower(*b)) { a++; b++; } return *a - *b; } static inline char * concat(const char *prefix, const char *suffix) { int prefixlen = strlen(prefix); int suffixlen = strlen(suffix); char *buf = malloc((prefixlen + suffixlen + 1) * sizeof(*buf)); strcpy(buf, prefix); strcpy(buf + prefixlen, suffix); return buf; } static inline char * _tcsrchrs(const char *str, char char1, char char2) { char *ptr1 = strrchr(str, char1); char *ptr2 = strrchr(str, char2); if(!ptr1) { return ptr2; } if(!ptr2) { return ptr1; } if(ptr1 < ptr2) { return ptr2; } return ptr1; } static inline void split_argv(const char *argv0, char **dir_ptr, char **basename_ptr, char **target_ptr, char **exe_ptr) { const char *sep = _tcsrchrs(argv0, '/', '\\'); char *dir = strdup(_T("")); const char *basename = argv0; if(sep) { dir = strdup(argv0); dir[sep + 1 - argv0] = '\0'; basename = sep + 1; } basename = strdup(basename); char *period = strchr(basename, '.'); if(period) { *period = '\0'; } char *target = strdup(basename); char *dash = strrchr(target, '-'); const char *exe = basename; if(dash) { *dash = '\0'; exe = dash + 1; } else { target = NULL; } if(dir_ptr) { *dir_ptr = dir; } if(basename_ptr) { *basename_ptr = basename; } if(target_ptr) { *target_ptr = target; } if(exe_ptr) { *exe_ptr = exe; } } static inline int run_final(const char *executable, const char *const *argv) { execvp(executable, (char **) argv); perror(executable); return 1; }