2018-06-29 23:52:09 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
function SourceFile(lines, text) {
|
|
|
|
lines = lines || [];
|
|
|
|
this.lines = lines;
|
|
|
|
this.text = text;
|
|
|
|
this.offset2line = {};
|
|
|
|
this.line2offset = {};
|
|
|
|
for (var info of lines) {
|
|
|
|
if (info.offset >= 0) {
|
|
|
|
this.offset2line[info.offset] = info.line;
|
|
|
|
this.line2offset[info.line] = info.offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.findLineForOffset = function(PC) {
|
|
|
|
if (this.offset2line) {
|
|
|
|
for (var i=0; i<16; i++) {
|
|
|
|
var line = this.offset2line[PC];
|
|
|
|
if (line >= 0) {
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
PC--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2018-06-30 14:26:41 +00:00
|
|
|
this.lineCount = function() { return lines.length; }
|
2018-06-29 23:52:09 +00:00
|
|
|
}
|
|
|
|
|
2018-07-03 03:45:08 +00:00
|
|
|
function CodeProject(worker, platform_id, platform, store, mainpath) {
|
2018-06-29 23:52:09 +00:00
|
|
|
var self = this;
|
2018-07-02 13:34:20 +00:00
|
|
|
|
|
|
|
var filedata = {};
|
|
|
|
var listings;
|
2018-06-29 23:52:09 +00:00
|
|
|
|
|
|
|
self.callbackBuildResult = function(result) { };
|
|
|
|
self.callbackBuildStatus = function(busy) { };
|
|
|
|
|
|
|
|
var pendingWorkerMessages = 0;
|
2018-07-03 03:45:08 +00:00
|
|
|
|
2018-06-29 23:52:09 +00:00
|
|
|
var tools_preloaded = {};
|
|
|
|
function preloadWorker(path) {
|
|
|
|
var tool = platform.getToolForFilename(path);
|
|
|
|
if (tool && !tools_preloaded[tool]) {
|
|
|
|
worker.postMessage({preload:tool, platform:platform_id});
|
|
|
|
tools_preloaded[tool] = true;
|
|
|
|
}
|
|
|
|
}
|
2018-07-03 03:45:08 +00:00
|
|
|
|
|
|
|
self.setMainPath = function(path) {
|
|
|
|
mainpath = path;
|
|
|
|
}
|
2018-06-30 14:26:41 +00:00
|
|
|
|
|
|
|
// TODO: get local file as well as presets?
|
2018-07-02 13:34:20 +00:00
|
|
|
self.loadFiles = function(paths, callback) {
|
2018-06-29 23:52:09 +00:00
|
|
|
var result = [];
|
|
|
|
function loadNext() {
|
2018-07-02 13:34:20 +00:00
|
|
|
var path = paths.shift();
|
|
|
|
if (!path) {
|
2018-06-29 23:52:09 +00:00
|
|
|
callback(null, result); // TODO?
|
|
|
|
} else {
|
2018-07-02 13:34:20 +00:00
|
|
|
store.getItem(path, function(err, value) {
|
2018-06-29 23:52:09 +00:00
|
|
|
if (err) {
|
|
|
|
callback(err);
|
|
|
|
} else if (value) {
|
|
|
|
result.push({
|
2018-07-02 13:34:20 +00:00
|
|
|
path:path,
|
|
|
|
filename:getFilenameForPath(path),
|
2018-06-29 23:52:09 +00:00
|
|
|
data:value
|
|
|
|
});
|
2018-07-02 13:34:20 +00:00
|
|
|
filedata[path] = value;
|
2018-06-29 23:52:09 +00:00
|
|
|
loadNext();
|
|
|
|
} else {
|
2018-07-02 13:34:20 +00:00
|
|
|
var webpath = "presets/" + platform_id + "/" + path;
|
|
|
|
if (platform_id == 'vcs' && path.indexOf('.') <= 0)
|
2018-06-29 23:52:09 +00:00
|
|
|
webpath += ".a"; // legacy stuff
|
2018-07-02 13:34:20 +00:00
|
|
|
// TODO: cache files
|
2018-06-29 23:52:09 +00:00
|
|
|
$.get( webpath, function( text ) {
|
|
|
|
console.log("GET",webpath,text.length,'bytes');
|
|
|
|
result.push({
|
2018-07-02 13:34:20 +00:00
|
|
|
path:path,
|
|
|
|
filename:getFilenameForPath(path),
|
2018-06-29 23:52:09 +00:00
|
|
|
data:text
|
|
|
|
});
|
2018-07-02 13:34:20 +00:00
|
|
|
filedata[path] = text;
|
2018-06-29 23:52:09 +00:00
|
|
|
loadNext();
|
|
|
|
}, 'text')
|
|
|
|
.fail(function() {
|
2018-07-02 13:34:20 +00:00
|
|
|
callback("Could not load preset " + path);
|
2018-06-29 23:52:09 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
loadNext(); // load first file
|
|
|
|
}
|
2018-07-02 13:34:20 +00:00
|
|
|
|
|
|
|
function parseFileDependencies(text) {
|
|
|
|
var files = [];
|
2018-06-29 23:52:09 +00:00
|
|
|
if (platform_id == 'verilog') {
|
|
|
|
var re = /^(`include|[.]include)\s+"(.+?)"/gm;
|
|
|
|
var m;
|
|
|
|
while (m = re.exec(text)) {
|
2018-07-02 13:34:20 +00:00
|
|
|
files.push(m[2]);
|
2018-06-29 23:52:09 +00:00
|
|
|
}
|
2018-07-02 13:34:20 +00:00
|
|
|
} else {
|
|
|
|
var re = /^([;#]|[/][/][#])link\s+"(.+?)"/gm;
|
|
|
|
var m;
|
|
|
|
while (m = re.exec(text)) {
|
|
|
|
files.push(m[2]);
|
2018-06-29 23:52:09 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-02 13:34:20 +00:00
|
|
|
return files;
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadFileDependencies(text, callback) {
|
|
|
|
var paths = parseFileDependencies(text);
|
|
|
|
self.loadFiles(paths, callback);
|
2018-06-29 23:52:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function okToSend() {
|
|
|
|
return pendingWorkerMessages++ == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateFileInStore(path, text) {
|
|
|
|
// protect against accidential whole-file deletion
|
|
|
|
if (text.trim().length) {
|
|
|
|
// TODO? (originalFileID != path || text != originalText)) {
|
|
|
|
store.setItem(path, text);
|
|
|
|
}
|
|
|
|
}
|
2018-07-02 13:34:20 +00:00
|
|
|
|
|
|
|
// TODO: test duplicate files, local paths mixed with presets
|
2018-07-03 03:45:08 +00:00
|
|
|
function buildWorkerMessage(depends) {
|
|
|
|
preloadWorker(mainpath);
|
2018-07-02 13:34:20 +00:00
|
|
|
var msg = {updates:[], buildsteps:[]};
|
|
|
|
// TODO: add preproc directive for __MAINFILE__
|
2018-07-03 02:40:15 +00:00
|
|
|
var mainfilename = getFilenameForPath(mainpath);
|
2018-07-03 03:45:08 +00:00
|
|
|
var maintext = self.getFile(mainpath);
|
2018-07-03 02:40:15 +00:00
|
|
|
msg.updates.push({path:mainfilename, data:maintext});
|
|
|
|
msg.buildsteps.push({path:mainfilename, platform:platform_id, tool:platform.getToolForFilename(mainpath), mainfile:true});
|
2018-07-02 13:34:20 +00:00
|
|
|
for (var i=0; i<depends.length; i++) {
|
|
|
|
var dep = depends[i];
|
|
|
|
if (dep.data) {
|
2018-07-03 03:45:08 +00:00
|
|
|
preloadWorker(dep.filename);
|
2018-07-02 13:34:20 +00:00
|
|
|
msg.updates.push({path:dep.filename, data:dep.data});
|
|
|
|
msg.buildsteps.push({path:dep.filename, platform:platform_id, tool:platform.getToolForFilename(dep.path)});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.getFile = function(path) {
|
|
|
|
return filedata[path];
|
|
|
|
}
|
|
|
|
|
|
|
|
self.iterateFiles = function(callback) {
|
|
|
|
for (var path in filedata) {
|
|
|
|
callback(path, self.getFile(path));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 03:45:08 +00:00
|
|
|
self.sendBuild = function() {
|
|
|
|
var text = self.getFile(mainpath);
|
|
|
|
loadFileDependencies(text, function(err, depends) {
|
|
|
|
if (err) {
|
|
|
|
console.log(err); // TODO?
|
|
|
|
}
|
|
|
|
var workermsg = buildWorkerMessage(depends);
|
|
|
|
worker.postMessage(workermsg);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-06-29 23:52:09 +00:00
|
|
|
self.updateFile = function(path, text, isBinary) {
|
|
|
|
updateFileInStore(path, text); // TODO: isBinary
|
2018-07-02 13:34:20 +00:00
|
|
|
filedata[path] = text;
|
2018-06-29 23:52:09 +00:00
|
|
|
if (okToSend()) {
|
2018-07-03 13:33:42 +00:00
|
|
|
if (!mainpath) mainpath = path;
|
2018-06-29 23:52:09 +00:00
|
|
|
self.callbackBuildStatus(true);
|
2018-07-03 03:45:08 +00:00
|
|
|
self.sendBuild();
|
2018-06-29 23:52:09 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-06-30 14:26:41 +00:00
|
|
|
self.processBuildResult = function(data) {
|
2018-07-02 13:34:20 +00:00
|
|
|
// TODO: link listings with source files
|
|
|
|
listings = data.listings;
|
|
|
|
if (listings) {
|
|
|
|
for (var lstname in listings) {
|
|
|
|
var lst = listings[lstname];
|
2018-06-29 23:52:09 +00:00
|
|
|
if (lst.lines)
|
|
|
|
lst.sourcefile = new SourceFile(lst.lines);
|
|
|
|
if (lst.asmlines)
|
|
|
|
lst.assemblyfile = new SourceFile(lst.asmlines, lst.text);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-07-02 13:34:20 +00:00
|
|
|
|
|
|
|
self.getListings = function() {
|
|
|
|
return listings;
|
|
|
|
}
|
2018-06-29 23:52:09 +00:00
|
|
|
|
|
|
|
worker.onmessage = function(e) {
|
|
|
|
if (pendingWorkerMessages > 1) {
|
2018-07-03 03:45:08 +00:00
|
|
|
self.sendBuild();
|
2018-06-29 23:52:09 +00:00
|
|
|
pendingWorkerMessages = 0;
|
|
|
|
} else {
|
|
|
|
pendingWorkerMessages = 0;
|
|
|
|
}
|
|
|
|
self.callbackBuildStatus(false);
|
|
|
|
if (e.data && !e.data.unchanged) {
|
2018-06-30 14:26:41 +00:00
|
|
|
self.processBuildResult(e.data);
|
2018-06-30 04:42:21 +00:00
|
|
|
self.callbackBuildResult(e.data); // call with data when changed
|
2018-06-29 23:52:09 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|