FFmpeg
Loading...
Searching...
No Matches
mscl.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/*
20 * msvc compiler wrapper, used as: mscl <compiler> <arguments...>
21 *
22 * cl.exe cannot write a GNU style dependency file directly. When
23 * -showIncludes is present on the command line, this wrapper converts the
24 * include records from the compiler's stdout into a .d file, written next to
25 * the object file as a byproduct of compilation.
26 *
27 * Dependency paths below the current directory are written relative to it,
28 * which keeps the .d files independent of how the environment maps Windows
29 * drives (MSYS, Cygwin and WSL all differ). Everything else stays absolute,
30 * in forward slash form. Spaces, '#' and '$' are escaped the same way gcc
31 * escapes them in -MD output.
32 *
33 * On a POSIX host driving a Windows compiler (cl.exe through WSL interop, for
34 * example) the records carry Windows paths. Each distinct drive or share root
35 * is translated once with wslpath or cygpath and the result is reused for
36 * every path below it.
37 */
38
39#include <ctype.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43
44#include "libavutil/macros.h"
45
46#ifdef _WIN32
47#define WIN32_LEAN_AND_MEAN
48#include <windows.h>
49#else
50#include <errno.h>
51#include <sys/wait.h>
52#include <unistd.h>
53#endif
54
55#define INC_PREFIX "Note: including file:"
56
57static const char *obj;
58static const char *src;
59
60static char *cwd;
61
62static char **deps;
63static size_t nb_deps, max_deps;
64
65static char *linebuf;
66static size_t line_len, line_max;
67
68static void die(const char *msg)
69{
70 fprintf(stderr, "mscl: %s\n", msg);
71 exit(1);
72}
73
74static void *xrealloc(void *ptr, size_t size)
75{
76 ptr = realloc(ptr, size);
77 if (!ptr)
78 die("out of memory");
79 return ptr;
80}
81
82static char *xstrdup(const char *s)
83{
84 size_t size = strlen(s) + 1;
85 return memcpy(xrealloc(NULL, size), s, size);
86}
87
88#ifdef _WIN32
89
90/* code page the compiler writes its output in */
91static UINT out_cp;
92
93static wchar_t *mb_to_wide(const char *s, UINT cp)
94{
95 int n = MultiByteToWideChar(cp, 0, s, -1, NULL, 0);
96 wchar_t *w = xrealloc(NULL, (n ? n : 1) * sizeof(*w));
97 if (!n)
98 *w = 0;
99 else
100 MultiByteToWideChar(cp, 0, s, -1, w, n);
101 return w;
102}
103
104static char *wide_to_mb(const wchar_t *w, UINT cp)
105{
106 int n = WideCharToMultiByte(cp, 0, w, -1, NULL, 0, NULL, NULL);
107 char *s = xrealloc(NULL, n ? n : 1);
108 if (!n)
109 *s = 0;
110 else
111 WideCharToMultiByte(cp, 0, w, -1, s, n, NULL, NULL);
112 return s;
113}
114
115static char *recode(const char *s, UINT from, UINT to)
116{
117 wchar_t *w = mb_to_wide(s, from);
118 char *out = wide_to_mb(w, to);
119 free(w);
120 return out;
121}
122
123static FILE *open_wb(const char *path)
124{
125 wchar_t *w = mb_to_wide(path, CP_UTF8);
126 FILE *f = _wfopen(w, L"wb");
127 free(w);
128 return f;
129}
130
131static int unlink_file(const char *path)
132{
133 wchar_t *w = mb_to_wide(path, CP_UTF8);
134 int ret = _wremove(w);
135 free(w);
136 return ret;
137}
138
139static int replace_file(const char *from, const char *to)
140{
141 wchar_t *wfrom = mb_to_wide(from, CP_UTF8), *wto = mb_to_wide(to, CP_UTF8);
142 int ret = !MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING);
143 free(wfrom);
144 free(wto);
145 return ret;
146}
147
148#else
149
150static FILE *open_wb(const char *path)
151{
152 return fopen(path, "wb");
153}
154
155static int unlink_file(const char *path)
156{
157 return remove(path);
158}
159
160static int replace_file(const char *from, const char *to)
161{
162 return rename(from, to);
163}
164
165#endif
166
167static const char *file_basename(const char *p)
168{
169 for (const char *q = p; *q; q++)
170 if (*q == '/' || *q == '\\')
171 p = q + 1;
172 return p;
173}
174
175static int is_source(const char *arg)
176{
177 static const char *const exts[] = {
178 ".c", ".cc", ".cpp", ".cxx", ".m", ".mm", ".s", ".S", ".asm"
179 };
180 const char *dot = strrchr(file_basename(arg), '.');
181 if (!dot)
182 return 0;
183 for (size_t i = 0; i < FF_ARRAY_ELEMS(exts); i++)
184 if (!strcmp(dot, exts[i]))
185 return 1;
186 return 0;
187}
188
189static int chr_eq(char a, char b)
190{
191#ifdef _WIN32
192 return tolower(a) == tolower(b);
193#else
194 return a == b;
195#endif
196}
197
198/* Relative form of a path below the current directory, NULL for any other. */
199static char *make_relative(const char *path)
200{
201 size_t i;
202
203 for (i = 0; cwd[i]; i++)
204 if (!path[i] || !chr_eq(path[i], cwd[i]))
205 return NULL;
206 if (path[i] != '/' || !path[i + 1])
207 return NULL;
208 return xstrdup(path + i + 1);
209}
210
211static void add_dep(char *path)
212{
213 for (size_t i = 0; i < nb_deps; i++)
214 if (!strcmp(deps[i], path)) {
215 free(path);
216 return;
217 }
218 if (nb_deps >= max_deps) {
219 max_deps = max_deps ? 2 * max_deps : 64;
220 deps = xrealloc(deps, max_deps * sizeof(*deps));
221 }
222 deps[nb_deps++] = path;
223}
224
225static const char *unmapped;
226
227#ifndef _WIN32
228
229/* Length of the root that "../" cannot climb out of, "//server/share" for
230 * UNC paths and "X:" for drive letter paths, 0 otherwise. */
231static size_t root_len(const char *p)
232{
233 size_t i = 0;
234
235 if (p[0] == '/' && p[1] == '/') {
236 for (i = 2; p[i] && p[i] != '/'; i++)
237 ;
238 if (p[i])
239 for (i++; p[i] && p[i] != '/'; i++)
240 ;
241 } else if (isalpha(p[0]) && p[1] == ':') {
242 i = 2;
243 }
244 return i;
245}
246
247static struct {
248 char *root;
249 char *host;
251static size_t nb_roots;
252
253static char *path_helper(const char *prog, const char *root)
254{
255 char *args[] = { (char *)prog, "-u", (char *)root, NULL };
256 char buf[4096];
257 size_t len = 0;
258 int fds[2], st;
259 pid_t pid;
260
261 if (pipe(fds) < 0)
262 die("pipe failed");
263 pid = fork();
264 if (pid < 0)
265 die("fork failed");
266 if (!pid) {
267 dup2(fds[1], STDOUT_FILENO);
268 close(fds[0]);
269 close(fds[1]);
270 execvp(prog, args);
271 _exit(127);
272 }
273 close(fds[1]);
274 for (;;) {
275 char tmp[512];
276 ssize_t n = read(fds[0], tmp, sizeof(tmp));
277 if (n < 0 && errno == EINTR)
278 continue;
279 if (n <= 0)
280 break;
281 if (len + n < sizeof(buf)) {
282 memcpy(buf + len, tmp, n);
283 len += n;
284 }
285 }
286 close(fds[0]);
287 if (waitpid(pid, &st, 0) < 0)
288 die("waitpid failed");
289 if (!WIFEXITED(st) || WEXITSTATUS(st) || !len)
290 return NULL;
291 buf[len] = 0;
292 len = strcspn(buf, "\r\n");
293 while (len && buf[len - 1] == '/')
294 len--;
295 buf[len] = 0;
296 return xstrdup(buf);
297}
298
299/* Translate a Windows path to the host namespace, NULL if impossible. */
300static char *host_path(const char *path)
301{
302 size_t r = root_len(path), i;
303 char *root, *host = NULL, *out;
304
305 if (path[r] == '/')
306 r++;
307 root = xstrdup(path);
308 root[r] = 0;
309 for (char *q = root; *q; q++)
310 *q = tolower(*q);
311
312 for (i = 0; i < nb_roots; i++)
313 if (!strcmp(roots[i].root, root))
314 break;
315 if (i == nb_roots) {
316 host = path_helper("wslpath", root);
317 if (!host)
318 host = path_helper("cygpath", root);
319 roots = xrealloc(roots, (nb_roots + 1) * sizeof(*roots));
320 roots[nb_roots].root = root;
321 roots[nb_roots].host = host;
322 nb_roots++;
323 } else {
324 host = roots[i].host;
325 free(root);
326 }
327 if (!host)
328 return NULL;
329
330 /* the root keeps its slash, the host form lost it */
331 out = xrealloc(NULL, strlen(host) + strlen(path + r) + 2);
332 strcpy(out, host);
333 strcat(out, "/");
334 strcat(out, path + r);
335 return out;
336}
337
338#endif
339
340static void add_include(char *p)
341{
342 char *own = NULL, *rel;
343
344#ifdef _WIN32
345 p = own = recode(p, out_cp, CP_UTF8);
346#endif
347
348 for (char *q = p; *q; q++)
349 if (*q == '\\')
350 *q = '/';
351
352#ifndef _WIN32
353 if (root_len(p)) {
354 own = host_path(p);
355 if (!own) {
356 if (!unmapped)
357 unmapped = xstrdup(p);
358 return;
359 }
360 p = own;
361 }
362#endif
363
364 rel = make_relative(p);
365 if (rel) {
366 free(own);
367 add_dep(rel);
368 } else {
369 add_dep(own ? own : xstrdup(p));
370 }
371}
372
373static void process_line(char *line)
374{
375 size_t len = strlen(line);
376 while (len && line[len - 1] == '\r')
377 line[--len] = 0;
378
379 if (!strncmp(line, INC_PREFIX, sizeof(INC_PREFIX) - 1)) {
380 char *p = line + sizeof(INC_PREFIX) - 1;
381 while (*p == ' ')
382 p++;
383 if (*p)
384 add_include(p);
385 return;
386 }
387 /* cl.exe echoes the source file name; drop it and empty lines */
388 if (*line && !(src && !strcmp(line, src)))
389 puts(line);
390}
391
392static void feed(const char *buf, size_t n)
393{
394 for (size_t i = 0; i < n; i++) {
395 if (buf[i] == '\n') {
396 linebuf[line_len] = 0;
398 line_len = 0;
399 } else {
400 if (line_len + 2 > line_max) {
401 line_max = line_max ? 2 * line_max : 4096;
403 }
404 linebuf[line_len++] = buf[i];
405 }
406 }
407}
408
409static void feed_flush(void)
410{
411 if (line_len) {
412 linebuf[line_len] = 0;
414 line_len = 0;
415 }
416}
417
418static void init_deps(void)
419{
420 size_t len;
421
422#ifdef _WIN32
423 DWORD size = GetCurrentDirectoryW(0, NULL);
424 wchar_t *wcwd = xrealloc(NULL, size * sizeof(*wcwd));
425 if (!GetCurrentDirectoryW(size, wcwd))
426 die("GetCurrentDirectory failed");
427 cwd = wide_to_mb(wcwd, CP_UTF8);
428 free(wcwd);
429#else
430 cwd = getcwd(NULL, 0);
431 if (!cwd)
432 die("getcwd failed");
433#endif
434 for (char *q = cwd; *q; q++)
435 if (*q == '\\')
436 *q = '/';
437 len = strlen(cwd);
438 while (len && cwd[len - 1] == '/')
439 cwd[--len] = 0;
440
441 linebuf = xrealloc(NULL, line_max = 4096);
442}
443
444#ifdef _WIN32
445
446/* Return the command line as received, minus our own program name, so the
447 * compiler gets its arguments verbatim without a requoting round-trip. */
448static wchar_t *cmdline_tail(void)
449{
450 wchar_t *p = GetCommandLineW();
451 if (*p == L'"') {
452 p++;
453 while (*p && *p != L'"')
454 p++;
455 if (*p)
456 p++;
457 } else {
458 while (*p && *p != L' ' && *p != L'\t')
459 p++;
460 }
461 while (*p == L' ' || *p == L'\t')
462 p++;
463 return _wcsdup(p);
464}
465
466/* Split the command line into UTF-8 arguments. CommandLineToArgvW would do the
467 * same, but we want to avoid pulling in shell32.dll. */
468static char **split_cmdline(const wchar_t *p, int *argc)
469{
470 wchar_t *buf = xrealloc(NULL, (wcslen(p) + 1) * sizeof(*buf));
471 char **argv = NULL;
472 int n = 0;
473
474 for (;;) {
475 wchar_t *q = buf;
476 int quoted = 0;
477
478 while (*p == L' ' || *p == L'\t')
479 p++;
480 if (!*p)
481 break;
482 for (;;) {
483 size_t bs = 0;
484 while (*p == L'\\') {
485 bs++;
486 p++;
487 }
488 if (*p == L'"') {
489 for (size_t i = 0; i < bs / 2; i++)
490 *q++ = L'\\';
491 if (bs & 1) {
492 *q++ = L'"';
493 } else if (quoted && p[1] == L'"') {
494 *q++ = L'"';
495 p++;
496 } else {
497 quoted = !quoted;
498 }
499 p++;
500 continue;
501 }
502 for (size_t i = 0; i < bs; i++)
503 *q++ = L'\\';
504 if (!*p || (!quoted && (*p == L' ' || *p == L'\t')))
505 break;
506 *q++ = *p++;
507 }
508 *q = 0;
509 argv = xrealloc(argv, (n + 2) * sizeof(*argv));
510 argv[n++] = wide_to_mb(buf, CP_UTF8);
511 }
512 if (argv)
513 argv[n] = NULL;
514 free(buf);
515 *argc = n;
516 return argv;
517}
518
519static int run(wchar_t *cmdline, int want_pipe)
520{
521 HANDLE rd = NULL, wr = NULL;
522 SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
523 STARTUPINFOW si = { .cb = sizeof(si) };
524 PROCESS_INFORMATION pi;
525 DWORD code = 1;
526
527 si.dwFlags = STARTF_USESTDHANDLES;
528 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
529 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
530 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
531 SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, 1);
532 SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, 1);
533 SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, 1);
534
535 if (want_pipe) {
536 if (!CreatePipe(&rd, &wr, &sa, 0))
537 die("CreatePipe failed");
538 SetHandleInformation(rd, HANDLE_FLAG_INHERIT, 0);
539 si.hStdOutput = wr;
540 /* English include records are required for the parsing above */
541 SetEnvironmentVariableA("VSLANG", "1033");
542 }
543
544 if (!CreateProcessW(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL,
545 &si, &pi))
546 die("cannot execute compiler");
547 CloseHandle(pi.hThread);
548
549 if (want_pipe) {
550 char buf[65536];
551 DWORD n;
552 CloseHandle(wr);
553 while (ReadFile(rd, buf, sizeof(buf), &n, NULL) && n > 0)
554 feed(buf, n);
555 CloseHandle(rd);
556 feed_flush();
557 }
558
559 WaitForSingleObject(pi.hProcess, INFINITE);
560 GetExitCodeProcess(pi.hProcess, &code);
561 CloseHandle(pi.hProcess);
562 return (int)code;
563}
564
565#else
566
567static int run(char **args)
568{
569 const char *wslenv;
570 int fds[2], st;
571 pid_t pid;
572
573 if (pipe(fds) < 0)
574 die("pipe failed");
575 setenv("VSLANG", "1033", 1);
576 /* WSL hands the environment to Windows programs only for the variables
577 * listed in WSLENV */
578 wslenv = getenv("WSLENV");
579 if (wslenv && *wslenv) {
580 char *e = xrealloc(NULL, strlen(wslenv) + sizeof(":VSLANG"));
581 strcpy(e, wslenv);
582 strcat(e, ":VSLANG");
583 setenv("WSLENV", e, 1);
584 free(e);
585 } else {
586 setenv("WSLENV", "VSLANG", 1);
587 }
588 pid = fork();
589 if (pid < 0)
590 die("fork failed");
591 if (!pid) {
592 dup2(fds[1], STDOUT_FILENO);
593 close(fds[0]);
594 close(fds[1]);
595 execvp(args[0], args);
596 perror(args[0]);
597 _exit(127);
598 }
599 close(fds[1]);
600 for (;;) {
601 char buf[65536];
602 ssize_t n = read(fds[0], buf, sizeof(buf));
603 if (n < 0 && errno == EINTR)
604 continue;
605 if (n <= 0)
606 break;
607 feed(buf, n);
608 }
609 close(fds[0]);
610 feed_flush();
611
612 if (waitpid(pid, &st, 0) < 0)
613 die("waitpid failed");
614 return WIFEXITED(st) ? WEXITSTATUS(st) : 128 + WTERMSIG(st);
615}
616
617#endif
618
619/* gcc style escaping for make: '\ ', '\#' and '$$' */
620static void fput_escaped(const char *s, FILE *f)
621{
622 for (; *s; s++) {
623 if (*s == ' ' || *s == '#')
624 fputc('\\', f);
625 else if (*s == '$')
626 fputc('$', f);
627 fputc(*s, f);
628 }
629}
630
631/* A failure to write the dependency file fails the build. */
632static int write_depfile(void)
633{
634 size_t len = strlen(obj);
635 char *path = xrealloc(NULL, len + 3), *tmp;
636 FILE *f;
637 int err;
638
639 memcpy(path, obj, len + 1);
640 if (len > 2 && !strcmp(path + len - 2, ".o"))
641 len -= 2;
642 strcpy(path + len, ".d");
643
644 if (unmapped) {
645 fprintf(stderr, "mscl: cannot map %s to a host path, "
646 "wslpath or cygpath is required\n", unmapped);
647 return 1;
648 }
649
650 tmp = xrealloc(NULL, len + 7);
651 memcpy(tmp, path, len + 2);
652 strcpy(tmp + len + 2, ".tmp");
653
654 f = open_wb(tmp);
655 if (f) {
657 fputc(':', f);
658 for (size_t i = 0; i < nb_deps; i++) {
659 fputc(' ', f);
660 fput_escaped(deps[i], f);
661 }
662 fputc('\n', f);
663 /* -MP style dummy rules; make then treats a vanished header as out
664 * of date instead of erroring out on a missing prerequisite */
665 for (size_t i = 0; i < nb_deps; i++) {
666 fput_escaped(deps[i], f);
667 fputs(":\n", f);
668 }
669 err = ferror(f);
670 if (!fclose(f) && !err && !replace_file(tmp, path))
671 return 0;
673 }
674 fprintf(stderr, "mscl: cannot write %s\n", path);
675 return 1;
676}
677
678int main(int argc, char **argv)
679{
680 int show_includes = 0;
681 int status;
682
683#ifdef _WIN32
684 argv = split_cmdline(GetCommandLineW(), &argc);
685 out_cp = GetConsoleOutputCP();
686 if (!out_cp)
687 out_cp = GetACP();
688#endif
689
690 if (argc < 2) {
691 fprintf(stderr, "usage: mscl <compiler> <arguments...>\n");
692 return 2;
693 }
694
695 for (int i = 2; i < argc; i++) {
696 const char *arg = argv[i];
697 if (!strcmp(arg, "-showIncludes") || !strcmp(arg, "/showIncludes"))
698 show_includes = 1;
699 else if (!strncmp(arg, "-Fo", 3) || !strncmp(arg, "/Fo", 3))
700 obj = arg + 3;
701 else if (is_source(arg))
703 }
704#ifdef _WIN32
705 if (src)
706 src = recode(src, CP_UTF8, out_cp);
707#endif
708
709 /* without an object there is nothing to write a .d file for, leave the
710 * include records alone in that case */
711 if (!obj)
712 show_includes = 0;
713
714#ifdef _WIN32
715 wchar_t *cmdline = cmdline_tail();
716 if (!show_includes)
717 return run(cmdline, 0);
718 init_deps();
719 status = run(cmdline, 1);
720#else
721 if (!show_includes) {
722 execvp(argv[1], argv + 1);
723 perror(argv[1]);
724 return 127;
725 }
726 init_deps();
727 status = run(argv + 1);
728#endif
729
730 /* A failed compilation is the primary result; do not write a dependency
731 * file from its truncated output. */
732 if (status != 0)
733 return status;
734 if (!write_depfile())
735 return 0;
737 return 1;
738}
static FILE * out
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
#define L(x)
Definition vpx_arith.h:36
static uint32_t BS_FUNC read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
int main
Definition dovi_rpuenc.c:38
int a
#define r
Definition input.c:42
#define b
Definition input.c:43
const char * arg
Definition jacosubdec.c:65
const char * from
Definition jacosubdec.c:64
const char * to
Definition webvttdec.c:36
uint8_t w
Definition llvidencdsp.c:39
Utility Preprocessor macros.
static void feed(const char *buf, size_t n)
Definition mscl.c:392
static const char * file_basename(const char *p)
Definition mscl.c:167
static void fput_escaped(const char *s, FILE *f)
Definition mscl.c:620
char * host
Definition mscl.c:249
static int unlink_file(const char *path)
Definition mscl.c:155
static int replace_file(const char *from, const char *to)
Definition mscl.c:160
static char * make_relative(const char *path)
Definition mscl.c:199
static void * xrealloc(void *ptr, size_t size)
Definition mscl.c:74
static size_t line_len
Definition mscl.c:66
static void add_dep(char *path)
Definition mscl.c:211
static void die(const char *msg)
Definition mscl.c:68
static struct @247131355217247325142334070304237061366312316121 * roots
#define INC_PREFIX
Definition mscl.c:55
static char * linebuf
Definition mscl.c:65
static size_t root_len(const char *p)
Definition mscl.c:231
static size_t line_max
Definition mscl.c:66
static int is_source(const char *arg)
Definition mscl.c:175
static const char * unmapped
Definition mscl.c:225
static size_t max_deps
Definition mscl.c:63
static char * cwd
Definition mscl.c:60
static void init_deps(void)
Definition mscl.c:418
char * root
Definition mscl.c:248
static size_t nb_deps
Definition mscl.c:63
static char * path_helper(const char *prog, const char *root)
Definition mscl.c:253
static char ** deps
Definition mscl.c:62
static FILE * open_wb(const char *path)
Definition mscl.c:150
static void feed_flush(void)
Definition mscl.c:409
static void process_line(char *line)
Definition mscl.c:373
static const char * obj
Definition mscl.c:57
static void add_include(char *p)
Definition mscl.c:340
static size_t nb_roots
Definition mscl.c:251
static int write_depfile(void)
Definition mscl.c:632
static int chr_eq(char a, char b)
Definition mscl.c:189
static char * host_path(const char *path)
Definition mscl.c:300
static char * xstrdup(const char *s)
Definition mscl.c:82
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
#define FF_ARRAY_ELEMS(a)
const uint8_t * code
Definition spdifenc.c:433
uint8_t run
Definition svq3.c:207
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
int size
int len
#define WaitForSingleObject(a, b)
Definition w32pthreads.h:64