C指針原理(13)-C指針基礎
#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);
}
C指針原理(13)-C指針基礎