Skip to content

Commit 1a2aaea

Browse files
committed
add map view for cosmic-stm8
1 parent 42e9860 commit 1a2aaea

2 files changed

Lines changed: 197 additions & 0 deletions

File tree

src/ToolchainManager.ts

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import * as events from 'events';
3838
import * as NodePath from 'path';
3939
import * as os from 'os';
4040
import { ICompileOptions, ArmBaseBuilderConfigData } from "./EIDEProjectModules";
41+
import * as utility from "./utility";
4142

4243
export type ToolchainName =
4344
'SDCC' | 'Keil_C51' | 'IAR_STM8' | 'GNU_SDCC_STM8' | 'COSMIC_STM8' |
@@ -1168,6 +1169,158 @@ class COSMIC_STM8 implements IToolchian {
11681169
}
11691170
}
11701171

1172+
// start 0000054b end 00000613 length 200 section .info.
1173+
// start ******** end ******** length 0 section .text *** removed ***
1174+
// start 000080f9 end 0000814a length 81 section .text
1175+
private _mapPattern__objSec = /start [^\s]+ end [^\s]+ length \s*(?<size>[^\s]+) section (?<sec>[^\s]+)/;
1176+
private _parseMap(mapPath: string): any {
1177+
1178+
const lines = fs.readFileSync(mapPath).toString().split(/\r\n|\n/);
1179+
1180+
const objDic: any = {};
1181+
const secList: string[] = [];
1182+
1183+
let headerFound = false;
1184+
let currentFile: string | undefined;
1185+
for (let idx = 0; idx < lines.length; idx++) {
1186+
1187+
const trimedLine = lines[idx].trim();
1188+
1189+
if (headerFound == false && trimedLine == 'Modules') {
1190+
headerFound = true;
1191+
idx++; // skip next line
1192+
continue;
1193+
}
1194+
1195+
if (headerFound) {
1196+
1197+
if (/^\-+$/.test(trimedLine))
1198+
break; // end of content
1199+
1200+
if (/\.\w+:$/.test(trimedLine)) {
1201+
currentFile = trimedLine.substr(0, trimedLine.length - 1);
1202+
objDic[currentFile] = {};
1203+
continue; // go next line
1204+
}
1205+
1206+
if (currentFile) {
1207+
const m = this._mapPattern__objSec.exec(trimedLine);
1208+
if (m && m.groups) {
1209+
const name = m.groups['sec'];
1210+
const size = parseInt(m.groups['size']);
1211+
if (['.info.', '.debug'].includes(name)) continue; // skip some unused section
1212+
if (!secList.includes(name)) secList.push(name);
1213+
if (objDic[currentFile][name] != undefined) {
1214+
objDic[currentFile][name] += size;
1215+
} else {
1216+
objDic[currentFile][name] = size;
1217+
}
1218+
}
1219+
}
1220+
}
1221+
}
1222+
1223+
return {
1224+
sections: secList,
1225+
objDic: objDic
1226+
};
1227+
};
1228+
1229+
parseMapFile(mapPath: string): string[] | Error {
1230+
1231+
if (!File.IsFile(mapPath))
1232+
return new Error(`No such file: ${mapPath}`);
1233+
1234+
const mapInfo = this._parseMap(mapPath);
1235+
const secList = mapInfo.sections;
1236+
const objDic = mapInfo.objDic;
1237+
1238+
let oldObjDic: any = {};
1239+
if (File.IsFile(mapPath + '.old')) {
1240+
const inf = this._parseMap(mapPath + '.old');
1241+
oldObjDic = inf.objDic;
1242+
}
1243+
1244+
const tableRows: string[][] = [];
1245+
1246+
// push header
1247+
let header: string[] = [];
1248+
header.push('Module');
1249+
header.push('Size');
1250+
header = header.concat(secList);
1251+
tableRows.push(header);
1252+
1253+
let objTotalSize: any = { new: 0, old: 0 };
1254+
let secTotalSize: any = {};
1255+
for (const objpath in objDic) {
1256+
1257+
const objInfo = objDic[objpath];
1258+
const row: string[] = [objpath];
1259+
1260+
let totalSize = 0;
1261+
for (const key in objInfo) {
1262+
totalSize += objInfo[key];
1263+
}
1264+
1265+
let oldInfo: any = {};
1266+
if (oldObjDic[objpath]) {
1267+
oldInfo = oldObjDic[objpath];
1268+
}
1269+
1270+
let oldTotalSize = 0;
1271+
for (const key in oldInfo) {
1272+
oldTotalSize += oldInfo[key];
1273+
}
1274+
1275+
objTotalSize.new += totalSize;
1276+
objTotalSize.old += oldTotalSize;
1277+
1278+
const diffSize = totalSize - oldTotalSize;
1279+
row.push(totalSize.toString() + `(${diffSize > 0 ? '+' : ''}${diffSize.toString()})`);
1280+
1281+
for (const sec of secList) {
1282+
1283+
const oldSecSize = oldInfo[sec] ? oldInfo[sec] : 0;
1284+
const nowSecSize = objInfo[sec] ? objInfo[sec] : 0;
1285+
const diffSize = nowSecSize - oldSecSize;
1286+
row.push(nowSecSize.toString() + `(${diffSize > 0 ? '+' : ''}${diffSize.toString()})`);
1287+
1288+
if (secTotalSize[sec] == undefined) {
1289+
secTotalSize[sec] = {
1290+
new: 0,
1291+
old: 0
1292+
};
1293+
};
1294+
1295+
secTotalSize[sec].new += nowSecSize;
1296+
secTotalSize[sec].old += oldSecSize;
1297+
}
1298+
1299+
tableRows.push(row);
1300+
}
1301+
1302+
const row_total: string[] = ['Subtotals'];
1303+
{
1304+
const diffSize = objTotalSize.new - objTotalSize.old;
1305+
row_total.push(objTotalSize.new.toString() + `(${diffSize > 0 ? '+' : ''}${diffSize.toString()})`);
1306+
1307+
for (const sec of secList) {
1308+
const oldSecSize = secTotalSize[sec].old ? secTotalSize[sec].old : 0;
1309+
const newSecSize = secTotalSize[sec].new ? secTotalSize[sec].new : 0;
1310+
const diffSize = newSecSize - oldSecSize;
1311+
row_total.push(newSecSize.toString() + `(${diffSize > 0 ? '+' : ''}${diffSize.toString()})`);
1312+
}
1313+
}
1314+
tableRows.push(row_total);
1315+
1316+
const tableLines = utility.makeTextTable(tableRows);
1317+
if (tableLines == undefined) {
1318+
return new Error(`Nothing for this map: ${mapPath} !`);
1319+
}
1320+
1321+
return tableLines;
1322+
}
1323+
11711324
getInternalDefines<T extends BuilderConfigData>(builderCfg: T, builderOpts: ICompileOptions): string[] {
11721325

11731326
const mList: string[] = [

src/utility.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,50 @@ import { ExeCmd } from '../lib/node-utility/Executable';
4242
import { GlobalEvent } from './GlobalEvents';
4343
import { SettingManager } from './SettingManager';
4444

45+
export function makeTextTable(rows: string[][], headerLines?: string[]): string[] | undefined {
46+
47+
if (rows.length == 0)
48+
return undefined;
49+
50+
// init column len
51+
const colMaxLenList: number[] = [];
52+
rows[0].forEach(colHeader => colMaxLenList.push(colHeader.length));
53+
const colSize = colMaxLenList.length;
54+
55+
// calcu all cols max len
56+
for (let index = 1; index < rows.length; index++) {
57+
const row = rows[index];
58+
for (let colIdx = 0; colIdx < colSize; colIdx++) {
59+
let maxLen = colMaxLenList[colIdx];
60+
colMaxLenList[colIdx] = row[colIdx].length > maxLen ? row[colIdx].length : maxLen;
61+
}
62+
}
63+
64+
let outputLines: string[] = headerLines || [];
65+
66+
// make header
67+
{
68+
const tableHeader = rows[0];
69+
70+
let header_str: string = '';
71+
tableHeader.forEach((headerName, idx) => header_str += `| ${headerName.padEnd(colMaxLenList[idx])} `);
72+
73+
outputLines.push(''.padEnd(header_str.length, '-'));
74+
outputLines.push(header_str);
75+
outputLines.push(''.padEnd(header_str.length, '-'));
76+
}
77+
78+
// make rows
79+
for (let index = 1; index < rows.length; index++) {
80+
const row = rows[index];
81+
let line_str: string = '';
82+
row.forEach((cellStr, colIdx) => line_str += `| ${cellStr.padEnd(colMaxLenList[colIdx])} `);
83+
outputLines.push(line_str);
84+
}
85+
86+
return outputLines;
87+
}
88+
4589
export function getGccBinutilsVersion(gccBinDirPath: string, toolprefix?: string, toolname?: string): string | undefined {
4690

4791
// example output:

0 commit comments

Comments
 (0)