1. 程式人生 > >C指標原理(13)-C指標基礎

C指標原理(13)-C指標基礎

規範路徑格式,win32(windows環境下,路徑之間的各個目錄分隔將“\”改為"/",用“/”分隔,這樣的好處是在UNIX和WINDOWS都相容,而且也簡化了目錄表示。

#ifdef _WIN32

static char normalize_slashes(char path)
{
    char p;
    for (p = path;
p; ++p)
        if (p == '\')
           
p = '/';
    return path;
}

static HMODULE tcc_module;

win32環境下,我們假設lib和include在tcc.exe所在的位置。

/ on win32, we suppose the lib and includes are at the location of 'tcc.exe' /
static void tcc_set_lib_path_w32(TCCState s)
{
    char path[1024],
p;

   得到 當前TCC的完整路徑
    GetModuleFileNameA(tcc_module, path, sizeof path);
   得到路徑的目錄部分,注意得到的值是一個位置,指示目錄部分的結尾處

    p = tcc_basename(normalize_slashes(strlwr(path)));

   跳過bin目錄名,取前面的目錄,因為tcc.exe可能在/bin/目錄下
    if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
        p -= 5;

   下面取前面的目錄,p--是為了刪掉目錄的最後一個"/"
    else if (p > path)
        p--;
    *p = 0;

    設定lib路徑
    tcc_set_lib_path(s, path);
}

加入系統目錄

#ifdef TCC_TARGET_PE
static void tcc_add_systemdir(TCCState *s)
{
    char buf[1000];
    GetSystemDirectory(buf, sizeof buf);
    tcc_add_library_path(s, normalize_slashes(buf));
}
#endi

靜態連結

#ifndef CONFIG_TCC_STATIC
void dlclose(void *p)
{
    FreeLibrary((HMODULE)p);
}
#endif

生成dll

#ifdef LIBTCC_AS_DLL
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
    if (DLL_PROCESS_ATTACH == dwReason)
        tcc_module = hDll;
    return TRUE;
}
#endif
#endif

下面是複製並截斷字串的函式,函式讀入緩衝區的指標、緩衝區的大小以及源字串,將源字串截斷並複製到緩衝區中。

/****/

/ copy a string and truncate it. /

PUB_FUNC char pstrcpy(char buf, int buf_size, const char *s)

{

    char q, q_end;

    int c;

    緩衝區大於0,則可以開始複製字串。

    if (buf_size > 0) {

        計算複製字串的起始位置

        q = buf;

        q_end = buf + buf_size - 1;


        複製buf_size大小的字串到新字串中,最後加上字串終結符'\0'

        while (q < q_end) {

            c = *s++;

            if (c == '\0')

                break;

            *q++ = c;

        }

        *q = '\0';

}

返回新生成的字串

    return buf;

}

可以呼叫上面這個函式,傳入指標,指定新字串在緩衝區的位置,可以先生成一個大的緩衝區,再分次將不同的字串截斷複製進來。

接下來是字串拼接函式,將新字串截斷並拼接到緩衝區中。


/* strcat and truncate. */
PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
{
    int len;
    len = strlen(buf);
    if (len < buf_size) 
        pstrcpy(buf + len, buf_size - len, s);
    return buf;
}

直接在記憶體中複製字串,不是以字串終結符為標誌進行復制,如下:

PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num)
{
    memcpy(out, in, num);
    out[num] = '\0';
    return out;
}

下面這個函式,找到檔案完整路徑中的目錄部分,本身很普通,其實現有些意思,從後面向前面找

/ extract the basename of a file /
PUB_FUNC char tcc_basename(const char name)
{
    先找到字串終結符0   

    char *p = strchr(name, 0);

   然後從後向前移動指標,發現有目錄分隔符後,停止

    while (p > name && !IS_DIRSEP(p[-1]))
        --p;

   返回目錄在檔案路徑字串的結尾位置。
    return p;
}

下面找到副檔名


/* extract extension part of a file
 *
 * (if no extension, return pointer to end-of-string)
 */
PUB_FUNC char *tcc_fileextension (const char *name)
{
    char *b = tcc_basename(name);

   找到標註副檔名前面的點號
    char *e = strrchr(b, '.');

   返回副檔名
    return e ? e : strchr(b, 0);

}