3 #include <unistd.h> /* TODO: I doubt this works on Windows... */
9 #include "tm_core_cmds.h"
10 #include "tm_crypto.h"
12 static int ruleCmd(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
15 target_list
*deps
= NULL
;
16 Jim_Obj
*target_subst
, *deps_subst
;
17 const char *recipe
= NULL
;
18 int i
, numtargs
, numdeps
;
19 const char *fmt
= "proc recipe::%s {TARGET INPUTS OODATE} { \
26 /* check to make sure we got the information we need */
27 if (argc
< 3 || argc
> 4) {
28 Jim_WrongNumArgs(interp
, 2, argv
, "rule target-list dep-list ?script?");
32 /* If we've got a recipe, store it */
34 recipe
= Jim_String(argv
[3]);
37 /* Perform variable substitution in the dependency lists */
38 Jim_SubstObj(interp
, argv
[2], &deps_subst
, 0);
40 /* Get all the dependencies and store them in a dep list */
41 numdeps
= Jim_ListLength(interp
, deps_subst
);
42 for (i
= 0; i
< numdeps
; i
++) {
43 Jim_Obj
*dep
= Jim_ListGetIndex(interp
, deps_subst
, i
);
44 const char *sdep
= Jim_String(dep
);
46 deps
= target_cons(sdep
, deps
);
49 /* Perform variable substitution in the target list */
50 Jim_SubstObj(interp
, argv
[1], &target_subst
, 0);
52 numtargs
= Jim_ListLength(interp
, target_subst
);
55 fprintf(stderr
, "ERROR: no targets specified for rule\n");
60 /* For each target in the list, create a rule and a proc */
61 for (i
= 0; i
< numtargs
; i
++) {
62 Jim_Obj
*target_obj
= Jim_ListGetIndex(interp
, target_subst
, i
);
63 const char *target
= Jim_String(target_obj
);
65 /* check if there's already a rule for this target */
66 rule
= find_rule(target
, tm_rules
);
68 /* if so, overwrite it with the new rule */
69 free_target_list(rule
->deps
);
71 rule
->deps
= target_list_copy(deps
);
73 rule
->recipe
= malloc(strlen(recipe
) + 1);
74 strcpy(rule
->recipe
, recipe
);
78 rule
->type
= TM_EXPLICIT
;
80 /* or else create a new rule */
81 rule
= new_rule(target
, deps
, recipe
);
82 tm_rules
= rule_cons(rule
, tm_rules
);
86 /* Do we need to set the default goal? */
87 if (tm_goal
== NULL
) {
88 const char *fmt_set
= "set TM_CURRENT_GOAL %s";
90 tm_goal
= malloc(strlen(target
) + 1);
91 strcpy(tm_goal
, target
);
93 len
= strlen(fmt_set
) + strlen(target
) + 1;
95 sprintf(cmd
, fmt_set
, target
);
96 ret
= Jim_Eval(interp
, cmd
);
98 if (ret
!= (JIM_OK
)) {
103 /* Create a proc representing this rule */
104 len
= strlen(fmt
) + strlen(target
) + (recipe
? strlen(recipe
) : 0) + 1;
106 sprintf(cmd
, fmt
, target
, recipe
? recipe
: "");
107 ret
= Jim_Eval(interp
, cmd
);
109 if (ret
!= (JIM_OK
)) {
114 free_target_list(deps
);
118 free_target_list(deps
);
122 /* Provide tm_crypto functionality to Jim Tcl */
123 static int sha1sumCmd(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
125 char hash
[CRYPTO_HASH_STRING_LENGTH
];
126 unsigned char digest
[CRYPTO_HASH_SIZE
];
127 const char *subcmd
= NULL
;
128 const char *string
= NULL
;
131 Jim_WrongNumArgs(interp
, 2, argv
, "sha1sum \"file\"|\"string\" <filename>|<string>");
135 subcmd
= Jim_String(argv
[1]);
136 string
= Jim_String(argv
[2]);
138 if (strcmp(subcmd
, "file") == 0) {
139 TM_CRYPTO_HASH_FILE(string
, digest
);
140 } else if (strcmp(subcmd
, "string") == 0) {
141 TM_CRYPTO_HASH_DATA(string
, digest
);
143 Jim_WrongNumArgs(interp
, 2, argv
, "Invalid subcommand for sha1sum (should be \"file\" or \"string\")");
147 TM_CRYPTO_HASH_TO_STRING(digest
, hash
);
149 Jim_SetResultString(interp
, hash
, CRYPTO_HASH_STRING_LENGTH
);
155 static int targetCmd(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
157 const char *target
= NULL
;
160 Jim_WrongNumArgs(interp
, 1, argv
, "target name");
164 target
= Jim_String(argv
[1]);
166 if (find_rule(target
, tm_rules
)) {
167 Jim_SetResultInt(interp
, 1);
169 Jim_SetResultInt(interp
, 0);
175 static int commandsCmd(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
177 const char *target
= NULL
;
178 tm_rule
*rule
= NULL
;
181 Jim_WrongNumArgs(interp
, 1, argv
, "commands target");
185 target
= Jim_String(argv
[1]);
186 rule
= find_rule(target
, tm_rules
);
188 if (rule
&& rule
->recipe
) {
189 Jim_SetResultInt(interp
, 1);
191 Jim_SetResultInt(interp
, 0);
198 * Searches along a of paths for the given package.
200 * Returns the allocated path to the package file if found,
201 * or NULL if not found.
203 static char *tm_FindPackage(Jim_Interp
*interp
, Jim_Obj
*prefixListObj
, const char *pkgName
)
206 int prefixc
= Jim_ListLength(interp
, prefixListObj
);
208 for (i
= 0; i
< prefixc
; i
++) {
209 Jim_Obj
*prefixObjPtr
= Jim_ListGetIndex(interp
, prefixListObj
, i
);
210 const char *prefix
= Jim_String(prefixObjPtr
);
211 int len
= strlen(prefix
) + strlen(pkgName
) + 2;
212 char *buf
= Jim_Alloc(len
);
214 if (strcmp(prefix
, ".") == 0) {
215 sprintf(buf
, "%s", pkgName
);
217 sprintf(buf
, "%s/%s", prefix
, pkgName
);
220 if (access(buf
, R_OK
) == 0) {
229 static int includeCmd(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
232 const char *filename
= NULL
;
233 Jim_Obj
*incpath
= Jim_GetGlobalVariableStr(interp
, TM_INCLUDE_PATH
, JIM_NONE
);
236 Jim_WrongNumArgs(interp
, 1, argv
, "include filename");
240 filename
= Jim_String(argv
[1]);
244 path
= tm_FindPackage(interp
, incpath
, filename
);
246 Jim_IncrRefCount(incpath
);
247 ret
= Jim_EvalFileGlobal(interp
, path
);
248 Jim_DecrRefCount(interp
, incpath
);
259 void tm_RegisterCoreCommands(Jim_Interp
*interp
)
261 Jim_CreateCommand(interp
, "rule", ruleCmd
, NULL
, NULL
);
262 Jim_CreateCommand(interp
, "include", includeCmd
, NULL
, NULL
);
263 Jim_CreateCommand(interp
, "target", targetCmd
, NULL
, NULL
);
264 Jim_CreateCommand(interp
, "commands", commandsCmd
, NULL
, NULL
);
265 Jim_CreateCommand(interp
, "sha1sum", sha1sumCmd
, NULL
, NULL
);