git-sqlite-vfs 0.0.1 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +67 -32
  2. package/bin/cli.js +53 -0
  3. package/c/Makefile +31 -16
  4. package/c/download-sqlite.cjs +17 -0
  5. package/c/git-merge-sqlitevfs.c +210 -186
  6. package/c/gitvfs.c +69 -21
  7. package/c/output/git-merge-sqlitevfs.exe +0 -0
  8. package/c/output/gitvfs.dll +0 -0
  9. package/c/output/gitvfs.o +0 -0
  10. package/c/output/gitvfs_test.exe +0 -0
  11. package/c/output/main.o +0 -0
  12. package/c/output/sqlite3.o +0 -0
  13. package/c/sqlite-autoconf-3450200/INSTALL +370 -0
  14. package/c/sqlite-autoconf-3450200/Makefile.am +20 -0
  15. package/c/sqlite-autoconf-3450200/Makefile.fallback +19 -0
  16. package/c/sqlite-autoconf-3450200/Makefile.in +1050 -0
  17. package/c/sqlite-autoconf-3450200/Makefile.msc +1069 -0
  18. package/c/sqlite-autoconf-3450200/README.txt +113 -0
  19. package/c/sqlite-autoconf-3450200/Replace.cs +223 -0
  20. package/c/sqlite-autoconf-3450200/aclocal.m4 +10204 -0
  21. package/c/sqlite-autoconf-3450200/compile +348 -0
  22. package/c/sqlite-autoconf-3450200/config.guess +1754 -0
  23. package/c/sqlite-autoconf-3450200/config.sub +1890 -0
  24. package/c/sqlite-autoconf-3450200/configure +16887 -0
  25. package/c/sqlite-autoconf-3450200/configure.ac +270 -0
  26. package/c/sqlite-autoconf-3450200/depcomp +791 -0
  27. package/c/sqlite-autoconf-3450200/install-sh +541 -0
  28. package/c/sqlite-autoconf-3450200/ltmain.sh +11251 -0
  29. package/c/sqlite-autoconf-3450200/missing +215 -0
  30. package/c/sqlite-autoconf-3450200/shell.c +29659 -0
  31. package/c/sqlite-autoconf-3450200/sqlite3.1 +161 -0
  32. package/c/sqlite-autoconf-3450200/sqlite3.c +255811 -0
  33. package/c/sqlite-autoconf-3450200/sqlite3.h +13357 -0
  34. package/c/sqlite-autoconf-3450200/sqlite3.pc.in +13 -0
  35. package/c/sqlite-autoconf-3450200/sqlite3.rc +83 -0
  36. package/c/sqlite-autoconf-3450200/sqlite3ext.h +719 -0
  37. package/c/sqlite-autoconf-3450200/sqlite3rc.h +3 -0
  38. package/c/sqlite-autoconf-3450200/tea/Makefile.in +475 -0
  39. package/c/sqlite-autoconf-3450200/tea/README +36 -0
  40. package/c/sqlite-autoconf-3450200/tea/aclocal.m4 +9 -0
  41. package/c/sqlite-autoconf-3450200/tea/configure +10179 -0
  42. package/c/sqlite-autoconf-3450200/tea/configure.ac +227 -0
  43. package/c/sqlite-autoconf-3450200/tea/doc/sqlite3.n +15 -0
  44. package/c/sqlite-autoconf-3450200/tea/generic/tclsqlite3.c +4080 -0
  45. package/c/sqlite-autoconf-3450200/tea/license.terms +6 -0
  46. package/c/sqlite-autoconf-3450200/tea/pkgIndex.tcl.in +10 -0
  47. package/c/sqlite-autoconf-3450200/tea/tclconfig/install-sh +528 -0
  48. package/c/sqlite-autoconf-3450200/tea/tclconfig/tcl.m4 +4067 -0
  49. package/c/sqlite-autoconf-3450200/tea/win/makefile.vc +430 -0
  50. package/c/sqlite-autoconf-3450200/tea/win/nmakehlp.c +815 -0
  51. package/c/sqlite-autoconf-3450200/tea/win/rules.vc +711 -0
  52. package/c/sqlite-autoconf-3450200.tar.gz +0 -0
  53. package/c/sqlite3.c +255811 -0
  54. package/c/sqlite3.h +13357 -0
  55. package/c/sqlite3ext.h +719 -0
  56. package/downloader.js +63 -0
  57. package/index.d.ts +14 -0
  58. package/index.js +103 -51
  59. package/install.js +13 -49
  60. package/package.json +22 -3
  61. package/c/output/git-merge-sqlitevfs +0 -0
  62. package/c/output/gitvfs.so +0 -0
  63. package/c/output/gitvfs_test +0 -0
  64. package/test.js +0 -209
