19 //#define GDC_DEPS_DEBUG
22 extern LIST
*var_get (const char *symbol
);
25 static LIST
*processDepFile (const char *fname
) {
27 FILE *fl
= fopen(fname
, "r");
28 if (fl
== NULL
) return NULL
;
31 fseek(fl
, 0, SEEK_END
);
33 if (fsize
<= 0) { fclose(fl
); return NULL
; }
34 fseek(fl
, 0, SEEK_SET
);
35 fcont
= calloc(fsize
+2, 1);
36 fread(fcont
, fsize
, 1, fl
);
38 uint8_t *tmp
= (uint8_t *)fcont
;
41 printf("{{%s}}\n", tmp
);
43 while (*tmp
&& *tmp
!= ':') ++tmp
;
44 if (tmp
[0] && tmp
[1]) {
47 while (*tmp
&& (tmp
[0] <= 32 || tmp
[0] == '\\')) ++tmp
;
48 if (!tmp
[0]) goto quit
;
50 printf("[%s]\n", tmp
);
53 while (*e
&& e
[0] > ' ' && e
[0] != '\\') ++e
;
55 res
= list_new(res
, (void *)tmp
, 0); // don't copy it
57 printf(" {%s}\n", tmp
);
69 int vasprintf(char **ret
, const char *format
, va_list args
)
74 /* Make sure it is determinate, despite manuals indicating otherwise */
77 int count
= vsnprintf(NULL
, 0, format
, args
);
80 char *buffer
= malloc(count
+ 1);
83 else if ((count
= vsnprintf(buffer
, count
+ 1, format
, copy
)) < 0)
88 va_end(copy
); // Each va_start() or va_copy() needs a va_end()
93 int asprintf(char **ret
, const char *format
, ...)
96 va_start(args
, format
);
97 int count
= vasprintf(ret
, format
, args
);
103 #define ADDARG(a_) do { \
104 if (argCount >= 510) goto error_quit; \
105 args[argCount++] = (a_); \
109 #define ADDARGPF(...) do { \
110 if (argCount >= 510) goto error_quit; \
111 asprintf(&args[argCount], __VA_ARGS__); \
117 #define ADDINCS(vname_) do { \
118 for (const LIST *hdrs = var_get(vname_); hdrs != NULL; hdrs = hdrs->next) { \
119 if (hdrs->string[0]) { \
120 ADDARGPF("-I%s", hdrs->string); \
121 ADDARGPF("-J%s", hdrs->string); \
128 // NULL: can't, do text scan
129 LIST
*gdcDeps (const char *srcfname
) {
131 const char *compilerBin
= NULL
;
132 static char *args
[512];
135 strcpy(tmpFName
, "/tmp/jamgdctmp_XXXXXX");
136 // get out if here if D compiler is not 'gdc'
138 const LIST
*gdc
= var_get("GDC");
139 if (gdc
== NULL
|| gdc
->string
== NULL
) return NULL
;
140 if (strcmp(gdc
->string
, "gdc") == 0) {
145 gdc
= var_get("ENABLE_GDC_DEPS");
146 if (gdc
== NULL
|| gdc
->string
== NULL
|| !gdc
->string
[0]) return NULL
;
150 int fd
= mkstemp(tmpFName
);
151 if (fd
< 0) return NULL
;
154 ADDARG(strdup(compilerBin
));
155 ADDARG(strdup("-c"));
156 ADDARG(strdup("-o"));
157 ADDARG(strdup("/dev/null"));
158 // copy '-fdebug' flags
159 for (const LIST
*flg
= var_get("GDCFLAGS.all"); flg
!= NULL
; flg
= flg
->next
) {
160 if (strncmp(flg
->string
, "-fdebug", 7) == 0) ADDARG(strdup(flg
->string
));
163 for (const LIST
*hdrs
= var_get("HDRS"); hdrs
!= NULL
; hdrs
= hdrs
->next
) {
164 if (hdrs
->string
[0]) {
165 ADDARGPF("-I%s", hdrs
->string
);
166 ADDARGPF("-J%s", hdrs
->string
);
170 static char zpath
[8192];
172 for (const LIST
*hdrs
= var_get("SUBDIR_TOKENS"); hdrs
!= NULL
; hdrs
= hdrs
->next
) {
173 if (hdrs
->string
[0]) {
175 strcat(zpath
, hdrs
->string
);
176 ADDARGPF("-I%s", zpath
);
177 ADDARGPF("-J%s", zpath
);
180 // add input file path to includes
181 strcpy(zpath
, srcfname
);
183 char *t
= strrchr(zpath
, '/');
186 ADDARGPF("-I%s", zpath
);
187 ADDARGPF("-J%s", zpath
);
191 ADDARGPF("-fmake-mdeps=%s", tmpFName
);
193 ADDARG(strdup(srcfname
));
195 args
[argCount
] = NULL
;
196 #ifdef GDC_DEPS_DEBUG
198 for (int f
= 0; f
< argCount
; ++f
) printf("%d: [%s]\n", f
, args
[f
]);
199 for (int f
= 0; f
< argCount
; ++f
) printf("%s ", args
[f
]); printf("\n");
202 pid_t child
= fork();
203 if (child
== (pid_t
)-1) goto error_quit
;
206 // close stdout and stderr
211 //fprintf(stderr, "SHIT!!!\n");
215 waitpid(child
, &status
, 0);
216 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) goto error_quit
;
217 #ifdef GDC_DEPS_DEBUG
218 printf("OK! %s\n", tmpFName
);
220 res
= processDepFile(tmpFName
);
224 while (--argCount
>= 0) free(args
[argCount
]);