feat(pkg): add basic package manager (add, remove, fetch, build deps)
- manifest.bux: parse [dependencies] section with up to 8 deps - manifest.bux: Manifest_AddDep, Manifest_RemoveDep, Manifest_ToString - cli.bux: bux add <name> <url> — adds dependency to bux.toml - cli.bux: bux remove <name> — removes dependency from bux.toml - cli.bux: bux fetch — git clone/pull dependencies into deps/ - cli.bux: Cli_BuildProject now merges deps/<name>/src/*.bux before user code - Selfhost bootstrap loop verified: C output deterministic ✓
This commit is contained in:
+168
-2
@@ -620,6 +620,115 @@ func Cli_Init() -> int {
|
|||||||
// Test command — build and run tests
|
// Test command — build and run tests
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Add — add a dependency to bux.toml
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func Cli_Add(pkgName: String, url: String) -> int {
|
||||||
|
let cwd: String = bux_getcwd();
|
||||||
|
let tomlPath: String = bux_path_join(cwd, "bux.toml");
|
||||||
|
if !FileExists(tomlPath) {
|
||||||
|
PrintLine("Error: no bux.toml found");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
var man: Manifest = Manifest_Load(tomlPath);
|
||||||
|
if Manifest_HasDep(man, pkgName) {
|
||||||
|
Print("Error: dependency '"); Print(pkgName); PrintLine("' already exists");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let added: bool = Manifest_AddDep(&man, pkgName, url);
|
||||||
|
if !added {
|
||||||
|
PrintLine("Error: cannot add dependency (max 8)");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let tomlContent: String = Manifest_ToString(man);
|
||||||
|
if !WriteFile(tomlPath, tomlContent) {
|
||||||
|
PrintLine("Error: cannot write bux.toml");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Print("Added dependency: "); Print(pkgName); Print(" = "); PrintLine(url);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Remove — remove a dependency from bux.toml
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func Cli_Remove(pkgName: String) -> int {
|
||||||
|
let cwd: String = bux_getcwd();
|
||||||
|
let tomlPath: String = bux_path_join(cwd, "bux.toml");
|
||||||
|
if !FileExists(tomlPath) {
|
||||||
|
PrintLine("Error: no bux.toml found");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
var man: Manifest = Manifest_Load(tomlPath);
|
||||||
|
if !Manifest_HasDep(man, pkgName) {
|
||||||
|
Print("Error: dependency '"); Print(pkgName); PrintLine("' not found");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let removed: bool = Manifest_RemoveDep(&man, pkgName);
|
||||||
|
if !removed {
|
||||||
|
PrintLine("Error: cannot remove dependency");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let tomlContent: String = Manifest_ToString(man);
|
||||||
|
if !WriteFile(tomlPath, tomlContent) {
|
||||||
|
PrintLine("Error: cannot write bux.toml");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Print("Removed dependency: "); PrintLine(pkgName);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Fetch — download dependencies into deps/
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func Cli_Fetch() -> int {
|
||||||
|
let cwd: String = bux_getcwd();
|
||||||
|
let tomlPath: String = bux_path_join(cwd, "bux.toml");
|
||||||
|
if !FileExists(tomlPath) {
|
||||||
|
PrintLine("Error: no bux.toml found");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let man: Manifest = Manifest_Load(tomlPath);
|
||||||
|
if man.depCount == 0 {
|
||||||
|
PrintLine("No dependencies to fetch");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let depsDir: String = bux_path_join(cwd, "deps");
|
||||||
|
discard bux_mkdir_if_needed(depsDir);
|
||||||
|
var i: int = 0;
|
||||||
|
while i < man.depCount {
|
||||||
|
var depName: String = "";
|
||||||
|
var depUrl: String = "";
|
||||||
|
if i == 0 { depName = man.depName0; depUrl = man.depUrl0; }
|
||||||
|
else if i == 1 { depName = man.depName1; depUrl = man.depUrl1; }
|
||||||
|
else if i == 2 { depName = man.depName2; depUrl = man.depUrl2; }
|
||||||
|
else if i == 3 { depName = man.depName3; depUrl = man.depUrl3; }
|
||||||
|
else if i == 4 { depName = man.depName4; depUrl = man.depUrl4; }
|
||||||
|
else if i == 5 { depName = man.depName5; depUrl = man.depUrl5; }
|
||||||
|
else if i == 6 { depName = man.depName6; depUrl = man.depUrl6; }
|
||||||
|
else if i == 7 { depName = man.depName7; depUrl = man.depUrl7; }
|
||||||
|
let depPath: String = bux_path_join(depsDir, depName);
|
||||||
|
if DirExists(depPath) {
|
||||||
|
Print("Updating "); PrintLine(depName);
|
||||||
|
let cmd: String = String_Concat("cd \"", String_Concat(depPath, "\" && git pull --quiet 2>/dev/null"));
|
||||||
|
discard bux_system(cmd);
|
||||||
|
} else {
|
||||||
|
Print("Fetching "); Print(depName); Print(" from "); PrintLine(depUrl);
|
||||||
|
let cmd: String = String_Concat("git clone --quiet \"", String_Concat(depUrl, String_Concat("\" \"", String_Concat(depPath, "\""))));
|
||||||
|
let rc: int = bux_system(cmd);
|
||||||
|
if rc != 0 {
|
||||||
|
Print("Error: failed to fetch "); PrintLine(depName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
PrintLine("Fetch complete");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Fmt command — format source files
|
// Fmt command — format source files
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -835,6 +944,43 @@ func Cli_BuildProject(projectDir: String) -> int {
|
|||||||
PrintLine("");
|
PrintLine("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Merge dependency declarations (deps shadow stdlib, user shadows deps)
|
||||||
|
if man.depCount > 0 {
|
||||||
|
let depsDir: String = bux_path_join(projectDir, "deps");
|
||||||
|
var di: int = 0;
|
||||||
|
while di < man.depCount {
|
||||||
|
var depName: String = "";
|
||||||
|
if di == 0 { depName = man.depName0; }
|
||||||
|
else if di == 1 { depName = man.depName1; }
|
||||||
|
else if di == 2 { depName = man.depName2; }
|
||||||
|
else if di == 3 { depName = man.depName3; }
|
||||||
|
else if di == 4 { depName = man.depName4; }
|
||||||
|
else if di == 5 { depName = man.depName5; }
|
||||||
|
else if di == 6 { depName = man.depName6; }
|
||||||
|
else if di == 7 { depName = man.depName7; }
|
||||||
|
let depSrcDir: String = bux_path_join(bux_path_join(depsDir, depName), "src");
|
||||||
|
if DirExists(depSrcDir) {
|
||||||
|
var depFileCount: int = 0;
|
||||||
|
let depFiles: *String = bux_list_dir(depSrcDir, ".bux", &depFileCount);
|
||||||
|
if depFileCount > 0 {
|
||||||
|
Print("Merging dependency: ");
|
||||||
|
PrintLine(depName);
|
||||||
|
var dfi: int = 0;
|
||||||
|
while dfi < depFileCount {
|
||||||
|
Print(" Merging ");
|
||||||
|
PrintLine(depFiles[dfi]);
|
||||||
|
let added: int = Cli_MergeFileInto(merged, depFiles[dfi], userNames, userNameCount);
|
||||||
|
Print(" -> ");
|
||||||
|
PrintInt(added as int64);
|
||||||
|
PrintLine(" decls added");
|
||||||
|
dfi = dfi + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
di = di + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy user declarations into merged (user shadows stdlib)
|
// Copy user declarations into merged (user shadows stdlib)
|
||||||
Cli_CopyModuleDecls(merged, userMerged);
|
Cli_CopyModuleDecls(merged, userMerged);
|
||||||
|
|
||||||
@@ -955,7 +1101,7 @@ func Cli_Run(args: *String, argCount: int) -> int {
|
|||||||
if argCount < 2 {
|
if argCount < 2 {
|
||||||
PrintLine("Bux Self-Hosting Compiler v0.2.0");
|
PrintLine("Bux Self-Hosting Compiler v0.2.0");
|
||||||
PrintLine("Usage: buxc <command> [args]");
|
PrintLine("Usage: buxc <command> [args]");
|
||||||
PrintLine("Commands: build, check, new, init, fmt, test, run, project, help, version");
|
PrintLine("Commands: build, check, new, init, add, remove, fetch, fmt, test, run, project, help, version");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -968,7 +1114,7 @@ func Cli_Run(args: *String, argCount: int) -> int {
|
|||||||
if String_Eq(cmd, "help") || String_Eq(cmd, "--help") || String_Eq(cmd, "-h") {
|
if String_Eq(cmd, "help") || String_Eq(cmd, "--help") || String_Eq(cmd, "-h") {
|
||||||
PrintLine("Bux Self-Hosting Compiler v0.2.0");
|
PrintLine("Bux Self-Hosting Compiler v0.2.0");
|
||||||
PrintLine("Usage: buxc <command> [args]");
|
PrintLine("Usage: buxc <command> [args]");
|
||||||
PrintLine("Commands: build, check, new, init, fmt, test, run, project, help, version");
|
PrintLine("Commands: build, check, new, init, add, remove, fetch, fmt, test, run, project, help, version");
|
||||||
PrintLine("Pipeline modules:");
|
PrintLine("Pipeline modules:");
|
||||||
PrintLine(" Lexer ✅ 695 lines");
|
PrintLine(" Lexer ✅ 695 lines");
|
||||||
PrintLine(" Parser ✅ 1004 lines");
|
PrintLine(" Parser ✅ 1004 lines");
|
||||||
@@ -991,6 +1137,26 @@ func Cli_Run(args: *String, argCount: int) -> int {
|
|||||||
return Cli_Init();
|
return Cli_Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if String_Eq(cmd, "add") {
|
||||||
|
if argCount < 4 {
|
||||||
|
PrintLine("Usage: buxc add <name> <url>");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return Cli_Add(args[2], args[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if String_Eq(cmd, "remove") {
|
||||||
|
if argCount < 3 {
|
||||||
|
PrintLine("Usage: buxc remove <name>");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return Cli_Remove(args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if String_Eq(cmd, "fetch") {
|
||||||
|
return Cli_Fetch();
|
||||||
|
}
|
||||||
|
|
||||||
if String_Eq(cmd, "fmt") {
|
if String_Eq(cmd, "fmt") {
|
||||||
let dir: String = ".";
|
let dir: String = ".";
|
||||||
if argCount >= 3 { dir = args[2]; }
|
if argCount >= 3 { dir = args[2]; }
|
||||||
|
|||||||
@@ -12,6 +12,23 @@ struct Manifest {
|
|||||||
version: String;
|
version: String;
|
||||||
pkgType: String;
|
pkgType: String;
|
||||||
output: String;
|
output: String;
|
||||||
|
depCount: int;
|
||||||
|
depName0: String;
|
||||||
|
depUrl0: String;
|
||||||
|
depName1: String;
|
||||||
|
depUrl1: String;
|
||||||
|
depName2: String;
|
||||||
|
depUrl2: String;
|
||||||
|
depName3: String;
|
||||||
|
depUrl3: String;
|
||||||
|
depName4: String;
|
||||||
|
depUrl4: String;
|
||||||
|
depName5: String;
|
||||||
|
depUrl5: String;
|
||||||
|
depName6: String;
|
||||||
|
depUrl6: String;
|
||||||
|
depName7: String;
|
||||||
|
depUrl7: String;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -24,6 +41,7 @@ func Manifest_Parse(content: String) -> Manifest {
|
|||||||
m.version = "0.1.0";
|
m.version = "0.1.0";
|
||||||
m.pkgType = "bin";
|
m.pkgType = "bin";
|
||||||
m.output = "Bin";
|
m.output = "Bin";
|
||||||
|
m.depCount = 0;
|
||||||
|
|
||||||
if String_Eq(content, "") { return m; }
|
if String_Eq(content, "") { return m; }
|
||||||
|
|
||||||
@@ -43,6 +61,8 @@ func Manifest_Parse(content: String) -> Manifest {
|
|||||||
currentSection = "Package";
|
currentSection = "Package";
|
||||||
} else if String_StartsWith(line, "[Build]") {
|
} else if String_StartsWith(line, "[Build]") {
|
||||||
currentSection = "Build";
|
currentSection = "Build";
|
||||||
|
} else if String_StartsWith(line, "[dependencies]") {
|
||||||
|
currentSection = "dependencies";
|
||||||
} else {
|
} else {
|
||||||
currentSection = "";
|
currentSection = "";
|
||||||
}
|
}
|
||||||
@@ -70,6 +90,18 @@ func Manifest_Parse(content: String) -> Manifest {
|
|||||||
if String_Eq(key, "Type") { m.pkgType = val; }
|
if String_Eq(key, "Type") { m.pkgType = val; }
|
||||||
} else if String_Eq(currentSection, "Build") {
|
} else if String_Eq(currentSection, "Build") {
|
||||||
if String_Eq(key, "Output") { m.output = val; }
|
if String_Eq(key, "Output") { m.output = val; }
|
||||||
|
} else if String_Eq(currentSection, "dependencies") {
|
||||||
|
if m.depCount < 8 {
|
||||||
|
if m.depCount == 0 { m.depName0 = key; m.depUrl0 = val; }
|
||||||
|
else if m.depCount == 1 { m.depName1 = key; m.depUrl1 = val; }
|
||||||
|
else if m.depCount == 2 { m.depName2 = key; m.depUrl2 = val; }
|
||||||
|
else if m.depCount == 3 { m.depName3 = key; m.depUrl3 = val; }
|
||||||
|
else if m.depCount == 4 { m.depName4 = key; m.depUrl4 = val; }
|
||||||
|
else if m.depCount == 5 { m.depName5 = key; m.depUrl5 = val; }
|
||||||
|
else if m.depCount == 6 { m.depName6 = key; m.depUrl6 = val; }
|
||||||
|
else if m.depCount == 7 { m.depName7 = key; m.depUrl7 = val; }
|
||||||
|
m.depCount = m.depCount + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = i + 1;
|
i = i + 1;
|
||||||
@@ -78,6 +110,138 @@ func Manifest_Parse(content: String) -> Manifest {
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Dependency helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func Manifest_HasDep(m: Manifest, name: String) -> bool {
|
||||||
|
var i: int = 0;
|
||||||
|
while i < m.depCount {
|
||||||
|
var depName: String = "";
|
||||||
|
if i == 0 { depName = m.depName0; }
|
||||||
|
else if i == 1 { depName = m.depName1; }
|
||||||
|
else if i == 2 { depName = m.depName2; }
|
||||||
|
else if i == 3 { depName = m.depName3; }
|
||||||
|
else if i == 4 { depName = m.depName4; }
|
||||||
|
else if i == 5 { depName = m.depName5; }
|
||||||
|
else if i == 6 { depName = m.depName6; }
|
||||||
|
else if i == 7 { depName = m.depName7; }
|
||||||
|
if String_Eq(depName, name) { return true; }
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Manifest_GetDepUrl(m: Manifest, name: String) -> String {
|
||||||
|
var i: int = 0;
|
||||||
|
while i < m.depCount {
|
||||||
|
var depName: String = "";
|
||||||
|
var depUrl: String = "";
|
||||||
|
if i == 0 { depName = m.depName0; depUrl = m.depUrl0; }
|
||||||
|
else if i == 1 { depName = m.depName1; depUrl = m.depUrl1; }
|
||||||
|
else if i == 2 { depName = m.depName2; depUrl = m.depUrl2; }
|
||||||
|
else if i == 3 { depName = m.depName3; depUrl = m.depUrl3; }
|
||||||
|
else if i == 4 { depName = m.depName4; depUrl = m.depUrl4; }
|
||||||
|
else if i == 5 { depName = m.depName5; depUrl = m.depUrl5; }
|
||||||
|
else if i == 6 { depName = m.depName6; depUrl = m.depUrl6; }
|
||||||
|
else if i == 7 { depName = m.depName7; depUrl = m.depUrl7; }
|
||||||
|
if String_Eq(depName, name) { return depUrl; }
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
func Manifest_AddDep(m: *Manifest, name: String, url: String) -> bool {
|
||||||
|
if Manifest_HasDep(*m, name) { return false; }
|
||||||
|
if m.depCount >= 8 { return false; }
|
||||||
|
if m.depCount == 0 { m.depName0 = name; m.depUrl0 = url; }
|
||||||
|
else if m.depCount == 1 { m.depName1 = name; m.depUrl1 = url; }
|
||||||
|
else if m.depCount == 2 { m.depName2 = name; m.depUrl2 = url; }
|
||||||
|
else if m.depCount == 3 { m.depName3 = name; m.depUrl3 = url; }
|
||||||
|
else if m.depCount == 4 { m.depName4 = name; m.depUrl4 = url; }
|
||||||
|
else if m.depCount == 5 { m.depName5 = name; m.depUrl5 = url; }
|
||||||
|
else if m.depCount == 6 { m.depName6 = name; m.depUrl6 = url; }
|
||||||
|
else if m.depCount == 7 { m.depName7 = name; m.depUrl7 = url; }
|
||||||
|
m.depCount = m.depCount + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Manifest_RemoveDep(m: *Manifest, name: String) -> bool {
|
||||||
|
var found: int = -1;
|
||||||
|
var i: int = 0;
|
||||||
|
while i < m.depCount {
|
||||||
|
var depName: String = "";
|
||||||
|
if i == 0 { depName = m.depName0; }
|
||||||
|
else if i == 1 { depName = m.depName1; }
|
||||||
|
else if i == 2 { depName = m.depName2; }
|
||||||
|
else if i == 3 { depName = m.depName3; }
|
||||||
|
else if i == 4 { depName = m.depName4; }
|
||||||
|
else if i == 5 { depName = m.depName5; }
|
||||||
|
else if i == 6 { depName = m.depName6; }
|
||||||
|
else if i == 7 { depName = m.depName7; }
|
||||||
|
if String_Eq(depName, name) { found = i; break; }
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
if found < 0 { return false; }
|
||||||
|
i = found;
|
||||||
|
while i < m.depCount - 1 {
|
||||||
|
if i == 0 { m.depName0 = m.depName1; m.depUrl0 = m.depUrl1; }
|
||||||
|
else if i == 1 { m.depName1 = m.depName2; m.depUrl1 = m.depUrl2; }
|
||||||
|
else if i == 2 { m.depName2 = m.depName3; m.depUrl2 = m.depUrl3; }
|
||||||
|
else if i == 3 { m.depName3 = m.depName4; m.depUrl3 = m.depUrl4; }
|
||||||
|
else if i == 4 { m.depName4 = m.depName5; m.depUrl4 = m.depUrl5; }
|
||||||
|
else if i == 5 { m.depName5 = m.depName6; m.depUrl5 = m.depUrl6; }
|
||||||
|
else if i == 6 { m.depName6 = m.depName7; m.depUrl6 = m.depUrl7; }
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
m.depCount = m.depCount - 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Serialize manifest back to TOML
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func Manifest_ToString(m: Manifest) -> String {
|
||||||
|
let sb: StringBuilder = StringBuilder_New();
|
||||||
|
StringBuilder_Append(&sb, "[Package]\n");
|
||||||
|
StringBuilder_Append(&sb, "Name = \"");
|
||||||
|
StringBuilder_Append(&sb, m.name);
|
||||||
|
StringBuilder_Append(&sb, "\"\n");
|
||||||
|
StringBuilder_Append(&sb, "Version = \"");
|
||||||
|
StringBuilder_Append(&sb, m.version);
|
||||||
|
StringBuilder_Append(&sb, "\"\n");
|
||||||
|
StringBuilder_Append(&sb, "Type = \"");
|
||||||
|
StringBuilder_Append(&sb, m.pkgType);
|
||||||
|
StringBuilder_Append(&sb, "\"\n\n");
|
||||||
|
StringBuilder_Append(&sb, "[Build]\n");
|
||||||
|
StringBuilder_Append(&sb, "Output = \"");
|
||||||
|
StringBuilder_Append(&sb, m.output);
|
||||||
|
StringBuilder_Append(&sb, "\"\n");
|
||||||
|
if m.depCount > 0 {
|
||||||
|
StringBuilder_Append(&sb, "\n[dependencies]\n");
|
||||||
|
var i: int = 0;
|
||||||
|
while i < m.depCount {
|
||||||
|
var depName: String = "";
|
||||||
|
var depUrl: String = "";
|
||||||
|
if i == 0 { depName = m.depName0; depUrl = m.depUrl0; }
|
||||||
|
else if i == 1 { depName = m.depName1; depUrl = m.depUrl1; }
|
||||||
|
else if i == 2 { depName = m.depName2; depUrl = m.depUrl2; }
|
||||||
|
else if i == 3 { depName = m.depName3; depUrl = m.depUrl3; }
|
||||||
|
else if i == 4 { depName = m.depName4; depUrl = m.depUrl4; }
|
||||||
|
else if i == 5 { depName = m.depName5; depUrl = m.depUrl5; }
|
||||||
|
else if i == 6 { depName = m.depName6; depUrl = m.depUrl6; }
|
||||||
|
else if i == 7 { depName = m.depName7; depUrl = m.depUrl7; }
|
||||||
|
StringBuilder_Append(&sb, depName);
|
||||||
|
StringBuilder_Append(&sb, " = \"");
|
||||||
|
StringBuilder_Append(&sb, depUrl);
|
||||||
|
StringBuilder_Append(&sb, "\"\n");
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return StringBuilder_Build(&sb);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Load manifest from file
|
// Load manifest from file
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user