@@ -0,0 +1,815 @@
1
+ /*
2
+ * ----------------------------------------------------------------------------
3
+ * nmakehlp.c --
4
+ *
5
+ * This is used to fix limitations within nmake and the environment.
6
+ *
7
+ * Copyright (c) 2002 by David Gravereaux.
8
+ * Copyright (c) 2006 by Pat Thoyts
9
+ *
10
+ * See the file "license.terms" for information on usage and redistribution of
11
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
+ * ----------------------------------------------------------------------------
13
+ */
14
+
15
+ #define _CRT_SECURE_NO_DEPRECATE
16
+ #include <windows.h>
17
+ #ifdef _MSC_VER
18
+ #pragma comment (lib, "user32.lib")
19
+ #pragma comment (lib, "kernel32.lib")
20
+ #endif
21
+ #include <stdio.h>
22
+ #include <math.h>
23
+
24
+ /*
25
+ * This library is required for x64 builds with _some_ versions of MSVC
26
+ */
27
+ #if defined(_M_IA64) || defined(_M_AMD64)
28
+ #if _MSC_VER >= 1400 && _MSC_VER < 1500
29
+ #pragma comment(lib, "bufferoverflowU")
30
+ #endif
31
+ #endif
32
+
33
+ /* ISO hack for dumb VC++ */
34
+ #ifdef _MSC_VER
35
+ #define snprintf _snprintf
36
+ #endif
37
+
38
+
39
+ /* protos */
40
+
41
+ static int CheckForCompilerFeature(const char *option);
42
+ static int CheckForLinkerFeature(char **options, int count);
43
+ static int IsIn(const char *string, const char *substring);
44
+ static int SubstituteFile(const char *substs, const char *filename);
45
+ static int QualifyPath(const char *path);
46
+ static int LocateDependency(const char *keyfile);
47
+ static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
48
+ static DWORD WINAPI ReadFromPipe(LPVOID args);
49
+
50
+ /* globals */
51
+
52
+ #define CHUNK 25
53
+ #define STATICBUFFERSIZE 1000
54
+ typedef struct {
55
+ HANDLE pipe;
56
+ char buffer[STATICBUFFERSIZE];
57
+ } pipeinfo;
58
+
59
+ pipeinfo Out = {INVALID_HANDLE_VALUE, ""};
60
+ pipeinfo Err = {INVALID_HANDLE_VALUE, ""};
61
+
62
+ /*
63
+ * exitcodes: 0 == no, 1 == yes, 2 == error
64
+ */
65
+
66
+ int
67
+ main(
68
+ int argc,
69
+ char *argv[])
70
+ {
71
+ char msg[300];
72
+ DWORD dwWritten;
73
+ int chars;
74
+ const char *s;
75
+
76
+ /*
77
+ * Make sure children (cl.exe and link.exe) are kept quiet.
78
+ */
79
+
80
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
81
+
82
+ /*
83
+ * Make sure the compiler and linker aren't effected by the outside world.
84
+ */
85
+
86
+ SetEnvironmentVariable("CL", "");
87
+ SetEnvironmentVariable("LINK", "");
88
+
89
+ if (argc > 1 && *argv[1] == '-') {
90
+ switch (*(argv[1]+1)) {
91
+ case 'c':
92
+ if (argc != 3) {
93
+ chars = snprintf(msg, sizeof(msg) - 1,
94
+ "usage: %s -c <compiler option>\n"
95
+ "Tests for whether cl.exe supports an option\n"
96
+ "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
97
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
98
+ &dwWritten, NULL);
99
+ return 2;
100
+ }
101
+ return CheckForCompilerFeature(argv[2]);
102
+ case 'l':
103
+ if (argc < 3) {
104
+ chars = snprintf(msg, sizeof(msg) - 1,
105
+ "usage: %s -l <linker option> ?<mandatory option> ...?\n"
106
+ "Tests for whether link.exe supports an option\n"
107
+ "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
108
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
109
+ &dwWritten, NULL);
110
+ return 2;
111
+ }
112
+ return CheckForLinkerFeature(&argv[2], argc-2);
113
+ case 'f':
114
+ if (argc == 2) {
115
+ chars = snprintf(msg, sizeof(msg) - 1,
116
+ "usage: %s -f <string> <substring>\n"
117
+ "Find a substring within another\n"
118
+ "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
119
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
120
+ &dwWritten, NULL);
121
+ return 2;
122
+ } else if (argc == 3) {
123
+ /*
124
+ * If the string is blank, there is no match.
125
+ */
126
+
127
+ return 0;
128
+ } else {
129
+ return IsIn(argv[2], argv[3]);
130
+ }
131
+ case 's':
132
+ if (argc == 2) {
133
+ chars = snprintf(msg, sizeof(msg) - 1,
134
+ "usage: %s -s <substitutions file> <file>\n"
135
+ "Perform a set of string map type substutitions on a file\n"
136
+ "exitcodes: 0\n",
137
+ argv[0]);
138
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
139
+ &dwWritten, NULL);
140
+ return 2;
141
+ }
142
+ return SubstituteFile(argv[2], argv[3]);
143
+ case 'V':
144
+ if (argc != 4) {
145
+ chars = snprintf(msg, sizeof(msg) - 1,
146
+ "usage: %s -V filename matchstring\n"
147
+ "Extract a version from a file:\n"
148
+ "eg: pkgIndex.tcl \"package ifneeded http\"",
149
+ argv[0]);
150
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
151
+ &dwWritten, NULL);
152
+ return 0;
153
+ }
154
+ s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
155
+ if (s && *s) {
156
+ printf("%s\n", s);
157
+ return 0;
158
+ } else
159
+ return 1; /* Version not found. Return non-0 exit code */
160
+
161
+ case 'Q':
162
+ if (argc != 3) {
163
+ chars = snprintf(msg, sizeof(msg) - 1,
164
+ "usage: %s -Q path\n"
165
+ "Emit the fully qualified path\n"
166
+ "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
167
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
168
+ &dwWritten, NULL);
169
+ return 2;
170
+ }
171
+ return QualifyPath(argv[2]);
172
+
173
+ case 'L':
174
+ if (argc != 3) {
175
+ chars = snprintf(msg, sizeof(msg) - 1,
176
+ "usage: %s -L keypath\n"
177
+ "Emit the fully qualified path of directory containing keypath\n"
178
+ "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
179
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
180
+ &dwWritten, NULL);
181
+ return 2;
182
+ }
183
+ return LocateDependency(argv[2]);
184
+ }
185
+ }
186
+ chars = snprintf(msg, sizeof(msg) - 1,
187
+ "usage: %s -c|-f|-l|-Q|-s|-V ...\n"
188
+ "This is a little helper app to equalize shell differences between WinNT and\n"
189
+ "Win9x and get nmake.exe to accomplish its job.\n",
190
+ argv[0]);
191
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
192
+ return 2;
193
+ }
194
+
195
+ static int
196
+ CheckForCompilerFeature(
197
+ const char *option)
198
+ {
199
+ STARTUPINFO si;
200
+ PROCESS_INFORMATION pi;
201
+ SECURITY_ATTRIBUTES sa;
202
+ DWORD threadID;
203
+ char msg[300];
204
+ BOOL ok;
205
+ HANDLE hProcess, h, pipeThreads[2];
206
+ char cmdline[100];
207
+
208
+ hProcess = GetCurrentProcess();
209
+
210
+ ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
211
+ ZeroMemory(&si, sizeof(STARTUPINFO));
212
+ si.cb = sizeof(STARTUPINFO);
213
+ si.dwFlags = STARTF_USESTDHANDLES;
214
+ si.hStdInput = INVALID_HANDLE_VALUE;
215
+
216
+ ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
217
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
218
+ sa.lpSecurityDescriptor = NULL;
219
+ sa.bInheritHandle = FALSE;
220
+
221
+ /*
222
+ * Create a non-inheritible pipe.
223
+ */
224
+
225
+ CreatePipe(&Out.pipe, &h, &sa, 0);
226
+
227
+ /*
228
+ * Dupe the write side, make it inheritible, and close the original.
229
+ */
230
+
231
+ DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
232
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
233
+
234
+ /*
235
+ * Same as above, but for the error side.
236
+ */
237
+
238
+ CreatePipe(&Err.pipe, &h, &sa, 0);
239
+ DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
240
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
241
+
242
+ /*
243
+ * Base command line.
244
+ */
245
+
246
+ lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
247
+
248
+ /*
249
+ * Append our option for testing
250
+ */
251
+
252
+ lstrcat(cmdline, option);
253
+
254
+ /*
255
+ * Filename to compile, which exists, but is nothing and empty.
256
+ */
257
+
258
+ lstrcat(cmdline, " .\\nul");
259
+
260
+ ok = CreateProcess(
261
+ NULL, /* Module name. */
262
+ cmdline, /* Command line. */
263
+ NULL, /* Process handle not inheritable. */
264
+ NULL, /* Thread handle not inheritable. */
265
+ TRUE, /* yes, inherit handles. */
266
+ DETACHED_PROCESS, /* No console for you. */
267
+ NULL, /* Use parent's environment block. */
268
+ NULL, /* Use parent's starting directory. */
269
+ &si, /* Pointer to STARTUPINFO structure. */
270
+ &pi); /* Pointer to PROCESS_INFORMATION structure. */
271
+
272
+ if (!ok) {
273
+ DWORD err = GetLastError();
274
+ int chars = snprintf(msg, sizeof(msg) - 1,
275
+ "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
276
+
277
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
278
+ FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
279
+ (300-chars), 0);
280
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
281
+ return 2;
282
+ }
283
+
284
+ /*
285
+ * Close our references to the write handles that have now been inherited.
286
+ */
287
+
288
+ CloseHandle(si.hStdOutput);
289
+ CloseHandle(si.hStdError);
290
+
291
+ WaitForInputIdle(pi.hProcess, 5000);
292
+ CloseHandle(pi.hThread);
293
+
294
+ /*
295
+ * Start the pipe reader threads.
296
+ */
297
+
298
+ pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
299
+ pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
300
+
301
+ /*
302
+ * Block waiting for the process to end.
303
+ */
304
+
305
+ WaitForSingleObject(pi.hProcess, INFINITE);
306
+ CloseHandle(pi.hProcess);
307
+
308
+ /*
309
+ * Wait for our pipe to get done reading, should it be a little slow.
310
+ */
311
+
312
+ WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
313
+ CloseHandle(pipeThreads[0]);
314
+ CloseHandle(pipeThreads[1]);
315
+
316
+ /*
317
+ * Look for the commandline warning code in both streams.
318
+ * - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
319
+ */
320
+
321
+ return !(strstr(Out.buffer, "D4002") != NULL
322
+ || strstr(Err.buffer, "D4002") != NULL
323
+ || strstr(Out.buffer, "D9002") != NULL
324
+ || strstr(Err.buffer, "D9002") != NULL
325
+ || strstr(Out.buffer, "D2021") != NULL
326
+ || strstr(Err.buffer, "D2021") != NULL);
327
+ }
328
+
329
+ static int
330
+ CheckForLinkerFeature(
331
+ char **options,
332
+ int count)
333
+ {
334
+ STARTUPINFO si;
335
+ PROCESS_INFORMATION pi;
336
+ SECURITY_ATTRIBUTES sa;
337
+ DWORD threadID;
338
+ char msg[300];
339
+ BOOL ok;
340
+ HANDLE hProcess, h, pipeThreads[2];
341
+ int i;
342
+ char cmdline[255];
343
+
344
+ hProcess = GetCurrentProcess();
345
+
346
+ ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
347
+ ZeroMemory(&si, sizeof(STARTUPINFO));
348
+ si.cb = sizeof(STARTUPINFO);
349
+ si.dwFlags = STARTF_USESTDHANDLES;
350
+ si.hStdInput = INVALID_HANDLE_VALUE;
351
+
352
+ ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
353
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
354
+ sa.lpSecurityDescriptor = NULL;
355
+ sa.bInheritHandle = TRUE;
356
+
357
+ /*
358
+ * Create a non-inheritible pipe.
359
+ */
360
+
361
+ CreatePipe(&Out.pipe, &h, &sa, 0);
362
+
363
+ /*
364
+ * Dupe the write side, make it inheritible, and close the original.
365
+ */
366
+
367
+ DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
368
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
369
+
370
+ /*
371
+ * Same as above, but for the error side.
372
+ */
373
+
374
+ CreatePipe(&Err.pipe, &h, &sa, 0);
375
+ DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
376
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
377
+
378
+ /*
379
+ * Base command line.
380
+ */
381
+
382
+ lstrcpy(cmdline, "link.exe -nologo ");
383
+
384
+ /*
385
+ * Append our option for testing.
386
+ */
387
+
388
+ for (i = 0; i < count; i++) {
389
+ lstrcat(cmdline, " \"");
390
+ lstrcat(cmdline, options[i]);
391
+ lstrcat(cmdline, "\"");
392
+ }
393
+
394
+ ok = CreateProcess(
395
+ NULL, /* Module name. */
396
+ cmdline, /* Command line. */
397
+ NULL, /* Process handle not inheritable. */
398
+ NULL, /* Thread handle not inheritable. */
399
+ TRUE, /* yes, inherit handles. */
400
+ DETACHED_PROCESS, /* No console for you. */
401
+ NULL, /* Use parent's environment block. */
402
+ NULL, /* Use parent's starting directory. */
403
+ &si, /* Pointer to STARTUPINFO structure. */
404
+ &pi); /* Pointer to PROCESS_INFORMATION structure. */
405
+
406
+ if (!ok) {
407
+ DWORD err = GetLastError();
408
+ int chars = snprintf(msg, sizeof(msg) - 1,
409
+ "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
410
+
411
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
412
+ FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
413
+ (300-chars), 0);
414
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
415
+ return 2;
416
+ }
417
+
418
+ /*
419
+ * Close our references to the write handles that have now been inherited.
420
+ */
421
+
422
+ CloseHandle(si.hStdOutput);
423
+ CloseHandle(si.hStdError);
424
+
425
+ WaitForInputIdle(pi.hProcess, 5000);
426
+ CloseHandle(pi.hThread);
427
+
428
+ /*
429
+ * Start the pipe reader threads.
430
+ */
431
+
432
+ pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
433
+ pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
434
+
435
+ /*
436
+ * Block waiting for the process to end.
437
+ */
438
+
439
+ WaitForSingleObject(pi.hProcess, INFINITE);
440
+ CloseHandle(pi.hProcess);
441
+
442
+ /*
443
+ * Wait for our pipe to get done reading, should it be a little slow.
444
+ */
445
+
446
+ WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
447
+ CloseHandle(pipeThreads[0]);
448
+ CloseHandle(pipeThreads[1]);
449
+
450
+ /*
451
+ * Look for the commandline warning code in the stderr stream.
452
+ */
453
+
454
+ return !(strstr(Out.buffer, "LNK1117") != NULL ||
455
+ strstr(Err.buffer, "LNK1117") != NULL ||
456
+ strstr(Out.buffer, "LNK4044") != NULL ||
457
+ strstr(Err.buffer, "LNK4044") != NULL ||
458
+ strstr(Out.buffer, "LNK4224") != NULL ||
459
+ strstr(Err.buffer, "LNK4224") != NULL);
460
+ }
461
+
462
+ static DWORD WINAPI
463
+ ReadFromPipe(
464
+ LPVOID args)
465
+ {
466
+ pipeinfo *pi = (pipeinfo *) args;
467
+ char *lastBuf = pi->buffer;
468
+ DWORD dwRead;
469
+ BOOL ok;
470
+
471
+ again:
472
+ if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
473
+ CloseHandle(pi->pipe);
474
+ return (DWORD)-1;
475
+ }
476
+ ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
477
+ if (!ok || dwRead == 0) {
478
+ CloseHandle(pi->pipe);
479
+ return 0;
480
+ }
481
+ lastBuf += dwRead;
482
+ goto again;
483
+
484
+ return 0; /* makes the compiler happy */
485
+ }
486
+
487
+ static int
488
+ IsIn(
489
+ const char *string,
490
+ const char *substring)
491
+ {
492
+ return (strstr(string, substring) != NULL);
493
+ }
494
+
495
+ /*
496
+ * GetVersionFromFile --
497
+ * Looks for a match string in a file and then returns the version
498
+ * following the match where a version is anything acceptable to
499
+ * package provide or package ifneeded.
500
+ */
501
+
502
+ static const char *
503
+ GetVersionFromFile(
504
+ const char *filename,
505
+ const char *match,
506
+ int numdots)
507
+ {
508
+ static char szBuffer[100];
509
+ char *szResult = NULL;
510
+ FILE *fp = fopen(filename, "rt");
511
+
512
+ if (fp != NULL) {
513
+ /*
514
+ * Read data until we see our match string.
515
+ */
516
+
517
+ while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
518
+ LPSTR p, q;
519
+
520
+ p = strstr(szBuffer, match);
521
+ if (p != NULL) {
522
+ /*
523
+ * Skip to first digit after the match.
524
+ */
525
+
526
+ p += strlen(match);
527
+ while (*p && !isdigit((unsigned char)*p)) {
528
+ ++p;
529
+ }
530
+
531
+ /*
532
+ * Find ending whitespace.
533
+ */
534
+
535
+ q = p;
536
+ while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q)
537
+ && !strchr("ab", q[-1])) || --numdots))) {
538
+ ++q;
539
+ }
540
+
541
+ *q = 0;
542
+ szResult = p;
543
+ break;
544
+ }
545
+ }
546
+ fclose(fp);
547
+ }
548
+ return szResult;
549
+ }
550
+
551
+ /*
552
+ * List helpers for the SubstituteFile function
553
+ */
554
+
555
+ typedef struct list_item_t {
556
+ struct list_item_t *nextPtr;
557
+ char * key;
558
+ char * value;
559
+ } list_item_t;
560
+
561
+ /* insert a list item into the list (list may be null) */
562
+ static list_item_t *
563
+ list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
564
+ {
565
+ list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t));
566
+ if (itemPtr) {
567
+ itemPtr->key = strdup(key);
568
+ itemPtr->value = strdup(value);
569
+ itemPtr->nextPtr = NULL;
570
+
571
+ while(*listPtrPtr) {
572
+ listPtrPtr = &(*listPtrPtr)->nextPtr;
573
+ }
574
+ *listPtrPtr = itemPtr;
575
+ }
576
+ return itemPtr;
577
+ }
578
+
579
+ static void
580
+ list_free(list_item_t **listPtrPtr)
581
+ {
582
+ list_item_t *tmpPtr, *listPtr = *listPtrPtr;
583
+ while (listPtr) {
584
+ tmpPtr = listPtr;
585
+ listPtr = listPtr->nextPtr;
586
+ free(tmpPtr->key);
587
+ free(tmpPtr->value);
588
+ free(tmpPtr);
589
+ }
590
+ }
591
+
592
+ /*
593
+ * SubstituteFile --
594
+ * As windows doesn't provide anything useful like sed and it's unreliable
595
+ * to use the tclsh you are building against (consider x-platform builds -
596
+ * eg compiling AMD64 target from IX86) we provide a simple substitution
597
+ * option here to handle autoconf style substitutions.
598
+ * The substitution file is whitespace and line delimited. The file should
599
+ * consist of lines matching the regular expression:
600
+ * \s*\S+\s+\S*$
601
+ *
602
+ * Usage is something like:
603
+ * nmakehlp -S << $** > $@
604
+ * @PACKAGE_NAME@ $(PACKAGE_NAME)
605
+ * @PACKAGE_VERSION@ $(PACKAGE_VERSION)
606
+ * <<
607
+ */
608
+
609
+ static int
610
+ SubstituteFile(
611
+ const char *substitutions,
612
+ const char *filename)
613
+ {
614
+ static char szBuffer[1024], szCopy[1024];
615
+ list_item_t *substPtr = NULL;
616
+ FILE *fp, *sp;
617
+
618
+ fp = fopen(filename, "rt");
619
+ if (fp != NULL) {
620
+
621
+ /*
622
+ * Build a list of substutitions from the first filename
623
+ */
624
+
625
+ sp = fopen(substitutions, "rt");
626
+ if (sp != NULL) {
627
+ while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) {
628
+ unsigned char *ks, *ke, *vs, *ve;
629
+ ks = (unsigned char*)szBuffer;
630
+ while (ks && *ks && isspace(*ks)) ++ks;
631
+ ke = ks;
632
+ while (ke && *ke && !isspace(*ke)) ++ke;
633
+ vs = ke;
634
+ while (vs && *vs && isspace(*vs)) ++vs;
635
+ ve = vs;
636
+ while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
637
+ *ke = 0, *ve = 0;
638
+ list_insert(&substPtr, (char*)ks, (char*)vs);
639
+ }
640
+ fclose(sp);
641
+ }
642
+
643
+ /* debug: dump the list */
644
+ #ifndef NDEBUG
645
+ {
646
+ int n = 0;
647
+ list_item_t *p = NULL;
648
+ for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
649
+ fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
650
+ }
651
+ }
652
+ #endif
653
+
654
+ /*
655
+ * Run the substitutions over each line of the input
656
+ */
657
+
658
+ while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
659
+ list_item_t *p = NULL;
660
+ for (p = substPtr; p != NULL; p = p->nextPtr) {
661
+ char *m = strstr(szBuffer, p->key);
662
+ if (m) {
663
+ char *cp, *op, *sp;
664
+ cp = szCopy;
665
+ op = szBuffer;
666
+ while (op != m) *cp++ = *op++;
667
+ sp = p->value;
668
+ while (sp && *sp) *cp++ = *sp++;
669
+ op += strlen(p->key);
670
+ while (*op) *cp++ = *op++;
671
+ *cp = 0;
672
+ memcpy(szBuffer, szCopy, sizeof(szCopy));
673
+ }
674
+ }
675
+ printf("%s", szBuffer);
676
+ }
677
+
678
+ list_free(&substPtr);
679
+ }
680
+ fclose(fp);
681
+ return 0;
682
+ }
683
+
684
+ BOOL FileExists(LPCTSTR szPath)
685
+ {
686
+ #ifndef INVALID_FILE_ATTRIBUTES
687
+ #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
688
+ #endif
689
+ DWORD pathAttr = GetFileAttributes(szPath);
690
+ return (pathAttr != INVALID_FILE_ATTRIBUTES &&
691
+ !(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
692
+ }
693
+
694
+
695
+ /*
696
+ * QualifyPath --
697
+ *
698
+ * This composes the current working directory with a provided path
699
+ * and returns the fully qualified and normalized path.
700
+ * Mostly needed to setup paths for testing.
701
+ */
702
+
703
+ static int
704
+ QualifyPath(
705
+ const char *szPath)
706
+ {
707
+ char szCwd[MAX_PATH + 1];
708
+
709
+ GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
710
+ printf("%s\n", szCwd);
711
+ return 0;
712
+ }
713
+
714
+ /*
715
+ * Implements LocateDependency for a single directory. See that command
716
+ * for an explanation.
717
+ * Returns 0 if found after printing the directory.
718
+ * Returns 1 if not found but no errors.
719
+ * Returns 2 on any kind of error
720
+ * Basically, these are used as exit codes for the process.
721
+ */
722
+ static int LocateDependencyHelper(const char *dir, const char *keypath)
723
+ {
724
+ HANDLE hSearch;
725
+ char path[MAX_PATH+1];
726
+ size_t dirlen;
727
+ int keylen, ret;
728
+ WIN32_FIND_DATA finfo;
729
+
730
+ if (dir == NULL || keypath == NULL)
731
+ return 2; /* Have no real error reporting mechanism into nmake */
732
+ dirlen = strlen(dir);
733
+ if ((dirlen + 3) > sizeof(path))
734
+ return 2;
735
+ strncpy(path, dir, dirlen);
736
+ strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */
737
+ keylen = strlen(keypath);
738
+
739
+ #if 0 /* This function is not available in Visual C++ 6 */
740
+ /*
741
+ * Use numerics 0 -> FindExInfoStandard,
742
+ * 1 -> FindExSearchLimitToDirectories,
743
+ * as these are not defined in Visual C++ 6
744
+ */
745
+ hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
746
+ #else
747
+ hSearch = FindFirstFile(path, &finfo);
748
+ #endif
749
+ if (hSearch == INVALID_HANDLE_VALUE)
750
+ return 1; /* Not found */
751
+
752
+ /* Loop through all subdirs checking if the keypath is under there */
753
+ ret = 1; /* Assume not found */
754
+ do {
755
+ int sublen;
756
+ /*
757
+ * We need to check it is a directory despite the
758
+ * FindExSearchLimitToDirectories in the above call. See SDK docs
759
+ */
760
+ if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
761
+ continue;
762
+ sublen = strlen(finfo.cFileName);
763
+ if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
764
+ continue; /* Path does not fit, assume not matched */
765
+ strncpy(path+dirlen+1, finfo.cFileName, sublen);
766
+ path[dirlen+1+sublen] = '\\';
767
+ strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
768
+ if (FileExists(path)) {
769
+ /* Found a match, print to stdout */
770
+ path[dirlen+1+sublen] = '\0';
771
+ QualifyPath(path);
772
+ ret = 0;
773
+ break;
774
+ }
775
+ } while (FindNextFile(hSearch, &finfo));
776
+ FindClose(hSearch);
777
+ return ret;
778
+ }
779
+
780
+ /*
781
+ * LocateDependency --
782
+ *
783
+ * Locates a dependency for a package.
784
+ * keypath - a relative path within the package directory
785
+ * that is used to confirm it is the correct directory.
786
+ * The search path for the package directory is currently only
787
+ * the parent and grandparent of the current working directory.
788
+ * If found, the command prints
789
+ * name_DIRPATH=<full path of located directory>
790
+ * and returns 0. If not found, does not print anything and returns 1.
791
+ */
792
+ static int LocateDependency(const char *keypath)
793
+ {
794
+ size_t i;
795
+ int ret;
796
+ static const char *paths[] = {"..", "..\\..", "..\\..\\.."};
797
+
798
+ for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
799
+ ret = LocateDependencyHelper(paths[i], keypath);
800
+ if (ret == 0)
801
+ return ret;
802
+ }
803
+ return ret;
804
+ }
805
+
806
+
807
+ /*
808
+ * Local variables:
809
+ * mode: c
810
+ * c-basic-offset: 4
811
+ * fill-column: 78
812
+ * indent-tabs-mode: t
813
+ * tab-width: 8
814
+ * End:
815
+ */