You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

866 lines
32 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. let isTesting = false;
  2. const ILCommentPrefix = "@@comments";
  3. const ILQuotesPrefix = "@@quotes";
  4. export class NewLineSettings {
  5. newLineAfter: Array<string>;
  6. noNewLineAfter: Array<string>;
  7. constructor() {
  8. this.newLineAfter = [];
  9. this.noNewLineAfter = [];
  10. }
  11. newLineAfterPush(keyword: string) {
  12. this.newLineAfter.push(keyword);
  13. }
  14. noNewLineAfterPush(keyword: string) {
  15. this.noNewLineAfter.push(keyword);
  16. }
  17. push(keyword: string, addNewLine: boolean) {
  18. if (addNewLine) {
  19. this.newLineAfterPush(keyword);
  20. }
  21. else {
  22. this.noNewLineAfterPush(keyword);
  23. }
  24. }
  25. }
  26. function ConstructNewLineSettings(dict): NewLineSettings {
  27. let settings: NewLineSettings = new NewLineSettings();
  28. for (let key in dict) {
  29. settings.push(key, dict[key]);
  30. }
  31. return settings;
  32. }
  33. function fetchHeader(url, wch) {
  34. try {
  35. var req = new XMLHttpRequest();
  36. req.open("HEAD", url, false);
  37. req.send(null);
  38. if (req.status == 200) {
  39. return req.getResponseHeader(wch);
  40. }
  41. else return false;
  42. } catch (e) {
  43. return "";
  44. }
  45. }
  46. declare global {
  47. interface String {
  48. regexIndexOf: (pattern: RegExp, startIndex?: number) => number;
  49. regexLastIndexOf: (pattern: RegExp, startIndex: number) => number;
  50. reverse: () => string;
  51. }
  52. }
  53. String.prototype.regexIndexOf = function (pattern, startIndex) {
  54. startIndex = startIndex || 0;
  55. var searchResult = this.substr(startIndex).search(pattern);
  56. return (-1 === searchResult) ? -1 : searchResult + startIndex;
  57. }
  58. String.prototype.regexLastIndexOf = function (pattern, startIndex) {
  59. startIndex = startIndex === undefined ? this.length : startIndex;
  60. var searchResult = this.substr(0, startIndex).reverse().regexIndexOf(pattern, 0);
  61. return (-1 === searchResult) ? -1 : this.length - ++searchResult;
  62. }
  63. String.prototype.reverse = function () {
  64. return this.split('').reverse().join('');
  65. }
  66. function wordWrap() {
  67. var d = document.getElementById("result");
  68. if (d.className == "") {
  69. d.className = "wordwrap";
  70. } else {
  71. d.className = "";
  72. }
  73. }
  74. function getHTMLInputElement(name: string): HTMLInputElement {
  75. return <HTMLInputElement>document.getElementById(name);
  76. }
  77. function noFormat() {
  78. let elements: Array<string> = ["remove_comments",
  79. "remove_lines",
  80. "remove_report",
  81. "check_alias",
  82. "sign_align",
  83. "sign_align_all",
  84. "new_line_after_port",
  85. "new_line",
  86. "use_space",
  87. "compress",
  88. "mix_letter"];
  89. var t = !(getHTMLInputElement("remove_comments").disabled);
  90. elements.forEach(element => {
  91. getHTMLInputElement(element).disabled = t;
  92. });
  93. let keyword = <HTMLFormElement>document.getElementById("keyword");
  94. for (let i = 0; i < keyword.elements.length; i++) {
  95. (<HTMLInputElement>keyword.elements[i]).disabled = t;
  96. }
  97. }
  98. function indent_decode() {
  99. var custom_indent: string = getHTMLInputElement("cust_indent").value;
  100. var result: string = indentDecode(custom_indent);
  101. document.getElementById("indent_s").innerHTML = result;
  102. }
  103. export function indentDecode(input: string): string {
  104. input = input.replace(/\\t/g, " ");
  105. var count = [" & one ", " & two ", " & three ", " & four ", " & five ", " & six ", " & seven ", " & eight ", " & many "];
  106. var tokens: Array<string> = input.split("");
  107. var result = "";
  108. var repeatedCharCount = 0;
  109. for (var i = 0; i < tokens.length; i++) {
  110. var char = input.substr(i, 1);
  111. if (char == input.substr(i + 1, 1)) {
  112. repeatedCharCount++;
  113. } else {
  114. switch (char) {
  115. case " ":
  116. char = "blankspace";
  117. break;
  118. case "\t":
  119. char = "tab";
  120. }
  121. repeatedCharCount = repeatedCharCount > 8 ? 8 : repeatedCharCount;
  122. result += count[repeatedCharCount] + char;
  123. repeatedCharCount = 0;
  124. }
  125. }
  126. if (result.length < 0) {
  127. switch (char) {
  128. case " ":
  129. char = "blankspace";
  130. break;
  131. case "\t":
  132. char = "tab";
  133. }
  134. repeatedCharCount = repeatedCharCount > 8 ? 8 : repeatedCharCount;
  135. result = count[repeatedCharCount] + char;
  136. }
  137. result = result.replace(/^ & /, "")
  138. return result;
  139. }
  140. function Compress(input: string) {
  141. input = input.replace(/\r\n/g, '');
  142. input = input.replace(/[\t ]+/g, ' ');
  143. input = input.replace(/[ ]?([&=:\-<>\+|])[ ]?/g, '$1');
  144. return input;
  145. }
  146. function MixLetters(input: string) {
  147. let arr = input.split("");
  148. for (var k = 0; k < arr.length; k++) {
  149. if (arr[k] === arr[k].toUpperCase() && Math.random() > 0.5) {
  150. arr[k] = arr[k].toLowerCase();
  151. } else if (Math.random() > 0.5) {
  152. arr[k] = arr[k].toUpperCase();
  153. }
  154. }
  155. return arr.join("");
  156. }
  157. function EscapeComments(arr: Array<string>, comments: Array<string>, commentIndex: number): number {
  158. for (var i = 0; i < arr.length; i++) {
  159. let line: string = arr[i];
  160. var firstCharIndex = line.regexIndexOf(/[a-zA-Z0-9\(\&\)%_\+'"|]/);
  161. var commentStartIndex = line.indexOf("--");
  162. if (firstCharIndex < commentStartIndex && firstCharIndex >= 0) {
  163. comments.push(line.substr(commentStartIndex));
  164. arr[i] = line.substr(firstCharIndex, commentStartIndex - firstCharIndex) + ILCommentPrefix + (commentIndex++);
  165. } else if ((firstCharIndex > commentStartIndex && commentStartIndex >= 0) || (firstCharIndex < 0 && commentStartIndex >= 0)) {
  166. comments.push(line.substr(commentStartIndex));
  167. arr[i] = ILCommentPrefix + (commentIndex++);
  168. } else {
  169. firstCharIndex = firstCharIndex < 0 ? 0 : firstCharIndex;
  170. arr[i] = line.substr(firstCharIndex);
  171. }
  172. }
  173. return commentIndex
  174. }
  175. function ToLowerCases(arr: Array<string>) {
  176. for (var i = 0; i < arr.length; i++) {
  177. arr[i] = arr[i].toLowerCase();
  178. }
  179. }
  180. function ToCamelCases(arr: Array<string>) {
  181. for (var i = 0; i < arr.length; i++) {
  182. arr[i] = arr[i].charAt(0) + arr[i].slice(1).toLowerCase();
  183. }
  184. }
  185. function ReplaceKeyWords(text: string, keywords: Array<string>): string {
  186. for (var k = 0; k < keywords.length; k++) {
  187. text = text.replace(new RegExp("([^a-zA-Z0-9_@]|^)" + keywords[k] + "([^a-zA-Z0-9_]|$)", 'gi'), "$1" + keywords[k] + "$2");
  188. }
  189. return text;
  190. }
  191. function SetKeywordCase(input: string, keywordcase: string, keywords, typenames) {
  192. let inputcase: string = keywordcase.toLowerCase();
  193. if (inputcase == "lowercase") {
  194. ToLowerCases(keywords);
  195. ToLowerCases(typenames);
  196. } else if (inputcase == "defaultcase") {
  197. ToCamelCases(keywords);
  198. ToCamelCases(typenames);
  199. }
  200. if (inputcase != "uppercase") {
  201. input = ReplaceKeyWords(input, keywords);
  202. input = ReplaceKeyWords(input, typenames);
  203. }
  204. return input;
  205. }
  206. function SetNewLinesAfterSymbols(text: string, newLineSettings: NewLineSettings): string {
  207. if (newLineSettings == null) {
  208. return text;
  209. }
  210. if (newLineSettings.newLineAfter != null) {
  211. newLineSettings.newLineAfter.forEach(symbol => {
  212. let regex: RegExp = new RegExp("(" + symbol.toUpperCase() + ")[ ]?([^ \r\n])", "g");
  213. text = text.replace(regex, '$1\r\n$2');
  214. });
  215. }
  216. if (newLineSettings.noNewLineAfter != null) {
  217. newLineSettings.noNewLineAfter.forEach(symbol => {
  218. let regex: RegExp = new RegExp("(" + symbol.toUpperCase() + ")[ \r\n]+", "g");
  219. text = text.replace(regex, '$1 ');
  220. });
  221. }
  222. return text;
  223. }
  224. export class BeautifierSettings {
  225. RemoveComments: boolean;
  226. RemoveAsserts: boolean;
  227. CheckAlias: boolean;
  228. SignAlign: boolean;
  229. SignAlignAll: boolean;
  230. KeywordCase: string;
  231. Indentation: string;
  232. NewLineSettings: NewLineSettings
  233. constructor(removeComments: boolean, removeReport: boolean, checkAlias: boolean,
  234. signAlign: boolean, signAlignAll: boolean, keywordCase: string, indentation: string,
  235. newLineSettings: NewLineSettings) {
  236. this.RemoveComments = removeComments;
  237. this.RemoveAsserts = removeReport;
  238. this.CheckAlias = checkAlias;
  239. this.SignAlign = signAlign;
  240. this.SignAlignAll = signAlignAll;
  241. this.KeywordCase = keywordCase;
  242. this.Indentation = indentation;
  243. this.NewLineSettings = newLineSettings;
  244. }
  245. }
  246. let KeyWords: Array<string> = ["ABS", "ACCESS", "AFTER", "ALIAS", "ALL", "AND", "ARCHITECTURE", "ARRAY", "ASSERT", "ATTRIBUTE", "BEGIN", "BLOCK", "BODY", "BUFFER", "BUS", "CASE", "COMPONENT", "CONFIGURATION", "CONSTANT", "CONTEXT", "COVER", "DISCONNECT", "DOWNTO", "DEFAULT", "ELSE", "ELSIF", "END", "ENTITY", "EXIT", "FAIRNESS", "FILE", "FOR", "FORCE", "FUNCTION", "GENERATE", "GENERIC", "GROUP", "GUARDED", "IF", "IMPURE", "IN", "INERTIAL", "INOUT", "IS", "LABEL", "LIBRARY", "LINKAGE", "LITERAL", "LOOP", "MAP", "MOD", "NAND", "NEW", "NEXT", "NOR", "NOT", "NULL", "OF", "ON", "OPEN", "OR", "OTHERS", "OUT", "PACKAGE", "PORT", "POSTPONED", "PROCEDURE", "PROCESS", "PROPERTY", "PROTECTED", "PURE", "RANGE", "RECORD", "REGISTER", "REJECT", "RELEASE", "REM", "REPORT", "RESTRICT", "RESTRICT_GUARANTEE", "RETURN", "ROL", "ROR", "SELECT", "SEQUENCE", "SEVERITY", "SHARED", "SIGNAL", "SLA", "SLL", "SRA", "SRL", "STRONG", "SUBTYPE", "THEN", "TO", "TRANSPORT", "TYPE", "UNAFFECTED", "UNITS", "UNTIL", "USE", "VARIABLE", "VMODE", "VPROP", "VUNIT", "WAIT", "WHEN", "WHILE", "WITH", "XNOR", "XOR"];
  247. let TypeNames: Array<string> = ["BOOLEAN", "BIT", "CHARACTER", "INTEGER", "TIME", "NATURAL", "POSITIVE", "STRING"];
  248. export function beautify(input: string, settings: BeautifierSettings) {
  249. input = RemoveExtraNewLines(input);
  250. input = input.replace(/[\t ]+/g, ' ');
  251. input = input.replace(/\([\t ]+/g, '\(');
  252. input = input.replace(/[ ]+;/g, ';');
  253. input = input.replace(/:[ ]*(PROCESS|ENTITY)/gi, ':$1');
  254. var arr = input.split("\r\n");
  255. var comments = [],
  256. commentsIndex = 0;
  257. commentsIndex = EscapeComments(arr, comments, commentsIndex);
  258. input = arr.join("\r\n");
  259. if (settings.RemoveComments) {
  260. input = input.replace(/@@comments[0-9]+/g, '');
  261. }
  262. input = ReplaceKeyWords(input, KeyWords);
  263. input = ReplaceKeyWords(input, TypeNames);
  264. input = input.replace(/(PORT|PROCESS|GENERIC)[\s]*\(/g, '$1 (');
  265. input = SetNewLinesAfterSymbols(input, settings.NewLineSettings);
  266. input = beautify2(input, settings);
  267. for (var k = 0; k < commentsIndex; k++) {
  268. input = input.replace(ILCommentPrefix + k, comments[k]);
  269. }
  270. input = input.replace(/@@semicolon/g, ";");
  271. input = input.replace(/@@[a-z]+/g, "");
  272. return input;
  273. }
  274. function beautify2(input, settings: BeautifierSettings): string {
  275. let arr = input.split("\r\n");
  276. let quotes = EscapeQuotes(arr);
  277. if (settings.RemoveAsserts) {
  278. RemoveAsserts(arr);//RemoveAsserts must be after EscapeQuotes
  279. }
  280. var singleline = [],
  281. singlelineIndex = 0;
  282. var align = [],
  283. align_max = [],
  284. align_i1 = 0,
  285. align_i = 0;
  286. var str = "",
  287. str1 = "";
  288. var p = 0;
  289. var n = 0,
  290. j = 0;
  291. var tab_n = 0,
  292. str_len = 0,
  293. port_s = "";
  294. var back_tab = false,
  295. forward_tab = false,
  296. semi_pos = 0,
  297. begin_b = true,
  298. port_b = false;
  299. var before_begin = true;
  300. var l = arr.length;
  301. ApplyNoNewLineAfter(arr, settings.NewLineSettings.noNewLineAfter);
  302. for (i = 0; i < l; i++) {
  303. if (arr[i].indexOf("BEGIN") >= 0) {
  304. before_begin = false;
  305. }
  306. if (arr[i].match(/FUNCTION|PROCEDURE/) != null) {
  307. arr[i] = arr[i].replace(/;/g, '@@semicolon');
  308. }
  309. if (port_s) {
  310. port_s += arr[i];
  311. var k_port = port_s.split("(").length;
  312. if (k_port == port_s.split(")").length) {
  313. arr[i] = arr[i] + "@@end";
  314. port_s = "";
  315. port_b = false;
  316. }
  317. }
  318. if ((!port_b && arr[i].regexIndexOf(/(\s|\(|^)(PORT|GENERIC|PROCESS|PROCEDURE)(\s|\(|$)/) >= 0) || (arr[i].regexIndexOf(/:[ ]?=[ ]?\(/) >= 0 && before_begin)) {
  319. port_b = true;
  320. port_s = arr[i];
  321. var k_port = port_s.split("(").length;
  322. if (k_port == 1) {
  323. port_b = false;
  324. port_s = "";
  325. } else if (k_port == port_s.split(")").length) {
  326. port_s = "";
  327. port_b = false;
  328. arr[i] = arr[i] + "@@singleend";
  329. } else {
  330. arr[i] = arr[i].replace(/(PORT|GENERIC|PROCEDURE)([a-z0-9A-Z_ ]+)\(([a-zA-Z0-9_\(\) ]+)/, '$1$2(\r\n$3');
  331. }
  332. }
  333. }
  334. input = arr.join("\r\n");
  335. input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end');
  336. input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 ');
  337. input = input.replace(/[ ]?([,])[ ]?/g, '$1 ');
  338. input = input.replace(/[ ]?(['"])(THEN)/g, '$1 $2');
  339. input = input.replace(/[ ]?(\?)?[ ]?(<|:|>|\/)?[ ]+(=)?[ ]?/g, ' $1$2$3 ');
  340. input = input.replace(/(IF)[ ]?([\(\)])/g, '$1 $2');
  341. input = input.replace(/([\(\)])[ ]?(THEN)/gi, '$1 $2');
  342. input = input.replace(/(^|[\(\)])[ ]?(AND|OR|XOR|XNOR)[ ]*([\(])/g, '$1 $2 $3');
  343. input = input.replace(/ ([\-\*\/=+<>])[ ]*([\-\*\/=+<>]) /g, " $1$2 ");
  344. input = input.replace(/\r\n[ \t]+--\r\n/g, "\r\n");
  345. input = input.replace(/[ ]+/g, ' ');
  346. input = input.replace(/\r\n\r\n\r\n/g, '\r\n');
  347. input = input.replace(/[\r\n\s]+$/g, '');
  348. input = input.replace(/[ \t]+\)/g, ')');
  349. var matches = input.match(/'([a-zA-Z]+)\s/g);
  350. if (matches != null) {
  351. for (var k2 = 0; k2 < matches.length; k2++) {
  352. input = input.replace(matches[k2], matches[k2].toUpperCase());
  353. }
  354. }
  355. input = input.replace(/(MAP)[ \r\n]+\(/g, '$1(');
  356. input = input.replace(/(;|THEN)[ ]?(@@comments[0-9]+)([a-zA-Z])/g, '$1 $2\r\n$3');
  357. input = input.replace(/[\r\n ]+RETURN/g, ' RETURN');
  358. input = input.replace(/BEGIN[\r\n ]+/g, 'BEGIN\r\n');
  359. input = input.replace(/ (PORT|GENERIC) /g, '\r\n$1 ');
  360. if (settings.CheckAlias) {
  361. var alias = [],
  362. subarr = [],
  363. o = 0,
  364. p = 0,
  365. p2 = 0,
  366. l2 = 0,
  367. i2 = 0;
  368. arr = input.split("ARCHITECTURE ");
  369. l = arr.length;
  370. for (i = 0; i < l; i++) {
  371. subarr = arr[i].split("ALIAS ");
  372. l2 = subarr.length;
  373. if (l2 > 1) {
  374. o = 0;
  375. for (i2 = 1; i2 < l2; i2++) {
  376. o = subarr[i2].indexOf(";", n);
  377. str = subarr[i2].substring(0, o);
  378. alias[p2++] = str.split(" IS ");
  379. }
  380. i2--;
  381. var str2 = subarr[i2].substr(o);
  382. for (p = 0; p < p2; p++) {
  383. var reg = new RegExp(alias[p][1], 'gi');
  384. str2 = str2.replace(reg, alias[p][0]);
  385. }
  386. subarr[i2] = subarr[i2].substring(0, o) + str2;
  387. }
  388. arr[i] = subarr.join("ALIAS ");
  389. }
  390. input = arr.join("ARCHITECTURE ");
  391. }
  392. arr = input.split("\r\n");
  393. l = arr.length;
  394. var signAlignPos = "";
  395. var if_b = 0,
  396. white_space = "",
  397. case_b = false,
  398. case_n = 0,
  399. procfun_b = false,
  400. semi_b = false,
  401. set_false = false,
  402. entity_b = false,
  403. then_b = false,
  404. conditional_b = false,
  405. generic_map_b = false,
  406. architecture_begin_b = false,
  407. process_begin_b = false,
  408. case_indent = [0, 0, 0, 0, 0, 0, 0];
  409. var align_groups = [],
  410. align_groups_max = [],
  411. lastAlignedSign = "",
  412. current_align_group = 0,
  413. aligned_group_starts = 0;
  414. var indent_start = [];
  415. for (i = 0; i < l; i++) {
  416. str = arr[i];
  417. str_len = str.length;
  418. if (str.replace(/[ \-\t]*/, "").length > 0) {
  419. var first_word = str.split(/[^\w]/)[0];
  420. var indent_start_last = indent_start.length == 0 ? 0 : indent_start[indent_start.length - 1];
  421. if (then_b) {
  422. arr[i] = " " + arr[i];
  423. if (str.indexOf(" THEN") >= 0) {
  424. then_b = false;
  425. back_tab = true;
  426. }
  427. }
  428. arr[i] = white_space + arr[i];
  429. if (first_word == "ELSIF") {
  430. tab_n = indent_start_last - 1;
  431. indent_start.pop();
  432. back_tab = true;
  433. } else if (str.indexOf("END CASE") == 0) {
  434. indent_start.pop();
  435. case_n--;
  436. tab_n = indent_start[indent_start.length - 1];
  437. } else if (first_word == "END") {
  438. tab_n = indent_start_last - 1;
  439. indent_start.pop();
  440. if (str.indexOf("END IF") == 0) {
  441. if_b--;
  442. }
  443. if (i == l - 1) {
  444. tab_n = 1;
  445. }
  446. } else if (first_word == "ELSE" && if_b) {
  447. tab_n = indent_start_last - 1;
  448. indent_start.pop();
  449. back_tab = true;
  450. } else if (case_n) {
  451. if (first_word == "WHEN") {
  452. tab_n = case_indent[case_n - 1];
  453. //back_tab = true;
  454. }
  455. } else if (first_word == "BEGIN") {
  456. if (begin_b) {
  457. if (architecture_begin_b) {
  458. tab_n = indent_start_last - 1;
  459. architecture_begin_b = false;
  460. } else if (process_begin_b) {
  461. tab_n = indent_start_last - 1;
  462. process_begin_b = false;
  463. } else {
  464. tab_n = indent_start_last;
  465. indent_start.push(tab_n + 1);
  466. }
  467. //indent_start.pop();
  468. back_tab = true;
  469. begin_b = false;
  470. if (procfun_b) {
  471. tab_n++;
  472. indent_start.push(tab_n);
  473. begin_b = true;
  474. }
  475. } else {
  476. back_tab = true;
  477. }
  478. } else if (first_word == "PROCESS") {
  479. begin_b = true;
  480. } else if (str.indexOf(": PROCESS") >= 0) {
  481. back_tab = true;
  482. begin_b = true;
  483. process_begin_b = true;
  484. } else if (str.indexOf(": ENTITY") >= 0) {
  485. back_tab = true;
  486. entity_b = true;
  487. } else if (str.indexOf("PROCEDURE ") >= 0) {
  488. back_tab = true;
  489. begin_b = true;
  490. }
  491. if (port_b && str.indexOf("@@") < 0) {
  492. if (i + 1 <= arr.length - 1 && arr[i + 1].indexOf("@@") < 0) {
  493. if (signAlignPos == ":") {
  494. if (str.indexOf(';') < 0) {
  495. arr[i] += arr[i + 1];
  496. arr[i + 1] = '@@removeline';
  497. }
  498. } else if (signAlignPos == "=>") {
  499. if (str.indexOf(',') < 0) {
  500. arr[i] += arr[i + 1];
  501. arr[i + 1] = '@@removeline';
  502. }
  503. }
  504. }
  505. }
  506. if (str.indexOf("PORT MAP") >= 0) {
  507. back_tab = true;
  508. port_b = true;
  509. if (str.indexOf(");") < 0) {
  510. align_i1 = align_i;
  511. var t = str.indexOf("=>");
  512. if (t >= 0) {
  513. signAlignPos = "=>";
  514. } else {
  515. if (i + 1 < arr.length) {
  516. t = arr[i + 1].indexOf("=>");
  517. if (t >= 0) {
  518. signAlignPos = "=>";
  519. }
  520. }
  521. }
  522. } else {
  523. signAlignPos = "";
  524. }
  525. } else if (str.indexOf("GENERIC MAP") >= 0) {
  526. tab_n++;
  527. indent_start.push(tab_n);
  528. generic_map_b = true;
  529. if (!begin_b) {
  530. back_tab = false;
  531. }
  532. } else if (str.indexOf("PORT (") >= 0 && begin_b) {
  533. back_tab = true;
  534. port_b = true;
  535. t = str.indexOf(":");
  536. if (str.indexOf(");") < 0) {
  537. align_i1 = align_i;
  538. if (t >= 0) {
  539. signAlignPos = ":";
  540. } else {
  541. t = arr[i + 1].indexOf(":");
  542. if (t >= 0) {
  543. signAlignPos = ":";
  544. }
  545. }
  546. } else {
  547. signAlignPos = "";
  548. }
  549. }
  550. if (set_false) {
  551. procfun_b = false;
  552. set_false = false;
  553. }
  554. if (str.indexOf("(") >= 0) {
  555. if (str.indexOf("PROCEDURE") >= 0 || str.indexOf("FUNCTION") >= 0) {
  556. procfun_b = true;
  557. back_tab = true;
  558. }
  559. if ((str.indexOf("GENERIC") >= 0 || str.indexOf(":= (") >= 0 || str.regexIndexOf(/PROCEDURE[a-zA-Z0-9_ ]+\(/) >= 0) && begin_b) {
  560. port_b = true;
  561. back_tab = true;
  562. }
  563. } else if (first_word == "FUNCTION") {
  564. back_tab = true;
  565. begin_b = true;
  566. }
  567. if (str.indexOf("@@singleend") >= 0) {
  568. back_tab = false;
  569. port_b = false;
  570. if (!begin_b) {
  571. forward_tab = true;
  572. }
  573. } else if (str.indexOf("@@end") >= 0 && port_b) {
  574. port_b = false;
  575. indent_start.pop();
  576. tab_n = indent_start[indent_start.length - 1];
  577. if (entity_b) {
  578. forward_tab = true;
  579. }
  580. if (generic_map_b) {
  581. forward_tab = true;
  582. generic_map_b = false;
  583. }
  584. }
  585. if (settings.SignAlignAll) {
  586. var alignedSigns = [":", "<=", "=>"];
  587. for (var currentSign = 0; currentSign < alignedSigns.length; currentSign++) {
  588. if (str.indexOf(alignedSigns[currentSign]) > 0) {
  589. var char_before_sign = str.split(alignedSigns[currentSign])[0];
  590. var char_before_sign_length = char_before_sign.length;
  591. align_groups.push(char_before_sign_length);
  592. align_groups_max.push(char_before_sign_length);
  593. if (alignedSigns[currentSign] == lastAlignedSign) {
  594. if (align_groups_max[current_align_group - 1] < char_before_sign_length) {
  595. for (var k3 = aligned_group_starts; k3 <= current_align_group; k3++) {
  596. align_groups_max[k3] = char_before_sign_length;
  597. }
  598. } else {
  599. align_groups_max[current_align_group] = align_groups_max[current_align_group - 1];
  600. }
  601. } else {
  602. aligned_group_starts = current_align_group;
  603. }
  604. arr[i] = char_before_sign + "@@alignall" + (current_align_group++) + str.substring(char_before_sign.length, arr[i].length);
  605. lastAlignedSign = alignedSigns[currentSign];
  606. break;
  607. }
  608. }
  609. if (currentSign == alignedSigns.length) {
  610. lastAlignedSign = "";
  611. }
  612. } else if (settings.SignAlign) {
  613. if (port_b && signAlignPos != "") {
  614. if (str.indexOf(signAlignPos) >= 0) {
  615. var a1 = arr[i].split(signAlignPos);
  616. var l1 = a1[0].length;
  617. if (align_i >= 0 && align_i > align_i1) {
  618. align_max[align_i] = align_max[align_i - 1];
  619. } else {
  620. align_max[align_i] = l1;
  621. }
  622. if (align_i > align_i1 && align_max[align_i] < l1) {
  623. for (var k3 = align_i1; k3 <= align_i; k3++) {
  624. align_max[k3] = l1;
  625. }
  626. }
  627. align[align_i] = l1;
  628. arr[i] = a1[0] + "@@align" + (align_i++) + signAlignPos + arr[i].substring(l1 + signAlignPos.length, arr[i].length);
  629. }
  630. }
  631. }
  632. tab_n = tab_n < 1 ? 1 : tab_n;
  633. if (str_len) {
  634. if (isTesting) {
  635. console.log(tab_n, arr[i], indent_start);
  636. }
  637. arr[i] = (Array(tab_n).join(settings.Indentation)) + arr[i]; //indent
  638. if (settings.NewLineSettings.newLineAfter.indexOf("port")) {
  639. if (str.indexOf('@@singleend') < 0) {
  640. arr[i] = arr[i].replace(/(PORT)([ \r\n\w]*)\(/, "$1$2\r\n" + (Array(tab_n).join(settings.Indentation)) + "(");
  641. }
  642. }
  643. if (settings.NewLineSettings.newLineAfter.indexOf("generic")) {
  644. if (str.indexOf('@@singleend') < 0) {
  645. arr[i] = arr[i].replace(/(GENERIC)([ \r\n\w]*)\(/, "$1$2\r\n" + (Array(tab_n).join(settings.Indentation)) + "(");
  646. }
  647. }
  648. }
  649. if (back_tab) {
  650. tab_n++;
  651. indent_start.push(tab_n);
  652. back_tab = false;
  653. }
  654. if (forward_tab) {
  655. tab_n = indent_start_last;
  656. indent_start.pop();
  657. forward_tab = false;
  658. }
  659. if (conditional_b && str.indexOf(";") >= 0) {
  660. conditional_b = false;
  661. white_space = "";
  662. } else if (str.indexOf(";") >= 0 && semi_b) {
  663. semi_b = false;
  664. tab_n = indent_start_last;
  665. indent_start.pop();
  666. } else if (!semi_b && str.indexOf(";") < 0 && !port_b) {
  667. if (!conditional_b) {
  668. if (str.indexOf("WHEN") > 3 && str.indexOf("<=") > 1) {
  669. conditional_b = true;
  670. white_space = (Array(str.indexOf("= ") + 3).join(" "));
  671. } else if (first_word == "WHEN" && i + 1 < arr.length && arr[i + 1].indexOf("WHEN") < 0) {
  672. tab_n = indent_start_last + 1;
  673. } else if (str.indexOf("=>") < 0 && ((str.indexOf(ILQuotesPrefix) >= 0 && str.indexOf("= " + ILQuotesPrefix) < 0 && str.indexOf("IF") < 0) || (str.indexOf("<=") > 0 && str.indexOf("IF") < 0 && str.indexOf("THEN") < 0))) {
  674. tab_n++;
  675. indent_start.push(tab_n);
  676. semi_b = true;
  677. }
  678. }
  679. }
  680. if (first_word == "ENTITY") {
  681. tab_n++;
  682. indent_start.push(tab_n);
  683. } else if (",RECORD,PACKAGE,FOR,COMPONENT,CONFIGURATION,".indexOf("," + first_word + ",") >= 0) {
  684. tab_n++;
  685. indent_start.push(tab_n);
  686. } else if (str.indexOf(": FOR ") >= 0) {
  687. tab_n++;
  688. indent_start.push(tab_n);
  689. } else if (first_word == "CASE" || str.indexOf(": CASE") >= 0) {
  690. tab_n++;
  691. indent_start.push(tab_n);
  692. case_indent[case_n] = tab_n;
  693. case_n++;
  694. } else if (first_word == "ARCHITECTURE") {
  695. tab_n++;
  696. indent_start.push(tab_n);
  697. begin_b = true;
  698. architecture_begin_b = true;
  699. } else if (first_word == "IF") {
  700. if_b++;
  701. tab_n++;
  702. indent_start.push(tab_n);
  703. if (str.indexOf(" THEN") < 0) {
  704. then_b = true;
  705. tab_n = indent_start_last;
  706. //indent_start.pop();
  707. }
  708. }
  709. if (procfun_b) {
  710. if (str.regexIndexOf(/(\))|(RETURN [A-Za-z0-9 ]+)[\r\n ]+IS/) >= 0) {
  711. tab_n = indent_start_last;
  712. indent_start.pop();
  713. set_false = true;
  714. }
  715. }
  716. }
  717. }
  718. input = arr.join("\r\n");
  719. input = input.replace(/[\t]*@@removeline\r\n/g, '');
  720. p = input.indexOf('PROCESS');
  721. while (p >= 0) {
  722. let nextBracket = input.indexOf('(', p);
  723. let nextNewLine = input.indexOf('\r\n', p);
  724. let nextCloseBracket = input.indexOf(')', nextBracket);
  725. if (nextBracket < nextNewLine && nextCloseBracket > nextNewLine) {
  726. let processArray = input.substring(p, nextCloseBracket).split('\r\n');
  727. if (settings.Indentation.replace(/[ ]+/g, '').length == 0) {
  728. for (var i = 1; i < processArray.length; i++) {
  729. processArray[i] = (Array(nextBracket - p + 2).join(' ')) + processArray[i];
  730. }
  731. } else {
  732. for (var i = 1; i < processArray.length; i++) {
  733. processArray[i] = settings.Indentation + processArray[i];
  734. }
  735. }
  736. input = input.substring(0, p) + processArray.join('\r\n') + input.substring(nextCloseBracket, input.length);
  737. p = input.regexIndexOf('PROCESS[ ]+\\(', nextCloseBracket);
  738. } else {
  739. p = input.indexOf('PROCESS[ ]+\\(', p + 7);
  740. }
  741. }
  742. input = SetKeywordCase(input, settings.KeywordCase, KeyWords, TypeNames);
  743. if (settings.SignAlignAll) {
  744. for (var k = 0; k < current_align_group; k++) {
  745. input = input.replace("@@alignall" + k, Array((align_groups_max[k] - align_groups[k] + 1)).join(" "));
  746. }
  747. }
  748. if (settings.SignAlign) {
  749. for (var k = 0; k < align_i; k++) {
  750. input = input.replace("@@align" + k, Array((align_max[k] - align[k] + 2)).join(" "));
  751. }
  752. }
  753. for (var k = 0; k < quotes.length; k++) {
  754. input = input.replace(ILQuotesPrefix + k, quotes[k]);
  755. }
  756. input = input.replace(/@@singleline[ \r\n]*/, " ");
  757. return input;
  758. }
  759. export function ApplyNoNewLineAfter(arr: Array<string>, noNewLineAfter: Array<string>) {
  760. if (noNewLineAfter == null) {
  761. return;
  762. }
  763. for (let i = 0; i < arr.length; i++) {
  764. noNewLineAfter.forEach(n => {
  765. let regex = new RegExp("(" + n.toUpperCase + ")[ a-z0-9]+[a-z0-9]+");
  766. if (arr[i].regexIndexOf(regex) >= 0) {
  767. arr[i] += "@@singleline";
  768. }
  769. });
  770. }
  771. }
  772. export function RemoveAsserts(arr: Array<string>) {
  773. let need_semi: boolean = false;
  774. let inAssert: boolean = false;
  775. let n: number = 0;
  776. for (let i = 0; i < arr.length; i++) {
  777. let has_semi: boolean = arr[i].indexOf(";") >= 0;
  778. if (need_semi) {
  779. arr[i] = '';
  780. }
  781. n = arr[i].indexOf("ASSERT ");
  782. if (n >= 0) {
  783. inAssert = true;
  784. arr[i] = '';
  785. }
  786. if (!has_semi) {
  787. if (inAssert) {
  788. need_semi = true;
  789. }
  790. }
  791. else {
  792. need_semi = false;
  793. }
  794. }
  795. }
  796. function EscapeQuotes(arr: Array<string>): Array<string> {
  797. let quotes: Array<string> = [];
  798. let quotesIndex = 0;
  799. for (let i = 0; i < arr.length; i++) {
  800. let quote = arr[i].match(/"([^"]+)"/g);
  801. if (quote != null) {
  802. for (var j = 0; j < quote.length; j++) {
  803. arr[i] = arr[i].replace(quote[j], ILQuotesPrefix + quotesIndex);
  804. quotes[quotesIndex++] = quote[j];
  805. }
  806. }
  807. }
  808. return quotes;
  809. }
  810. function RemoveExtraNewLines(input: any) {
  811. input = input.replace(/(?:\r\n|\r|\n)/g, '\r\n');
  812. input = input.replace(/ \r\n/g, '\r\n');
  813. input = input.replace(/\r\n\r\n\r\n/g, '\r\n');
  814. return input;
  815. }