一种跨平台获取程序名称的方法
代码来自于postgresql
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>/** is_absolute_path** By making this a macro we avoid needing to include path.c in libpq.*/
#ifndef WIN32
#define IS_DIR_SEP(ch) ((ch) == '/')#define is_absolute_path(filename) \
( \IS_DIR_SEP((filename)[0]) \
)
#else
#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */
#define is_absolute_path(filename) \
( \IS_DIR_SEP((filename)[0]) || \(isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \IS_DIR_SEP((filename)[2])) \
)
#endif/** skip_drive** On Windows, a path may begin with "C:" or "//network/". Advance over* this and point to the effective start of the path.*/
#ifdef WIN32static char *
skip_drive(const char *path)
{if (IS_DIR_SEP(path[0]) && IS_DIR_SEP(path[1])){path += 2;while (*path && !IS_DIR_SEP(*path))path++;}else if (isalpha((unsigned char) path[0]) && path[1] == ':'){path += 2;}return (char *) path;
}
#else#define skip_drive(path) (path)
#endif#if defined(WIN32) || defined(__CYGWIN__)
#define EXE ".exe"
#else
#define EXE ""
#endif/* msb for char */
#define HIGHBIT (0x80)
#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT)/** Case-independent comparison of two null-terminated strings.*/
int
pg_strcasecmp(const char *s1, const char *s2)
{for (;;){unsigned char ch1 = (unsigned char) *s1++;unsigned char ch2 = (unsigned char) *s2++;if (ch1 != ch2){if (ch1 >= 'A' && ch1 <= 'Z')ch1 += 'a' - 'A';else if (IS_HIGHBIT_SET(ch1) && isupper(ch1))ch1 = tolower(ch1);if (ch2 >= 'A' && ch2 <= 'Z')ch2 += 'a' - 'A';else if (IS_HIGHBIT_SET(ch2) && isupper(ch2))ch2 = tolower(ch2);if (ch1 != ch2)return (int) ch1 - (int) ch2;}if (ch1 == 0)break;}return 0;
}char *
last_dir_separator(const char *filename)
{const char *p,*ret = NULL;for (p = skip_drive(filename); *p; p++)if (IS_DIR_SEP(*p))ret = p;return (char *) ret;
}const char *
get_progname(const char *argv0)
{const char *nodir_name;char *progname;nodir_name = last_dir_separator(argv0);if (nodir_name)nodir_name++;elsenodir_name = skip_drive(argv0);progname = strdup(nodir_name);if (progname == NULL){fprintf(stderr, "%s: out of memory\n", nodir_name);abort();}#if defined(__CYGWIN__) || defined(WIN32)/* strip ".exe" suffix, regardless of case */if (strlen(progname) > sizeof(EXE) - 1 &&pg_strcasecmp(progname + strlen(progname) - (sizeof(EXE) - 1), EXE) == 0)progname[strlen(progname) - (sizeof(EXE) - 1)] = '\0';#endifreturn progname;
}const char *progname;int main(int argc, char *argv[]) {// 注意:argv[0]可能不包含完整路径,只包含程序名printf("Executable name (from argv[0]): %s\n", argv[0]);progname = get_progname(argv[0]);printf("progname is:%s\n",progname);return 0;
}