mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-25 18:33:11 +00:00
server: updated parsing, flags
This commit is contained in:
parent
d31a8c4efe
commit
c6345ec728
@ -695,3 +695,9 @@ export function coerceToArray<T>(arrobj: any) : T[] {
|
||||
else if (typeof arrobj === 'object') return Array.from(Object.values(arrobj))
|
||||
else throw new Error(`Expected array or object, got "${arrobj}"`);
|
||||
}
|
||||
|
||||
export function replaceAll(s:string, search:string, replace:string) : string {
|
||||
if (s == '') return '';
|
||||
if (search == '') return s;
|
||||
return s.split(search).join(replace);
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ export class SourceEditor implements ProjectView {
|
||||
errorwidgets = [];
|
||||
errormarks = [];
|
||||
inspectWidget;
|
||||
refreshDelayMsec = 300;
|
||||
|
||||
createDiv(parent:HTMLElement) {
|
||||
var div = document.createElement('div');
|
||||
@ -77,6 +78,9 @@ export class SourceEditor implements ProjectView {
|
||||
this.editor.setSelection({line:0,ch:0}, {line:0,ch:0}, {scroll:true}); // move cursor to start
|
||||
}
|
||||
this.setupEditor();
|
||||
if (current_project.getToolForFilename(this.path).startsWith("remote:")) {
|
||||
this.refreshDelayMsec = 1000; // remote URLs get slower refresh
|
||||
}
|
||||
return div;
|
||||
}
|
||||
|
||||
@ -114,7 +118,7 @@ export class SourceEditor implements ProjectView {
|
||||
clearTimeout(this.updateTimer);
|
||||
this.updateTimer = setTimeout( () => {
|
||||
current_project.updateFile(this.path, this.editor.getValue());
|
||||
}, 300);
|
||||
}, this.refreshDelayMsec);
|
||||
if (this.markHighlight) {
|
||||
this.markHighlight.clear();
|
||||
this.markHighlight = null;
|
||||
|
@ -58,6 +58,7 @@ const VCS_PRESETS = [
|
||||
];
|
||||
|
||||
function getToolForFilename_vcs(fn: string) {
|
||||
if (fn.endsWith("-llvm.c")) return "remote:llvm-mos";
|
||||
if (fn.endsWith(".wiz")) return "wiz";
|
||||
if (fn.endsWith(".bb") || fn.endsWith(".bas")) return "bataribasic";
|
||||
if (fn.endsWith(".ca65")) return "ca65";
|
||||
|
@ -3,15 +3,15 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { spawn } from 'child_process';
|
||||
import { CodeListingMap, WorkerBuildStep, WorkerError, WorkerErrorResult, WorkerFileUpdate, WorkerResult, isOutputResult } from '../../common/workertypes';
|
||||
import { getBasePlatform, getRootBasePlatform } from '../../common/util';
|
||||
import { getBasePlatform, getRootBasePlatform, replaceAll } from '../../common/util';
|
||||
import { BuildStep, makeErrorMatcher } from '../workermain';
|
||||
import { parseObjDumpListing, parseObjDumpSymbolTable } from './clang';
|
||||
import { parseObjDump } from './clang';
|
||||
|
||||
|
||||
const LLVM_MOS_TOOL: ServerBuildTool = {
|
||||
name: 'llvm-mos',
|
||||
version: '',
|
||||
extensions: ['.c', '.cpp', '.s'],
|
||||
extensions: ['.c', '.cpp', '.s', '.S', '.C'],
|
||||
archs: ['6502'],
|
||||
platforms: ['atari8', 'c64', 'nes', 'pce', 'vcs'],
|
||||
platform_configs: {
|
||||
@ -27,11 +27,9 @@ const LLVM_MOS_TOOL: ServerBuildTool = {
|
||||
},
|
||||
c64: {
|
||||
command: 'mos-c64-clang',
|
||||
libargs: ['-D', '__C64__']
|
||||
},
|
||||
atari8: {
|
||||
command: 'mos-atari8-clang',
|
||||
libargs: ['-D', '__ATARI__']
|
||||
},
|
||||
nes: {
|
||||
command: 'mos-nes-nrom-clang', // TODO
|
||||
@ -39,7 +37,9 @@ const LLVM_MOS_TOOL: ServerBuildTool = {
|
||||
},
|
||||
pce: {
|
||||
command: 'mos-pce-clang', // TODO
|
||||
libargs: ['-D', '__PCE__']
|
||||
},
|
||||
vcs: {
|
||||
command: 'mos-atari2600-3e-clang', // TODO
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -175,6 +175,10 @@ export class ServerBuildEnv {
|
||||
resolve(this.processOutput(step));
|
||||
}
|
||||
} else {
|
||||
errorData = replaceAll(errorData, this.sessionDir, '');
|
||||
errorData = replaceAll(errorData, this.rootdir, '');
|
||||
// remove folder paths
|
||||
errorData = errorData.replace(/(\/var\/folders\/.+?\/).+?:/g, '');
|
||||
let errorResult = await this.processErrors(step, errorData);
|
||||
if (errorResult.errors.length === 0) {
|
||||
errorResult.errors.push({ line: 0, msg: `Build failed.\n\n${errorData}` });
|
||||
@ -203,10 +207,9 @@ export class ServerBuildEnv {
|
||||
|
||||
async processDebugInfo(step: WorkerBuildStep): Promise<WorkerResult> {
|
||||
let dbgfile = path.join(this.sessionDir, 'debug.out');
|
||||
let dbglist = await fs.promises.readFile(dbgfile);
|
||||
let listings = parseObjDumpListing(dbglist.toString());
|
||||
let symbolmap = parseObjDumpSymbolTable(dbglist.toString());
|
||||
return { output: [], listings, symbolmap };
|
||||
let dbglist = (await fs.promises.readFile(dbgfile)).toString();
|
||||
let { listings, symbolmap, segments } = parseObjDump(dbglist);
|
||||
return { output: [], listings, symbolmap, segments };
|
||||
}
|
||||
|
||||
async compileAndLink(step: WorkerBuildStep, updates: WorkerFileUpdate[]): Promise<WorkerResult> {
|
||||
|
@ -1,27 +1,37 @@
|
||||
import path from 'path';
|
||||
import { CodeListing, CodeListingMap } from "../../common/workertypes";
|
||||
import { CodeListing, CodeListingMap, Segment } from "../../common/workertypes";
|
||||
|
||||
export function parseObjDumpSymbolTable(symbolTable) {
|
||||
const lines = symbolTable.split('\n');
|
||||
const result = {};
|
||||
export function parseObjDump(lst: string) {
|
||||
// parse symbol map
|
||||
const lines = lst.split('\n');
|
||||
const symbolmap = {};
|
||||
const segments : Segment[] = [];
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i].trim();
|
||||
if (line.startsWith('00')) {
|
||||
if (line.startsWith("Disassembly")) break;
|
||||
if (line.startsWith('0')) {
|
||||
const parts = line.split(/\s+/);
|
||||
if (parts.length < 5) continue;
|
||||
const symbol = parts[parts.length-1];
|
||||
const address = parseInt(parts[0], 16);
|
||||
result[symbol] = address;
|
||||
const address = parseInt(parts[0], 16) & 0xffff; // TODO: 32-bit addresses
|
||||
symbolmap[symbol] = address;
|
||||
// is it a segment?
|
||||
if (symbol.startsWith('__')) {
|
||||
if (symbol.endsWith('_start')) {
|
||||
let name = symbol.substring(2, symbol.length - 6);
|
||||
let type = parts[2] == '.text' ? 'rom' : 'ram';
|
||||
segments.push({ name, start: address, size: 0, type })
|
||||
} else if (symbol.endsWith('_size')) {
|
||||
let name = symbol.substring(2, symbol.length - 5);
|
||||
let seg = segments.find(s => s.name === name);
|
||||
if (seg) seg.size = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function parseObjDumpListing(lst: string): CodeListingMap {
|
||||
const lines = lst.split('\n');
|
||||
const result: CodeListingMap = {};
|
||||
// parse listings
|
||||
const listings: CodeListingMap = {};
|
||||
var lastListing : CodeListing = null;
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i].trim();
|
||||
if (line.startsWith(';')) {
|
||||
@ -32,18 +42,18 @@ export function parseObjDumpListing(lst: string): CodeListingMap {
|
||||
const file = path.basename(fileParts[0].trim()).split('.')[0] + '.lst';
|
||||
const lineNumber = parseInt(fileParts[1], 10);
|
||||
if (lineNumber > 0) {
|
||||
if (!result[file]) result[file] = { lines: [], text: lst };
|
||||
lastListing = result[file];
|
||||
if (!listings[file]) listings[file] = { lines: [], text: lst };
|
||||
lastListing = listings[file];
|
||||
lastListing.lines.push({ line: lineNumber, offset: null });
|
||||
}
|
||||
}
|
||||
} else if (lastListing && line.match(/^\s*[A-F0-9]+:.+/i)) {
|
||||
const offsetIndex = line.indexOf(':');
|
||||
if (offsetIndex !== -1) {
|
||||
const offset = parseInt(line.substring(0, offsetIndex).trim(), 16);
|
||||
const offset = parseInt(line.substring(0, offsetIndex).trim(), 16) & 0xffff; // TODO: 32-bit addresses;
|
||||
lastListing.lines[lastListing.lines.length - 1].offset = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return { listings, symbolmap, segments };
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user