| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #define _CRT_SECURE_NO_DEPRECATE |
| | #include <windows.h> |
| | #ifdef _MSC_VER |
| | #pragma comment (lib, "user32.lib") |
| | #pragma comment (lib, "kernel32.lib") |
| | #endif |
| | #include <stdio.h> |
| |
|
| | |
| | |
| | |
| | #if defined(_M_IA64) || defined(_M_AMD64) |
| | #if _MSC_VER >= 1400 && _MSC_VER < 1500 |
| | #pragma comment(lib, "bufferoverflowU") |
| | #endif |
| | #endif |
| |
|
| | |
| | #if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1900 |
| | #define snprintf _snprintf |
| | #endif |
| |
|
| |
|
| | |
| |
|
| | static int CheckForCompilerFeature(const char *option); |
| | static int CheckForLinkerFeature(char **options, int count); |
| | static int IsIn(const char *string, const char *substring); |
| | static int SubstituteFile(const char *substs, const char *filename); |
| | static int QualifyPath(const char *path); |
| | static int LocateDependency(const char *keyfile); |
| | static const char *GetVersionFromFile(const char *filename, const char *match, int numdots); |
| | static DWORD WINAPI ReadFromPipe(LPVOID args); |
| |
|
| | |
| |
|
| | #define CHUNK 25 |
| | #define STATICBUFFERSIZE 1000 |
| | typedef struct { |
| | HANDLE pipe; |
| | char buffer[STATICBUFFERSIZE]; |
| | } pipeinfo; |
| |
|
| | pipeinfo Out = {INVALID_HANDLE_VALUE, ""}; |
| | pipeinfo Err = {INVALID_HANDLE_VALUE, ""}; |
| | |
| | |
| | |
| | |
| |
|
| | int |
| | main( |
| | int argc, |
| | char *argv[]) |
| | { |
| | char msg[300]; |
| | DWORD dwWritten; |
| | int chars; |
| | const char *s; |
| |
|
| | |
| | |
| | |
| |
|
| | SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); |
| |
|
| | |
| | |
| | |
| |
|
| | SetEnvironmentVariable("CL", ""); |
| | SetEnvironmentVariable("LINK", ""); |
| |
|
| | if (argc > 1 && *argv[1] == '-') { |
| | switch (*(argv[1]+1)) { |
| | case 'c': |
| | if (argc != 3) { |
| | chars = snprintf(msg, sizeof(msg) - 1, |
| | "usage: %s -c <compiler option>\n" |
| | "Tests for whether cl.exe supports an option\n" |
| | "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, |
| | &dwWritten, NULL); |
| | return 2; |
| | } |
| | return CheckForCompilerFeature(argv[2]); |
| | case 'l': |
| | if (argc < 3) { |
| | chars = snprintf(msg, sizeof(msg) - 1, |
| | "usage: %s -l <linker option> ?<mandatory option> ...?\n" |
| | "Tests for whether link.exe supports an option\n" |
| | "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, |
| | &dwWritten, NULL); |
| | return 2; |
| | } |
| | return CheckForLinkerFeature(&argv[2], argc-2); |
| | case 'f': |
| | if (argc == 2) { |
| | chars = snprintf(msg, sizeof(msg) - 1, |
| | "usage: %s -f <string> <substring>\n" |
| | "Find a substring within another\n" |
| | "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, |
| | &dwWritten, NULL); |
| | return 2; |
| | } else if (argc == 3) { |
| | |
| | |
| | |
| |
|
| | return 0; |
| | } else { |
| | return IsIn(argv[2], argv[3]); |
| | } |
| | case 's': |
| | if (argc == 2) { |
| | chars = snprintf(msg, sizeof(msg) - 1, |
| | "usage: %s -s <substitutions file> <file>\n" |
| | "Perform a set of string map type substutitions on a file\n" |
| | "exitcodes: 0\n", |
| | argv[0]); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, |
| | &dwWritten, NULL); |
| | return 2; |
| | } |
| | return SubstituteFile(argv[2], argv[3]); |
| | case 'V': |
| | if (argc != 4) { |
| | chars = snprintf(msg, sizeof(msg) - 1, |
| | "usage: %s -V filename matchstring\n" |
| | "Extract a version from a file:\n" |
| | "eg: pkgIndex.tcl \"package ifneeded http\"", |
| | argv[0]); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, |
| | &dwWritten, NULL); |
| | return 0; |
| | } |
| | s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0'); |
| | if (s && *s) { |
| | printf("%s\n", s); |
| | return 0; |
| | } else |
| | return 1; |
| |
|
| | case 'Q': |
| | if (argc != 3) { |
| | chars = snprintf(msg, sizeof(msg) - 1, |
| | "usage: %s -Q path\n" |
| | "Emit the fully qualified path\n" |
| | "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, |
| | &dwWritten, NULL); |
| | return 2; |
| | } |
| | return QualifyPath(argv[2]); |
| |
|
| | case 'L': |
| | if (argc != 3) { |
| | chars = snprintf(msg, sizeof(msg) - 1, |
| | "usage: %s -L keypath\n" |
| | "Emit the fully qualified path of directory containing keypath\n" |
| | "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, |
| | &dwWritten, NULL); |
| | return 2; |
| | } |
| | return LocateDependency(argv[2]); |
| | } |
| | } |
| | chars = snprintf(msg, sizeof(msg) - 1, |
| | "usage: %s -c|-f|-l|-Q|-s|-V ...\n" |
| | "This is a little helper app to equalize shell differences between WinNT and\n" |
| | "Win9x and get nmake.exe to accomplish its job.\n", |
| | argv[0]); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL); |
| | return 2; |
| | } |
| | |
| | static int |
| | CheckForCompilerFeature( |
| | const char *option) |
| | { |
| | STARTUPINFO si; |
| | PROCESS_INFORMATION pi; |
| | SECURITY_ATTRIBUTES sa; |
| | DWORD threadID; |
| | char msg[300]; |
| | BOOL ok; |
| | HANDLE hProcess, h, pipeThreads[2]; |
| | char cmdline[100]; |
| |
|
| | hProcess = GetCurrentProcess(); |
| |
|
| | memset(&pi, 0, sizeof(PROCESS_INFORMATION)); |
| | memset(&si, 0, sizeof(STARTUPINFO)); |
| | si.cb = sizeof(STARTUPINFO); |
| | si.dwFlags = STARTF_USESTDHANDLES; |
| | si.hStdInput = INVALID_HANDLE_VALUE; |
| |
|
| | memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
| | sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
| | sa.lpSecurityDescriptor = NULL; |
| | sa.bInheritHandle = FALSE; |
| |
|
| | |
| | |
| | |
| |
|
| | CreatePipe(&Out.pipe, &h, &sa, 0); |
| |
|
| | |
| | |
| | |
| |
|
| | DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, |
| | DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); |
| |
|
| | |
| | |
| | |
| |
|
| | CreatePipe(&Err.pipe, &h, &sa, 0); |
| | DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE, |
| | DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); |
| |
|
| | |
| | |
| | |
| |
|
| | lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch "); |
| |
|
| | |
| | |
| | |
| |
|
| | lstrcat(cmdline, option); |
| |
|
| | |
| | |
| | |
| |
|
| | lstrcat(cmdline, " .\\nul"); |
| |
|
| | ok = CreateProcess( |
| | NULL, |
| | cmdline, |
| | NULL, |
| | NULL, |
| | TRUE, |
| | DETACHED_PROCESS, |
| | NULL, |
| | NULL, |
| | &si, |
| | &pi); |
| |
|
| | if (!ok) { |
| | DWORD err = GetLastError(); |
| | int chars = snprintf(msg, sizeof(msg) - 1, |
| | "Tried to launch: \"%s\", but got error [%lu]: ", cmdline, err); |
| |
|
| | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| |
| | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars], |
| | (300-chars), 0); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL); |
| | return 2; |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | CloseHandle(si.hStdOutput); |
| | CloseHandle(si.hStdError); |
| |
|
| | WaitForInputIdle(pi.hProcess, 5000); |
| | CloseHandle(pi.hThread); |
| |
|
| | |
| | |
| | |
| |
|
| | pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID); |
| | pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID); |
| |
|
| | |
| | |
| | |
| |
|
| | WaitForSingleObject(pi.hProcess, INFINITE); |
| | CloseHandle(pi.hProcess); |
| |
|
| | |
| | |
| | |
| |
|
| | WaitForMultipleObjects(2, pipeThreads, TRUE, 500); |
| | CloseHandle(pipeThreads[0]); |
| | CloseHandle(pipeThreads[1]); |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | return !(strstr(Out.buffer, "D4002") != NULL |
| | || strstr(Err.buffer, "D4002") != NULL |
| | || strstr(Out.buffer, "D9002") != NULL |
| | || strstr(Err.buffer, "D9002") != NULL |
| | || strstr(Out.buffer, "D2021") != NULL |
| | || strstr(Err.buffer, "D2021") != NULL); |
| | } |
| | |
| | static int |
| | CheckForLinkerFeature( |
| | char **options, |
| | int count) |
| | { |
| | STARTUPINFO si; |
| | PROCESS_INFORMATION pi; |
| | SECURITY_ATTRIBUTES sa; |
| | DWORD threadID; |
| | char msg[300]; |
| | BOOL ok; |
| | HANDLE hProcess, h, pipeThreads[2]; |
| | int i; |
| | char cmdline[255]; |
| |
|
| | hProcess = GetCurrentProcess(); |
| |
|
| | memset(&pi, 0, sizeof(PROCESS_INFORMATION)); |
| | memset(&si, 0, sizeof(STARTUPINFO)); |
| | si.cb = sizeof(STARTUPINFO); |
| | si.dwFlags = STARTF_USESTDHANDLES; |
| | si.hStdInput = INVALID_HANDLE_VALUE; |
| |
|
| | memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
| | sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
| | sa.lpSecurityDescriptor = NULL; |
| | sa.bInheritHandle = TRUE; |
| |
|
| | |
| | |
| | |
| |
|
| | CreatePipe(&Out.pipe, &h, &sa, 0); |
| |
|
| | |
| | |
| | |
| |
|
| | DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, |
| | DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); |
| |
|
| | |
| | |
| | |
| |
|
| | CreatePipe(&Err.pipe, &h, &sa, 0); |
| | DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE, |
| | DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); |
| |
|
| | |
| | |
| | |
| |
|
| | lstrcpy(cmdline, "link.exe -nologo "); |
| |
|
| | |
| | |
| | |
| |
|
| | for (i = 0; i < count; i++) { |
| | lstrcat(cmdline, " \""); |
| | lstrcat(cmdline, options[i]); |
| | lstrcat(cmdline, "\""); |
| | } |
| |
|
| | ok = CreateProcess( |
| | NULL, |
| | cmdline, |
| | NULL, |
| | NULL, |
| | TRUE, |
| | DETACHED_PROCESS, |
| | NULL, |
| | NULL, |
| | &si, |
| | &pi); |
| |
|
| | if (!ok) { |
| | DWORD err = GetLastError(); |
| | int chars = snprintf(msg, sizeof(msg) - 1, |
| | "Tried to launch: \"%s\", but got error [%lu]: ", cmdline, err); |
| |
|
| | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| |
| | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars], |
| | (300-chars), 0); |
| | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL); |
| | return 2; |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | CloseHandle(si.hStdOutput); |
| | CloseHandle(si.hStdError); |
| |
|
| | WaitForInputIdle(pi.hProcess, 5000); |
| | CloseHandle(pi.hThread); |
| |
|
| | |
| | |
| | |
| |
|
| | pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID); |
| | pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID); |
| |
|
| | |
| | |
| | |
| |
|
| | WaitForSingleObject(pi.hProcess, INFINITE); |
| | CloseHandle(pi.hProcess); |
| |
|
| | |
| | |
| | |
| |
|
| | WaitForMultipleObjects(2, pipeThreads, TRUE, 500); |
| | CloseHandle(pipeThreads[0]); |
| | CloseHandle(pipeThreads[1]); |
| |
|
| | |
| | |
| | |
| |
|
| | return !(strstr(Out.buffer, "LNK1117") != NULL || |
| | strstr(Err.buffer, "LNK1117") != NULL || |
| | strstr(Out.buffer, "LNK4044") != NULL || |
| | strstr(Err.buffer, "LNK4044") != NULL || |
| | strstr(Out.buffer, "LNK4224") != NULL || |
| | strstr(Err.buffer, "LNK4224") != NULL); |
| | } |
| | |
| | static DWORD WINAPI |
| | ReadFromPipe( |
| | LPVOID args) |
| | { |
| | pipeinfo *pi = (pipeinfo *) args; |
| | char *lastBuf = pi->buffer; |
| | DWORD dwRead; |
| | BOOL ok; |
| |
|
| | again: |
| | if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) { |
| | CloseHandle(pi->pipe); |
| | return (DWORD)-1; |
| | } |
| | ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L); |
| | if (!ok || dwRead == 0) { |
| | CloseHandle(pi->pipe); |
| | return 0; |
| | } |
| | lastBuf += dwRead; |
| | goto again; |
| |
|
| | return 0; |
| | } |
| | |
| | static int |
| | IsIn( |
| | const char *string, |
| | const char *substring) |
| | { |
| | return (strstr(string, substring) != NULL); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | static const char * |
| | GetVersionFromFile( |
| | const char *filename, |
| | const char *match, |
| | int numdots) |
| | { |
| | static char szBuffer[100]; |
| | char *szResult = NULL; |
| | FILE *fp = fopen(filename, "rt"); |
| |
|
| | if (fp != NULL) { |
| | |
| | |
| | |
| |
|
| | while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) { |
| | LPSTR p, q; |
| |
|
| | p = strstr(szBuffer, match); |
| | if (p != NULL) { |
| | |
| | |
| | |
| |
|
| | p += strlen(match); |
| | while (*p && !isdigit((unsigned char)*p)) { |
| | ++p; |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | q = p; |
| | while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q) |
| | && !strchr("ab", q[-1])) || --numdots))) { |
| | ++q; |
| | } |
| |
|
| | *q = 0; |
| | szResult = p; |
| | break; |
| | } |
| | } |
| | fclose(fp); |
| | } |
| | return szResult; |
| | } |
| | |
| | |
| | |
| | |
| |
|
| | typedef struct list_item_t { |
| | struct list_item_t *nextPtr; |
| | char * key; |
| | char * value; |
| | } list_item_t; |
| |
|
| | |
| | static list_item_t * |
| | list_insert(list_item_t **listPtrPtr, const char *key, const char *value) |
| | { |
| | list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t)); |
| | if (itemPtr) { |
| | itemPtr->key = strdup(key); |
| | itemPtr->value = strdup(value); |
| | itemPtr->nextPtr = NULL; |
| |
|
| | while(*listPtrPtr) { |
| | listPtrPtr = &(*listPtrPtr)->nextPtr; |
| | } |
| | *listPtrPtr = itemPtr; |
| | } |
| | return itemPtr; |
| | } |
| |
|
| | static void |
| | list_free(list_item_t **listPtrPtr) |
| | { |
| | list_item_t *tmpPtr, *listPtr = *listPtrPtr; |
| | while (listPtr) { |
| | tmpPtr = listPtr; |
| | listPtr = listPtr->nextPtr; |
| | free(tmpPtr->key); |
| | free(tmpPtr->value); |
| | free(tmpPtr); |
| | } |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | static int |
| | SubstituteFile( |
| | const char *substitutions, |
| | const char *filename) |
| | { |
| | static char szBuffer[1024], szCopy[1024]; |
| | list_item_t *substPtr = NULL; |
| | FILE *fp, *sp; |
| |
|
| | fp = fopen(filename, "rt"); |
| | if (fp != NULL) { |
| |
|
| | |
| | |
| | |
| |
|
| | sp = fopen(substitutions, "rt"); |
| | if (sp != NULL) { |
| | while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) { |
| | unsigned char *ks, *ke, *vs, *ve; |
| | ks = (unsigned char*)szBuffer; |
| | while (ks && *ks && isspace(*ks)) ++ks; |
| | ke = ks; |
| | while (ke && *ke && !isspace(*ke)) ++ke; |
| | vs = ke; |
| | while (vs && *vs && isspace(*vs)) ++vs; |
| | ve = vs; |
| | while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve; |
| | *ke = 0, *ve = 0; |
| | list_insert(&substPtr, (char*)ks, (char*)vs); |
| | } |
| | fclose(sp); |
| | } |
| |
|
| | |
| | #ifndef NDEBUG |
| | { |
| | int n = 0; |
| | list_item_t *p = NULL; |
| | for (p = substPtr; p != NULL; p = p->nextPtr, ++n) { |
| | fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value); |
| | } |
| | } |
| | #endif |
| |
|
| | |
| | |
| | |
| |
|
| | while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) { |
| | list_item_t *p = NULL; |
| | for (p = substPtr; p != NULL; p = p->nextPtr) { |
| | char *m = strstr(szBuffer, p->key); |
| | if (m) { |
| | char *cp, *op, *sp; |
| | cp = szCopy; |
| | op = szBuffer; |
| | while (op != m) *cp++ = *op++; |
| | sp = p->value; |
| | while (sp && *sp) *cp++ = *sp++; |
| | op += strlen(p->key); |
| | while (*op) *cp++ = *op++; |
| | *cp = 0; |
| | memcpy(szBuffer, szCopy, sizeof(szCopy)); |
| | } |
| | } |
| | printf("%s", szBuffer); |
| | } |
| |
|
| | list_free(&substPtr); |
| | } |
| | fclose(fp); |
| | return 0; |
| | } |
| | |
| | BOOL FileExists(LPCTSTR szPath) |
| | { |
| | #ifndef INVALID_FILE_ATTRIBUTES |
| | #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) |
| | #endif |
| | DWORD pathAttr = GetFileAttributes(szPath); |
| | return (pathAttr != INVALID_FILE_ATTRIBUTES && |
| | !(pathAttr & FILE_ATTRIBUTE_DIRECTORY)); |
| | } |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | static int |
| | QualifyPath( |
| | const char *szPath) |
| | { |
| | char szCwd[MAX_PATH + 1]; |
| |
|
| | GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL); |
| | printf("%s\n", szCwd); |
| | return 0; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | static int LocateDependencyHelper(const char *dir, const char *keypath) |
| | { |
| | HANDLE hSearch; |
| | char path[MAX_PATH+1]; |
| | size_t dirlen; |
| | int keylen, ret; |
| | WIN32_FIND_DATA finfo; |
| |
|
| | if (dir == NULL || keypath == NULL) { |
| | return 2; |
| | } |
| | dirlen = strlen(dir); |
| | if (dirlen > sizeof(path) - 3) { |
| | return 2; |
| | } |
| | strncpy(path, dir, dirlen); |
| | strncpy(path+dirlen, "\\*", 3); |
| | keylen = strlen(keypath); |
| |
|
| | #if 0 |
| | |
| | |
| | |
| | |
| | |
| | hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0); |
| | #else |
| | hSearch = FindFirstFile(path, &finfo); |
| | #endif |
| | if (hSearch == INVALID_HANDLE_VALUE) |
| | return 1; |
| |
|
| | |
| | ret = 1; |
| | do { |
| | int sublen; |
| | |
| | |
| | |
| | |
| | if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) |
| | continue; |
| | sublen = strlen(finfo.cFileName); |
| | if ((dirlen+1+sublen+1+keylen+1) > sizeof(path)) |
| | continue; |
| | strncpy(path+dirlen+1, finfo.cFileName, sublen); |
| | path[dirlen+1+sublen] = '\\'; |
| | strncpy(path+dirlen+1+sublen+1, keypath, keylen+1); |
| | if (FileExists(path)) { |
| | |
| | path[dirlen+1+sublen] = '\0'; |
| | QualifyPath(path); |
| | ret = 0; |
| | break; |
| | } |
| | } while (FindNextFile(hSearch, &finfo)); |
| | FindClose(hSearch); |
| | return ret; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | static int LocateDependency(const char *keypath) |
| | { |
| | size_t i; |
| | int ret; |
| | static const char *paths[] = {"..", "..\\..", "..\\..\\.."}; |
| |
|
| | for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) { |
| | ret = LocateDependencyHelper(paths[i], keypath); |
| | if (ret == 0) { |
| | return ret; |
| | } |
| | } |
| | return ret; |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|