Skip to content

Commit 2abfec2

Browse files
committed
move dosbox api here
1 parent 389bd89 commit 2abfec2

File tree

19 files changed

+993
-91
lines changed

19 files changed

+993
-91
lines changed

masm-tasm/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,6 @@
464464
"yarn": false
465465
},
466466
"devDependencies": {
467-
"@types/glob": "^9.0.0",
468467
"@types/js-yaml": "^4.0.9",
469468
"@types/mocha": "^10.0.10",
470469
"@types/node-fetch": "^2.6.13",
@@ -475,9 +474,10 @@
475474
"@vscode/test-electron": "^2.5.2",
476475
"@vscode/test-web": "^0.0.74",
477476
"assert": "^2.1.0",
477+
"browser-or-node": "^3.0.0",
478478
"del": "^8.0.1",
479479
"download": "^8.0.0",
480-
"emulators": "^8.3.9",
480+
"emulators": "https://github.com/dosasm/emulators/releases/download/v8.3.9-dosasm4.0/emulators-v8.3.9-dosasm4.0.tgz",
481481
"eslint": "^9.39.1",
482482
"glob": "^11.0.3",
483483
"js-yaml": "^4.1.0",
@@ -491,7 +491,8 @@
491491
"typescript": "^5.9.3",
492492
"vscode-uri": "^3.1.0",
493493
"webpack": "^5.102.1",
494-
"webpack-cli": "^6.0.1"
494+
"webpack-cli": "^6.0.1",
495+
"webpack-node-externals": "^3.0.0"
495496
},
496497
"repository": {
497498
"type": "git",

masm-tasm/pnpm-lock.yaml

Lines changed: 23 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

masm-tasm/src/ASM/manager.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import * as vscode from 'vscode';
22

3-
import { API } from './vscode-dosbox';
3+
import { API } from '../dosbox-api/vscode-dosbox-api';
4+
import { api } from '../dosbox-api/vscode-dosbox-api.impl';
45
import * as Diag from '../diagnose/main';
56
import * as conf from '../utils/configuration';
67
import { logger } from '../utils/logger';
78
import { uriUtils } from '../utils/util';
89

9-
export * from './vscode-dosbox';
10+
export * from '../dosbox-api/vscode-dosbox-api';
1011

1112
export interface AsmResult {
1213
message: string,
@@ -56,21 +57,6 @@ export function activateManager(context: vscode.ExtensionContext, actions: ExecA
5657
}
5758
logger.channel(actionMessage(actionType, _uri.fsPath));
5859

59-
const vscode_dosbox = vscode.extensions.getExtension<API>('xsro.vscode-dosbox');
60-
61-
if (vscode_dosbox === undefined) {
62-
throw new Error("can't get extension xsro.vscode-dosbox");
63-
}
64-
let api: API | undefined = vscode_dosbox.exports;
65-
if (!vscode_dosbox.isActive) {
66-
api = await vscode_dosbox?.activate();
67-
}
68-
logger.log(vscode_dosbox);
69-
70-
if (api === undefined) {
71-
throw new Error("can't get api from" + vscode_dosbox?.id);
72-
}
73-
7460
const doc = await vscode.workspace.openTextDocument(_uri);
7561
if (doc.isDirty && conf.extConf.get<boolean>('ASM.savefirst', true)) {
7662
await doc.save();
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Manage DOSBox's configuration file
3+
*/
4+
export class Conf {
5+
private _target: string[] = [];
6+
private eol = "\n";
7+
constructor(confStr: string = "") {
8+
if (confStr.includes("\r\n")) {
9+
this.eol = "\r\n";
10+
}
11+
this._target = confStr.split(this.eol);
12+
if (!Array.isArray(this._target)) {
13+
throw new Error("error target");
14+
}
15+
}
16+
17+
/**check whether the config file has the item or not
18+
* @returns line number of the section or key
19+
*/
20+
has(section: string, key?: string): number | undefined {
21+
let sectionIdx = this._target.findIndex((val) => {
22+
return val.trim().toLowerCase() === `[${section.trim().toLowerCase()}]`;
23+
});
24+
if (key === undefined && sectionIdx >= 0) {
25+
return sectionIdx;
26+
}
27+
for (let i = sectionIdx + 1; i < this._target.length; i++) {
28+
const line = this._target[i];
29+
if (typeof line !== "string") {
30+
continue;
31+
}
32+
if (line.trimLeft().startsWith("[")) {
33+
break;
34+
}
35+
const kv = line.replace(/#.*/g, "");
36+
const [_key, _value] = kv.split("=");
37+
if (key && key.trim().toLowerCase() === _key.trim().toLowerCase()) {
38+
return i;
39+
}
40+
}
41+
return undefined;
42+
}
43+
44+
get(section: string, key: string) {
45+
const idx = this.has(section, key);
46+
if (idx !== undefined) {
47+
const [name, value] = this._target[idx]
48+
.replace(/#.*/g, "")
49+
.trim()
50+
.split("=");
51+
if (value) {
52+
return value.trim();
53+
}
54+
}
55+
}
56+
57+
update(section: string, key: string, value: boolean | number | string) {
58+
let idx = this.has(section, key);
59+
if (idx !== undefined) {
60+
this._target[idx] = `${key} = ${value.toString()}`;
61+
return;
62+
}
63+
idx = this.has(section);
64+
if (idx !== undefined) {
65+
this._target.splice(idx + 1, 0, `${key}=${value}`);
66+
return;
67+
} else {
68+
this._target.push(`[${section}]`);
69+
this._target.push(`${key}=${value}`);
70+
return;
71+
}
72+
}
73+
74+
updateAutoexec(context: string[]) {
75+
const section = "[autoexec]";
76+
const idx = this._target.findIndex((val) => val === section);
77+
if (idx >= 0) {
78+
for (let i = idx + 1; i < this._target.length; i++) {
79+
if (!this._target[i].trim().startsWith("#")) {
80+
this._target[i] = "#" + this._target[i];
81+
}
82+
if (this._target[i].trim().startsWith("[")) {
83+
break;
84+
}
85+
}
86+
this._target.splice(idx + 1, 0, ...context);
87+
} else {
88+
this._target.push("[autoexec]", ...context);
89+
}
90+
}
91+
toString() {
92+
return this._target.join(this.eol);
93+
}
94+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import * as cp from "child_process";
2+
import * as vscode from "vscode";
3+
import { logger } from "../logger";
4+
import { Conf } from "./conf";
5+
import * as api from "../vscode-dosbox-api";
6+
import { DosboxResult } from "../vscode-dosbox-api";
7+
import { fromBundle } from "./fromBundle";
8+
9+
const fs = vscode.workspace.fs;
10+
11+
export class DOSBox implements api.Dosbox {
12+
private _conf: Conf = new Conf("");
13+
constructor(
14+
public readonly command: string,
15+
public dstConfPath: vscode.Uri,
16+
public cwd?: string
17+
) {}
18+
19+
/** set the dosbox configuration file template
20+
*
21+
* @param template the path of the reference.conf file
22+
*/
23+
async setConf(template: vscode.Uri) {
24+
const text = await fs.readFile(template);
25+
this._conf = new Conf(text.toString());
26+
}
27+
28+
updateConf = (
29+
section: string,
30+
key: string,
31+
value: string | number | boolean
32+
) => this._conf.update(section, key, value);
33+
updateAutoexec = (context: string[]) => this._conf.updateAutoexec(context);
34+
35+
async run(params?: string[], cpHandler?: (p: cp.ChildProcess) => void) {
36+
const text = new TextEncoder().encode(this._conf.toString());
37+
await fs.writeFile(this.dstConfPath, text);
38+
const cmd = this.command;
39+
const parameter = Array.isArray(params)
40+
? params.join(" ")
41+
: `-conf "${this.dstConfPath.fsPath}"`;
42+
const command = cmd.includes("<params>")
43+
? cmd.replace("<params>", parameter)
44+
: cmd + " " + parameter;
45+
console.log(command);
46+
return new Promise<DosboxResult>((resolve, reject) => {
47+
const p = cp.exec(command, { cwd: this.cwd }, (error, stdout, stderr) => {
48+
if (error) {
49+
logger.error(JSON.stringify(error), p, this);
50+
vscode.window.showErrorMessage(
51+
"can't open dosbox with command: " + command + "cwd:" + this.cwd
52+
);
53+
reject(error);
54+
} else {
55+
resolve({ stdout, stderr, exitCode: p.exitCode });
56+
}
57+
});
58+
if (cpHandler) {
59+
cpHandler(p);
60+
}
61+
});
62+
}
63+
64+
async fromBundle(
65+
bundle: Uint8Array,
66+
tempFolder: vscode.Uri,
67+
useBundleConf: boolean = false
68+
): Promise<void> {
69+
const confText = await fromBundle(bundle, tempFolder);
70+
if (useBundleConf) {
71+
this._conf = new Conf(confText);
72+
}
73+
}
74+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as Jszip from "jszip";
2+
import * as vscode from "vscode";
3+
4+
const fs = vscode.workspace.fs;
5+
6+
/**
7+
* open dosbox-like emulator from bundle
8+
*
9+
* @param bundle bundle data
10+
* @param tempFolder the folder for exact all files to
11+
* @returns the dosbox.conf file in the jsdos bundle
12+
*/
13+
export async function fromBundle(
14+
bundle: Uint8Array,
15+
tempFolder: vscode.Uri
16+
): Promise<string | undefined> {
17+
const zip = new Jszip();
18+
await zip.loadAsync(bundle);
19+
Object.keys(zip.files).forEach(async function (filename) {
20+
const e = zip.files[filename];
21+
const data = await e.async("uint8array");
22+
const dest = vscode.Uri.joinPath(tempFolder, filename);
23+
if (e.dir === false) {
24+
await fs.writeFile(dest, data);
25+
}
26+
});
27+
const filename = ".jsdos/dosbox.conf";
28+
if (zip.file(filename)) {
29+
const data = await zip.files[filename].async("string");
30+
return data.replace(/mount\s+c\s+\./g, `mount c "${tempFolder.fsPath}"`);
31+
}
32+
}

0 commit comments

Comments
 (0)