一种跨平台获取程序名称的方法

一种跨平台获取程序名称的方法

代码来自于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 WIN32

static 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++;
    else
        nodir_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';
    #endif

    return 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;
}

你可能感兴趣的:(C项目,c语言)