From bb366d605bb4e1fca189efc713de8e0e26df771e Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Fri, 8 Sep 2023 16:23:47 +0200 Subject: [PATCH 01/70] Update deps and fix gcov parsing (#1) * Update deps and fix gcov parsing --- .eslintrc.cjs | 31 + README.md | 75 +- package-lock.json | 1029 ------------------------- package.json | 133 ++-- src/coverage.ts | 33 +- src/extension.ts | 113 ++- src/gcov.ts | 98 +++ src/gdb.ts | 1253 +++++++++++++++++-------------- src/mi2.ts | 1827 ++++++++++++++++++++++----------------------- src/parser.c.ts | 3 - src/parser.mi2.ts | 45 +- src/settings.ts | 17 +- tsconfig.json | 13 +- yarn.lock | 1252 +++++++++++++++++++++++++++++++ 14 files changed, 3180 insertions(+), 2742 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 package-lock.json create mode 100644 src/gcov.ts create mode 100644 yarn.lock diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..b24cc29 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,31 @@ +module.exports = { + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + ], + plugins: [ + "@typescript-eslint" + ], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + tsconfigRootDir: __dirname, + }, + root: true, + rules: { + "@typescript-eslint/no-unused-vars": "off", + "no-unused-vars": [ + 1, + { + argsIgnorePattern: "^_" + } + ], + "max-len": [ + 1, + { + code: 100, + } + ] + } +} diff --git a/README.md b/README.md index f61f550..4d6478c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,19 @@

-An extension to debug or execute GnuCOBOL code. Install from [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=OlegKunitsyn.gnucobol-debug) or [Open VSX-Registry](https://open-vsx.org/extension/OlegKunitsyn/gnucobol-debug). +An extension to debug or execute GnuCOBOL code. Forked from [COBOL Degub](https://github.com/OlegKunitsyn/gnucobol-debug). + +- [Features](#features) +- [Requirements](#requirements) + - [Binaries](#binaries) +- [Usage](#usage) +- [Code coverage](#code-coverage) +- [Attaching to a running process](#attaching-to-a-running-process) + - [Local Process](#local-process) + - [Remote Debugger (GDBServer)](#remote-debugger-gdbserver) +- [Documentation](#documentation) +- [Troubleshooting](#troubleshooting) +- [Development](#development) ### Features * Setting breakpoints @@ -26,23 +38,15 @@ An extension to debug or execute GnuCOBOL code. Install from [VS Code Marketplac * Watch pane with expressions * Code coverage * No mainframe required -* GnuCOBOL Docker ![Screenshot](screenshot.png) ### Requirements -A COBOL-syntax extension i.e. `bitlang.gnucobol` (recommended, note: the previously recommended `bitlang.cobol` was split and now is intended to target MicroFocus products only), or - if you target a mainframe dialect: `broadcommfd.cobol-language-support`, `rechinformatica.rech-editor-cobol` or `ibm.zopeneditor` installed. -Otherwise, the breakpoints will be unavailable. +This extension is meant to work with our COBOL language extension [Superbol VSCode](https://github.com/OCamlPro/superbol-vscode-platform). -Now you may choose between *local* and *container* execution environment. Or try both of them :) - -#### Local -* GnuCOBOL `cobc` 2.2+ installed. -* GNU Debugger `gdb` 6.0+ installed. - -#### Container -* [GnuCOBOL Docker](https://hub.docker.com/r/olegkunitsyn/gnucobol) container up and running. -The image includes GnuCOBOL, GNU Debugger and all required dependencies needed to debug or execute your code. See an example below. +#### Binaries +* GnuCOBOL `cobc` 3.1+ installed. +* GNU Debugger `gdb` 13.0+ installed. ### Usage When your `launch.json` config is set up, you can debug or execute your COBOL program. If you debug a Compilation Group (main- and sub- programs), you need to list sub-programs inside `group` property. Here's an example: @@ -66,7 +70,7 @@ Pick `COBOL debugger` from the dropdown on the Debug pane in VS Code. Press the The debugger uses C sourcecode generated by the compiler upon each debugging session. If the sourcemap isn't accurate or you see any other issues, please make a bug-report. ### Code coverage -You can estimate an execution flow of your COBOL program. +You can estimate an execution flow of your COBOL program. ![Coverage](coverage.png) @@ -88,36 +92,6 @@ Set `coverage` property to `true` in your `launch.json` and start debugging sess The extension decodes the code-coverage files in `gcov` format generated by the compiler. -### Docker -You may debug or execute your COBOL program inside [GnuCOBOL Docker](https://hub.docker.com/r/olegkunitsyn/gnucobol) container. Start the container and share your working directory by `Ctrl+Shift+P` and command `GnuCOBOL Docker: start`, or in the terminal: -```bash -docker run -d -i --name gnucobol -w ${workspaceRoot} -v ${workspaceRoot}:${workspaceRoot} olegkunitsyn/gnucobol:3.1-dev -docker exec -i gnucobol cobc -V -docker exec -i gnucobol gdb -v -``` - -Add `docker` property to your `launch.json` and start debugging session. -Here's an example: -```json -{ - "version": "0.2.0", - "configurations": [ - { - "name": "COBOL debugger", - "type": "gdb", - "request": "launch", - "cobcargs": ["-free", "-x"], - "docker": "olegkunitsyn/gnucobol:3.1-dev" - } - ] -} -``` - -Stop the container by `Ctrl+Shift+P` and command `GnuCOBOL Docker: stop`, or in the terminal: -```bash -docker rm --force gnucobol -``` - ### Attaching to a running process You may debug your COBOL program attaching to a running process. In order to achieve that, you have two options: @@ -147,7 +121,8 @@ Here's an example: ``` #### Remote Debugger (GDBServer) -Add `remoteDebugger` property to your `launch.json`. +Add `remoteDebugger` property to your `launch.json`. + Here's an example: ```json { @@ -164,12 +139,12 @@ Here's an example: } ``` -### Roadmap -- Mac -- Unit testing - Your contribution is always welcome! +### Documentation + +For a more in depth documentation please check the [Superbol Documentation](https://ocamlpro.com/superbol/) + ### Troubleshooting Add `verbose` property to your `launch.json` and start debugging session. In `DEBUG CONSOLE` you will see complete communication log between `gdb` and VS Code. Here's an example: ```json @@ -190,7 +165,7 @@ Add `verbose` property to your `launch.json` and start debugging session. In `DE ### Development * Fork the repository. * Clone it to your machine and open with VS Code. -* Install dependencies by `npm install` command in the terminal. +* Install dependencies by `yarn install` command in the terminal. * Pick `Extension` from the dropdown on the Debug pane and press `F5`. This will open new VS Code instance with your cloned extension in debugging mode. * Follow Requirements and Usage sections above. * In the first VS Code instance you may put breakpoints to explore the functionality. diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index de66f5d..0000000 --- a/package-lock.json +++ /dev/null @@ -1,1029 +0,0 @@ -{ - "name": "gnucobol-debug", - "version": "2.31.37", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", - "dev": true - }, - "@babel/highlight": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "@types/node": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.0.tgz", - "integrity": "sha512-WE4IOAC6r/yBZss1oQGM5zs2D7RuKR6Q+w+X2SouPofnWn+LbCqClRyhO3ZE7Ix8nmFgo/oVuuE01cJT2XB13A==", - "dev": true - }, - "@types/vscode": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.45.0.tgz", - "integrity": "sha512-b0Gyir7sPBCqiKLygAhn/AYVfzWD+SMPkWltBrIuPEyTOxSU1wVApWY/FcxYO2EWTRacoubTl4+gvZf86RkecA==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gcov-parse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gcov-parse/-/gcov-parse-1.0.1.tgz", - "integrity": "sha512-W6D3ea3aso6ri4KkR4kGHLUm0KzDwKq5FzQlja4k7quaA8CDv5FhizJdH/2GVJ8MuMuBZHETIgkcV8mu015gtg==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", - "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.4", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - } - } - }, - "n-readlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/n-readlines/-/n-readlines-1.0.0.tgz", - "integrity": "sha512-ISDqGcspVu6U3VKqtJZG1uR55SmNNF9uK0EMq1IvNVVZOui6MW6VR0+pIZhqz85ORAGp+4zW+5fJ/SE7bwEibA==" - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.1.tgz", - "integrity": "sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true - }, - "tslint": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", - "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "typescript": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", - "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", - "dev": true - }, - "vscode-debugadapter": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.40.0.tgz", - "integrity": "sha512-cudm9ROtFRxiBgcM+B8cQXA1DfsRKaOfEYDMh9upxbYxN3v0c40SHCPmNivIYp7LDzcG60UGaIYD1vsUfC1Qcg==", - "requires": { - "mkdirp": "^0.5.1", - "vscode-debugprotocol": "1.40.0" - } - }, - "vscode-debugadapter-testsupport": { - "version": "1.40.3", - "resolved": "https://registry.npmjs.org/vscode-debugadapter-testsupport/-/vscode-debugadapter-testsupport-1.40.3.tgz", - "integrity": "sha512-geWmnxFX2Z7wxlgRHUaULtPj3u6d29reGzzKLFXYPd59I9xgudcFdS1dSczjO6Pwkb2jkfFcXAyNGRSzu+kBSg==", - "dev": true, - "requires": { - "vscode-debugprotocol": "1.40.0" - } - }, - "vscode-debugprotocol": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.40.0.tgz", - "integrity": "sha512-Fwze+9qbLDPuQUhtITJSu/Vk6zIuakNM1iR2ZiZRgRaMEgBpMs2JSKaT0chrhJHCOy6/UbpsUbUBIseF6msV+g==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - } - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } -} diff --git a/package.json b/package.json index e597762..760fa55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "gnucobol-debug", - "displayName": "COBOL debugger", + "name": "superbol-vscode-debug", + "displayName": "Superbol debugger", "description": "Debug or execute COBOL code. No mainframe required.", "keywords": [ "cobol", @@ -10,7 +10,17 @@ "code coverage" ], "version": "2.31.37", - "publisher": "OlegKunitsyn", + "publisher": "OCamlPro SAS", + "contributors": [ + { + "name": "Emilien Lemaire", + "email": "emilien.lemaire@ocamlpro.com" + }, + { + "name": "Olegs Kunicins", + "email": "olegs.kunicins@gmail.com" + } + ], "license": "GPL-3.0", "icon": "icon.png", "engines": { @@ -18,16 +28,14 @@ }, "main": "./out/src/extension", "activationEvents": [ - "onDebugResolve", - "onCommand:gnucobol-debug.dockerStart", - "onCommand:gnucobol-debug.dockerStop" + "onDebugResolve" ], "categories": [ "Debuggers" ], "repository": { "type": "git", - "url": "https://github.com/OlegKunitsyn/gnucobol-debug.git" + "url": "https://github.com/OCamlPro/superbol-vscode-debug.git" }, "capabilities": { "untrustedWorkspaces": { @@ -35,39 +43,15 @@ } }, "contributes": { - "commands": [ - { - "command": "gnucobol-debug.dockerStart", - "title": "GnuCOBOL Docker: start" - }, - { - "command": "gnucobol-debug.dockerStop", - "title": "GnuCOBOL Docker: stop" - } - ], "breakpoints": [ { "language": "cobol" - }, - { - "language": "COBOL" - }, - { - "language": "ACUCOBOL" - }, - { - "language": "OpenCOBOL" - }, - { - "language": "GnuCOBOL" - }, - { - "language": "entcobol" } ], "debuggers": [ { "type": "gdb", + "languages": ["cobol", "COBOL"], "program": "./out/src/gdb.js", "runtime": "node", "label": "COBOL debugger", @@ -95,11 +79,6 @@ "description": "Path to gdb", "default": "gdb" }, - "docker": { - "type": "string", - "description": "Docker image", - "default": "olegkunitsyn/gnucobol:3.1-dev" - }, "cobcpath": { "type": "string", "description": "Path to cobc", @@ -201,7 +180,7 @@ }, "initialConfigurations": [ { - "name": "COBOL debugger", + "name": "Superbol debugger", "type": "gdb", "request": "launch", "cobcargs": [ @@ -209,59 +188,69 @@ "-x" ], "coverage": true + } + ], + "configurationSnippets": [ + { + "label": "Superbol: debug launch", + "description": "New Superbol launch request", + "body": { + "type": "gdb", + "request": "launch", + "name": "${2: Superbol debugger}" + } }, { - "name": "COBOL debugger attach local", - "type": "gdb", - "request": "attach", - "cobcargs": [ - "-free", - "-x" - ], - "pid": "${input:pid}" + "label": "Superbol: debug attach local", + "description": "New Superbol attach local request", + "body": { + "type": "gdb", + "request": "attach", + "name": "${2: Superbol debugger}", + "pid": "${3:0}" + } }, { - "name": "COBOL debugger attach remote", - "type": "gdb", - "request": "attach", - "cobcargs": [ - "-free", - "-x" - ], - "remoteDebugger": "${input:remoteDebugger}" + "label": "Superbol: debug attach remote", + "description": "New Superbol attach remote request", + "body": { + "type": "gdb", + "request": "attach", + "name": "${2: Superbol debugger}", + "remoteDebugger": "${3:host:port}" + } } ] } ], "configuration": { - "type": "object", - "title": "COBOL Debugger", + "title": "Superbol Debugger", "properties": { - "Cobol_Debugger.display_variable_attributes": { + "superbol_debugger.display_variable_attributes": { "type": "boolean", "default": false, "description": "Displaying Data Storages and Fields attributes(e.g. size of Alphanumerics or digits and scale of numerics).", "scope": "resource" }, - "Cobol_Debugger.cwd": { + "superbol_debugger.cwd": { "type": "string", "default": "${workspaceRoot}", "description": "Path to project", "scope": "application" }, - "Cobol_Debugger.target": { + "superbol_debugger.target": { "type": "string", "description": "Path to source code", "default": "${file}", "scope": "application" }, - "Cobol_Debugger.gdbpath": { + "superbol_debugger.gdbpath": { "type": "string", "description": "Path to gdb", "default": "gdb", "scope": "application" }, - "Cobol_Debugger.cobcpath": { + "superbol_debugger.cobcpath": { "type": "string", "description": "Path to cobc", "default": "cobc", @@ -277,18 +266,20 @@ "test": "mocha -u tdd ./out/test/" }, "devDependencies": { - "@types/node": "^13.13.0", - "@types/mocha": "^5.2.7", + "@types/mocha": "^10.0.1", + "@types/node": "^20.3.2", "@types/vscode": "^1.44.0", - "typescript": "^3.8.3", - "mocha": "^6.2.0", - "vscode-debugadapter-testsupport": "^1.40.3", - "tslint": "^5.18.0" + "@typescript-eslint/eslint-plugin": "^5.60.1", + "@typescript-eslint/parser": "^5.60.1", + "eslint": "^8.43.0", + "eslint_d": "^12.2.1", + "mocha": "^10.2.0", + "typescript": "^5.1.6", + "vscode-debugadapter-testsupport": "^1.40.3" }, "dependencies": { - "gcov-parse": "^1.0.1", - "n-readlines": "^1.0.0", - "vscode-debugadapter": "^1.40.0", - "vscode-debugprotocol": "^1.40.0" + "@vscode/debugadapter": "^1.40.0", + "@vscode/debugprotocol": "^1.40.0", + "n-readlines": "^1.0.0" } } diff --git a/src/coverage.ts b/src/coverage.ts index 62330d2..90469a1 100644 --- a/src/coverage.ts +++ b/src/coverage.ts @@ -14,11 +14,11 @@ import { import * as os from "os"; import * as nativePath from "path"; import * as ChildProcess from "child_process"; -import {SourceMap} from "./parser.c"; -import * as gcov from "gcov-parse"; +import { SourceMap } from "./parser.c"; +import { GcovData, loadGcovData } from "./gcov"; export class CoverageStatus implements Disposable { - private coverages: gcov.Coverage[] = []; + private coverages: GcovData[] = []; private sourceMap: SourceMap; private statusBar: StatusBarItem = window.createStatusBarItem(StatusBarAlignment.Right, 100); readonly RED: TextEditorDecorationType = window.createTextEditorDecorationType({ @@ -55,19 +55,10 @@ export class CoverageStatus implements Disposable { this.statusBar.command = this.COMMAND; } - public show(gcovFiles: string[], sourceMap: SourceMap, docker: string = undefined) { - if (docker !== undefined) { - for (let i = 0; i < gcovFiles.length; i++) { - const localPath = nativePath.resolve(os.tmpdir(), nativePath.basename(gcovFiles[i])); - ChildProcess.spawnSync('docker', ['cp', `gnucobol:${gcovFiles[i]}.gcda`, `${localPath}.gcda`]); - ChildProcess.spawnSync('docker', ['cp', `gnucobol:${gcovFiles[i]}.gcno`, `${localPath}.gcno`]); - gcovFiles[i] = localPath; - } - } - - this.coverages = gcov.parse(gcovFiles); - this.sourceMap = sourceMap; - this.updateStatus(); + public async show(cFiles: string[], sourceMap: SourceMap) { + this.coverages = await loadGcovData(cFiles); + this.sourceMap = sourceMap; + this.updateStatus(); } public dispose() { @@ -83,20 +74,22 @@ export class CoverageStatus implements Disposable { const red: Range[] = []; const green: Range[] = []; for (const coverage of this.coverages) { - for (const line of coverage.lines) { - if (this.sourceMap.hasLineCobol(coverage.file, line.line)) { - const map = this.sourceMap.getLineCobol(coverage.file, line.line); + for (const file of coverage.files) { + for (const line of file.lines) { + if (this.sourceMap.hasLineCobol(file.file, line.line_number)) { + const map = this.sourceMap.getLineCobol(file.file, line.line_number); if (editor.document.uri.fsPath !== map.fileCobol) { continue; } const range = new Range(map.lineCobol - 1, 0, map.lineCobol - 1, Number.MAX_VALUE); - if (line.executed) { + if (line.count > 0) { green.push(range); } else { red.push(range); } } } + } } if (red.length === 0 || !this.highlight) { editor.setDecorations(this.RED, []); diff --git a/src/extension.ts b/src/extension.ts index 947b83a..1042d2a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,71 +3,24 @@ import {GDBDebugSession} from "./gdb"; import {CoverageStatus} from './coverage'; import {DebuggerSettings} from "./settings"; -const dockerTerminal = vscode.window.createTerminal("GnuCOBOL Docker"); -const dockerMessage = "Property 'docker' is not defined in launch.json"; export function activate(context: vscode.ExtensionContext) { - const dockerStart = vscode.commands.registerCommand('gnucobol-debug.dockerStart', function () { - let config: vscode.DebugConfiguration; - let workspaceRoot: string = vscode.workspace.workspaceFolders[0].uri.fsPath; - for (config of vscode.workspace.getConfiguration('launch', vscode.workspace.workspaceFolders[0].uri).get('configurations') as []) { - if (config.type !== 'gdb') { - continue; - } - if (config.docker === undefined) { - vscode.window.showInformationMessage(dockerMessage); - break; - } - if (process.platform === "win32") { - workspaceRoot = workspaceRoot - .replace(/.*:/, s => "/" + s.toLowerCase().replace(":", "")) - .replace(/\\/g, "/"); - } - vscode.workspace.workspaceFolders[0].uri.fsPath - .replace(/.*:/, s => "/" + s.toLowerCase().replace(":", "")).replace(/\\/g, "/"); - dockerTerminal.show(true); - dockerTerminal.sendText(`docker run -d -i --name gnucobol -w ${workspaceRoot} -v ${workspaceRoot}:${workspaceRoot} ${config.docker}`); - break; - } - }); - - const dockerStop = vscode.commands.registerCommand('gnucobol-debug.dockerStop', function () { - let config: vscode.DebugConfiguration; - for (config of vscode.workspace.getConfiguration('launch', vscode.workspace.workspaceFolders[0].uri).get('configurations') as []) { - if (config.type !== 'gdb') { - continue; - } - if (config.docker === undefined) { - vscode.window.showInformationMessage(dockerMessage); - break; - } - dockerTerminal.show(true); - dockerTerminal.sendText(`docker rm --force gnucobol`); - break; - } - }); - context.subscriptions.push( - dockerStart, - dockerStop, vscode.debug.registerDebugConfigurationProvider('gdb', new GdbConfigurationProvider()), - vscode.debug.registerDebugAdapterDescriptorFactory('gdb', new GdbAdapterDescriptorFactory(new CoverageStatus(), new GDBDebugSession())), - ); -} - -export function deactivate() { - dockerTerminal.dispose(); + vscode.debug. + registerDebugAdapterDescriptorFactory( + 'gdb', + new GdbAdapterDescriptorFactory(new CoverageStatus(), new GDBDebugSession()))); } class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { - resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): vscode.ProviderResult { + resolveDebugConfiguration( + _folder: vscode.WorkspaceFolder | undefined, + config: vscode.DebugConfiguration, + _token?: vscode.CancellationToken): + vscode.ProviderResult + { config.gdbargs = ["-q", "--interpreter=mi2"]; - if (config.docker !== undefined) { - config.cobcpath = 'docker'; - config.gdbpath = 'docker'; - config.cobcargs = ['exec', '-i', 'gnucobol', 'cobc'].concat(config.cobcargs); - config.gdbargs = ['exec', '-i', 'gnucobol', 'gdb'].concat(config.gdbargs); - } const settings = new DebuggerSettings(); if (config.cwd === undefined) { config.cwd = settings.cwd; @@ -89,13 +42,57 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { } return config; } + + provideDebugConfigurations( + _folder: vscode.WorkspaceFolder, + _token?: vscode.CancellationToken): + vscode.ProviderResult { + const launchConfigDefault: vscode.DebugConfiguration = { + name: "Superbol debugger", + type: "gdb", + request: "launch", + cobcargs: [ + "-free", + "-x" + ], + coverage: true + }; + + const attachLocalConfiguration: vscode.DebugConfiguration = { + name: "Superbol debugger attach local", + type: "gdb", + request: "attach", + cobcargs: [ + "-free", + "-x" + ], + pid: "${input:pid}" + }; + + const attachRemoteConfiguration: vscode.DebugConfiguration = { + name: "Superbol debugger attach remote", + type: "gdb", + request: "attach", + cobcargs: [ + "-free", + "-x" + ], + remoteDebugger: "${input:remoteDebugger}" + } + + return [ + launchConfigDefault, + attachLocalConfiguration, + attachRemoteConfiguration + ]; + } } class GdbAdapterDescriptorFactory implements vscode.DebugAdapterDescriptorFactory { constructor(public coverageBar: CoverageStatus, public debugSession: GDBDebugSession) { } - createDebugAdapterDescriptor(session: vscode.DebugSession): vscode.ProviderResult { + createDebugAdapterDescriptor(_session: vscode.DebugSession): vscode.ProviderResult { this.debugSession.coverageStatus = this.coverageBar; return new vscode.DebugAdapterInlineImplementation(this.debugSession); } diff --git a/src/gcov.ts b/src/gcov.ts new file mode 100644 index 0000000..8a374b3 --- /dev/null +++ b/src/gcov.ts @@ -0,0 +1,98 @@ +import * as vscode from "vscode"; +import * as child_process from "child_process"; + +export interface GcovLineData { + count: number; + function_name: string; + line_number: number; + unexecuted_block: boolean; +} + +export interface GcovFunctionData { + blocks: number; + blocks_executed: number; + demangled_name: string; + start_column: number; + start_line: number; + end_column: number; + end_line: number; + execution_count: number; + name: string; +} + +export interface GcovFileData { + file: string; + lines: GcovLineData[]; + functions: GcovFunctionData[]; +} + +export interface GcovData { + files: GcovFileData[]; + current_working_directory: string; + data_file: string; +} + +function getGcovBinary() { + return "gcov"; +} + +export async function isGcovCompatible() { + const gcovBinary = getGcovBinary(); + const command = `${gcovBinary} --help`; + return new Promise((resolve, _reject) => { + child_process.exec(command, (err, stdout, _stderr) => { + if (err) { + void vscode.window.showErrorMessage( + `Error while trying to run gcov, try to change the "Gcov Binary" setting. ${err.message}` + ); + resolve(false); + return; + } + const gcovOutput = stdout.toString(); + const supportsRequiredArgs = + gcovOutput.includes("--json-format") && gcovOutput.includes("--stdout"); + if (!supportsRequiredArgs) { + void vscode.window.showErrorMessage( + `The gcov version is not compatible. Please use at least version 9.` + ); + } + resolve(supportsRequiredArgs); + }); + }); +} + +export async function loadGcovData(paths: string[]): Promise { + if (paths.length === 0) { + return []; + } + + const gcovBinary = getGcovBinary(); + + let command = `${gcovBinary} --stdout --json-format`; + for (const path of paths) { + command += ` "${path}"`; + } + return new Promise((resolve, reject) => { + child_process.exec( + command, + { maxBuffer: 256 * 1024 * 1024 }, + (err, stdout, _stderr) => { + if (err) { + console.error(`exec error: ${err.message}`); + reject(); + return; + } + const gcovOutput = stdout.toString(); + const output = []; + const parts = gcovOutput.split("\n"); + for (const part of parts) { + if (part.length === 0) { + continue; + } + output.push(JSON.parse(part)); + } + resolve(output); + } + ); + }); +} diff --git a/src/gdb.ts b/src/gdb.ts index eb8ca1d..27525ca 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -1,597 +1,726 @@ -import * as DebugAdapter from 'vscode-debugadapter'; +import * as DebugAdapter from '@vscode/debugadapter'; import { - DebugSession, - Handles, - InitializedEvent, - OutputEvent, - Scope, - Source, - StackFrame, - StoppedEvent, - TerminatedEvent, - Thread, - ThreadEvent -} from 'vscode-debugadapter'; -import {DebugProtocol} from 'vscode-debugprotocol'; -import {VariableObject} from './debugger'; -import {MINode} from './parser.mi2'; -import {MI2} from './mi2'; -import {CoverageStatus} from './coverage'; -import {DebuggerSettings} from './settings'; + DebugSession, + Handles, + InitializedEvent, + OutputEvent, + Scope, + Source, + StackFrame, + StoppedEvent, + TerminatedEvent, + Thread, + ThreadEvent +} from '@vscode/debugadapter'; +import { DebugProtocol } from 'vscode-debugprotocol'; +import { Breakpoint, VariableObject } from './debugger'; +import { MINode } from './parser.mi2'; +import { MI2 } from './mi2'; +import { CoverageStatus } from './coverage'; +import { DebuggerSettings } from './settings'; const STACK_HANDLES_START = 1000; const VAR_HANDLES_START = 512 * 256 + 1000; class ExtendedVariable { - constructor(public name, public options) { - } + constructor(public _name: string, public _options: unknown) { + } } export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments { - cwd: string; - target: string; - arguments: string; - gdbpath: string; - gdbargs: string[]; - cobcpath: string; - cobcargs: string[]; - env: any; - group: string[]; - verbose: boolean; - coverage: boolean; - docker: string; + cwd: string; + target: string; + arguments: string; + gdbpath: string; + gdbargs: string[]; + cobcpath: string; + cobcargs: string[]; + env: NodeJS.ProcessEnv; + group: string[]; + verbose: boolean; + coverage: boolean; } export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { - cwd: string; - target: string; - arguments: string; - gdbpath: string; - gdbargs: string[]; - cobcpath: string; - cobcargs: string[]; - env: any; - group: string[]; - verbose: boolean; - pid: string; - remoteDebugger: string; + cwd: string; + target: string; + arguments: string; + gdbpath: string; + gdbargs: string[]; + cobcpath: string; + cobcargs: string[]; + env: NodeJS.ProcessEnv; + group: string[]; + verbose: boolean; + pid: string; + remoteDebugger: string; } export class GDBDebugSession extends DebugSession { - protected variableHandles = new Handles(VAR_HANDLES_START); - protected variableHandlesReverse: { [id: string]: number } = {}; - protected useVarObjects: boolean; - protected quit: boolean; - protected needContinue: boolean; - protected started: boolean; - protected attached: boolean; - protected crashed: boolean; - protected debugReady: boolean; - protected miDebugger: MI2; - coverageStatus: CoverageStatus; - private docker: string; - private showVariableDetails: boolean; - private settings = new DebuggerSettings(); - - protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void { - response.body.supportsSetVariable = true; + protected variableHandles = + new Handles(VAR_HANDLES_START); + protected variableHandlesReverse: { [id: string]: number } = {}; + protected useVarObjects: boolean; + protected quit: boolean; + protected needContinue: boolean; + protected started: boolean; + protected attached: boolean; + protected crashed: boolean; + protected debugReady: boolean; + protected miDebugger: MI2; + coverageStatus: CoverageStatus; + private showVariableDetails: boolean; + private settings = new DebuggerSettings(); + + protected initializeRequest( + response: DebugProtocol.InitializeResponse, + _args: DebugProtocol.InitializeRequestArguments): + void + { + response.body.supportsSetVariable = true; + this.sendResponse(response); + } + + protected launchRequest( + response: DebugProtocol.LaunchResponse, + args: LaunchRequestArguments): + void + { + if (!args.coverage) { + this.coverageStatus = undefined; + } + this.started = false; + this.attached = false; + + this.miDebugger = + new MI2( + args.gdbpath, + args.gdbargs, + args.cobcpath, + args.cobcargs, + args.env, + args.verbose, + args.noDebug); + this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); + this.miDebugger.on("quit", () => this.quitEvent()); + this.miDebugger.on("exited-normally", () => this.quitEvent()); + this.miDebugger.on("stopped", (info: MINode) => this.stopEvent(info)); + this.miDebugger.on("msg", (type: string, message: string) => this.handleMsg(type, message)); + this.miDebugger.on("breakpoint", (info: MINode) => this.handleBreakpoint(info)); + this.miDebugger.on("step-end", (info?: MINode) => this.handleBreak(info)); + this.miDebugger.on("step-out-end", (info?: MINode) => this.handleBreak(info)); + this.miDebugger.on("step-other", (info?: MINode) => this.handleBreak(info)); + this.miDebugger.on("signal-stop", (info: MINode) => this.handlePause(info)); + this.miDebugger.on("thread-created", (info: MINode) => this.threadCreatedEvent(info)); + this.miDebugger.on("thread-exited", (info: MINode) => this.threadExitedEvent(info)); + this.sendEvent(new InitializedEvent()); + this.quit = false; + this.needContinue = false; + this.crashed = false; + this.debugReady = false; + this.useVarObjects = false; + this.miDebugger.load(args.cwd, args.target, args.arguments, args.group).then( + /*onfulfilled:*/ () => { + setTimeout(() => { + this.miDebugger.emit("ui-break-done"); + }, 50); this.sendResponse(response); - } - - protected launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments): void { - if (!args.coverage) { - this.coverageStatus = undefined; - } - this.docker = args.docker; - this.started = false; - this.attached = false; - - this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.cobcpath, args.cobcargs, args.env, args.verbose, args.noDebug); - this.miDebugger.on("launcherror", this.launchError.bind(this)); - this.miDebugger.on("quit", this.quitEvent.bind(this)); - this.miDebugger.on("exited-normally", this.quitEvent.bind(this)); - this.miDebugger.on("stopped", this.stopEvent.bind(this)); - this.miDebugger.on("msg", this.handleMsg.bind(this)); - this.miDebugger.on("breakpoint", this.handleBreakpoint.bind(this)); - this.miDebugger.on("step-end", this.handleBreak.bind(this)); - this.miDebugger.on("step-out-end", this.handleBreak.bind(this)); - this.miDebugger.on("step-other", this.handleBreak.bind(this)); - this.miDebugger.on("signal-stop", this.handlePause.bind(this)); - this.miDebugger.on("thread-created", this.threadCreatedEvent.bind(this)); - this.miDebugger.on("thread-exited", this.threadExitedEvent.bind(this)); - this.sendEvent(new InitializedEvent()); - this.quit = false; - this.needContinue = false; - this.crashed = false; - this.debugReady = false; - this.useVarObjects = false; - this.miDebugger.load(args.cwd, args.target, args.arguments, args.group).then(() => { - setTimeout(() => { - this.miDebugger.emit("ui-break-done"); - }, 50); - this.sendResponse(response); - this.miDebugger.start().then(() => { - this.started = true; - if (this.crashed) - this.handlePause(undefined); - }, err => { - this.sendErrorResponse(response, 100, `Failed to start MI Debugger: ${err.toString()}`); - }); - }, err => { - this.sendErrorResponse(response, 103, `Failed to load MI Debugger: ${err.toString()}`); + this.miDebugger.start().then(() => { + this.started = true; + if (this.crashed) + this.handlePause(undefined); + }, + (err: Error) => { + this.sendErrorResponse(response, 100, `Failed to start MI Debugger: ${err.toString()}`); }); - } - - protected attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments): void { - if (!args.pid && !args.remoteDebugger) { - this.sendErrorResponse(response, 100, `Failed to start MI Debugger: pid or remoteDebugger is mandatory`); - return; - } - - this.coverageStatus = undefined; - this.attached = true; - this.started = false; - - this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.cobcpath, args.cobcargs, args.env, args.verbose, false); - this.miDebugger.on("launcherror", this.launchError.bind(this)); - this.miDebugger.on("quit", this.quitEvent.bind(this)); - this.miDebugger.on("exited-normally", this.quitEvent.bind(this)); - this.miDebugger.on("stopped", this.stopEvent.bind(this)); - this.miDebugger.on("msg", this.handleMsg.bind(this)); - this.miDebugger.on("breakpoint", this.handleBreakpoint.bind(this)); - this.miDebugger.on("step-end", this.handleBreak.bind(this)); - this.miDebugger.on("step-out-end", this.handleBreak.bind(this)); - this.miDebugger.on("step-other", this.handleBreak.bind(this)); - this.miDebugger.on("signal-stop", this.handlePause.bind(this)); - this.miDebugger.on("thread-created", this.threadCreatedEvent.bind(this)); - this.miDebugger.on("thread-exited", this.threadExitedEvent.bind(this)); - this.sendEvent(new InitializedEvent()); - this.quit = false; - this.needContinue = true; - this.crashed = false; - this.debugReady = false; - this.useVarObjects = false; - this.miDebugger.attach(args.cwd, args.target, args.arguments, args.group).then(() => { - setTimeout(() => { - this.miDebugger.emit("ui-break-done"); - }, 50); - this.sendResponse(response); - this.miDebugger.start(args.pid || args.remoteDebugger).then(() => { - this.attached = true; - if (this.crashed) - this.handlePause(undefined); - }, err => { - this.sendErrorResponse(response, 100, `Failed to start MI Debugger: ${err.toString()}`); - }); - }, err => { - this.sendErrorResponse(response, 103, `Failed to load MI Debugger: ${err.toString()}`); + }, + /*onrejected:*/ (err: Error) => { + this.sendErrorResponse(response, 103, `Failed to load MI Debugger: ${err.toString()}`); + }); + } + + protected attachRequest( + response: DebugProtocol.AttachResponse, + args: AttachRequestArguments): + void + { + if (!args.pid && !args.remoteDebugger) { + this.sendErrorResponse( + response, + 100, + `Failed to start MI Debugger: pid or remoteDebugger is mandatory`); + return; + } + + this.coverageStatus = undefined; + this.attached = true; + this.started = false; + + this.miDebugger = new MI2( + args.gdbpath, + args.gdbargs, + args.cobcpath, + args.cobcargs, + args.env, + args.verbose, + false); + this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); + this.miDebugger.on("quit", () => this.quitEvent()); + this.miDebugger.on("exited-normally", () => this.quitEvent()); + this.miDebugger.on("stopped", (info: MINode) => this.stopEvent(info)); + this.miDebugger.on("msg", (type: string, message: string) => this.handleMsg(type, message)); + this.miDebugger.on("breakpoint", (info: MINode) => this.handleBreakpoint(info)); + this.miDebugger.on("step-end", (info?: MINode) => this.handleBreak(info)); + this.miDebugger.on("step-out-end", (info?: MINode) => this.handleBreak(info)); + this.miDebugger.on("step-other", (info?: MINode) => this.handleBreak(info)); + this.miDebugger.on("signal-stop", (info: MINode) => this.handlePause(info)); + this.miDebugger.on("thread-created", (info: MINode) => this.threadCreatedEvent(info)); + this.miDebugger.on("thread-exited", (info: MINode) => this.threadExitedEvent(info)); + this.sendEvent(new InitializedEvent()); + this.quit = false; + this.needContinue = true; + this.crashed = false; + this.debugReady = false; + this.useVarObjects = false; + this.miDebugger.attach(args.cwd, args.target, args.arguments, args.group).then( + () => { + setTimeout(() => { + this.miDebugger.emit("ui-break-done"); + }, 50); + this.sendResponse(response); + this.miDebugger.start(args.pid || args.remoteDebugger).then(() => { + this.attached = true; + if (this.crashed) + this.handlePause(undefined); + }, + (err: Error) => { + this.sendErrorResponse(response, 100, `Failed to start MI Debugger: ${err.toString()}`); }); - } - - protected handleMsg(type: string, msg: string) { - if (type == "target") - type = "stdout"; - if (type == "log") - type = "stderr"; - this.sendEvent(new OutputEvent(msg, type)); - } - - protected handleBreakpoint(info: MINode) { - const event = new StoppedEvent("breakpoint", parseInt(info.record("thread-id"))); - (event as DebugProtocol.StoppedEvent).body.allThreadsStopped = info.record("stopped-threads") == "all"; - this.sendEvent(event); - } - - protected handleBreak(info?: MINode) { - const event = new StoppedEvent("step", info ? parseInt(info.record("thread-id")) : 1); - (event as DebugProtocol.StoppedEvent).body.allThreadsStopped = info ? info.record("stopped-threads") == "all" : true; - this.sendEvent(event); - } - - protected handlePause(info: MINode) { - const event = new StoppedEvent("user request", parseInt(info.record("thread-id"))); - (event as DebugProtocol.StoppedEvent).body.allThreadsStopped = info.record("stopped-threads") == "all"; - this.sendEvent(event); - } - - protected stopEvent(info: MINode) { - if (!this.started) - this.crashed = true; - if (!this.quit) { - const event = new StoppedEvent("exception", parseInt(info.record("thread-id"))); - (event as DebugProtocol.StoppedEvent).body.allThreadsStopped = info.record("stopped-threads") == "all"; - this.sendEvent(event); + }, + (err: Error) => { + this.sendErrorResponse(response, 103, `Failed to load MI Debugger: ${err.toString()}`); + }); + } + + protected handleMsg(type: string, msg: string) { + if (type == "target") + type = "stdout"; + if (type == "log") + type = "stderr"; + this.sendEvent(new OutputEvent(msg, type)); + } + + protected handleBreakpoint(info: MINode) { + const event = new StoppedEvent("breakpoint", parseInt(info.record("thread-id"))); + (event).body.allThreadsStopped = + info.record("stopped-threads") == "all"; + this.sendEvent(event); + } + + protected handleBreak(info?: MINode) { + const event = new StoppedEvent("step", info ? parseInt(info.record("thread-id")) : 1); + (event).body.allThreadsStopped = + info ? info.record("stopped-threads") == "all" : true; + this.sendEvent(event); + } + + protected handlePause(info: MINode) { + const event = new StoppedEvent("user request", parseInt(info.record("thread-id"))); + (event).body.allThreadsStopped = + info.record("stopped-threads") == "all"; + this.sendEvent(event); + } + + protected stopEvent(info: MINode) { + if (!this.started) + this.crashed = true; + if (!this.quit) { + const event = new StoppedEvent("exception", parseInt(info.record("thread-id"))); + (event).body.allThreadsStopped = + info.record("stopped-threads") == "all"; + this.sendEvent(event); + } + } + + protected threadCreatedEvent(info: MINode) { + this.sendEvent(new ThreadEvent("started", info.record("id"))); + } + + protected threadExitedEvent(info: MINode) { + this.sendEvent(new ThreadEvent("exited", info.record("id"))); + } + + protected quitEvent() { + if (this.quit) + return; + + if (this.coverageStatus !== undefined) { + this.coverageStatus.show( + this.miDebugger.getGcovFiles(), + this.miDebugger.getSourceMap()).catch( + (err: Error) => console.log(err)); + } + + this.quit = true; + this.sendEvent(new TerminatedEvent()); + } + + protected launchError(err: Error) { + this.handleMsg("stderr", "Could not start debugger process\n"); + this.handleMsg("stderr", err.toString() + "\n"); + this.quitEvent(); + } + + protected disconnectRequest( + response: DebugProtocol.DisconnectResponse, + _args: DebugProtocol.DisconnectArguments): + void + { + if (this.attached) + this.miDebugger.detach(); + else + this.miDebugger.stop(); + this.sendResponse(response); + } + + protected async setVariableRequest( + response: DebugProtocol.SetVariableResponse, + args: DebugProtocol.SetVariableArguments): + Promise + { + try { + let id: number | string | VariableObject | ExtendedVariable; + if (args.variablesReference < VAR_HANDLES_START) { + id = args.variablesReference - STACK_HANDLES_START; + } else { + id = this.variableHandles.get(args.variablesReference); + } + + let name = args.name; + if (typeof id == "string") { + name = `${id}.${args.name}`; + if (this.showVariableDetails && args.name === "value") { + name = id; } - } - - protected threadCreatedEvent(info: MINode) { - this.sendEvent(new ThreadEvent("started", info.record("id"))); - } - - protected threadExitedEvent(info: MINode) { - this.sendEvent(new ThreadEvent("exited", info.record("id"))); - } - - protected quitEvent() { - if (this.quit) - return; - - if (this.coverageStatus !== undefined) { - this.coverageStatus.show(this.miDebugger.getGcovFiles(), this.miDebugger.getSourceMap(), this.docker); + } + if (!this.showVariableDetails || args.name === "value") { + await this.miDebugger.changeVariable(name, args.value); + response.body = { + value: args.value + }; + } + this.sendResponse(response); + } catch (err) { + this.sendErrorResponse(response, 11, `Could not continue: ${err}`); + } + } + + protected setFunctionBreakPointsRequest( + response: DebugProtocol.SetFunctionBreakpointsResponse, + args: DebugProtocol.SetFunctionBreakpointsArguments): + void + { + const cb = () => { + this.debugReady = true; + const all: Thenable<[boolean, Breakpoint]>[] = []; + args.breakpoints.forEach(brk => { + all.push(this.miDebugger.addBreakPoint({ + raw: brk.name, + condition: brk.condition, + countCondition: brk.hitCondition + })); + }); + Promise.all(all).then(brkpoints => { + const finalBrks: DebugProtocol.Breakpoint[] = []; + brkpoints.forEach(brkp => { + if (brkp[0]) + finalBrks.push({ line: brkp[1].line, verified: brkp[0] }); + }); + response.body = { + breakpoints: finalBrks + }; + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 10, msg.toString()); + }); + }; + if (this.debugReady) + cb(); + else + this.miDebugger.once("debug-ready", cb); + } + + protected setBreakPointsRequest( + response: DebugProtocol.SetBreakpointsResponse, + args: DebugProtocol.SetBreakpointsArguments): + void + { + const cb = () => { + this.debugReady = true; + this.miDebugger.clearBreakPoints().then(() => { + const path = args.source.path; + const all = args.breakpoints.map(brk => { + return this.miDebugger.addBreakPoint({ + file: path, + line: brk.line, + condition: brk.condition, + countCondition: brk.hitCondition + }); + }); + Promise.all(all).then(brkpoints => { + const finalBrks: DebugAdapter.Breakpoint[] = []; + brkpoints.forEach(brkp => { + if (brkp[0]) + finalBrks.push(new DebugAdapter.Breakpoint(true, brkp[1].line)); + }); + response.body = { + breakpoints: finalBrks + }; + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 9, msg.toString()); + }); + }, + (msg: Error) => { + this.sendErrorResponse(response, 9, msg.toString()); + }); + }; + if (this.debugReady) + cb(); + else + this.miDebugger.once("debug-ready", cb); + } + + protected threadsRequest(response: DebugProtocol.ThreadsResponse): void { + if (!this.miDebugger) { + this.sendResponse(response); + return; + } + this.miDebugger.getThreads().then( + threads => { + response.body = { + threads: [] + }; + for (const thread of threads) { + let threadName = thread.name; + if (threadName === undefined) { + threadName = thread.targetId; + } + if (threadName === undefined) { + threadName = ""; + } + response.body.threads.push( + new Thread(thread.id, thread.id.toString() + ":" + threadName)); } - - this.quit = true; - this.sendEvent(new TerminatedEvent()); - } - - protected launchError(err: any) { - this.handleMsg("stderr", "Could not start debugger process\n"); - this.handleMsg("stderr", err.toString() + "\n"); - this.quitEvent(); - } - - protected disconnectRequest(response: DebugProtocol.DisconnectResponse, args: DebugProtocol.DisconnectArguments): void { - if (this.attached) - this.miDebugger.detach(); - else - this.miDebugger.stop(); this.sendResponse(response); - } - - protected async setVariableRequest(response: DebugProtocol.SetVariableResponse, args: DebugProtocol.SetVariableArguments): Promise { - try { - let id: number | string | VariableObject | ExtendedVariable; - if (args.variablesReference < VAR_HANDLES_START) { - id = args.variablesReference - STACK_HANDLES_START; - } else { - id = this.variableHandles.get(args.variablesReference); - } - - let name = args.name; - if (typeof id == "string") { - name = `${id}.${args.name}`; - if (this.showVariableDetails && args.name === "value") { - name = id; - } - } - if (!this.showVariableDetails || args.name === "value") { - await this.miDebugger.changeVariable(name, args.value); - response.body = { - value: args.value - }; - } - this.sendResponse(response); - } catch (err) { - this.sendErrorResponse(response, 11, `Could not continue: ${err}`); + }, + (err: Error) => { + this.sendErrorResponse(response, 13, `Could not get threads: ${err.toString()}`) + }); + } + + // Supports 256 threads. + protected threadAndLevelToFrameId(threadId: number, level: number) { + return level << 8 | threadId; + } + + protected frameIdToThreadAndLevel(frameId: number) { + return [frameId & 0xff, frameId >> 8]; + } + + protected stackTraceRequest( + response: DebugProtocol.StackTraceResponse, + args: DebugProtocol.StackTraceArguments): + void + { + this.miDebugger.getStack(args.levels, args.threadId).then( + stack => { + const ret: StackFrame[] = []; + stack.forEach(element => { + let source: Source = undefined; + const file = element.file; + if (file) { + source = new Source(element.fileName, file); } - } - - protected setFunctionBreakPointsRequest(response: DebugProtocol.SetFunctionBreakpointsResponse, args: DebugProtocol.SetFunctionBreakpointsArguments): void { - const cb = (() => { - this.debugReady = true; - const all = []; - args.breakpoints.forEach(brk => { - all.push(this.miDebugger.addBreakPoint({ - raw: brk.name, - condition: brk.condition, - countCondition: brk.hitCondition - })); - }); - Promise.all(all).then(brkpoints => { - const finalBrks = []; - brkpoints.forEach(brkp => { - if (brkp[0]) - finalBrks.push({line: brkp[1].line}); - }); - response.body = { - breakpoints: finalBrks - }; - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 10, msg.toString()); - }); - }).bind(this); - if (this.debugReady) - cb(); - else - this.miDebugger.once("debug-ready", cb); - } - protected setBreakPointsRequest(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments): void { - const cb = (() => { - this.debugReady = true; - this.miDebugger.clearBreakPoints().then(() => { - const path = args.source.path; - const all = args.breakpoints.map(brk => { - return this.miDebugger.addBreakPoint({ - file: path, - line: brk.line, - condition: brk.condition, - countCondition: brk.hitCondition - }); - }); - Promise.all(all).then(brkpoints => { - const finalBrks = []; - brkpoints.forEach(brkp => { - if (brkp[0]) - finalBrks.push(new DebugAdapter.Breakpoint(true, brkp[1].line)); - }); - response.body = { - breakpoints: finalBrks - }; - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 9, msg.toString()); - }); - }, msg => { - this.sendErrorResponse(response, 9, msg.toString()); - }); - }).bind(this); - if (this.debugReady) - cb(); - else - this.miDebugger.once("debug-ready", cb); - } - - protected threadsRequest(response: DebugProtocol.ThreadsResponse): void { - if (!this.miDebugger) { - this.sendResponse(response); - return; + ret.push(new StackFrame( + this.threadAndLevelToFrameId(args.threadId, element.level), + element.function + "@" + element.address, + source, + element.line, + 0)); + }); + response.body = { + stackFrames: ret + }; + this.sendResponse(response); + }, + (err: Error) => { + this.sendErrorResponse(response, 12, `Failed to get Stack Trace: ${err.toString()}`); + }); + } + + protected configurationDoneRequest( + response: DebugProtocol.ConfigurationDoneResponse, + _args: DebugProtocol.ConfigurationDoneArguments): + void + { + if (this.needContinue) { + this.miDebugger.continue().then(_done => { + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 2, `Could not continue: ${msg.toString()}`); + }); + } else + this.sendResponse(response); + } + + protected scopesRequest( + response: DebugProtocol.ScopesResponse, + args: DebugProtocol.ScopesArguments): + void + { + const scopes = new Array(); + scopes.push(new Scope("Local", STACK_HANDLES_START + (args.frameId || 0), false)); + + response.body = { + scopes: scopes + }; + this.sendResponse(response); + } + + protected async variablesRequest( + response: DebugProtocol.VariablesResponse, + args: DebugProtocol.VariablesArguments): + Promise + { + this.showVariableDetails = this.settings.displayVariableAttributes; + + let id: number | string | VariableObject | ExtendedVariable; + if (args.variablesReference < VAR_HANDLES_START) { + id = args.variablesReference - STACK_HANDLES_START; + } else { + id = this.variableHandles.get(args.variablesReference); + } + + if (typeof id == "number") { + try { + const variables: DebugProtocol.Variable[] = []; + const [threadId, level] = this.frameIdToThreadAndLevel(id); + const stackVariables = await this.miDebugger.getStackVariables(threadId, level); + for (const stackVariable of stackVariables) { + let reference = 0; + if (this.showVariableDetails || !!stackVariable.children.size) { + reference = this.variableHandles.create(stackVariable.cobolName); + } + + let value = stackVariable.value || "null"; + if (this.showVariableDetails) { + value = stackVariable.displayableType; + } + + variables.push({ + name: stackVariable.cobolName, + evaluateName: stackVariable.cobolName, + value: value, + type: stackVariable.displayableType, + variablesReference: reference + }); } - this.miDebugger.getThreads().then( - threads => { - response.body = { - threads: [] - }; - for (const thread of threads) { - let threadName = thread.name; - if (threadName === undefined) { - threadName = thread.targetId; - } - if (threadName === undefined) { - threadName = ""; - } - response.body.threads.push(new Thread(thread.id, thread.id + ":" + threadName)); - } - this.sendResponse(response); - }); - } - - // Supports 256 threads. - protected threadAndLevelToFrameId(threadId: number, level: number) { - return level << 8 | threadId; - } - - protected frameIdToThreadAndLevel(frameId: number) { - return [frameId & 0xff, frameId >> 8]; - } - - protected stackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments): void { - this.miDebugger.getStack(args.levels, args.threadId).then(stack => { - const ret: StackFrame[] = []; - stack.forEach(element => { - let source = undefined; - const file = element.file; - if (file) { - source = new Source(element.fileName, file); - } - - ret.push(new StackFrame( - this.threadAndLevelToFrameId(args.threadId, element.level), - element.function + "@" + element.address, - source, - element.line, - 0)); - }); - response.body = { - stackFrames: ret - }; - this.sendResponse(response); - }, err => { - this.sendErrorResponse(response, 12, `Failed to get Stack Trace: ${err.toString()}`); - }); - } - - protected configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse, args: DebugProtocol.ConfigurationDoneArguments): void { - if (this.needContinue) { - this.miDebugger.continue().then(done => { - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 2, `Could not continue: ${msg}`); - }); - } else - this.sendResponse(response); - } - - protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void { - const scopes = new Array(); - scopes.push(new Scope("Local", STACK_HANDLES_START + (parseInt(args.frameId as any) || 0), false)); response.body = { - scopes: scopes + variables: variables }; this.sendResponse(response); - } - - protected async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise { - this.showVariableDetails = this.settings.displayVariableAttributes; - - let id: number | string | VariableObject | ExtendedVariable; - if (args.variablesReference < VAR_HANDLES_START) { - id = args.variablesReference - STACK_HANDLES_START; - } else { - id = this.variableHandles.get(args.variablesReference); - } - - if (typeof id == "number") { - try { - const variables: DebugProtocol.Variable[] = []; - const [threadId, level] = this.frameIdToThreadAndLevel(id); - const stackVariables = await this.miDebugger.getStackVariables(threadId, level); - for (const stackVariable of stackVariables) { - let reference = 0; - if (this.showVariableDetails || !!stackVariable.children.size) { - reference = this.variableHandles.create(stackVariable.cobolName); - } - - let value = stackVariable.value || "null"; - if (this.showVariableDetails) { - value = stackVariable.displayableType; - } - - variables.push({ - name: stackVariable.cobolName, - evaluateName: stackVariable.cobolName, - value: value, - type: stackVariable.displayableType, - variablesReference: reference - }); - } - - response.body = { - variables: variables - }; - this.sendResponse(response); - } catch (err) { - this.sendErrorResponse(response, 1, `Could not expand variable: ${err}`); - } - } else if (typeof id == "string") { - try { - // TODO: this evals on an (effectively) unknown thread for multithreaded programs. - const stackVariable = await this.miDebugger.evalCobField(id, 0, 0); - - let variables: DebugProtocol.Variable[] = []; - - if (this.showVariableDetails) { - variables = stackVariable.toDebugProtocolVariable(this.showVariableDetails); - } - - for (const child of stackVariable.children.values()) { - const childId = `${id}.${child.cobolName}`; - let reference = 0; - if (this.showVariableDetails || !!child.children.size) { - reference = this.variableHandles.create(childId); - } - - let value = child.displayableType; - if (!this.showVariableDetails) { - const evaluatedChild = await this.miDebugger.evalCobField(childId, 0, 0); - value = evaluatedChild.value || "null"; - } - - variables.push({ - name: child.cobolName, - evaluateName: child.cobolName, - value: value, - type: child.displayableType, - variablesReference: reference - }); - } - response.body = { - variables: variables - }; - this.sendResponse(response); - } catch (err) { - this.sendErrorResponse(response, 1, `Could not expand variable: ${err}`); - } - } else { - response.body = { - variables: [] - }; - this.sendResponse(response); + } catch (err) { + this.sendErrorResponse( + response, + 1, + `Could not expand variable: ${(err).toString()}`); + } + } else if (typeof id == "string") { + try { + // TODO: this evals on an (effectively) unknown thread for multithreaded programs. + const stackVariable = await this.miDebugger.evalCobField(id, 0, 0); + + let variables: DebugProtocol.Variable[] = []; + + if (this.showVariableDetails) { + variables = stackVariable.toDebugProtocolVariable(this.showVariableDetails); } - } - - protected pauseRequest(response: DebugProtocol.ContinueResponse, args: DebugProtocol.ContinueArguments): void { - this.miDebugger.interrupt().then(done => { - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 3, `Could not pause: ${msg}`); - }); - } - - protected continueRequest(response: DebugProtocol.ContinueResponse, args: DebugProtocol.ContinueArguments): void { - this.miDebugger.continue().then(done => { - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 2, `Could not continue: ${msg}`); - }); - } - - protected stepInRequest(response: DebugProtocol.NextResponse, args: DebugProtocol.NextArguments): void { - this.miDebugger.stepInto().then(done => { - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 4, `Could not step in: ${msg}`); - }); - } - - protected stepOutRequest(response: DebugProtocol.NextResponse, args: DebugProtocol.NextArguments): void { - this.miDebugger.stepOut().then(done => { - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 5, `Could not step out: ${msg}`); - }); - } - - protected nextRequest(response: DebugProtocol.NextResponse, args: DebugProtocol.NextArguments): void { - this.miDebugger.stepOver().then(done => { - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 6, `Could not step over: ${msg}`); - }); - } - protected evaluateRequest(response: DebugProtocol.EvaluateResponse, args: DebugProtocol.EvaluateArguments): void { - const [threadId, level] = this.frameIdToThreadAndLevel(args.frameId); - if (args.context == "watch" || args.context == "variables" || args.context == "hover") { - this.miDebugger.evalExpression(args.expression, threadId, level).then((res) => { - response.body = { - variablesReference: 0, - result: !!res ? res : "not available" - }; - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 7, msg.toString()); - }); - } else { - this.miDebugger.sendUserInput(args.expression, threadId, level).then(output => { - if (typeof output == "undefined") - response.body = { - result: "", - variablesReference: 0 - }; - else - response.body = { - result: JSON.stringify(output), - variablesReference: 0 - }; - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 8, msg.toString()); - }); + for (const child of stackVariable.children.values()) { + const childId = `${id}.${child.cobolName}`; + let reference = 0; + if (this.showVariableDetails || !!child.children.size) { + reference = this.variableHandles.create(childId); + } + + let value = child.displayableType; + if (!this.showVariableDetails) { + const evaluatedChild = await this.miDebugger.evalCobField(childId, 0, 0); + value = evaluatedChild.value || "null"; + } + + variables.push({ + name: child.cobolName, + evaluateName: child.cobolName, + value: value, + type: child.displayableType, + variablesReference: reference + }); } - } - - protected gotoTargetsRequest(response: DebugProtocol.GotoTargetsResponse, args: DebugProtocol.GotoTargetsArguments): void { - this.miDebugger.goto(args.source.path, args.line).then(done => { - response.body = { - targets: [{ - id: 1, - label: args.source.name, - column: args.column, - line: args.line - }] - }; - this.sendResponse(response); - }, msg => { - this.sendErrorResponse(response, 16, `Could not jump: ${msg}`); - }); - } - - protected gotoRequest(response: DebugProtocol.GotoResponse, args: DebugProtocol.GotoArguments): void { + response.body = { + variables: variables + }; this.sendResponse(response); - } + } catch (err) { + this.sendErrorResponse( + response, + 1, + `Could not expand variable: ${(err).toString()}`); + } + } else { + response.body = { + variables: [] + }; + this.sendResponse(response); + } + } + + protected pauseRequest( + response: DebugProtocol.ContinueResponse, + _args: DebugProtocol.ContinueArguments): + void + { + this.miDebugger.interrupt().then(_done => { + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 3, `Could not pause: ${msg.toString()}`); + }); + } + + protected continueRequest( + response: DebugProtocol.ContinueResponse, + _args: DebugProtocol.ContinueArguments): + void + { + this.miDebugger.continue().then(_done => { + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 2, `Could not continue: ${msg.toString()}`); + }); + } + + protected stepInRequest( + response: DebugProtocol.NextResponse, + _args: DebugProtocol.NextArguments): + void + { + this.miDebugger.stepInto().then(_done => { + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 4, `Could not step in: ${msg.toString()}`); + }); + } + + protected stepOutRequest( + response: DebugProtocol.NextResponse, + _args: DebugProtocol.NextArguments): + void + { + this.miDebugger.stepOut().then(_done => { + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 5, `Could not step out: ${msg.toString()}`); + }); + } + + protected nextRequest( + response: DebugProtocol.NextResponse, + _args: DebugProtocol.NextArguments): + void + { + this.miDebugger.stepOver().then(_done => { + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 6, `Could not step over: ${msg.toString()}`); + }); + } + + protected evaluateRequest( + response: DebugProtocol.EvaluateResponse, + args: DebugProtocol.EvaluateArguments): + void + { + const [threadId, level] = this.frameIdToThreadAndLevel(args.frameId); + if (args.context == "watch" || args.context == "variables" || args.context == "hover") { + this.miDebugger.evalExpression(args.expression, threadId, level).then((res) => { + response.body = { + variablesReference: 0, + result: res ? res : "not available" + }; + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 7, msg.toString()); + }); + } else { + this.miDebugger.sendUserInput(args.expression, threadId, level).then(output => { + if (typeof output == "undefined") + response.body = { + result: "", + variablesReference: 0 + }; + else + response.body = { + result: JSON.stringify(output), + variablesReference: 0 + }; + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 8, msg.toString()); + }); + } + } + + protected gotoTargetsRequest( + response: DebugProtocol.GotoTargetsResponse, + args: DebugProtocol.GotoTargetsArguments): + void + { + this.miDebugger.goto(args.source.path, args.line).then(_done => { + response.body = { + targets: [{ + id: 1, + label: args.source.name, + column: args.column, + line: args.line + }] + }; + this.sendResponse(response); + }, + (msg: Error) => { + this.sendErrorResponse(response, 16, `Could not jump: ${msg.toString()}`); + }); + } + + protected gotoRequest( + response: DebugProtocol.GotoResponse, + _args: DebugProtocol.GotoArguments): + void + { + this.sendResponse(response); + } } DebugSession.run(GDBDebugSession); diff --git a/src/mi2.ts b/src/mi2.ts index 1eef1bf..a7f7745 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -2,979 +2,972 @@ import {Breakpoint, IDebugger, MIError, Stack, Thread, DebuggerVariable} from ". import * as ChildProcess from "child_process"; import {EventEmitter} from "events"; import {MINode, parseMI} from './parser.mi2'; -import * as nativePathFromPath from "path"; +import * as path from "path"; import * as fs from "fs"; import {SourceMap} from "./parser.c"; import {parseExpression, cleanRawValue} from "./functions"; -const nativePath = { - resolve: function (...args: string[]): string { - const nat = nativePathFromPath.resolve(...args); - if (process.platform === "win32" && this.cobcpath === "docker" && this.gdbpath === "docker") { - return nat.replace(/.*:/, s => "/" + s.toLowerCase().replace(":", "")).replace(/\\/g, "/"); - } - return nat; - }, - dirname: function (path: string): string { - const nat = nativePathFromPath.dirname(path); - if (process.platform === "win32" && this.cobcpath === "docker" && this.gdbpath === "docker") { - return nat.replace(/.*:/, s => "/" + s.toLowerCase().replace(":", "")).replace(/\\/g, "/"); - } - return nat; - }, - basename: function (path: string): string { - return nativePathFromPath.basename(path); - }, - isAbsolute: function (path: string): boolean { - return nativePathFromPath.isAbsolute(path); - }, - join: function (...args: string[]) { - return nativePathFromPath.join(...args); - }, - normalize: function (path: string) { - return nativePathFromPath.normalize(path); - } -}; - -const nonOutput = /(^(?:\d*|undefined)[\*\+\-\=\~\@\&\^])([^\*\+\-\=\~\@\&\^]{1,})/; +const nonOutput = /(^(?:\d*|undefined)[*+\-=~@&^])([^*+\-=~@&]{1,})/; const gdbRegex = /(?:\d*|undefined)\(gdb\)/; const numRegex = /\d+/; -const gcovRegex = /\"([0-9a-z_\-\/\s\\:]+\.o)\"/gi; +const gcovRegex = /"([0-9a-z_\-/\s\\:]+\.o)"/gi; export function escape(str: string) { - return str.replace(/\\/g, "\\\\").replace(/"/g, "\\\""); + return str.replace(/\\/g, "\\\\").replace(/"/g, "\\\""); } export function couldBeOutput(line: string) { - return !nonOutput.exec(line); + return !nonOutput.exec(line); } export class MI2 extends EventEmitter implements IDebugger { - private map: SourceMap; - private gcovFiles: Set = new Set(); - public procEnv: any; - private currentToken: number = 1; - private handlers: { [index: number]: (info: MINode) => any } = {}; - private breakpoints: Map = new Map(); - private buffer: string; - private errbuf: string; - private process: ChildProcess.ChildProcess; - private lastStepCommand: Function; - private hasCobGetFieldStringFunction: boolean = true; - private hasCobPutFieldStringFunction: boolean = true; - - constructor(public gdbpath: string, public gdbArgs: string[], public cobcpath: string, public cobcArgs: string[], procEnv: any, public verbose: boolean, public noDebug: boolean) { - super(); - if (procEnv) { - const env = {}; - // Duplicate process.env so we don't override it - for (const key in process.env) - if (process.env.hasOwnProperty(key)) { - env[key] = process.env[key]; - } - // Overwrite with user specified variables - for (const key in procEnv) { - if (procEnv.hasOwnProperty(key)) { - if (procEnv === null) { - delete env[key]; - } else { - env[key] = procEnv[key]; - } - } - } - this.procEnv = env; - } - } - - load(cwd: string, target: string, targetargs: string, group: string[]): Thenable { - if (!nativePath.isAbsolute(target) || (this.cobcpath === "docker" && this.gdbpath === "docker")) { - target = nativePath.resolve(cwd, target); - } - group.forEach(e => { - e = nativePath.join(cwd, e); - }); - - return new Promise((resolve, reject) => { - if (!fs.existsSync(cwd)) { - reject(new Error("cwd does not exist.")); - } - - if (!!this.noDebug) { - const args = this.cobcArgs - .concat([target]) - .concat(group) - .concat(['-job=' + targetargs]); - this.process = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); - this.process.stderr.on("data", ((data) => { - this.log("stderr", data); - }).bind(this)); - this.process.stdout.on("data", ((data) => { - this.log("stdout", data); - }).bind(this)); - this.process.on("exit", (() => { - this.emit("quit"); - }).bind(this)); - return; - } - - const args = this.cobcArgs.concat([ - '-g', - '-fsource-location', - '-ftraceall', - '-Q', - '--coverage', - '-A', - '--coverage', - '-v', - target - ]).concat(group); - const buildProcess = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); - buildProcess.stderr.on('data', (data) => { - if (this.verbose) - this.log("stderr", data); - let match; - do { - match = gcovRegex.exec(data); - if (match) { - this.gcovFiles.add(match[1].split('.').slice(0, -1).join('.')); - } - } while (match); - }); - buildProcess.on('exit', (code) => { - if (code !== 0) { - this.emit("quit"); - return; - } - - if (this.verbose) { - this.log("stderr", `COBOL file ${target} compiled with exit code: ${code}`); - } - - try { - this.map = new SourceMap(cwd, [target].concat(group)); - } catch (e) { - this.log('stderr', e); - } - - if (this.verbose) { - this.log("stderr", this.map.toString()); - } - - target = nativePath.resolve(cwd, nativePath.basename(target)); - target = target.split('.').slice(0, -1).join('.'); - // FIXME: the following should prefix "cobcrun.exe" if in "module mode", see #13 - // FIXME: if we need this code twice then add a comment why, otherwise move to a new function - if (process.platform === "win32" && this.cobcpath !== "docker" && this.gdbpath !== "docker") { - target = target + '.exe'; - } - - this.process = ChildProcess.spawn(this.gdbpath, this.gdbArgs, {cwd: cwd, env: this.procEnv}); - this.process.stdout.on("data", this.stdout.bind(this)); - this.process.stderr.on("data", ((data) => { - this.log("stderr", data); - }).bind(this)); - this.process.on("exit", (() => { - this.emit("quit"); - }).bind(this)); - this.process.on("error", ((err) => { - this.emit("launcherror", err); - }).bind(this)); - const promises = this.initCommands(target, targetargs, cwd); - Promise.all(promises).then(() => { - this.emit("debug-ready"); - resolve(); - }, reject); - }); - }); - } - - attach(cwd: string, target: string, targetargs: string, group: string[]): Thenable { - if (!nativePath.isAbsolute(target)) { - target = nativePath.join(cwd, target); - } - group.forEach(e => { - e = nativePath.join(cwd, e); - }); - - return new Promise((resolve, reject) => { - if (!fs.existsSync(cwd)) { - reject(new Error("cwd does not exist.")); - } - - const args = this.cobcArgs.concat([ - '-g', - '-fsource-location', - '-ftraceall', - '-v', - target - ]).concat(group); - const buildProcess = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); - buildProcess.stderr.on('data', (data) => { - if (this.verbose) - this.log("stderr", data); - }); - buildProcess.on('exit', (code) => { - if (code !== 0) { - this.emit("quit"); - return; - } - - if (this.verbose) { - this.log("stderr", `COBOL file ${target} compiled with exit code: ${code}`); - } - - try { - this.map = new SourceMap(cwd, [target].concat(group)); - } catch (e) { - this.log('stderr', e); - } - - if (this.verbose) { - this.log("stderr", this.map.toString()); - } - - target = nativePath.resolve(cwd, nativePath.basename(target)); - target = target.split('.').slice(0, -1).join('.'); - // FIXME: the following should prefix "cobcrun.exe" if in "module mode", see #13 - if (process.platform === "win32") { - target = target + '.exe'; - } - - this.process = ChildProcess.spawn(this.gdbpath, this.gdbArgs, {cwd: cwd, env: this.procEnv}); - this.process.stdout.on("data", this.stdout.bind(this)); - this.process.stderr.on("data", ((data) => { - this.log("stderr", data); - }).bind(this)); - this.process.on("exit", (() => { - this.emit("quit"); - }).bind(this)); - this.process.on("error", ((err) => { - this.emit("launcherror", err); - }).bind(this)); - const promises = this.initCommands(target, targetargs, cwd); - Promise.all(promises).then(() => { - this.emit("debug-ready"); - resolve(); - }, reject); - }); - }); - } - - protected initCommands(target: string, targetargs: string, cwd: string) { - if (!nativePath.isAbsolute(target)) { - target = nativePath.join(cwd, target); - } - if (process.platform === "win32") { - cwd = nativePath.dirname(target); - } - - const cmds = [ - this.sendCommand("gdb-set target-async on", false), - this.sendCommand("gdb-set print repeats 1000", false), - this.sendCommand("gdb-set args " + targetargs, false), - this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), - this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\"", false), - ]; - return cmds; - } - - stdout(data) { - if (this.verbose) { - this.log("stderr", "stdout: " + data); - } - if (typeof data == "string") { - this.buffer += data; - } else { - this.buffer += data.toString("utf8"); - } - const end = this.buffer.lastIndexOf('\n'); - if (end != -1) { - this.onOutput(this.buffer.substr(0, end)); - this.buffer = this.buffer.substr(end + 1); - } - if (this.buffer.length) { - if (this.onOutputPartial(this.buffer)) { - this.buffer = ""; - } - } - } - - stderr(data) { - if (this.verbose) { - this.log("stderr", "stderr: " + data); - } - if (typeof data == "string") { - this.errbuf += data; - } else { - this.errbuf += data.toString("utf8"); - } - const end = this.errbuf.lastIndexOf('\n'); - if (end != -1) { - this.onOutputStderr(this.errbuf.substr(0, end)); - this.errbuf = this.errbuf.substr(end + 1); - } - if (this.errbuf.length) { - this.logNoNewLine("stderr", this.errbuf); - this.errbuf = ""; - } - } - - stdin(data: string, cb?: any) { - if (this.isReady()) { - if (this.verbose) { - this.log("stderr", "stdin: " + data); - } - this.process.stdin.write(data + "\n", cb); - } - } - - onOutputStderr(lines) { - lines = lines.split('\n'); - lines.forEach(line => { - this.log("stderr", line); - }); - } - - onOutputPartial(line) { - if (couldBeOutput(line)) { - this.logNoNewLine("stdout", line); - return true; - } - return false; - } - - onOutput(linesStr: string) { - const lines = linesStr.split('\n'); - lines.forEach(line => { - if (couldBeOutput(line)) { - if (!gdbRegex.exec(line)) { - this.log("stdout", line); - } + private map: SourceMap; + private gcovFiles: Set = new Set(); + public procEnv: NodeJS.ProcessEnv; + private currentToken = 1; + private handlers: { [index: number]: (_: MINode) => unknown } = {}; + private breakpoints: Map = new Map(); + private buffer: string; + private errbuf: string; + private process: ChildProcess.ChildProcess; + private lastStepCommand: () => Thenable; + private hasCobGetFieldStringFunction = true; + private hasCobPutFieldStringFunction = true; + + constructor( + public gdbpath: string, + public gdbArgs: string[], + public cobcpath: string, + public cobcArgs: string[], + procEnv: NodeJS.ProcessEnv, + public verbose: boolean, + public noDebug: boolean | null) + { + super(); + if (procEnv) { + const env = {}; + // Duplicate process.env so we don't override it + for (const key in process.env) + if (key in process.env) { + env[key] = process.env[key]; + } + // Overwrite with user specified variables + for (const key in procEnv) { + if (key in procEnv) { + if (procEnv === null) { + delete env[key]; } else { - const parsed = parseMI(line); - if (this.verbose) { - this.log("stderr", "GDB -> App: " + JSON.stringify(parsed)); - } - let handled = false; - if (parsed.token !== undefined) { - if (this.handlers[parsed.token]) { - this.handlers[parsed.token](parsed); - delete this.handlers[parsed.token]; - handled = true; - } - } - if (!handled && parsed.resultRecords && parsed.resultRecords.resultClass == "error") { - this.log("stderr", parsed.result("msg") || line); - } - if (parsed.outOfBandRecord) { - parsed.outOfBandRecord.forEach(record => { - if (record.isStream) { - this.log(record.type, record.content); - } else { - if (record.type == "exec") { - this.emit("exec-async-output", parsed); - if (record.asyncClass == "running") { - this.emit("running", parsed); - } else if (record.asyncClass == "stopped") { - const reason = parsed.record("reason"); - if (this.verbose) { - this.log("stderr", "stop: " + reason); - } - if (reason == "breakpoint-hit") { - this.emit("breakpoint", parsed); - } else if (reason == "end-stepping-range") { - if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { - this.lastStepCommand(); - } else { - this.emit("step-end", parsed); - } - } else if (reason == "function-finished") { - if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { - this.lastStepCommand(); - } else { - this.emit("step-out-end", parsed); - } - } else if (reason == "signal-received") { - this.emit("signal-stop", parsed); - } else if (reason == "exited-normally") { - this.emit("exited-normally", parsed); - } else if (reason == "exited") { // exit with error code != 0 - if (this.verbose) { - this.log("stderr", "Program exited with code " + parsed.record("exit-code")); - } - this.emit("quit", parsed); - } else { - if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { - this.continue(); - } else { - if (this.verbose) { - this.log("stderr", "Not implemented stop reason (assuming exception): " + reason); - } - this.emit("stopped", parsed); - } - } - } else { - if (this.verbose) { - this.log("stderr", JSON.stringify(parsed)); - } - } - } else if (record.type == "notify") { - if (record.asyncClass == "thread-created") { - this.emit("thread-created", parsed); - } else if (record.asyncClass == "thread-exited") { - this.emit("thread-exited", parsed); - } - } - } - }); - handled = true; - } - if (parsed.token == undefined && parsed.resultRecords == undefined && parsed.outOfBandRecord.length == 0) { - handled = true; - } - if (!handled) { - if (this.verbose) { - this.log("stderr", "Unhandled: " + JSON.stringify(parsed)); - } - } + env[key] = procEnv[key]; } - }); - } - - start(attachTarget?: string): Thenable { - return new Promise((resolve, reject) => { - if (!!this.noDebug) { - return; - } - this.once("ui-break-done", () => { - let command = "exec-run"; - let expectingResultClass = "running"; - if (!!attachTarget) { - if (/^d+$/.test(attachTarget)) { - command = `target-attach ${attachTarget}`; - expectingResultClass = "done"; - } else { - command = `target-select remote ${attachTarget}`; - expectingResultClass = "connected"; - } - } - - this.sendCommand(command).then((info) => { - if (info.resultRecords.resultClass == expectingResultClass) { - resolve(); - } else { - reject(); - } - }, reject); - }); - }); - } - - stop() { - const proc = this.process; - const to = setTimeout(() => { - process.kill(-proc.pid); - }, 1000); - this.process.on("exit", function (code) { - clearTimeout(to); - }); - this.sendCommand("gdb-exit"); - } - - detach() { - const proc = this.process; - const to = setTimeout(() => { - process.kill(-proc.pid); - }, 1000); - this.process.on("exit", function (code) { - clearTimeout(to); - }); - this.sendCommand("target-detach"); - } - - interrupt(): Thenable { - if (this.verbose) { - this.log("stderr", "interrupt"); + } + } + this.procEnv = env; + } + } + + load(cwd: string, target: string, targetargs: string, group: string[]): Thenable { + group.map(e => { path.join(cwd, e); }); + + return new Promise((resolve, reject) => { + if (!fs.existsSync(cwd)) { + reject(new Error("cwd does not exist.")); + } + + if (this.noDebug) { + const args = (this.cobcArgs || []) + .concat([target]) + .concat(group) + .concat(['-job=' + targetargs]); + this.process = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); + this.process.stderr.on("data", ((data: string) => { + this.log("stderr", data); + })); + this.process.stdout.on("data", ((data: string) => { + this.log("stdout", data); + })); + this.process.on("exit", (() => { + this.emit("quit"); + })); + return; + } + + const args = (this.cobcArgs || []).concat([ + '-g', //enable debugger + '-fsource-location', //generate source location code + '-ftraceall', // generate trace code + '-Q', // (with `--coverage`): enable C linker coverage + '--coverage', + '-A', // (with `--coverage`): enable C compiler coverage + '--coverage', + '-v', // verbose mode + target + ]).concat(group); + const buildProcess = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); + buildProcess.stderr.on('data', (data: string) => { + if (this.verbose) + this.log("stderr", data); + let match: RegExpExecArray; + do { + match = gcovRegex.exec(data); + if (match) { + this.gcovFiles.add(match[1].split('.').slice(0, -1).join('.')); + } + } while (match); + }); + buildProcess.on('exit', (code) => { + if (code !== 0) { + this.emit("quit"); + return; } - return new Promise((resolve, reject) => { - this.sendCommand("exec-interrupt").then((info) => { - resolve(info.resultRecords.resultClass == "done"); - }, reject); - }); - } - continue(): Thenable { if (this.verbose) { - this.log("stderr", "continue"); + this.log("stderr", `COBOL file ${target} compiled with exit code: ${code}`); } - return new Promise((resolve, reject) => { - this.sendCommand("exec-continue").then((info) => { - resolve(info.resultRecords.resultClass == "running"); - }, reject); - }); - } - /** - * The command executes the line, then pauses at the next line. - * The underlying function executes entirely. - * FIXME: Implement execution graph instead of exec-next fallback - */ - stepOver(): Thenable { - this.lastStepCommand = this.stepOver; - if (this.verbose) { - this.log("stderr", "stepOver"); - } - return new Promise((resolve, reject) => { - this.sendCommand("exec-next").then((info) => { - resolve(info.resultRecords.resultClass == "running"); - }, reject); - }); - } - - /** - * The command executes the line, then pauses at the next line. - * The command goes into the underlying function, then pauses at the first line. - */ - stepInto(): Thenable { - this.lastStepCommand = this.stepInto; - if (this.verbose) { - this.log("stderr", "stepInto"); + try { + this.map = new SourceMap(cwd, [target].concat(group)); + } catch (e) { + this.log('stderr', (e).toString()); } - return new Promise((resolve, reject) => { - this.sendCommand("exec-step").then((info) => { - resolve(info.resultRecords.resultClass == "running"); - }, reject); - }); - } - /** - * The comand executes the function, then pauses at the next line outside. - */ - stepOut(): Thenable { - this.lastStepCommand = this.stepOut; if (this.verbose) { - this.log("stderr", "stepOut"); + this.log("stderr", this.map.toString()); } - return new Promise((resolve, reject) => { - this.sendCommand("exec-finish").then((info) => { - resolve(info.resultRecords.resultClass == "running"); - }, reject); - }); - } - goto(filename: string, line: number): Thenable { - if (this.verbose) { - this.log("stderr", "goto"); + target = path.resolve(cwd, path.basename(target)); + target = target.split('.').slice(0, -1).join('.'); + // FIXME: the following should prefix "cobcrun.exe" if in "module mode", see #13 + // FIXME: if we need this code twice then add a comment why, otherwise move to a new + // function + if (process.platform === "win32") { + target = target + '.exe'; + } + + this.process = ChildProcess.spawn( + this.gdbpath, + this.gdbArgs, + { cwd: cwd, + env: this.procEnv }); + this.process.stdout.on("data", (data: string) => this.stdout(data)); + this.process.stderr.on("data", (data: string) => { this.log("stderr", data); }); + this.process.on("exit", () => { this.emit("quit"); }); + this.process.on("error", (err) => { this.emit("launcherror", err); }); + const promises = this.initCommands(target, targetargs, cwd); + Promise.all(promises).then(() => { + this.emit("debug-ready"); + resolve(undefined); + }, reject); + }); + }); + } + + attach(cwd: string, target: string, targetargs: string, group: string[]): Thenable { + if (!path.isAbsolute(target)) { + target = path.join(cwd, target); + } + group.map(e => { path.join(cwd, e) }); + + return new Promise((resolve, reject) => { + if (!fs.existsSync(cwd)) { + reject(new Error("cwd does not exist.")); + } + + const args = (this.cobcArgs || []).concat([ + '-g', + '-fsource-location', + '-ftraceall', + '-v', + target + ]).concat(group); + const buildProcess = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); + buildProcess.stderr.on('data', (data: string) => { + if (this.verbose) + this.log("stderr", data); + }); + buildProcess.on('exit', (code) => { + if (code !== 0) { + this.emit("quit"); + return; } - return new Promise((resolve, reject) => { - const target: string = '"' + (filename ? escape(filename) + ":" : "") + line + '"'; - this.sendCommand("break-insert -t " + target).then(() => { - this.sendCommand("exec-jump " + target).then((info) => { - resolve(info.resultRecords.resultClass == "running"); - }, reject); - }, reject); - }); - } - async changeVariable(name: string, rawValue: string): Promise { if (this.verbose) { - this.log("stderr", "changeVariable"); + this.log("stderr", `COBOL file ${target} compiled with exit code: ${code}`); } - const functionName = await this.getCurrentFunctionName(); - - const cleanedRawValue = cleanRawValue(rawValue); - try { - const variable = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); - - if (variable.attribute.type === "integer") { - await this.sendCommand(`gdb-set var ${variable.cName}=${cleanedRawValue}`); - } else if (this.hasCobPutFieldStringFunction && variable.cName.startsWith("f_")) { - await this.sendCommand(`data-evaluate-expression "(int)cob_put_field_str(&${variable.cName}, \\"${cleanedRawValue}\\")"`); - } else { - const finalValue = variable.formatValue(cleanedRawValue); - let cName = variable.cName; - if (variable.cName.startsWith("f_")) { - cName += ".data"; - } - await this.sendCommand(`data-evaluate-expression "(void)memcpy(${cName}, \\"${finalValue}\\", ${variable.size})"`); - } + this.map = new SourceMap(cwd, [target].concat(group)); } catch (e) { - if (e.message.includes("No symbol \"cob_put_field_str\"")) { - this.hasCobPutFieldStringFunction = false; - return this.changeVariable(name, rawValue); - } - this.log("stderr", `Failed to set cob field value on ${functionName}.${name}`); - this.log("stderr", e.message); - throw e; - } - } - - loadBreakPoints(breakpoints: Breakpoint[]): Thenable<[boolean, Breakpoint][]> { - if (this.verbose) { - this.log("stderr", "loadBreakPoints"); + this.log('stderr', (e).toString()); } - const promisses = []; - breakpoints.forEach(breakpoint => { - promisses.push(this.addBreakPoint(breakpoint)); - }); - return Promise.all(promisses); - } - setBreakPointCondition(bkptNum, condition): Thenable { if (this.verbose) { - this.log("stderr", "setBreakPointCondition"); + this.log("stderr", this.map.toString()); } - return this.sendCommand("break-condition " + bkptNum + " " + condition); - } - addBreakPoint(breakpoint: Breakpoint): Thenable<[boolean, Breakpoint]> { + target = path.resolve(cwd, path.basename(target)); + target = target.split('.').slice(0, -1).join('.'); + // FIXME: the following should prefix "cobcrun.exe" if in "module mode", see #13 + if (process.platform === "win32") { + target = target + '.exe'; + } + + this.process = ChildProcess.spawn( + this.gdbpath, + this.gdbArgs, + { cwd: cwd, + env: this.procEnv }); + this.process.stdout.on("data", (data: string) => this.stdout(data)); + this.process.stderr.on("data", (data: string) => { this.log("stderr", data); }); + this.process.on("exit", () => { this.emit("quit"); }); + this.process.on("error", (err) => { this.emit("launcherror", err); }); + const promises = this.initCommands(target, targetargs, cwd); + Promise.all(promises).then(() => { + this.emit("debug-ready"); + resolve(undefined); + }, reject); + }); + }); + } + + protected initCommands(target: string, targetargs: string, cwd: string) { + if (!path.isAbsolute(target)) { + target = path.join(cwd, target); + } + if (process.platform === "win32") { + cwd = path.dirname(target); + } + + const cmds = [ + this.sendCommand("gdb-set target-async on", false), + this.sendCommand("gdb-set print repeats 1000", false), + this.sendCommand("gdb-set args " + targetargs, false), + this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), + this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\"", false), + ]; + return cmds; + } + + stdout(data: string) { + if (this.verbose) { + this.log("stderr", "stdout: " + data); + } + this.buffer += data; + const end = this.buffer.lastIndexOf('\n'); + if (end != -1) { + this.onOutput(this.buffer.substring(0, end)); + this.buffer = this.buffer.substring(end + 1); + } + if (this.buffer.length) { + if (this.onOutputPartial(this.buffer)) { + this.buffer = ""; + } + } + } + + stderr(data: string) { + if (this.verbose) { + this.log("stderr", "stderr: " + data); + } + this.errbuf += data; + const end = this.errbuf.lastIndexOf('\n'); + if (end != -1) { + this.onOutputStderr(this.errbuf.substring(0, end)); + this.errbuf = this.errbuf.substring(end + 1); + } + if (this.errbuf.length) { + this.logNoNewLine("stderr", this.errbuf); + this.errbuf = ""; + } + } + + stdin(data: string, cb?: (_err: Error) => void) { + if (this.isReady()) { + if (this.verbose) { + this.log("stderr", "stdin: " + data); + } + this.process.stdin.write(data + "\n", cb); + } + } + + onOutputStderr(lines: string) { + const linesArr = lines.split('\n'); + linesArr.forEach(line => { + this.log("stderr", line); + }); + } + + onOutputPartial(line: string) { + if (couldBeOutput(line)) { + this.logNoNewLine("stdout", line); + return true; + } + return false; + } + + onOutput(linesStr: string) { + const lines = linesStr.split('\n'); + lines.forEach(line => { + if (couldBeOutput(line)) { + if (!gdbRegex.exec(line)) { + this.log("stdout", line); + } + } else { + const parsed = parseMI(line); if (this.verbose) { - this.log("stderr", "addBreakPoint "); - } - - return new Promise((resolve, reject) => { - if (this.breakpoints.has(breakpoint)) { - return resolve([false, undefined]); - } - let location = ""; - if (breakpoint.countCondition) { - if (breakpoint.countCondition[0] == ">") { - location += "-i " + numRegex.exec(breakpoint.countCondition.substr(1))[0] + " "; - } else { - const match = numRegex.exec(breakpoint.countCondition)[0]; - if (match.length != breakpoint.countCondition.length) { - this.log("stderr", "Unsupported break count expression: '" + breakpoint.countCondition + "'. Only supports 'X' for breaking once after X times or '>X' for ignoring the first X breaks"); - location += "-t "; - } else if (parseInt(match) != 0) { - location += "-t -i " + parseInt(match) + " "; - } - } - } - - const map = this.map.getLineC(breakpoint.file, breakpoint.line); - if (map.fileC === '' && map.lineC === 0) { - return; - } - - if (breakpoint.raw) { - location += '"' + escape(breakpoint.raw) + '"'; + this.log("stderr", "GDB -> App: " + JSON.stringify(parsed)); + } + let handled = false; + if (parsed.token !== undefined) { + if (this.handlers[parsed.token]) { + this.handlers[parsed.token](parsed); + delete this.handlers[parsed.token]; + handled = true; + } + } + if (!handled && parsed.resultRecords && parsed.resultRecords.resultClass == "error") { + this.log("stderr", parsed.result("msg") || line); + } + if (parsed.outOfBandRecord) { + parsed.outOfBandRecord.forEach(record => { + if (record.isStream) { + this.log(record.type, record.content); } else { - location += '"' + escape(map.fileC) + ":" + map.lineC + '"'; - } - - this.sendCommand("break-insert -f " + location).then((result) => { - if (result.resultRecords.resultClass == "done") { - const bkptNum = parseInt(result.result("bkpt.number")); - const map = this.map.getLineCobol(result.result("bkpt.file"), parseInt(result.result("bkpt.line"))); - const newBrk = { - file: map.fileCobol, - line: map.lineCobol, - condition: breakpoint.condition - }; - if (breakpoint.condition) { - this.setBreakPointCondition(bkptNum, breakpoint.condition).then((result) => { - if (result.resultRecords.resultClass == "done") { - this.breakpoints.set(newBrk, bkptNum); - resolve([true, newBrk]); - } else { - resolve([false, undefined]); - } - }, reject); + if (record.type == "exec") { + this.emit("exec-async-output", parsed); + if (record.asyncClass == "running") { + this.emit("running", parsed); + } else if (record.asyncClass == "stopped") { + const reason = parsed.record("reason"); + if (this.verbose) { + this.log("stderr", "stop: " + reason); + } + if (reason == "breakpoint-hit") { + this.emit("breakpoint", parsed); + } else if (reason == "end-stepping-range") { + if (!this.map.hasLineCobol( + parsed.record('frame.fullname'), + parseInt(parsed.record('frame.line')))) + { + void this.lastStepCommand().then(); } else { - this.breakpoints.set(newBrk, bkptNum); - resolve([true, newBrk]); + this.emit("step-end", parsed); } - } else { - reject(result); - } - }, reject); - }); - } - - removeBreakPoint(breakpoint: Breakpoint): Thenable { - if (this.verbose) { - this.log("stderr", "removeBreakPoint"); - } - return new Promise((resolve, reject) => { - if (!this.breakpoints.has(breakpoint)) { - return resolve(false); - } - this.sendCommand("break-delete " + this.breakpoints.get(breakpoint)).then((result) => { - if (result.resultRecords.resultClass == "done") { - this.breakpoints.delete(breakpoint); - resolve(true); - } else resolve(false); - }); - }); - } - - clearBreakPoints(): Thenable { - if (this.verbose) { - this.log("stderr", "clearBreakPoints"); - } - return new Promise((resolve, reject) => { - this.sendCommand("break-delete").then((result) => { - if (result.resultRecords.resultClass == "done") { - this.breakpoints.clear(); - resolve(true); - } else resolve(false); - }, () => { - resolve(false); - }); - }); - } - - async getThreads(): Promise { - if (this.verbose) { - this.log("stderr", "getThreads"); - } - return new Promise((resolve, reject) => { - if (!!this.noDebug) { - return; - } - this.sendCommand("thread-info").then((result) => { - resolve(result.result("threads").map(element => { - const ret: Thread = { - id: parseInt(MINode.valueOf(element, "id")), - targetId: MINode.valueOf(element, "target-id") - }; - const name = MINode.valueOf(element, "name"); - if (name) { - ret.name = name; + } else if (reason == "function-finished") { + if (!this.map.hasLineCobol( + parsed.record('frame.fullname'), + parseInt(parsed.record('frame.line')))) + { + void this.lastStepCommand(); + } else { + this.emit("step-out-end", parsed); } - return ret; - })); - }, reject); - }); - } - - async getStack(maxLevels: number, thread: number): Promise { - if (this.verbose) { - this.log("stderr", "getStack"); - } - let command = "stack-list-frames"; - if (thread != 0) { - command += ` --thread ${thread}`; - } - if (maxLevels) { - command += " 0 " + maxLevels; - } - const result = await this.sendCommand(command); - const stack = result.result("stack"); - const ret: Stack[] = []; - return stack.map(element => { - const level = MINode.valueOf(element, "@frame.level"); - const addr = MINode.valueOf(element, "@frame.addr"); - const func = MINode.valueOf(element, "@frame.func"); - const filename = MINode.valueOf(element, "@frame.file"); - let file: string = MINode.valueOf(element, "@frame.fullname"); - if (file) { - file = nativePath.normalize(file); - } - const from = parseInt(MINode.valueOf(element, "@frame.from")); - - let line = 0; - const lnstr = MINode.valueOf(element, "@frame.line"); - if (lnstr) { - line = parseInt(lnstr); - } - - const map = this.map.getLineCobol(file, line); - return { - address: addr, - fileName: nativePath.basename(map.fileCobol), - file: map.fileCobol, - function: func || from, - level: level, - line: map.lineCobol - }; - }); - } - - async getCurrentFunctionName(): Promise { - if (this.verbose) { - this.log("stderr", "getCurrentFunctionName"); - } - const response = await this.sendCommand("stack-info-frame"); - return response.result("frame.func").toLowerCase(); - } - - async getStackVariables(thread: number, frame: number): Promise { - if (this.verbose) { - this.log("stderr", "getStackVariables"); - } - - const functionName = await this.getCurrentFunctionName(); - - const variablesResponse = await this.sendCommand(`stack-list-variables --thread ${thread} --frame ${frame} --all-values`); - const variables = variablesResponse.result("variables"); - - const currentFrameVariables = new Set(); - for (const element of variables) { - const key = MINode.valueOf(element, "name"); - const value = MINode.valueOf(element, "value"); - - if (key.startsWith("b_")) { - const cobolVariable = this.map.getVariableByC(`${functionName}.${key}`); - - if (cobolVariable) { - try { - cobolVariable.setValue(value); - } catch (e) { - this.log("stderr", `Failed to set value on ${functionName}.${key}`); - this.log("stderr", e.message); - throw e; + } else if (reason == "signal-received") { + this.emit("signal-stop", parsed); + } else if (reason == "exited-normally") { + this.emit("exited-normally", parsed); + } else if (reason == "exited") { // exit with error code != 0 + if (this.verbose) { + this.log("stderr", "Program exited with code " + + parsed.record("exit-code")); + } + this.emit("quit", parsed); + } else { + if (!this.map.hasLineCobol( + parsed.record('frame.fullname'), + parseInt(parsed.record('frame.line')))) + { + void this.continue(); + } else { + if (this.verbose) { + this.log( + "stderr", + "Not implemented stop reason (assuming exception): " + reason); + } + this.emit("stopped", parsed); } - currentFrameVariables.add(cobolVariable); + } + } else { + if (this.verbose) { + this.log("stderr", JSON.stringify(parsed)); + } } + } else if (record.type == "notify") { + if (record.asyncClass == "thread-created") { + this.emit("thread-created", parsed); + } else if (record.asyncClass == "thread-exited") { + this.emit("thread-exited", parsed); + } + } } - } - return Array.from(currentFrameVariables); - } - - examineMemory(from: number, length: number): Thenable { - if (this.verbose) { - this.log("stderr", "examineMemory"); - } - return new Promise((resolve, reject) => { - this.sendCommand("data-read-memory-bytes 0x" + from.toString(16) + " " + length).then((result) => { - resolve(result.result("memory[0].contents")); + }); + handled = true; + } + if (parsed.token == undefined + && parsed.resultRecords == undefined + && parsed.outOfBandRecord.length == 0) + { + handled = true; + } + if (!handled) { + if (this.verbose) { + this.log("stderr", "Unhandled: " + JSON.stringify(parsed)); + } + } + } + }); + } + + start(attachTarget?: string): Thenable { + return new Promise((resolve, reject) => { + if (this.noDebug) { + return; + } + this.once("ui-break-done", () => { + let command = "exec-run"; + let expectingResultClass = "running"; + if (attachTarget) { + if (/^d+$/.test(attachTarget)) { + command = `target-attach ${attachTarget}`; + expectingResultClass = "done"; + } else { + command = `target-select remote ${attachTarget}`; + expectingResultClass = "connected"; + } + } + + this.sendCommand(command).then((info) => { + if (info.resultRecords.resultClass == expectingResultClass) { + resolve(true); + } else { + reject(); + } + }, reject); + }); + }); + } + + stop() { + const proc = this.process; + if (proc) { + const to = setTimeout(() => { + process.kill(-proc.pid); + }, 1000); + this.process.on("exit", function (_code) { + clearTimeout(to); + }); + } + void this.sendCommand("gdb-exit"); + } + + detach() { + const proc = this.process; + if (proc) { + const to = setTimeout(() => { + process.kill(-proc.pid); + }, 1000); + this.process.on("exit", function (_code) { + clearTimeout(to); + }); + } + void this.sendCommand("target-detach"); + } + + interrupt(): Thenable { + if (this.verbose) { + this.log("stderr", "interrupt"); + } + return new Promise((resolve, reject) => { + this.sendCommand("exec-interrupt").then((info) => { + resolve(info.resultRecords.resultClass == "done"); + }, reject); + }); + } + + continue(): Thenable { + if (this.verbose) { + this.log("stderr", "continue"); + } + return new Promise((resolve, reject) => { + this.sendCommand("exec-continue").then((info) => { + resolve(info.resultRecords.resultClass == "running"); + }, reject); + }); + } + + /** + * The command executes the line, then pauses at the next line. + * The underlying function executes entirely. + * FIXME: Implement execution graph instead of exec-next fallback + */ + stepOver(): Thenable { + this.lastStepCommand = () => this.stepOver(); + if (this.verbose) { + this.log("stderr", "stepOver"); + } + return new Promise((resolve, reject) => { + this.sendCommand("exec-next").then((info) => { + resolve(info.resultRecords.resultClass == "running"); + }, reject); + }); + } + + /** + * The command executes the line, then pauses at the next line. + * The command goes into the underlying function, then pauses at the first line. + */ + stepInto(): Thenable { + this.lastStepCommand = () => this.stepInto() ; + if (this.verbose) { + this.log("stderr", "stepInto"); + } + return new Promise((resolve, reject) => { + this.sendCommand("exec-step").then((info) => { + resolve(info.resultRecords.resultClass == "running"); + }, reject); + }); + } + + /** + * The comand executes the function, then pauses at the next line outside. + */ + stepOut(): Thenable { + this.lastStepCommand = () => this.stepOut() ; + if (this.verbose) { + this.log("stderr", "stepOut"); + } + return new Promise((resolve, reject) => { + this.sendCommand("exec-finish").then((info) => { + resolve(info.resultRecords.resultClass == "running"); + }, reject); + }); + } + + goto(filename: string, line: number): Thenable { + if (this.verbose) { + this.log("stderr", "goto"); + } + return new Promise((resolve, reject) => { + const target: string = '"' + (filename ? escape(filename) + ":" : "") + line.toString() + '"'; + this.sendCommand("break-insert -t " + target).then(() => { + this.sendCommand("exec-jump " + target).then((info) => { + resolve(info.resultRecords.resultClass == "running"); + }, reject); + }, reject); + }); + } + + async changeVariable(name: string, rawValue: string): Promise { + if (this.verbose) { + this.log("stderr", "changeVariable"); + } + + const functionName = await this.getCurrentFunctionName(); + + const cleanedRawValue = cleanRawValue(rawValue); + + try { + const variable = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); + + if (variable.attribute.type === "integer") { + await this.sendCommand(`gdb-set var ${variable.cName}=${cleanedRawValue}`); + } else if (this.hasCobPutFieldStringFunction && variable.cName.startsWith("f_")) { + await this.sendCommand( + `data-evaluate-expression + "(int)cob_put_field_str(&${variable.cName}, \\"${cleanedRawValue}\\")"`); + } else { + const finalValue = variable.formatValue(cleanedRawValue); + let cName = variable.cName; + if (variable.cName.startsWith("f_")) { + cName += ".data"; + } + await + this.sendCommand(`data-evaluate-expression + "(void)memcpy(${cName}, \\"${finalValue}\\", ${variable.size})"`); + } + } catch (e) { + if ((e).message.includes("No symbol \"cob_put_field_str\"")) { + this.hasCobPutFieldStringFunction = false; + return this.changeVariable(name, rawValue); + } + this.log("stderr", `Failed to set cob field value on ${functionName}.${name}`); + this.log("stderr", (e).message); + throw e; + } + } + + loadBreakPoints(breakpoints: Breakpoint[]): Thenable<[boolean, Breakpoint][]> { + if (this.verbose) { + this.log("stderr", "loadBreakPoints"); + } + const promisses = []; + breakpoints.forEach(breakpoint => { + promisses.push(this.addBreakPoint(breakpoint)); + }); + return Promise.all(promisses); + } + + setBreakPointCondition(bkptNum: number, condition: string): Thenable { + if (this.verbose) { + this.log("stderr", "setBreakPointCondition"); + } + return this.sendCommand("break-condition " + bkptNum.toString() + " " + condition); + } + + addBreakPoint(breakpoint: Breakpoint): Thenable<[boolean, Breakpoint]> { + if (this.verbose) { + this.log("stderr", "addBreakPoint "); + } + + return new Promise((resolve, reject) => { + if (this.breakpoints.has(breakpoint)) { + return resolve([false, undefined]); + } + let location = ""; + if (breakpoint.countCondition) { + if (breakpoint.countCondition[0] == ">") { + location += "-i " + numRegex.exec(breakpoint.countCondition.substring(1))[0] + " "; + } else { + const match = numRegex.exec(breakpoint.countCondition)[0]; + if (match.length != breakpoint.countCondition.length) { + this.log( + "stderr", + "Unsupported break count expression: '" + + breakpoint.countCondition + + "'. Only supports 'X' for breaking once after X times or '>X' for ignoring the " + + "first X breaks"); + location += "-t "; + } else if (parseInt(match) != 0) { + location += "-t -i " + parseInt(match).toString() + " "; + } + } + } + + const map = this.map.getLineC(breakpoint.file, breakpoint.line); + if (map.fileC === '' && map.lineC === 0) { + return; + } + + if (breakpoint.raw) { + location += '"' + escape(breakpoint.raw) + '"'; + } else { + location += '"' + escape(map.fileC) + ":" + map.lineC.toString() + '"'; + } + + this.sendCommand("break-insert -f " + location).then((result) => { + if (result.resultRecords.resultClass == "done") { + const bkptNum = parseInt(result.result("bkpt.number")); + const bkptlocation = (result.result("bkpt.original-location")).split(':'); + const map = this.map.getLineCobol(bkptlocation[0], parseInt(bkptlocation[1])); + const newBrk = { + file: map.fileCobol, + line: map.lineCobol, + condition: breakpoint.condition + }; + if (breakpoint.condition) { + this.setBreakPointCondition(bkptNum, breakpoint.condition) + .then((result: MINode) => { + if (result.resultRecords.resultClass == "done") { + this.breakpoints.set(newBrk, bkptNum); + resolve([true, newBrk]); + } else { + resolve([false, undefined]); + } }, reject); - }); - } - - async evalExpression(expression: string, thread: number, frame: number): Promise { - const functionName = await this.getCurrentFunctionName(); - - if (this.verbose) { - this.log("stderr", "evalExpression"); - } - - let [finalExpression, variableNames] = parseExpression(expression, functionName, this.map); - - for (const variableName of variableNames) { - const variable = this.map.getVariableByC(`${functionName}.${variableName}`); - if (variable) { - await this.evalVariable(variable, thread, frame); - const value = variable.value; - finalExpression = `const ${variableName}=${value};` + finalExpression; - } - } - - try { - const result = `${eval(finalExpression)}`; - if (/[^0-9.\-+]/g.test(result)) { - return `"${result}"`; - } - return result; - } catch (e) { - this.log("stderr", e.message); - return `Failed to evaluate ${expression}`; - } - } - - async evalCobField(name: string, thread: number, frame: number): Promise { - const functionName = await this.getCurrentFunctionName(); - - if (this.verbose) { - this.log("stderr", "evalCobField"); - } - - try { - const variable = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); - return await this.evalVariable(variable, thread, frame); - } catch (e) { - this.log("stderr", `Failed to eval cob field value on ${functionName}.${name}`); + } else { + this.breakpoints.set(newBrk, bkptNum); + resolve([true, newBrk]); + } + } else { + reject(result); + } + }, reject); + }); + } + + removeBreakPoint(breakpoint: Breakpoint): Thenable { + if (this.verbose) { + this.log("stderr", "removeBreakPoint"); + } + return new Promise((resolve, _reject) => { + if (!this.breakpoints.has(breakpoint)) { + return resolve(false); + } + this.sendCommand("break-delete " + this.breakpoints.get(breakpoint).toString()) + .then( + (result: MINode) => { + if (result.resultRecords.resultClass == "done") { + this.breakpoints.delete(breakpoint); + resolve(true); + } else resolve(false); + }, + (err: Error) => console.log(err)); + }); + } + + clearBreakPoints(): Thenable { + if (this.verbose) { + this.log("stderr", "clearBreakPoints"); + } + return new Promise((resolve, _reject) => { + this.sendCommand("break-delete").then((result) => { + if (result.resultRecords.resultClass == "done") { + this.breakpoints.clear(); + resolve(true); + } else resolve(false); + }, () => { + resolve(false); + }); + }); + } + + async getThreads(): Promise { + if (this.verbose) { + this.log("stderr", "getThreads"); + } + return new Promise((resolve, reject) => { + if (this.noDebug) { + return; + } + this.sendCommand("thread-info").then((result) => { + resolve((result.result("threads")).map(element => { + const ret: Thread = { + id: parseInt(MINode.valueOf(element, "id")), + targetId: MINode.valueOf(element, "target-id") + }; + const name = MINode.valueOf(element, "name"); + if (name) { + ret.name = name; + } + return ret; + })); + }, reject); + }); + } + + async getStack(maxLevels: number, thread: number): Promise { + if (this.verbose) { + this.log("stderr", "getStack"); + } + let command = "stack-list-frames"; + if (thread != 0) { + command += ` --thread ${thread}`; + } + if (maxLevels) { + command += " 0 " + maxLevels.toString(); + } + const result = await this.sendCommand(command); + const stack = result.result("stack"); + return stack.map(element => { + const level = MINode.valueOf(element, "@frame.level"); + const addr = MINode.valueOf(element, "@frame.addr"); + const func = MINode.valueOf(element, "@frame.func"); + const filename = MINode.valueOf(element, "@frame.file"); + let file: string = MINode.valueOf(element, "@frame.fullname"); + if (file) { + file = path.normalize(file); + } + const from = parseInt(MINode.valueOf(element, "@frame.from")); + + let line = 0; + const lnstr = MINode.valueOf(element, "@frame.line"); + if (lnstr) { + line = parseInt(lnstr); + } + + const map = this.map.getLineCobol(file, line); + return { + address: addr, + fileName: path.basename(map.fileCobol), + file: map.fileCobol, + function: func || from, + level: level, + line: map.lineCobol + }; + }); + } + + async getCurrentFunctionName(): Promise { + if (this.verbose) { + this.log("stderr", "getCurrentFunctionName"); + } + const response = await this.sendCommand("stack-info-frame"); + return response.result("frame.func").toLowerCase(); + } + + async getStackVariables(thread: number, frame: number): Promise { + if (this.verbose) { + this.log("stderr", "getStackVariables"); + } + + const functionName = await this.getCurrentFunctionName(); + + const variablesResponse = await this.sendCommand(`stack-list-variables --thread ${thread} --frame ${frame} --all-values`); + const variables = variablesResponse.result("variables"); + + const currentFrameVariables = new Set(); + for (const element of variables) { + const key = MINode.valueOf(element, "name"); + const value = MINode.valueOf(element, "value"); + + if (key.startsWith("b_")) { + const cobolVariable = this.map.getVariableByC(`${functionName}.${key}`); + + if (cobolVariable) { + try { + cobolVariable.setValue(value); + } catch (e) { + this.log("stderr", `Failed to set value on ${functionName}.${key}`); this.log("stderr", e.message); throw e; + } + currentFrameVariables.add(cobolVariable); } + } } + return Array.from(currentFrameVariables); + } - private async evalVariable(variable: DebuggerVariable, thread: number, frame: number): Promise { - if (this.verbose) { - this.log("stderr", "evalVariable"); - } - - let command = "data-evaluate-expression "; - if (thread != 0) { - command += `--thread ${thread} --frame ${frame} `; - } - - if (this.hasCobGetFieldStringFunction && variable.cName.startsWith("f_")) { - command += `"(char *)cob_get_field_str_buffered(&${variable.cName})"`; - } else if (variable.cName.startsWith("f_")) { - command += `${variable.cName}.data`; - } else { - command += variable.cName; - } - - let dataResponse; - let value = null; - try { - dataResponse = await this.sendCommand(command); - value = dataResponse.result("value"); - if (value === "0x0") { - value = null; - } - } catch (error) { - if (error.message.includes("No symbol \"cob_get_field_str_buffered\"")) { - this.hasCobGetFieldStringFunction = false; - return this.evalVariable(variable, thread, frame); - } - this.log("stderr", error.message); - } - - if (this.hasCobGetFieldStringFunction) { - variable.setValueUsage(value); - } else { - variable.setValue(value); - } - - return variable; - } - - private logNoNewLine(type: string, msg: string): void { - this.emit("msg", type, msg); + examineMemory(from: number, length: number): Thenable { + if (this.verbose) { + this.log("stderr", "examineMemory"); } + return new Promise((resolve, reject) => { + this.sendCommand("data-read-memory-bytes 0x" + from.toString(16) + " " + length).then((result) => { + resolve(result.result("memory[0].contents")); + }, reject); + }); + } - private log(type: string, msg: string): void { - this.emit("msg", type, msg[msg.length - 1] == '\n' ? msg : (msg + "\n")); - } - - sendUserInput(command: string, threadId: number = 0, frameLevel: number = 0): Thenable { - return new Promise((resolve, reject) => { - this.stdin(command, resolve); - }); - } + async evalExpression(expression: string, thread: number, frame: number): Promise { + const functionName = await this.getCurrentFunctionName(); - private sendCommand(command: string, suppressFailure: boolean = false): Thenable { - return new Promise((resolve, reject) => { - const sel = this.currentToken++; - this.handlers[sel] = (node: MINode) => { - if (node && node.resultRecords && node.resultRecords.resultClass === "error") { - if (suppressFailure) { - this.log("stderr", `WARNING: Error executing command '${command}'`); - resolve(node); - } else - reject(new MIError(node.result("msg") || "Internal error", command)); - } else - resolve(node); - }; - this.stdin(sel + "-" + command); - }); + if (this.verbose) { + this.log("stderr", "evalExpression"); } - isReady(): boolean { - return !!this.process; - } + let [finalExpression, variableNames] = parseExpression(expression, functionName, this.map); - getGcovFiles(): string[] { - return Array.from(this.gcovFiles); - } - - getSourceMap(): SourceMap { - return this.map; - } + for (const variableName of variableNames) { + const variable = this.map.getVariableByC(`${functionName}.${variableName}`); + if (variable) { + await this.evalVariable(variable, thread, frame); + const value = variable.value; + finalExpression = `const ${variableName}=${value};` + finalExpression; + } + } + + try { + const result = `${eval(finalExpression)}`; + if (/[^0-9.\-+]/g.test(result)) { + return `"${result}"`; + } + return result; + } catch (e) { + this.log("stderr", e.message); + return `Failed to evaluate ${expression}`; + } + } + + async evalCobField(name: string, thread: number, frame: number): Promise { + const functionName = await this.getCurrentFunctionName(); + + if (this.verbose) { + this.log("stderr", "evalCobField"); + } + + try { + const variable = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); + return await this.evalVariable(variable, thread, frame); + } catch (e) { + this.log("stderr", `Failed to eval cob field value on ${functionName}.${name}`); + this.log("stderr", e.message); + throw e; + } + } + + private async evalVariable(variable: DebuggerVariable, thread: number, frame: number): Promise { + if (this.verbose) { + this.log("stderr", "evalVariable"); + } + + let command = "data-evaluate-expression "; + if (thread != 0) { + command += `--thread ${thread} --frame ${frame} `; + } + + if (this.hasCobGetFieldStringFunction && variable.cName.startsWith("f_")) { + command += `"(char *)cob_get_field_str_buffered(&${variable.cName})"`; + } else if (variable.cName.startsWith("f_")) { + command += `${variable.cName}.data`; + } else { + command += variable.cName; + } + + let dataResponse; + let value = null; + try { + dataResponse = await this.sendCommand(command); + value = dataResponse.result("value"); + if (value === "0x0") { + value = null; + } + } catch (error) { + if (error.message.includes("No symbol \"cob_get_field_str_buffered\"")) { + this.hasCobGetFieldStringFunction = false; + return this.evalVariable(variable, thread, frame); + } + this.log("stderr", error.message); + } + + if (this.hasCobGetFieldStringFunction) { + variable.setValueUsage(value); + } else { + variable.setValue(value); + } + + return variable; + } + + private logNoNewLine(type: string, msg: string): void { + this.emit("msg", type, msg); + } + + private log(type: string, msg: string): void { + this.emit("msg", type, msg[msg.length - 1] == '\n' ? msg : (msg + "\n")); + } + + sendUserInput(command: string, threadId: number = 0, frameLevel: number = 0): Thenable { + return new Promise((resolve, reject) => { + this.stdin(command, resolve); + }); + } + + private sendCommand(command: string, suppressFailure: boolean = false): Thenable { + return new Promise((resolve, reject) => { + const sel = this.currentToken++; + this.handlers[sel] = (node: MINode) => { + if (node && node.resultRecords && node.resultRecords.resultClass === "error") { + if (suppressFailure) { + this.log("stderr", `WARNING: Error executing command '${command}'`); + resolve(node); + } else + reject(new MIError(node.result("msg") || "Internal error", command)); + } else + resolve(node); + }; + this.stdin(sel + "-" + command); + }); + } + + isReady(): boolean { + return !!this.process; + } + + getGcovFiles(): string[] { + return Array.from(this.gcovFiles); + } + + getSourceMap(): SourceMap { + return this.map; + } } diff --git a/src/parser.c.ts b/src/parser.c.ts index 0a5c9f3..fdbf657 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -5,9 +5,6 @@ import {DebuggerVariable, Attribute, VariableType} from "./debugger"; const nativePath = { resolve: function (...args: string[]): string { const nat = nativePathFromPath.resolve(...args); - if (process.platform === "win32" && this.cobcpath === "docker" && this.gdbpath === "docker") { - return nat.replace(/.*:/, s => "/" + s.toLowerCase().replace(":", "")).replace(/\\/g, "/"); - } return nat; }, basename: function (path: string): string { diff --git a/src/parser.mi2.ts b/src/parser.mi2.ts index 876005c..fbf7ddc 100644 --- a/src/parser.mi2.ts +++ b/src/parser.mi2.ts @@ -42,7 +42,7 @@ function parseString(str: string): string { bufIndex += ret.write('\v', bufIndex); else if (str[i] == '0') bufIndex += ret.write('\0', bufIndex); - else if (m = octalMatch.exec(str.substr(i))) { + else if (m = octalMatch.exec(str.substring(i))) { ret.writeUInt8(parseInt(m[0], 8), bufIndex++); i += 2; } else @@ -60,10 +60,15 @@ function parseString(str: string): string { return ret.slice(0, bufIndex).toString("utf8"); } +export type ResultRecords = { + resultClass: string; + results: [string, unknown][] +} + export class MINode implements MIInfo { token: number; outOfBandRecord: { isStream: boolean, type: string, asyncClass: string, output: [string, any][], content: string }[]; - resultRecords: { resultClass: string, results: [string, any][] }; + resultRecords: ResultRecords; constructor(token: number, info: { isStream: boolean, type: string, asyncClass: string, output: [string, any][], content: string }[], result: { resultClass: string, results: [string, any][] }) { this.token = token; @@ -95,7 +100,7 @@ export class MINode implements MIInfo { do { let target = pathRegex.exec(path); if (target) { - path = path.substr(target[0].length); + path = path.substring(target[0].length); if (current.length && typeof current != "string") { const found = []; for (const element of current) { @@ -111,11 +116,11 @@ export class MINode implements MIInfo { } else return undefined; } else if (path[0] == '@') { current = [current]; - path = path.substr(1); + path = path.substring(1); } else { target = indexRegex.exec(path); if (target) { - path = path.substr(target[0].length); + path = path.substring(target[0].length); const i = parseInt(target[1]); if (current.length && typeof current != "string" && i >= 0 && i < current.length) { current = current[i]; @@ -166,7 +171,7 @@ export function parseMI(output: string): MINode { return ""; let stringEnd = 1; let inString = true; - let remaining = output.substr(1); + let remaining = output.substring(1); let escaped = false; while (inString) { if (escaped) @@ -176,16 +181,16 @@ export function parseMI(output: string): MINode { else if (remaining[0] == '"') inString = false; - remaining = remaining.substr(1); + remaining = remaining.substring(1); stringEnd++; } let str; try { - str = parseString(output.substr(0, stringEnd)); + str = parseString(output.substring(0, stringEnd)); } catch (e) { - str = output.substr(0, stringEnd); + str = output.substring(0, stringEnd); } - output = output.substr(stringEnd); + output = output.substring(stringEnd); return str; }; @@ -196,9 +201,9 @@ export function parseMI(output: string): MINode { return undefined; const oldContent = output; const canBeValueList = output[0] == '['; - output = output.substr(1); + output = output.substring(1); if (output[0] == '}' || output[0] == ']') { - output = output.substr(1); // ] or } + output = output.substring(1); // ] or } return []; } if (canBeValueList) { @@ -209,7 +214,7 @@ export function parseMI(output: string): MINode { const remaining = output; while ((value = parseCommaValue()) !== undefined) values.push(value); - output = output.substr(1); // ] + output = output.substring(1); // ] return values; } } @@ -219,7 +224,7 @@ export function parseMI(output: string): MINode { results.push(result); while (result = parseCommaResult()) results.push(result); - output = output.substr(1); // } + output = output.substring(1); // } return results; } output = (canBeValueList ? '[' : '{') + output; @@ -239,7 +244,7 @@ export function parseMI(output: string): MINode { const variableMatch = variableRegex.exec(output); if (!variableMatch) return undefined; - output = output.substr(variableMatch[0].length + 1); + output = output.substring(variableMatch[0].length + 1); const variable = variableMatch[1]; return [variable, parseValue()]; }; @@ -247,28 +252,28 @@ export function parseMI(output: string): MINode { parseCommaValue = () => { if (output[0] != ',') return undefined; - output = output.substr(1); + output = output.substring(1); return parseValue(); }; parseCommaResult = () => { if (output[0] != ',') return undefined; - output = output.substr(1); + output = output.substring(1); return parseResult(); }; let match = undefined; while (match = outOfBandRecordRegex.exec(output)) { - output = output.substr(match[0].length); + output = output.substring(match[0].length); if (match[1] && token === undefined && match[1] !== "undefined") { token = parseInt(match[1]); } if (match[2]) { const classMatch = asyncClassRegex.exec(output); - output = output.substr(classMatch[1].length); + output = output.substring(classMatch[1].length); const asyncRecord = { isStream: false, type: asyncRecordType[match[2]], @@ -292,7 +297,7 @@ export function parseMI(output: string): MINode { } if (match = resultRecordRegex.exec(output)) { - output = output.substr(match[0].length); + output = output.substring(match[0].length); if (match[1] && token === undefined) { token = parseInt(match[1]); } diff --git a/src/settings.ts b/src/settings.ts index ab4cd08..d2bcfdb 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,14 +1,27 @@ import * as vscode from 'vscode'; +type InspectResult = { + key: string; + defaultValue?: T; + globalValue?: T; + workspaceValue?: T; + workspaceFolderValue?: T; + defaultLanguageValue?: T; + globalLanguageValue?: T; + workspaceLanguageValue?: T; + workspaceFolderLanguageValue?: T; + languageIds?: string[]; +} | undefined + export class DebuggerSettings { private readonly extensionSettings: vscode.WorkspaceConfiguration; constructor() { - this.extensionSettings = vscode.workspace.getConfiguration("Cobol_Debugger"); + this.extensionSettings = vscode.workspace.getConfiguration("superbol_debugger"); } private getWithFallback(settings: vscode.WorkspaceConfiguration, section: string): T { - const info: any = settings.inspect(section); + const info: InspectResult = settings.inspect(section); if (info.workspaceFolderValue !== undefined) { return info.workspaceFolderValue; } else if (info.workspaceValue !== undefined) { diff --git a/tsconfig.json b/tsconfig.json index eaf29ab..0bc5e51 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,14 @@ { "compilerOptions": { "module": "commonjs", - "target": "es6", + "target": "es2020", "outDir": "out", - "lib": [ - "es6" - ], "sourceMap": true, "rootDir": ".", - "plugins": [ - { - "name": "tslint-language-service" - } - ] }, + "include": ["src"], "exclude": [ "node_modules", ".vscode-test" ] -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..abc796a --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1252 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + +"@eslint/eslintrc@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" + integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.5.2" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.43.0": + version "8.43.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0" + integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@types/json-schema@^7.0.9": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/mocha@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" + integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== + +"@types/node@^20.3.2": + version "20.3.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.2.tgz#fa6a90f2600e052a03c18b8cb3fd83dd4e599898" + integrity sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw== + +"@types/semver@^7.3.12": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@types/vscode@^1.44.0": + version "1.79.1" + resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.79.1.tgz#ab568315f9c844a8f4fa8f168b2d6dbf1f58dd02" + integrity sha512-Ikwc4YbHABzqthrWfeAvItaAIfX9mdjMWxqNgTpGjhgOu0TMRq9LzyZ2yBK0JhYqoSjEubEPawf6zJgnl6Egtw== + +"@typescript-eslint/eslint-plugin@^5.60.1": + version "5.60.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz#81382d6ecb92b8dda70e91f9035611cb2fecd1c3" + integrity sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.60.1" + "@typescript-eslint/type-utils" "5.60.1" + "@typescript-eslint/utils" "5.60.1" + debug "^4.3.4" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.60.1": + version "5.60.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.60.1.tgz#0f2f58209c0862a73e3d5a56099abfdfa21d0fd3" + integrity sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q== + dependencies: + "@typescript-eslint/scope-manager" "5.60.1" + "@typescript-eslint/types" "5.60.1" + "@typescript-eslint/typescript-estree" "5.60.1" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.60.1": + version "5.60.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz#35abdb47f500c68c08f2f2b4f22c7c79472854bb" + integrity sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ== + dependencies: + "@typescript-eslint/types" "5.60.1" + "@typescript-eslint/visitor-keys" "5.60.1" + +"@typescript-eslint/type-utils@5.60.1": + version "5.60.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz#17770540e98d65ab4730c7aac618003f702893f4" + integrity sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A== + dependencies: + "@typescript-eslint/typescript-estree" "5.60.1" + "@typescript-eslint/utils" "5.60.1" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.60.1": + version "5.60.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.60.1.tgz#a17473910f6b8d388ea83c9d7051af89c4eb7561" + integrity sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg== + +"@typescript-eslint/typescript-estree@5.60.1": + version "5.60.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz#8c71824b7165b64d5ebd7aa42968899525959834" + integrity sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw== + dependencies: + "@typescript-eslint/types" "5.60.1" + "@typescript-eslint/visitor-keys" "5.60.1" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.60.1": + version "5.60.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.60.1.tgz#6861ebedbefba1ac85482d2bdef6f2ff1eb65b80" + integrity sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.60.1" + "@typescript-eslint/types" "5.60.1" + "@typescript-eslint/typescript-estree" "5.60.1" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/visitor-keys@5.60.1": + version "5.60.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz#19a877358bf96318ec35d90bfe6bd1445cce9434" + integrity sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw== + dependencies: + "@typescript-eslint/types" "5.60.1" + eslint-visitor-keys "^3.3.0" + +"@vscode/debugadapter@^1.40.0": + version "1.61.0" + resolved "https://registry.yarnpkg.com/@vscode/debugadapter/-/debugadapter-1.61.0.tgz#5e40595ee2e699b5fd447f3ea3c961a8e8573bc3" + integrity sha512-VDGLUFDVAdnftUebZe4uQCIFUbJ7rTc2Grps4D/CXl+qyzTZSQLv5VADEOZ6kBYG4SvlnMLql5vPQ0G6XvUCvQ== + dependencies: + "@vscode/debugprotocol" "1.61.0" + +"@vscode/debugprotocol@1.61.0", "@vscode/debugprotocol@^1.40.0": + version "1.61.0" + resolved "https://registry.yarnpkg.com/@vscode/debugprotocol/-/debugprotocol-1.61.0.tgz#82bbcaba5a925f1f58246c9f50b669855c9f23f9" + integrity sha512-K/kF27jIStVFqlmUaGc2u+Dj8IR7YdEiSqShWr7MWhDudqpAW7uu7XMwoFwjpuC9LSaVwJMIX7EFC5OJ/RmnDQ== + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.8.0: + version "8.9.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" + integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +core_d@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/core_d/-/core_d-5.0.1.tgz#695c9c9baa483d7321db47a452887738048a1822" + integrity sha512-37lZyhJY1hzgFbfU4LzY4zL09QPwPfV2W/3YBOtN7mkdvVaeP1OVnDZI6zxggtlPwG/BuE5wIr0xptlVJk5EPA== + dependencies: + supports-color "^8.1.0" + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + +eslint@^8.12.0, eslint@^8.43.0: + version "8.43.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.43.0.tgz#3e8c6066a57097adfd9d390b8fc93075f257a094" + integrity sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.3" + "@eslint/js" "8.43.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.5.2" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + +eslint_d@^12.2.1: + version "12.2.1" + resolved "https://registry.yarnpkg.com/eslint_d/-/eslint_d-12.2.1.tgz#e5faf55acdc74d0e6e4f13ade464421f1f8e4152" + integrity sha512-qOJ9cTi5AaH5bOgEoCkv41DJ637mHgzffbOLojwU4wadwC6qbR+OxVJRvVzH0v2XYmQOvw4eiJK7ivrr5SvzsA== + dependencies: + core_d "^5.0.1" + eslint "^8.12.0" + nanolru "^1.0.0" + optionator "^0.9.1" + +espree@^9.5.2: + version "9.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" + integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@5.0.0, find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mocha@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +n-readlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/n-readlines/-/n-readlines-1.0.1.tgz#bbb7364d38bc31a170a199f986fcacfa76b95f6e" + integrity sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +nanolru@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nanolru/-/nanolru-1.0.0.tgz#0a5679cd4e4578c4ca3741e610b71c4c9b5afaf8" + integrity sha512-GyQkE8M32pULhQk7Sko5raoIbPalAk90ICG+An4fq6fCsFHsP6fB2K46WGXVdoJpy4SGMnZ/EKbo123fZJomWg== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.1: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +semver@^7.3.7: + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1, supports-color@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typescript@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +vscode-debugadapter-testsupport@^1.40.3: + version "1.51.0" + resolved "https://registry.yarnpkg.com/vscode-debugadapter-testsupport/-/vscode-debugadapter-testsupport-1.51.0.tgz#d60c4d9e2b70d094d9449abffdf3745898e698a4" + integrity sha512-rb8tfn7J3kxLi1rRhEyG5ggGkFcJH2WrYYrq6Vb1tDAcHoFXF580M1dAA2jPOrc0I14GuWxMnndvfGkfG10VxA== + dependencies: + vscode-debugprotocol "1.51.0" + +vscode-debugprotocol@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.51.0.tgz#c03168dac778b6c24ce17b3511cb61e89c11b2df" + integrity sha512-dzKWTMMyebIMPF1VYMuuQj7gGFq7guR8AFya0mKacu+ayptJfaRuM0mdHCqiOth4FnRP8mPhEroFPx6Ift8wHA== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 351f4f694981b40f446ec226bc3b21eef646afa7 Mon Sep 17 00:00:00 2001 From: David Declerck Date: Thu, 23 Nov 2023 16:39:48 +0100 Subject: [PATCH 02/70] Some improvements --- package.json | 130 +++++++++++++++++++++++++---------------------- src/extension.ts | 79 +++++++++++++++++++--------- src/settings.ts | 25 ++++----- 3 files changed, 135 insertions(+), 99 deletions(-) diff --git a/package.json b/package.json index 760fa55..a947d87 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superbol-vscode-debug", - "displayName": "Superbol debugger", + "displayName": "SuperBOL Debugger for GnuCOBOL", "description": "Debug or execute COBOL code. No mainframe required.", "keywords": [ "cobol", @@ -11,16 +11,16 @@ ], "version": "2.31.37", "publisher": "OCamlPro SAS", - "contributors": [ - { - "name": "Emilien Lemaire", - "email": "emilien.lemaire@ocamlpro.com" - }, - { - "name": "Olegs Kunicins", - "email": "olegs.kunicins@gmail.com" - } - ], + "contributors": [ + { + "name": "Emilien Lemaire", + "email": "emilien.lemaire@ocamlpro.com" + }, + { + "name": "Olegs Kunicins", + "email": "olegs.kunicins@gmail.com" + } + ], "license": "GPL-3.0", "icon": "icon.png", "engines": { @@ -28,7 +28,8 @@ }, "main": "./out/src/extension", "activationEvents": [ - "onDebugResolve" + "onDebugResolve", + "onDebugInitialConfigurations" ], "categories": [ "Debuggers" @@ -54,7 +55,7 @@ "languages": ["cobol", "COBOL"], "program": "./out/src/gdb.js", "runtime": "node", - "label": "COBOL debugger", + "label": "SuperBOL Debugger for GnuCOBOL", "configurationAttributes": { "launch": { "required": [], @@ -84,13 +85,15 @@ "description": "Path to cobc", "default": "cobc" }, + "libcobpath": { + "type": "string", + "description": "Path to libcob", + "default": null + }, "cobcargs": { "type": "array", "description": "Extra arguments for cobc", - "default": [ - "-free", - "-x" - ] + "default": ["-free", "-x"] }, "group": { "type": "array", @@ -142,13 +145,15 @@ "description": "Path to cobc", "default": "cobc" }, + "libcobpath": { + "type": "string", + "description": "Path to libcob", + "default": null + }, "cobcargs": { "type": "array", "description": "Extra arguments for cobc", - "default": [ - "-free", - "-x" - ] + "default": ["-free", "-x"] }, "group": { "type": "array", @@ -178,82 +183,83 @@ } } }, - "initialConfigurations": [ - { - "name": "Superbol debugger", - "type": "gdb", - "request": "launch", - "cobcargs": [ - "-free", - "-x" - ], - "coverage": true - } - ], "configurationSnippets": [ { - "label": "Superbol: debug launch", - "description": "New Superbol launch request", + "label": "SuperBOL: debug launch", + "description": "New SuperBOL launch request", "body": { + "name": "${2:SuperBOL: debug launch}", "type": "gdb", "request": "launch", - "name": "${2: Superbol debugger}" + "target": "$${_:{file}}", + "arguments": "", + "cwd": "$${_:{workspaceRoot}}", + "group": [], + "cobcargs": ["-free", "-x"], + "coverage": true, + "verbose": false } }, { - "label": "Superbol: debug attach local", - "description": "New Superbol attach local request", + "label": "SuperBOL: debug attach local", + "description": "New SuperBOL attach local request", "body": { + "name": "${2:SuperBOL: debug attach local}", "type": "gdb", "request": "attach", - "name": "${2: Superbol debugger}", - "pid": "${3:0}" + "pid": "${3:0}", + "target": "$${_:{file}}", + "arguments": "", + "cwd": "$${_:{workspaceRoot}}", + "group": [], + "cobcargs": ["-free", "-x"], + "verbose": false } }, { - "label": "Superbol: debug attach remote", - "description": "New Superbol attach remote request", + "label": "SuperBOL: debug attach remote", + "description": "New SuperBOL attach remote request", "body": { + "name": "${2:SuperBOL: debug attach remote}", "type": "gdb", "request": "attach", - "name": "${2: Superbol debugger}", - "remoteDebugger": "${3:host:port}" + "remoteDebugger": "${3:host:port}", + "target": "$${_:{file}}", + "arguments": "", + "cwd": "$${_:{workspaceRoot}}", + "group": [], + "cobcargs": ["-free", "-x"], + "verbose": false } } ] } ], "configuration": { - "title": "Superbol Debugger", + "title": "SuperBOL Debugger", "properties": { - "superbol_debugger.display_variable_attributes": { + "superbol-vscode-debug.displayVariableAttributes": { "type": "boolean", "default": false, - "description": "Displaying Data Storages and Fields attributes(e.g. size of Alphanumerics or digits and scale of numerics).", + "description": "Displaying Data Storages and Fields attributes (e.g. size of Alphanumerics or digits and scale of numerics).", "scope": "resource" }, - "superbol_debugger.cwd": { - "type": "string", - "default": "${workspaceRoot}", - "description": "Path to project", - "scope": "application" - }, - "superbol_debugger.target": { + "superbol-vscode-debug.pathToGDB": { "type": "string", - "description": "Path to source code", - "default": "${file}", + "description": "Path to the `gdb` command", + "default": "gdb", "scope": "application" }, - "superbol_debugger.gdbpath": { + "superbol-vscode-debug.pathToCobc": { "type": "string", - "description": "Path to gdb", - "default": "gdb", + "description": "Path to the `cobc` command", + "default": "/usr/local/gnucobol/bin/cobc", "scope": "application" }, - "superbol_debugger.cobcpath": { + "superbol-vscode-debug.pathToLibCob": { "type": "string", - "description": "Path to cobc", - "default": "cobc", + "description": "Path to the folder containing `libcob`", + "default": "/usr/local/gnucobol/lib", "scope": "application" } } diff --git a/src/extension.ts b/src/extension.ts index 1042d2a..a1286df 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -20,26 +20,49 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { _token?: vscode.CancellationToken): vscode.ProviderResult { - config.gdbargs = ["-q", "--interpreter=mi2"]; const settings = new DebuggerSettings(); - if (config.cwd === undefined) { - config.cwd = settings.cwd; + if (config.name === undefined) { + config.name = "SuperBOL: default debug"; } - if (config.target === undefined) { - config.target = settings.target; + if (config.type === undefined) { + config.type = "gdb"; } - if (config.group === undefined) { - config.group = []; + if (config.request === undefined) { + config.request = "launch"; + } + if (config.target === undefined) { + config.target = "${file}"; } if (config.arguments === undefined) { config.arguments = ""; } + if (config.cwd === undefined) { + config.cwd = "${workspaceRoot}"; + } + if (config.group === undefined) { + config.group = []; + } if (config.gdbpath === undefined) { config.gdbpath = settings.gdbpath; } if (config.cobcpath === undefined) { config.cobcpath = settings.cobcpath; } + if (config.cobcargs === undefined) { + config.cobcargs = ["-free", "-x"]; + } + if (config.libcobpath === undefined) { + config.libcobpath = settings.libcobpath; + } + if (config.env === undefined) { + config.env = { ["LD_LIBRARY_PATH"] : config.libcobpath }; + } else { + config.env.LD_LIBRARY_PATH = config.libcobpath + ";" + config.env.LD_LIBRARY_PATH; + } + if (config.coverage === undefined) { + config.coverage = true; + } + config.gdbargs = ["-q", "--interpreter=mi2"]; return config; } @@ -48,36 +71,42 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { _token?: vscode.CancellationToken): vscode.ProviderResult { const launchConfigDefault: vscode.DebugConfiguration = { - name: "Superbol debugger", + name: "SuperBOL: debug launch", type: "gdb", request: "launch", - cobcargs: [ - "-free", - "-x" - ], - coverage: true + target: "${file}", + arguments: "", + cwd: "${workspaceRoot}", + group: [], + cobcargs: ["-free", "-x"], + coverage: true, + verbose: false }; const attachLocalConfiguration: vscode.DebugConfiguration = { - name: "Superbol debugger attach local", + name: "SuperBOL: debug attach local", type: "gdb", request: "attach", - cobcargs: [ - "-free", - "-x" - ], - pid: "${input:pid}" + pid: "${input:pid}", + target: "${file}", + arguments: "", + cwd: "${workspaceRoot}", + group: [], + cobcargs: ["-free", "-x"], + verbose: false }; const attachRemoteConfiguration: vscode.DebugConfiguration = { - name: "Superbol debugger attach remote", + name: "SuperBOL: debug attach remote", type: "gdb", request: "attach", - cobcargs: [ - "-free", - "-x" - ], - remoteDebugger: "${input:remoteDebugger}" + remoteDebugger: "${input:remoteDebugger}", + target: "${file}", + arguments: "", + cwd: "${workspaceRoot}", + group: [], + cobcargs: ["-free", "-x"], + verbose: false } return [ diff --git a/src/settings.ts b/src/settings.ts index d2bcfdb..ca01fb0 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -15,9 +15,14 @@ type InspectResult = { export class DebuggerSettings { private readonly extensionSettings: vscode.WorkspaceConfiguration; + private readonly superbolExtensionSettings: vscode.WorkspaceConfiguration; constructor() { - this.extensionSettings = vscode.workspace.getConfiguration("superbol_debugger"); + this.extensionSettings = vscode.workspace.getConfiguration("superbol-vscode-debug"); + this.superbolExtensionSettings = vscode.workspace.getConfiguration("superbol"); + +console.log(this.getWithFallback(this.superbolExtensionSettings, "path")); + } private getWithFallback(settings: vscode.WorkspaceConfiguration, section: string): T { @@ -33,22 +38,18 @@ export class DebuggerSettings { } public get displayVariableAttributes(): boolean { - return this.getWithFallback(this.extensionSettings, "display_variable_attributes"); - } - - public get cwd(): string { - return this.getWithFallback(this.extensionSettings, "cwd"); - } - - public get target(): string { - return this.getWithFallback(this.extensionSettings, "target"); + return this.getWithFallback(this.extensionSettings, "displayVariableAttributes"); } public get gdbpath(): string { - return this.getWithFallback(this.extensionSettings, "gdbpath"); + return this.getWithFallback(this.extensionSettings, "pathToGDB"); } public get cobcpath(): string { - return this.getWithFallback(this.extensionSettings, "cobcpath"); + return this.getWithFallback(this.extensionSettings, "pathToCobc"); + } + + public get libcobpath(): string { + return this.getWithFallback(this.extensionSettings, "pathToLibCob"); } } From 33be1a04a6d25ceb43892ab08427595ea6fff784 Mon Sep 17 00:00:00 2001 From: David Declerck Date: Wed, 6 Dec 2023 16:14:03 +0100 Subject: [PATCH 03/70] Remove compilation from extenstion - should rely on preBuildTask --- package.json | 29 ------------------ src/extension.ts | 9 ------ src/gdb.ts | 8 ----- src/mi2.ts | 79 ++---------------------------------------------- src/parser.c.ts | 3 ++ src/settings.ts | 9 ++---- 6 files changed, 7 insertions(+), 130 deletions(-) diff --git a/package.json b/package.json index a947d87..d629a45 100644 --- a/package.json +++ b/package.json @@ -80,21 +80,11 @@ "description": "Path to gdb", "default": "gdb" }, - "cobcpath": { - "type": "string", - "description": "Path to cobc", - "default": "cobc" - }, "libcobpath": { "type": "string", "description": "Path to libcob", "default": null }, - "cobcargs": { - "type": "array", - "description": "Extra arguments for cobc", - "default": ["-free", "-x"] - }, "group": { "type": "array", "description": "Compilation Group for executable", @@ -140,21 +130,11 @@ "description": "Path to gdb", "default": "gdb" }, - "cobcpath": { - "type": "string", - "description": "Path to cobc", - "default": "cobc" - }, "libcobpath": { "type": "string", "description": "Path to libcob", "default": null }, - "cobcargs": { - "type": "array", - "description": "Extra arguments for cobc", - "default": ["-free", "-x"] - }, "group": { "type": "array", "description": "Compilation Group for executable", @@ -195,7 +175,6 @@ "arguments": "", "cwd": "$${_:{workspaceRoot}}", "group": [], - "cobcargs": ["-free", "-x"], "coverage": true, "verbose": false } @@ -212,7 +191,6 @@ "arguments": "", "cwd": "$${_:{workspaceRoot}}", "group": [], - "cobcargs": ["-free", "-x"], "verbose": false } }, @@ -228,7 +206,6 @@ "arguments": "", "cwd": "$${_:{workspaceRoot}}", "group": [], - "cobcargs": ["-free", "-x"], "verbose": false } } @@ -250,12 +227,6 @@ "default": "gdb", "scope": "application" }, - "superbol-vscode-debug.pathToCobc": { - "type": "string", - "description": "Path to the `cobc` command", - "default": "/usr/local/gnucobol/bin/cobc", - "scope": "application" - }, "superbol-vscode-debug.pathToLibCob": { "type": "string", "description": "Path to the folder containing `libcob`", diff --git a/src/extension.ts b/src/extension.ts index a1286df..c7f7dd9 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -45,12 +45,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.gdbpath === undefined) { config.gdbpath = settings.gdbpath; } - if (config.cobcpath === undefined) { - config.cobcpath = settings.cobcpath; - } - if (config.cobcargs === undefined) { - config.cobcargs = ["-free", "-x"]; - } if (config.libcobpath === undefined) { config.libcobpath = settings.libcobpath; } @@ -78,7 +72,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { arguments: "", cwd: "${workspaceRoot}", group: [], - cobcargs: ["-free", "-x"], coverage: true, verbose: false }; @@ -92,7 +85,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { arguments: "", cwd: "${workspaceRoot}", group: [], - cobcargs: ["-free", "-x"], verbose: false }; @@ -105,7 +97,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { arguments: "", cwd: "${workspaceRoot}", group: [], - cobcargs: ["-free", "-x"], verbose: false } diff --git a/src/gdb.ts b/src/gdb.ts index 27525ca..52fe4e9 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -33,8 +33,6 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum arguments: string; gdbpath: string; gdbargs: string[]; - cobcpath: string; - cobcargs: string[]; env: NodeJS.ProcessEnv; group: string[]; verbose: boolean; @@ -47,8 +45,6 @@ export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArgum arguments: string; gdbpath: string; gdbargs: string[]; - cobcpath: string; - cobcargs: string[]; env: NodeJS.ProcessEnv; group: string[]; verbose: boolean; @@ -96,8 +92,6 @@ export class GDBDebugSession extends DebugSession { new MI2( args.gdbpath, args.gdbargs, - args.cobcpath, - args.cobcargs, args.env, args.verbose, args.noDebug); @@ -159,8 +153,6 @@ export class GDBDebugSession extends DebugSession { this.miDebugger = new MI2( args.gdbpath, args.gdbargs, - args.cobcpath, - args.cobcargs, args.env, args.verbose, false); diff --git a/src/mi2.ts b/src/mi2.ts index a7f7745..ab812ae 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -37,8 +37,6 @@ export class MI2 extends EventEmitter implements IDebugger { constructor( public gdbpath: string, public gdbArgs: string[], - public cobcpath: string, - public cobcArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean | null) @@ -73,57 +71,6 @@ export class MI2 extends EventEmitter implements IDebugger { reject(new Error("cwd does not exist.")); } - if (this.noDebug) { - const args = (this.cobcArgs || []) - .concat([target]) - .concat(group) - .concat(['-job=' + targetargs]); - this.process = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); - this.process.stderr.on("data", ((data: string) => { - this.log("stderr", data); - })); - this.process.stdout.on("data", ((data: string) => { - this.log("stdout", data); - })); - this.process.on("exit", (() => { - this.emit("quit"); - })); - return; - } - - const args = (this.cobcArgs || []).concat([ - '-g', //enable debugger - '-fsource-location', //generate source location code - '-ftraceall', // generate trace code - '-Q', // (with `--coverage`): enable C linker coverage - '--coverage', - '-A', // (with `--coverage`): enable C compiler coverage - '--coverage', - '-v', // verbose mode - target - ]).concat(group); - const buildProcess = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); - buildProcess.stderr.on('data', (data: string) => { - if (this.verbose) - this.log("stderr", data); - let match: RegExpExecArray; - do { - match = gcovRegex.exec(data); - if (match) { - this.gcovFiles.add(match[1].split('.').slice(0, -1).join('.')); - } - } while (match); - }); - buildProcess.on('exit', (code) => { - if (code !== 0) { - this.emit("quit"); - return; - } - - if (this.verbose) { - this.log("stderr", `COBOL file ${target} compiled with exit code: ${code}`); - } - try { this.map = new SourceMap(cwd, [target].concat(group)); } catch (e) { @@ -157,7 +104,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.emit("debug-ready"); resolve(undefined); }, reject); - }); + }); } @@ -172,28 +119,6 @@ export class MI2 extends EventEmitter implements IDebugger { reject(new Error("cwd does not exist.")); } - const args = (this.cobcArgs || []).concat([ - '-g', - '-fsource-location', - '-ftraceall', - '-v', - target - ]).concat(group); - const buildProcess = ChildProcess.spawn(this.cobcpath, args, {cwd: cwd, env: this.procEnv}); - buildProcess.stderr.on('data', (data: string) => { - if (this.verbose) - this.log("stderr", data); - }); - buildProcess.on('exit', (code) => { - if (code !== 0) { - this.emit("quit"); - return; - } - - if (this.verbose) { - this.log("stderr", `COBOL file ${target} compiled with exit code: ${code}`); - } - try { this.map = new SourceMap(cwd, [target].concat(group)); } catch (e) { @@ -225,7 +150,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.emit("debug-ready"); resolve(undefined); }, reject); - }); + }); } diff --git a/src/parser.c.ts b/src/parser.c.ts index fdbf657..e37e316 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -203,6 +203,9 @@ export class SourceMap { if (!nativePath.isAbsolute(fileCobol)) { fileCobol = nativePath.join(this.cwd, fileCobol); } + if ((process.platform === "win32") && (/[a-z]:/.test(fileCobol))) { + fileCobol = fileCobol.charAt(0).toUpperCase() + fileCobol.slice(1); + } return this.lines.find(e => e.fileCobol === fileCobol && e.lineCobol === lineCobol) ?? new Line('', 0, '', 0); } diff --git a/src/settings.ts b/src/settings.ts index ca01fb0..d73217e 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -19,10 +19,9 @@ export class DebuggerSettings { constructor() { this.extensionSettings = vscode.workspace.getConfiguration("superbol-vscode-debug"); +// Get SuperBOL base extension settings (for instance to get LibCob path) +// Though shouls should be obtained by querying the extension instead ? this.superbolExtensionSettings = vscode.workspace.getConfiguration("superbol"); - -console.log(this.getWithFallback(this.superbolExtensionSettings, "path")); - } private getWithFallback(settings: vscode.WorkspaceConfiguration, section: string): T { @@ -45,10 +44,6 @@ console.log(this.getWithFallback(this.superbolExtensionSettings, "path") return this.getWithFallback(this.extensionSettings, "pathToGDB"); } - public get cobcpath(): string { - return this.getWithFallback(this.extensionSettings, "pathToCobc"); - } - public get libcobpath(): string { return this.getWithFallback(this.extensionSettings, "pathToLibCob"); } From 49c057dba8533ae72998155afb877c5d4acb631e Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 19 Dec 2023 13:57:27 +0100 Subject: [PATCH 04/70] Minor adaptations for integration into SuperBOL --- src/debugger.ts | 2 +- src/extension.ts | 17 +++++++++-------- src/gdb.ts | 21 ++++++++++++--------- src/mi2.ts | 2 +- src/settings.ts | 42 ++++++++---------------------------------- 5 files changed, 31 insertions(+), 53 deletions(-) diff --git a/src/debugger.ts b/src/debugger.ts index b62db68..5721bc1 100644 --- a/src/debugger.ts +++ b/src/debugger.ts @@ -1,5 +1,5 @@ import {MINode} from "./parser.mi2"; -import {DebugProtocol} from "vscode-debugprotocol/lib/debugProtocol"; +import {DebugProtocol} from "@vscode/debugprotocol"; import {removeLeadingZeroes} from "./functions"; import {SourceMap} from "./parser.c"; diff --git a/src/extension.ts b/src/extension.ts index c7f7dd9..6b1ff27 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -37,7 +37,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { config.arguments = ""; } if (config.cwd === undefined) { - config.cwd = "${workspaceRoot}"; + config.cwd = "${workspaceFolder}"; } if (config.group === undefined) { config.group = []; @@ -65,37 +65,38 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { _token?: vscode.CancellationToken): vscode.ProviderResult { const launchConfigDefault: vscode.DebugConfiguration = { - name: "SuperBOL: debug launch", + name: "SuperBOL: debug (launch)", type: "gdb", request: "launch", + preLaunchTask: "Superbol: build (debug)", target: "${file}", arguments: "", - cwd: "${workspaceRoot}", + cwd: "${workspaceFolder}", group: [], coverage: true, verbose: false }; const attachLocalConfiguration: vscode.DebugConfiguration = { - name: "SuperBOL: debug attach local", + name: "SuperBOL: debug (attach local)", type: "gdb", request: "attach", pid: "${input:pid}", target: "${file}", arguments: "", - cwd: "${workspaceRoot}", + cwd: "${workspaceFolder}", group: [], verbose: false }; const attachRemoteConfiguration: vscode.DebugConfiguration = { - name: "SuperBOL: debug attach remote", + name: "SuperBOL: debug (attach remote)", type: "gdb", request: "attach", - remoteDebugger: "${input:remoteDebugger}", + remoteDebugger: "${input:remote-debugger}", target: "${file}", arguments: "", - cwd: "${workspaceRoot}", + cwd: "${workspaceFolder}", group: [], verbose: false } diff --git a/src/gdb.ts b/src/gdb.ts index 52fe4e9..8c4376c 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -12,7 +12,7 @@ import { Thread, ThreadEvent } from '@vscode/debugadapter'; -import { DebugProtocol } from 'vscode-debugprotocol'; +import { DebugProtocol } from '@vscode/debugprotocol'; import { Breakpoint, VariableObject } from './debugger'; import { MINode } from './parser.mi2'; import { MI2 } from './mi2'; @@ -125,11 +125,13 @@ export class GDBDebugSession extends DebugSession { this.handlePause(undefined); }, (err: Error) => { - this.sendErrorResponse(response, 100, `Failed to start MI Debugger: ${err.toString()}`); + this.sendErrorResponse(response, 100, + `Failed to start MI Debugger: ${err.toString()}`); }); }, /*onrejected:*/ (err: Error) => { - this.sendErrorResponse(response, 103, `Failed to load MI Debugger: ${err.toString()}`); + this.sendErrorResponse(response, 103, + `Failed to load MI Debugger: ${err.toString()}`); }); } @@ -139,10 +141,9 @@ export class GDBDebugSession extends DebugSession { void { if (!args.pid && !args.remoteDebugger) { - this.sendErrorResponse( - response, - 100, - `Failed to start MI Debugger: pid or remoteDebugger is mandatory`); + this.sendErrorResponse (response, 100, + `Failed to start MI Debugger: PID or remote-debugger argument + required`); return; } @@ -186,11 +187,13 @@ export class GDBDebugSession extends DebugSession { this.handlePause(undefined); }, (err: Error) => { - this.sendErrorResponse(response, 100, `Failed to start MI Debugger: ${err.toString()}`); + this.sendErrorResponse(response, 100, + `Failed to start MI Debugger: ${err.toString()}`); }); }, (err: Error) => { - this.sendErrorResponse(response, 103, `Failed to load MI Debugger: ${err.toString()}`); + this.sendErrorResponse(response, 103, + `Failed to load MI Debugger: ${err.toString()}`); }); } diff --git a/src/mi2.ts b/src/mi2.ts index ab812ae..b2fae46 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -163,7 +163,7 @@ export class MI2 extends EventEmitter implements IDebugger { } const cmds = [ - this.sendCommand("gdb-set target-async on", false), + this.sendCommand("gdb-set mi-async on", false), this.sendCommand("gdb-set print repeats 1000", false), this.sendCommand("gdb-set args " + targetargs, false), this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), diff --git a/src/settings.ts b/src/settings.ts index d73217e..7aaeb84 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,50 +1,24 @@ import * as vscode from 'vscode'; -type InspectResult = { - key: string; - defaultValue?: T; - globalValue?: T; - workspaceValue?: T; - workspaceFolderValue?: T; - defaultLanguageValue?: T; - globalLanguageValue?: T; - workspaceLanguageValue?: T; - workspaceFolderLanguageValue?: T; - languageIds?: string[]; -} | undefined - export class DebuggerSettings { - private readonly extensionSettings: vscode.WorkspaceConfiguration; - private readonly superbolExtensionSettings: vscode.WorkspaceConfiguration; + private readonly debugSettings: vscode.WorkspaceConfiguration; constructor() { - this.extensionSettings = vscode.workspace.getConfiguration("superbol-vscode-debug"); -// Get SuperBOL base extension settings (for instance to get LibCob path) -// Though shouls should be obtained by querying the extension instead ? - this.superbolExtensionSettings = vscode.workspace.getConfiguration("superbol"); - } - - private getWithFallback(settings: vscode.WorkspaceConfiguration, section: string): T { - const info: InspectResult = settings.inspect(section); - if (info.workspaceFolderValue !== undefined) { - return info.workspaceFolderValue; - } else if (info.workspaceValue !== undefined) { - return info.workspaceValue; - } else if (info.globalValue !== undefined) { - return info.globalValue; - } - return info.defaultValue; + this.debugSettings = + vscode.workspace.getConfiguration("superbol.debugger"); + //this.globalSettings = + // vscode.workspace.getConfiguration("superbol"); } public get displayVariableAttributes(): boolean { - return this.getWithFallback(this.extensionSettings, "displayVariableAttributes"); + return this.debugSettings.get ("display-variable-attributes"); } public get gdbpath(): string { - return this.getWithFallback(this.extensionSettings, "pathToGDB"); + return this.debugSettings.get ("gdb-path"); } public get libcobpath(): string { - return this.getWithFallback(this.extensionSettings, "pathToLibCob"); + return this.debugSettings.get ("libcob-path"); } } From 576a36ad20514331d7ba7457a6227dd02a01fb0c Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 20 Dec 2023 09:51:58 +0100 Subject: [PATCH 05/70] Fix warning about a call to namespace object --- src/parser.c.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser.c.ts b/src/parser.c.ts index e37e316..b69346c 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -1,4 +1,4 @@ -import * as readline from "n-readlines"; +import readline from "n-readlines"; import * as nativePathFromPath from "path"; import {DebuggerVariable, Attribute, VariableType} from "./debugger"; From a19b379babb23eff609454336447ab906166d4eb Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 20 Dec 2023 10:05:52 +0100 Subject: [PATCH 06/70] Change some fields to match the SuperBOL main extension --- src/extension.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 6b1ff27..57da0c6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -68,7 +68,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { name: "SuperBOL: debug (launch)", type: "gdb", request: "launch", - preLaunchTask: "Superbol: build (debug)", + preLaunchTask: "SuperBOL: build (debug)", target: "${file}", arguments: "", cwd: "${workspaceFolder}", @@ -93,7 +93,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { name: "SuperBOL: debug (attach remote)", type: "gdb", request: "attach", - remoteDebugger: "${input:remote-debugger}", + "remote-debugger": "${input:remote-debugger}", target: "${file}", arguments: "", cwd: "${workspaceFolder}", From dd2a466a9e396012aa32dfb59200cba40084a510 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 8 Apr 2024 13:54:51 +0200 Subject: [PATCH 07/70] Fix default config resolver This aligns the code of `extension.GdbConfigurationProvider.resolveDebugConfiguration` with `extension.GdbConfigurationProvider.provideDebugConfigurations`, so that the debugger can be launched directly in workspaces that lack a `launch.json`. --- src/extension.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/extension.ts b/src/extension.ts index 047b836..586158a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -38,6 +38,9 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.request === undefined) { config.request = "launch"; } + if (config.preLaunchTask === undefined) { + config.preLaunchTask = "SuperBOL: build (debug)"; + } if (config.target === undefined) { config.target = "${file}"; } From ba251cfae08d9af87ce7a8689b311ea6c480ce59 Mon Sep 17 00:00:00 2001 From: marcsosduma <31162117+marcsosduma@users.noreply.github.com> Date: Tue, 9 Apr 2024 11:16:12 +0200 Subject: [PATCH 08/70] Add support for several terminal emulator programs --- README.md | 10 +---- package.json | 4 ++ src/mi2.ts | 121 ++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 111 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 242fcba..cec5ffa 100644 --- a/README.md +++ b/README.md @@ -156,13 +156,6 @@ Add `gdbtty` property to your `launch.json`. Here’s an example: ``` ![GdbTTY](gdbttydisplay.png) -* Linux Requirements: `xterm` - -How to install xterm on Ubuntu: -``` -sudo apt-get install xterm -``` - On Linux you can see the output of the application in Vs Code itself. Add `gdbtty` property with `vscode` value to your `launch.json`. Here is an example: ```json { @@ -179,8 +172,9 @@ On Linux you can see the output of the application in Vs Code itself. Add `gdbtt ``` ![GdbTTY](gdbttyvscode.png) -### Documentation +You can also use these options with `gdbtty`: `xterm`, `gnome-terminal`, `konsole` and `xfce4-terminal`. +### Documentation For a more in depth documentation please check the [Superbol Documentation](https://ocamlpro.com/superbol/) ### Troubleshooting diff --git a/package.json b/package.json index e437aeb..365d467 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,10 @@ true, false, "vscode", + "xterm", + "gnome-terminal", + "xfce4-terminal", + "konsole", "external" ] } diff --git a/src/mi2.ts b/src/mi2.ts index c37f6a1..57d5eeb 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -943,7 +943,7 @@ export class MI2 extends EventEmitter implements IDebugger { try_find++; if (xterm_device != "") break; } - if (xterm_device === "") this.log("stderr", "tty: Install 'xterm' to use gdb's tty option\n"); + if (xterm_device === "") this.log("stderr", "tty: Install a terminal to use gdb's tty option\n"); } if (xterm_device.includes("pts")) { this.gdbArgs.push("--tty=" + xterm_device); @@ -991,24 +991,113 @@ export class MI2 extends EventEmitter implements IDebugger { return strCode; } + isTerminalInstalled(terminalCommand: string): boolean { + try { + ChildProcess.execSync(`command -v ${terminalCommand}`); + return true; + } catch (error) { + return false; + } + } + + createXFCETerminal(sleepVal, target) { + let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; + let param = "bash -c 'echo \"GnuCOBOL DEBUG\"; sleep " + sleepVal + ";'"; + const xfce4_terminal_args = [ + "--title", "GnuCOBOL Debug - " + dispTarget, + "--font=DejaVu Sans Mono 14", + "--command", param + ] + const xfce_process = ChildProcess.spawn("xfce4-terminal", xfce4_terminal_args, { + detached: true, + stdio: 'ignore' + }); + xfce_process.unref(); + } + + createKDETerminal(sleepVal, target) { + let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; + let param = "bash -c 'echo \"GnuCOBOL DEBUG\"; sleep " + sleepVal + ";'"; + const konsole_args = [ + "--title", "GnuCOBOL Debug - " + dispTarget, + "--separate", + "--nofork", + "--hold", + "-e", + param + ] + const kde_process = ChildProcess.spawn("konsole", konsole_args, { + detached: true, + stdio: 'ignore' + }); + kde_process.unref(); + } + + createGNOMETerminal(sleepVal, target) { + let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; + const gnome_terminal_args = [ + "--title", "GnuCOBOL Debug - " + dispTarget, + "--", + "bash", "-c","echo 'GnuCOBOL DEBUG';" + "sleep " + sleepVal + ";" + ] + const gnome_process = ChildProcess.spawn("gnome-terminal", gnome_terminal_args, { + detached: true, + stdio: 'ignore', + }); + gnome_process.unref(); + } + + createXtermTerminal(sleepVal, target) { + let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; + const xterm_args = [ + "-title", "GnuCOBOL Debug - " + dispTarget, + "-fa", "DejaVu Sans Mono", + "-fs", "14", + "-e", "/usr/bin/tty;" + + "echo 'GnuCOBOL DEBUG';" + + "sleep " + sleepVal + ";" + ] + const xterm_process = ChildProcess.spawn("xterm", xterm_args, { + detached: true, + stdio: 'ignore', + }); + xterm_process.unref(); + } + // Opens a terminal to show the application screen - gdbtty createTerminal(gdbtty, sleepVal, target) { + let findTerminal = true; if (gdbtty != "vscode") { - let dispTarget = (target.length > 50) ? "..." + target.substr(target.length - 50, target.length) : target; - const xterm_args = [ - "-title", "GnuCOBOL Debug - " + dispTarget, - "-fa", "DejaVu Sans Mono", - "-fs", "14", - "-e", "/usr/bin/tty;" + - "echo 'GnuCOBOL DEBUG';" + - "sleep " + sleepVal + ";" - ] - - const xterm_process = ChildProcess.spawn("xterm", xterm_args, { - detached: true, - stdio: 'ignore', - }); - xterm_process.unref(); + if (typeof gdbtty === 'string' && gdbtty!="external") { + if(this.isTerminalInstalled(gdbtty)){ + findTerminal = false; + switch (gdbtty) { + case "xterm": + this.createXtermTerminal(sleepVal, target); + break; + case "gnome-terminal": + this.createGNOMETerminal(sleepVal, target); + break; + case "konsole": + this.createKDETerminal(sleepVal, target); + break; + case "xfce4-terminal": + this.createXFCETerminal(sleepVal, target); + break; + } + } + } + if(findTerminal){ + if(this.isTerminalInstalled("xterm")){ + this.createXtermTerminal(sleepVal, target); + }else if(this.isTerminalInstalled("gnome-terminal")){ + this.createGNOMETerminal(sleepVal, target); + }else if(this.isTerminalInstalled("xfce4-terminal")){ + this.createXFCETerminal(sleepVal, target); + }else if(this.isTerminalInstalled("konsole")){ + this.createKDETerminal(sleepVal, target); + } + } } else { let terminal = this.selectTerminal(); if (!terminal) { From b6180e11955c2906be9b07ea0812b340d9511253 Mon Sep 17 00:00:00 2001 From: marcsosduma <31162117+marcsosduma@users.noreply.github.com> Date: Tue, 9 Apr 2024 11:19:15 +0200 Subject: [PATCH 09/70] Correction of BUG in subroutine parser --- src/parser.c.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/parser.c.ts b/src/parser.c.ts index 52279aa..9954933 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -31,6 +31,7 @@ const versionRegex = /\/\*\sGenerated by\s+cobc\s([0-9a-z\-\.]+)\s+\*\//i; const subroutineRegex = /\sPerform\s/i; const frame_ptrFindRegex = /frame\_ptr\-\-\;/; const fixOlderFormat = /cob\_trace\_stmt/; +const programExit = /\/\*\sProgram\s\exit\s+\*\//i; globalThis.varOccurs = []; @@ -75,6 +76,8 @@ export class SourceMap { private parse(fileC: string): void { let nat = fileC; + let hasProgramExit = false; + if (!nativePath.isAbsolute(fileC)) { nat = nativePathFromPath.resolve(this.cwd, fileC); fileC = nativePath.resolve(this.cwd, fileC); @@ -116,9 +119,9 @@ export class SourceMap { } // fix new codegen match = procedureFixRegex.exec(line); - if (match && this.lines.length > 0) { + if (match && this.lines.length > 0 && !hasProgramExit) { let isOldFormat = fixOlderFormat.exec(this.lineBefore); - if(this.isVersion2_2_or_3_1_1 || !isOldFormat){ // Is it in the old format? + if(fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? let line = this.lines.pop(); line.lineC = parseInt(match[1]); this.lines.push(line); @@ -173,6 +176,10 @@ export class SourceMap { } } this.lineBefore = line; + match = programExit.exec(line); + if (match) { + hasProgramExit=true;; + } lineNumber++; } } From ac6e7d43be647590d911ae3c93ec0899aecfc95e Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 9 Apr 2024 11:46:14 +0200 Subject: [PATCH 10/70] Fix some links in the README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cec5ffa..a930da9 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ An extension to debug or execute GnuCOBOL code. Forked from [COBOL Degub](https: ![Screenshot](screenshot.png) ### Requirements -This extension is meant to work with our COBOL language extension [Superbol VSCode](https://github.com/OCamlPro/superbol-vscode-platform). +This extension is meant to work in combination with the [SuperBOL Studio](https://github.com/OCamlPro/superbol-vscode-platform) extension for COBOL. #### Binaries * GnuCOBOL `cobc` 3.1+ installed. @@ -175,7 +175,7 @@ On Linux you can see the output of the application in Vs Code itself. Add `gdbtt You can also use these options with `gdbtty`: `xterm`, `gnome-terminal`, `konsole` and `xfce4-terminal`. ### Documentation -For a more in depth documentation please check the [Superbol Documentation](https://ocamlpro.com/superbol/) +For a more in depth documentation please check the [SuperBOL Documentation](https://get-superbol.com/studio/) ### Troubleshooting Add `verbose` property to your `launch.json` and start debugging session. In `DEBUG CONSOLE` you will see complete communication log between `gdb` and VS Code. Here's an example: From 3e61d84f4f6972395ede9fb6573c6ee87dfaf0e4 Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Fri, 3 May 2024 11:09:22 +0200 Subject: [PATCH 11/70] Auto-update coverage highlighting (#7) * Restore gcovFiles retrieval * Fix coverage disabling * Remove formatting changes --- src/coverage.ts | 10 ++++++++++ src/gdb.ts | 11 ++++++----- src/mi2.ts | 2 ++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/coverage.ts b/src/coverage.ts index a12305a..251c05f 100644 --- a/src/coverage.ts +++ b/src/coverage.ts @@ -56,6 +56,7 @@ export class CoverageStatus implements Disposable { } public async show(cFiles: string[], sourceMap: SourceMap) { + this.highlight = true; this.coverages = await loadGcovData(cFiles); this.sourceMap = sourceMap; this.updateStatus(); @@ -65,6 +66,15 @@ export class CoverageStatus implements Disposable { this.statusBar.dispose(); } + public setHighlight(highlighted: boolean) { + this.highlight = highlighted; + } + + public hide() { + this.highlight = false; + this.updateStatus(); + } + private updateStatus() { const editor = window.activeTextEditor; if (editor === undefined) { diff --git a/src/gdb.ts b/src/gdb.ts index d46e13b..e3d7512 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -67,6 +67,7 @@ export class GDBDebugSession extends DebugSession { coverageStatus: CoverageStatus; private showVariableDetails: boolean; private settings = new DebuggerSettings(); + private showCoverage: boolean = true; protected initializeRequest(response: DebugProtocol.InitializeResponse, _args: DebugProtocol.InitializeRequestArguments): void { response.body.supportsSetVariable = true; @@ -74,9 +75,7 @@ export class GDBDebugSession extends DebugSession { } protected launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments): void { - if (!args.coverage) { - this.coverageStatus = undefined; - } + this.showCoverage = args.coverage; this.started = false; this.attached = false; @@ -124,7 +123,7 @@ export class GDBDebugSession extends DebugSession { return; } - this.coverageStatus = undefined; + this.showCoverage = false; this.attached = true; this.started = false; @@ -212,8 +211,10 @@ export class GDBDebugSession extends DebugSession { if (this.quit) return; - if (this.coverageStatus !== undefined) { + if (this.showCoverage) { this.coverageStatus.show(this.miDebugger.getGcovFiles(), this.miDebugger.getSourceMap()).catch((err: Error) => console.log(err)); + } else { + this.coverageStatus.hide(); } this.quit = true; diff --git a/src/mi2.ts b/src/mi2.ts index 57d5eeb..e985692 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -70,6 +70,8 @@ export class MI2 extends EventEmitter implements IDebugger { reject(new Error("cwd does not exist.")); } + let target_no_ext = target.split('.').slice(0, -1).join('.'); + this.gcovFiles.add(target_no_ext); try { this.map = new SourceMap(cwd, [target].concat(group)); } catch (e) { From 07ab8b419e2e660216de3c85c6c2ce3b1f442353 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 26 Jul 2024 12:21:46 +0200 Subject: [PATCH 12/70] Make the `preLaunchTask` optional in launch configuration --- src/extension.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 586158a..f9d8796 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -38,9 +38,12 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.request === undefined) { config.request = "launch"; } - if (config.preLaunchTask === undefined) { - config.preLaunchTask = "SuperBOL: build (debug)"; - } + if (config.preLaunchTask === undefined) { + config.preLaunchTask = "SuperBOL: build (debug)"; + } else if (config.preLaunchTask === "none" || + config.preLaunchTask === "") { + delete config.preLaunchTask; + } if (config.target === undefined) { config.target = "${file}"; } From d203ea1be727e9c32fea0861d9f3a89d94cb09a5 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 26 Jul 2024 12:22:40 +0200 Subject: [PATCH 13/70] Proper disposal of the debug adapter factory --- src/extension.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index f9d8796..b5a2b5f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -10,15 +10,18 @@ const MAX_COLUMN_INDEX = 300; const COBOL_RESERVED_WORDS = ["perform", "move", "to", "set", "add", "subtract", "call", "inquire", "modify", "invoke", "if", "not", "end-if", "until", "varying", "evaluate", "true", "when", "false", "go", "thru", "zeros", "spaces", "zero", "space", "inspect", "tallying", "exit", "paragraph", "method", "cycle", "from", "by", "and", "or", "of", "length", "function", "program", "synchronized", "end-synchronized", "string", "end-string", "on", "reference", "value", "returning", "giving", "replacing", "goback", "all", "open", "i-o", "input", "output", "close", "compute", "unstring", "using", "delete", "start", "read", "write", "rewrite", "with", "lock", "else", "upper-case", "lower-case", "display", "accept", "at", "clear-screen", "initialize", "line", "col", "key", "is", "self", "null", "stop", "run", "upon", "environment-name", "environment-value"] export function activate(context: vscode.ExtensionContext) { + const provider = new GdbConfigurationProvider(); + const factory = new GdbAdapterDescriptorFactory(new CoverageStatus(), new GDBDebugSession()); context.subscriptions.push( - vscode.debug.registerDebugConfigurationProvider('gdb', new GdbConfigurationProvider()), - vscode.debug.registerDebugAdapterDescriptorFactory('gdb', new GdbAdapterDescriptorFactory(new CoverageStatus(), new GDBDebugSession())), + vscode.debug.registerDebugConfigurationProvider('gdb', provider), + vscode.debug.registerDebugAdapterDescriptorFactory('gdb', factory, vscode.DebugConfigurationProviderTriggerKind.Dynamic), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL31', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL3.1', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL32', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL3.2', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('COBOL', new GnuCOBOLEvalExpressionFactory()), + factory, ); } From 2fec4e8c13ad1c44b163ab2822fa8da5d3ea9005 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 26 Jul 2024 15:44:47 +0200 Subject: [PATCH 14/70] Disable handling of code coverage by default --- package.json | 4 ++-- src/extension.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 365d467..a72f350 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "coverage": { "type": "boolean", "description": "Enable code coverage", - "default": true + "default": false }, "verbose": { "type": "boolean", @@ -193,7 +193,7 @@ "arguments": "", "cwd": "$${_:{workspaceRoot}}", "group": [], - "coverage": true, + "coverage": false, "verbose": false, "gdbtty": true } diff --git a/src/extension.ts b/src/extension.ts index b5a2b5f..7162a36 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -71,7 +71,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { config.env.LD_LIBRARY_PATH = config.libcobpath + ";" + config.env.LD_LIBRARY_PATH; } if (config.coverage === undefined) { - config.coverage = true; + config.coverage = false; } if (config.gdbtty === undefined) { config.gdbtty = true; @@ -92,7 +92,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { arguments: "", cwd: "${workspaceFolder}", group: [], - coverage: true, + coverage: false, verbose: false, gdbtty: true }; From eb434cba87e619872c5205414a5eea6a4fdb4e97 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 26 Jul 2024 10:13:04 +0200 Subject: [PATCH 15/70] Rename debugger type to avoid conflicting with proper "gdb" --- package.json | 8 ++++---- src/extension.ts | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index a72f350..82aa1ba 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ ], "debuggers": [ { - "type": "gdb", + "type": "superbol-gdb", "languages": ["cobol", "COBOL"], "program": "./out/src/gdb.js", "runtime": "node", @@ -187,7 +187,7 @@ "description": "New SuperBOL launch request", "body": { "name": "${2:SuperBOL: debug launch}", - "type": "gdb", + "type": "superbol-gdb", "request": "launch", "target": "$${_:{file}}", "arguments": "", @@ -203,7 +203,7 @@ "description": "New SuperBOL attach local request", "body": { "name": "${2:SuperBOL: debug attach local}", - "type": "gdb", + "type": "superbol-gdb", "request": "attach", "pid": "${3:0}", "target": "$${_:{file}}", @@ -218,7 +218,7 @@ "description": "New SuperBOL attach remote request", "body": { "name": "${2:SuperBOL: debug attach remote}", - "type": "gdb", + "type": "superbol-gdb", "request": "attach", "remoteDebugger": "${3:host:port}", "target": "$${_:{file}}", diff --git a/src/extension.ts b/src/extension.ts index 7162a36..5abdbd2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -13,8 +13,8 @@ export function activate(context: vscode.ExtensionContext) { const provider = new GdbConfigurationProvider(); const factory = new GdbAdapterDescriptorFactory(new CoverageStatus(), new GDBDebugSession()); context.subscriptions.push( - vscode.debug.registerDebugConfigurationProvider('gdb', provider), - vscode.debug.registerDebugAdapterDescriptorFactory('gdb', factory, vscode.DebugConfigurationProviderTriggerKind.Dynamic), + vscode.debug.registerDebugConfigurationProvider('superbol-gdb', provider), + vscode.debug.registerDebugAdapterDescriptorFactory('superbol-gdb', factory, vscode.DebugConfigurationProviderTriggerKind.Dynamic), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL31', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL3.1', new GnuCOBOLEvalExpressionFactory()), @@ -29,14 +29,14 @@ export function deactivate() { } class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { - resolveDebugConfiguration(_folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { + public resolveDebugConfiguration(_folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { config.gdbargs = ["-q", "--interpreter=mi2"]; const settings = new DebuggerSettings(); if (config.name === undefined) { config.name = "SuperBOL: default debug"; } if (config.type === undefined) { - config.type = "gdb"; + config.type = "superbol-gdb"; } if (config.request === undefined) { config.request = "launch"; @@ -79,13 +79,13 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { return config; } - provideDebugConfigurations( + public provideDebugConfigurations( _folder: vscode.WorkspaceFolder, _token?: vscode.CancellationToken): vscode.ProviderResult { const launchConfigDefault: vscode.DebugConfiguration = { name: "SuperBOL: debug (launch)", - type: "gdb", + type: "superbol-gdb", request: "launch", preLaunchTask: "SuperBOL: build (debug)", target: "${file}", @@ -99,7 +99,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { const attachLocalConfiguration: vscode.DebugConfiguration = { name: "SuperBOL: debug (attach local)", - type: "gdb", + type: "superbol-gdb", request: "attach", pid: "${input:pid}", target: "${file}", @@ -111,7 +111,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { const attachRemoteConfiguration: vscode.DebugConfiguration = { name: "SuperBOL: debug (attach remote)", - type: "gdb", + type: "superbol-gdb", request: "attach", "remote-debugger": "${input:remote-debugger}", target: "${file}", From fc6fcb43515a296e413b7d17d743aa1854e047e0 Mon Sep 17 00:00:00 2001 From: engboris Date: Fri, 23 May 2025 17:31:21 +0200 Subject: [PATCH 16/70] Make configs CamelCase --- src/settings.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/settings.ts b/src/settings.ts index 79e1465..db845fd 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -4,20 +4,20 @@ export class DebuggerSettings { private readonly debugSettings: vscode.WorkspaceConfiguration; constructor() { - this.debugSettings = vscode.workspace.getConfiguration("superbol.debugger"); - //this.globalSettings = vscode.workspace.getConfiguration("superbol"); + this.debugSettings = vscode.workspace.getConfiguration("superbol.debugger"); + //this.globalSettings = vscode.workspace.getConfiguration("superbol"); } public get displayVariableAttributes(): boolean { - return this.debugSettings.get("display-variable-attributes"); + return this.debugSettings.get("displayVariableAttributes"); } public get gdbpath(): string { - return this.debugSettings.get("gdb-path"); + return this.debugSettings.get("gdbPath"); } public get libcobpath(): string { - return this.debugSettings.get("libcob-path"); + return this.debugSettings.get("libcobPath"); } public get gdbtty(): string { From 3ec60ca45bb3d29582428d8aca0ddd84185949d2 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 28 May 2025 15:32:14 +0200 Subject: [PATCH 17/70] Fix case of remote debugger input --- src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index 5abdbd2..48cb6c2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -113,7 +113,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { name: "SuperBOL: debug (attach remote)", type: "superbol-gdb", request: "attach", - "remote-debugger": "${input:remote-debugger}", + remoteDebugger: "${input:remoteDebugger}", target: "${file}", arguments: "", cwd: "${workspaceFolder}", From be19317e25895b51f8ceca56c6ee448264d488bb Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 7 Nov 2025 10:37:39 +0100 Subject: [PATCH 18/70] Handle function names that contain dashes --- CHANGELOG.md | 4 ++++ src/parser.c.ts | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a81f4e..eb2162b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Next + +* Fix handling of programs with dashes `-` in their name [PR #14](https://github.com/ocamlpro/superbol-vscode-debug/pull/14) + ## 3.32.0 * Updates [Issue #138](https://github.com/OlegKunitsyn/gnucobol-debug/issues/138) by MARCOS MARTINS DUMA * Migrate from TSLint to ESLint diff --git a/src/parser.c.ts b/src/parser.c.ts index 9954933..13327a0 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -35,6 +35,13 @@ const programExit = /\/\*\sProgram\s\exit\s+\*\//i; globalThis.varOccurs = []; +function cobEncodeInvalidChars (s: string): string { + // TODO: properly mimick `libcob:cob_encode_invalid_chars` + // Meaning: Also replace any character in /[^a-zA-Z0-9-]/ into "_XX", where + // XX is the hexadecimal ascii code of the characher being replaced + return s.replace("-","__"); +} + export class Line { fileCobol: string; fileC: string; @@ -104,7 +111,7 @@ export class SourceMap { } match = functionRegex.exec(line); if (match) { - functionName = match[1].toLowerCase() + "_"; + functionName = cobEncodeInvalidChars(match[1]).toLowerCase() + "_"; } match = procedureRegex.exec(line); if (match && !match[2]) { From 3e7f1d1bb59cb124198c28710648ed8f9e8d5b18 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 7 Nov 2025 10:49:04 +0100 Subject: [PATCH 19/70] Set `gdbtty` default configuration to `false` --- CHANGELOG.md | 1 + package.json | 2 +- src/extension.ts | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb2162b..ff2a6d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Set `gdbtty` to `false` by default [PR #15](https://github.com/ocamlpro/superbol-vscode-debug/pull/15) * Fix handling of programs with dashes `-` in their name [PR #14](https://github.com/ocamlpro/superbol-vscode-debug/pull/14) ## 3.32.0 diff --git a/package.json b/package.json index 82aa1ba..5756267 100644 --- a/package.json +++ b/package.json @@ -195,7 +195,7 @@ "group": [], "coverage": false, "verbose": false, - "gdbtty": true + "gdbtty": false } }, { diff --git a/src/extension.ts b/src/extension.ts index 48cb6c2..8a4c68b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -74,7 +74,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { config.coverage = false; } if (config.gdbtty === undefined) { - config.gdbtty = true; + config.gdbtty = false; } return config; } @@ -94,7 +94,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { group: [], coverage: false, verbose: false, - gdbtty: true + gdbtty: false }; const attachLocalConfiguration: vscode.DebugConfiguration = { From bc06433d0be867c90e3f008a519ef77fd0513f40 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 10 Nov 2025 09:59:46 +0100 Subject: [PATCH 20/70] Enable out-of-workspace debug Also don't force a `preLaunchTask` unless we are in a workspace. --- src/extension.ts | 10 ++-------- src/gdb.ts | 13 +++++++++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 8a4c68b..78d2882 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -29,7 +29,7 @@ export function deactivate() { } class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { - public resolveDebugConfiguration(_folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { + public resolveDebugConfiguration(workspaceFolder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { config.gdbargs = ["-q", "--interpreter=mi2"]; const settings = new DebuggerSettings(); if (config.name === undefined) { @@ -41,7 +41,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.request === undefined) { config.request = "launch"; } - if (config.preLaunchTask === undefined) { + if (config.preLaunchTask === undefined && workspaceFolder != undefined) { config.preLaunchTask = "SuperBOL: build (debug)"; } else if (config.preLaunchTask === "none" || config.preLaunchTask === "") { @@ -53,9 +53,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.arguments === undefined) { config.arguments = ""; } - if (config.cwd === undefined) { - config.cwd = "${workspaceFolder}"; - } if (config.group === undefined) { config.group = []; } @@ -90,7 +87,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { preLaunchTask: "SuperBOL: build (debug)", target: "${file}", arguments: "", - cwd: "${workspaceFolder}", group: [], coverage: false, verbose: false, @@ -104,7 +100,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { pid: "${input:pid}", target: "${file}", arguments: "", - cwd: "${workspaceFolder}", group: [], verbose: false }; @@ -116,7 +111,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { remoteDebugger: "${input:remoteDebugger}", target: "${file}", arguments: "", - cwd: "${workspaceFolder}", group: [], verbose: false } diff --git a/src/gdb.ts b/src/gdb.ts index e3d7512..9571de9 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -15,6 +15,7 @@ import { import {DebugProtocol} from '@vscode/debugprotocol'; import {Breakpoint, VariableObject} from './debugger'; import {MINode} from './parser.mi2'; +import * as path from "path"; import {MI2} from './mi2'; import {CoverageStatus} from './coverage'; import {DebuggerSettings} from './settings'; @@ -28,7 +29,7 @@ class ExtendedVariable { } export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments { - cwd: string; + cwd: string | null; target: string; arguments: string; gdbpath: string; @@ -41,7 +42,7 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum } export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { - cwd: string; + cwd: string | null; target: string; arguments: string; gdbpath: string; @@ -98,7 +99,9 @@ export class GDBDebugSession extends DebugSession { this.crashed = false; this.debugReady = false; this.useVarObjects = false; - this.miDebugger.load(args.cwd, args.target, args.arguments, args.group, args.gdbtty).then( + // Run in the target executables' directory, unless specificed. + let cwd = args.cwd ?? path.dirname (args.target); + this.miDebugger.load(cwd, args.target, args.arguments, args.group, args.gdbtty).then( /*onfulfilled:*/ () => { setTimeout(() => { this.miDebugger.emit("ui-break-done"); @@ -146,7 +149,9 @@ export class GDBDebugSession extends DebugSession { this.crashed = false; this.debugReady = false; this.useVarObjects = false; - this.miDebugger.attach(args.cwd, args.target, args.arguments, args.group).then(() => { + // Run in the target executables' directory, unless specificed. + let cwd = args.cwd ?? path.dirname (args.target); + this.miDebugger.attach(cwd, args.target, args.arguments, args.group).then(() => { setTimeout(() => { this.miDebugger.emit("ui-break-done"); }, 50); From 6fe0eeddf152f6c96047959c2079aa27535bc593 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 10 Nov 2025 10:25:55 +0100 Subject: [PATCH 21/70] Update `CHANGELOG.md` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff2a6d1..234fb95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Enable launching a debug session outside a workspace [PR #16](https://github.com/ocamlpro/superbol-vscode-debug/pull/16) * Set `gdbtty` to `false` by default [PR #15](https://github.com/ocamlpro/superbol-vscode-debug/pull/15) * Fix handling of programs with dashes `-` in their name [PR #14](https://github.com/ocamlpro/superbol-vscode-debug/pull/14) From f4d8e2dc132bcf3db02f9fc5003c81a584720b07 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 12 Nov 2025 09:46:38 +0100 Subject: [PATCH 22/70] Support breakpoints in dynamically loaded modules --- CHANGELOG.md | 1 + src/debugger.ts | 1 + src/mi2.ts | 95 +++++++++++++++++++++++++++++++++++++--- src/parser.c.ts | 114 ++++++++++++++++++++++++++++++++++-------------- 4 files changed, 172 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 234fb95..24ca879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Add support for dynamically loaded sub-modules (e.g, via CALL + literal) [PR #17](https://github.com/ocamlpro/superbol-vscode-debug/pull/17) * Enable launching a debug session outside a workspace [PR #16](https://github.com/ocamlpro/superbol-vscode-debug/pull/16) * Set `gdbtty` to `false` by default [PR #15](https://github.com/ocamlpro/superbol-vscode-debug/pull/15) * Fix handling of programs with dashes `-` in their name [PR #14](https://github.com/ocamlpro/superbol-vscode-debug/pull/14) diff --git a/src/debugger.ts b/src/debugger.ts index fd7b79d..4f6bcdf 100644 --- a/src/debugger.ts +++ b/src/debugger.ts @@ -405,6 +405,7 @@ export class DebuggerVariable { public cobolName: string, public cName: string, public functionName: string, + public rootFileC: string, public attribute: Attribute = null, public size: number = null, public value: string = null, diff --git a/src/mi2.ts b/src/mi2.ts index e985692..afa8bb8 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -32,6 +32,7 @@ export class MI2 extends EventEmitter implements IDebugger { private currentToken = 1; private handlers: { [index: number]: (_: MINode) => unknown } = {}; private breakpoints: Map = new Map(); + private ignoredBreakpoints: Set = new Set(); private buffer: string; private errbuf: string; private process: ChildProcess.ChildProcess; @@ -79,7 +80,7 @@ export class MI2 extends EventEmitter implements IDebugger { } if (this.verbose) { - this.log("stderr", this.map.toString()); + this.log("stderr", this.map.toString("created")); } target = path.resolve(cwd, path.basename(target)); @@ -133,7 +134,7 @@ export class MI2 extends EventEmitter implements IDebugger { } if (this.verbose) { - this.log("stderr", this.map.toString()); + this.log("stderr", this.map.toString("created")); } target = path.resolve(cwd, path.basename(target)); @@ -172,6 +173,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.sendCommand("gdb-set charset UTF-8", false), this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\"", false), + this.sendCommand("gdb-set stop-on-solib-events 1", false), ]; return cmds; } @@ -309,6 +311,9 @@ export class MI2 extends EventEmitter implements IDebugger { this.log("stderr", "Program exited with code " + parsed.record("exit-code")); } this.emit("quit", parsed); + } else if (reason == "solib-event") { + this.onSolibEvent (parsed); + this.resume (); } else { if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { void this.continue(); @@ -320,15 +325,29 @@ export class MI2 extends EventEmitter implements IDebugger { } } } else { - if (this.verbose) { - this.log("stderr", JSON.stringify(parsed)); - } + this.debug (() => JSON.stringify(parsed)); } } else if (record.type == "notify") { if (record.asyncClass == "thread-created") { this.emit("thread-created", parsed); } else if (record.asyncClass == "thread-exited") { this.emit("thread-exited", parsed); + } else if (record.asyncClass == "library-loaded") { + // Possibly unreachable if `stop-on-solib-events` is on; still handle in case. + let libname = record.output.find((e) => e[0] == "target-name")?.[1]; + if (this.map.addLib (libname)) { + this.debug (() => this.map.toString ("updated")); + this.reloadBreakPoints (); + } + } else if (record.asyncClass == "library-unloaded") { + // Ditto: possibly unreachable if `stop-on-solib-events` is on; still handle in case. + let libname = record.output.find((e) => e[0] == "target-name")?.[1]; + if (this.map.remLib (libname)) { + this.debug (() => this.map.toString ("updated")); + this.reloadBreakPoints (); + } + } else { + this.debug (() => JSON.stringify(parsed)); } } } @@ -347,6 +366,25 @@ export class MI2 extends EventEmitter implements IDebugger { }); } + private onSolibEvent(node: MINode): void { + const added: [string, any][] = node.record("added") ?? []; + const removed: [string, any][] = node.record("removed") ?? []; + const isLib = (lib: [string, any]) => lib[0] == "library"; + let libsChanged = false; + libsChanged = added.filter(isLib).reduce((libsChanged, lib) => { + this.debug("loaded library:", lib[1]); + return this.map.addLib(lib[1]) || libsChanged; + }, libsChanged); + libsChanged = removed.filter(isLib).reduce((libsChanged, lib) => { + this.debug("unloaded library:", lib[1]); + return this.map.remLib(lib[1]) || libsChanged; + }, libsChanged); + if (libsChanged) { + this.debug (() => this.map.toString ("updated")); + this.reloadBreakPoints (); + } + } + start(attachTarget?: string): Thenable { let command = "exec-run"; let expectingResultClass = "running"; @@ -432,6 +470,14 @@ export class MI2 extends EventEmitter implements IDebugger { }); } + private resume () { + if (this.lastStepCommand != undefined) { + void this.lastStepCommand (); + } else { + void this.continue (); + } + } + /** * The command executes the line, then pauses at the next line. * The underlying function executes entirely. @@ -562,6 +608,15 @@ export class MI2 extends EventEmitter implements IDebugger { return Promise.all(promisses); } + private reloadBreakPoints(): Thenable<[boolean, Breakpoint][]> { + // TODO: ignore previously set breakpoints after library unloading? + // Library unloading should mostly happen at the end of executions, + // so we can probaly let gdb deal with those (and live with the warnings). + let breakpoints = Array.from (this.ignoredBreakpoints); + this.ignoredBreakpoints.clear (); + return this.loadBreakPoints (breakpoints); + } + setBreakPointCondition(bkptNum: number, condition: string): Thenable { if (this.verbose) { this.log("stderr", "setBreakPointCondition"); @@ -595,6 +650,11 @@ export class MI2 extends EventEmitter implements IDebugger { const map = this.map.getLineC(breakpoint.file, breakpoint.line); if (map.fileC === '' && map.lineC === 0) { + this.debug (() => [ + "addBreakPoint: ignoring breakpoint for unknown source file:", + JSON.stringify(breakpoint) + ]); + this.ignoredBreakpoints.add(breakpoint); return; } @@ -640,7 +700,12 @@ export class MI2 extends EventEmitter implements IDebugger { } return new Promise((resolve, _reject) => { if (!this.breakpoints.has(breakpoint)) { - return resolve(false); + if (this.ignoredBreakpoints.has(breakpoint)) { + this.ignoredBreakpoints.delete(breakpoint); + return resolve(true); + } else { + return resolve(false); + } } this.sendCommand("break-delete " + this.breakpoints.get(breakpoint).toString()).then((result: MINode) => { if (result.resultRecords.resultClass == "done") { @@ -658,9 +723,12 @@ export class MI2 extends EventEmitter implements IDebugger { return new Promise((resolve, _reject) => { this.sendCommand("break-delete").then((result) => { if (result.resultRecords.resultClass == "done") { + this.ignoredBreakpoints.clear (); this.breakpoints.clear(); resolve(true); - } else resolve(false); + } else { + resolve(false); + } }, () => { resolve(false); }); @@ -886,6 +954,19 @@ export class MI2 extends EventEmitter implements IDebugger { this.emit("msg", type, msg[msg.length - 1] == '\n' ? msg : (msg + "\n")); } + private debug (...msg: (string | (() => (string | string[])))[]) { + if (this.verbose) { + this.log ("stderr", msg.flatMap (f => { + if (typeof (f) == "string") { + return [f]; + } else { + const r = f (); + return (typeof (r) == "string") ? [r] : r; + } + }).join (' ')); + } + } + sendUserInput(command: string, threadId: number = 0, frameLevel: number = 0): Thenable { return new Promise((resolve, reject) => { this.stdin(command, resolve); diff --git a/src/parser.c.ts b/src/parser.c.ts index 13327a0..2d830a3 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -19,6 +19,10 @@ const nativePath = { } }; +function cFile (filename: string) : string { + return nativePath.basename(filename.split('.').slice(0, -1).join('.') + '.c'); +} + const procedureRegex = /\/\*\sLine:\s([0-9]+)(\s+:\sEntry\s)?/i; const procedureFixRegex = /#line\s([0-9]+)\s".*\.c"/i; const attributeRegex = /static\sconst\scob_field_attr\s(a_[0-9]+).*\{(0x\d+),\s*([0-9-]*),\s*([0-9-]*),\s*(0x\d{4}),.*/i; @@ -43,17 +47,14 @@ function cobEncodeInvalidChars (s: string): string { } export class Line { - fileCobol: string; - fileC: string; - lineCobol: number; - lineC: number; endPerformLine: number; // 002 - stepOver in routines with "perform" - public constructor(filePathCobol: string, lineCobol: number, filePathC: string, lineC: number) { - this.fileCobol = filePathCobol; - this.lineCobol = lineCobol; - this.fileC = filePathC; - this.lineC = lineC; + public constructor + (public fileCobol: string, + public lineCobol: number, + public fileC: string, + public rootFileC: string, + public lineC: number) { this.endPerformLine = -1; // 002 - stepOver in routines with "perform" } @@ -62,6 +63,8 @@ export class Line { } } +const dummyLine = new Line('', 0, '', '', 0); + export class SourceMap { private cwd: string; private lines: Line[] = new Array(); @@ -69,22 +72,53 @@ export class SourceMap { private variablesByC = new Map(); private attributes = new Map(); private dataStorages = new Map(); + private loadedLibs = new Set(); private version: string; - private lineBefore: string = ""; - private performLine: number = -1; // 002 - stepOver in routines with "perform" + private performLine: number = -1; // 002 - stepOver in routines with "perform" private isVersion2_2_or_3_1_1: boolean = false; constructor(cwd: string, filesCobol: string[]) { this.cwd = fs.realpathSync(nativePathFromPath.resolve(cwd)); filesCobol.forEach(e => { - this.parse(nativePath.basename(e.split('.').slice(0, -1).join('.') + '.c')); + this.register (cFile (e)); }); } - private parse(fileC: string): void { - let nat = fileC; - let hasProgramExit = false; + public addLib (libFile: string) : boolean { + if (this.loadedLibs.has (libFile)) { + return false; + } + this.loadedLibs.add (libFile); + const c = nativePath.resolve (this.cwd, cFile (libFile)); + if (!fs.existsSync (c)) { + return false; + } + this.register (c); + return true; + } + + public remLib (libFile: string) : boolean { + if (!this.loadedLibs.has (libFile)) { + return false; + } + this.loadedLibs.delete (libFile); + this.unregister (nativePath.resolve (this.cwd, cFile (libFile))); + return true; + } + + private unregister (givenFileC: string) : void { + const [natFileC, fileC, cleanedFile] = this.ensureAbsolute (givenFileC); + this.lines = this.lines.filter (line => line.rootFileC != fileC) ?? []; + for (const [k, v] of this.variablesByC) { + if (v.rootFileC == fileC) this.variablesByC.delete(k); + } + for (const [k, v] of this.variablesByCobol) { + if (v.rootFileC == fileC) this.variablesByCobol.delete(k); + } + } + private ensureAbsolute (fileC: string) : [string, string, string] { + let nat = fileC; if (!nativePath.isAbsolute(fileC)) { nat = nativePathFromPath.resolve(this.cwd, fileC); fileC = nativePath.resolve(this.cwd, fileC); @@ -93,12 +127,27 @@ export class SourceMap { const basename = nativePath.basename(fileC); const cleanedFile = basename.substring(0, basename.lastIndexOf(".c")); - let lineNumber = 0; + return [process.platform === "win32" ? nat : fileC, fileC, cleanedFile]; + } + + private register (givenFileC: string) : void { + this.parse (givenFileC); // just parse the file. + } - const reader = new readline(process.platform === "win32" ? nat : fileC); + private parse (givenFileC: string, + prevLine: string | undefined = undefined, + rootFileC: string | undefined = undefined) : void { + + const [natFileC, fileC, cleanedFile] = this.ensureAbsolute (givenFileC); + rootFileC = rootFileC ?? fileC; + + let hasProgramExit = false; + let lineNumber = 0; let row: false | Buffer; let fileCobol: string; let functionName: string; + + const reader = new readline(natFileC); while (row = reader.next()) { const line = row.toString(); let match = fileCobolRegex.exec(line); @@ -118,16 +167,16 @@ export class SourceMap { if (this.lines.length > 0 && fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && this.lines[this.lines.length - 1].lineCobol === parseInt(match[1])) { this.lines.pop(); } - if(subroutineRegex.exec(line)) + if(subroutineRegex.exec(line)) this.performLine=-2; // must find line of frame_ptr - else - this.performLine=-1; - this.lines.push(new Line(fileCobol, parseInt(match[1]), fileC, lineNumber + 2)); + else + this.performLine=-1; + this.lines.push(new Line(fileCobol, parseInt(match[1]), fileC, rootFileC, lineNumber + 2)); } // fix new codegen match = procedureFixRegex.exec(line); if (match && this.lines.length > 0 && !hasProgramExit) { - let isOldFormat = fixOlderFormat.exec(this.lineBefore); + let isOldFormat = fixOlderFormat.exec(prevLine); if(fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? let line = this.lines.pop(); line.lineC = parseInt(match[1]); @@ -145,7 +194,8 @@ export class SourceMap { if (match[3].startsWith("[")) { size = parseInt(match[3].substring(1, match[3].length - 1)); } - const dataStorage = new DebuggerVariable(match[4], match[2], functionName, new Attribute(null, VariableType[match[1]], 0, 0), size); + const dataStorage = new DebuggerVariable(match[4], match[2], functionName, rootFileC, + new Attribute(null, VariableType[match[1]], 0, 0), size); this.dataStorages.set(`${functionName}.${dataStorage.cName}`, dataStorage); this.variablesByC.set(`${functionName}.${dataStorage.cName}`, dataStorage); this.variablesByCobol.set(`${functionName}.${dataStorage.cobolName.toUpperCase()}`, dataStorage); @@ -154,7 +204,8 @@ export class SourceMap { if (match) { const attribute = this.attributes.get(`${cleanedFile}.${match[4]}`); const dataStorage = this.dataStorages.get(`${functionName}.${match[3]}`); - const field = new DebuggerVariable(match[5], match[1], functionName, attribute, parseInt(match[2])); + const field = new DebuggerVariable(match[5], match[1], functionName, rootFileC, + attribute, parseInt(match[2])); this.variablesByC.set(`${functionName}.${field.cName}`, field); @@ -167,7 +218,7 @@ export class SourceMap { } match = fileIncludeRegex.exec(line); if (match) { - this.parse(match[1]); + this.parse(match[1], prevLine, rootFileC); } match = versionRegex.exec(line); if (match) { @@ -182,12 +233,12 @@ export class SourceMap { this.lines.push(line); } } - this.lineBefore = line; match = programExit.exec(line); if (match) { hasProgramExit=true;; } lineNumber++; + prevLine = line; } } @@ -241,8 +292,7 @@ export class SourceMap { if (!nativePath.isAbsolute(fileC)) { fileC = nativePath.join(this.cwd, fileC); } - let line = this.lines.find(e => e.fileC === fileC && e.lineC === lineC) ?? new Line('', 0, '', 0); - return line.endPerformLine; + return this.lines.find(e => e.fileC === fileC && e.lineC === lineC)?.endPerformLine ?? -1; } // 002 @@ -257,22 +307,22 @@ export class SourceMap { if (!nativePath.isAbsolute(fileCobol)) { fileCobol = nativePath.join(this.cwd, fileCobol); } - return this.lines.find(e => fileNameCompare(e.fileCobol, fileCobol) && e.lineCobol === lineCobol) ?? new Line('', 0, '', 0); + return this.lines.find(e => fileNameCompare(e.fileCobol, fileCobol) && e.lineCobol === lineCobol) ?? dummyLine; } public getLineCobol(fileC: string, lineC: number): Line { if (!nativePath.isAbsolute(fileC)) { fileC = nativePath.join(this.cwd, fileC); } - return this.lines.find(e => e.fileC === fileC && e.lineC === lineC) ?? new Line('', 0, '', 0); + return this.lines.find(e => e.fileC === fileC && e.lineC === lineC) ?? dummyLine; } public getVersion(): string { return this.version; } - public toString(): string { - let out = `SourceMap created: lines ${this.lines.length}, vars ${this.variablesByC.size}\n`; + public toString(event = "created"): string { + let out = `SourceMap ${event}: lines ${this.lines.length}, vars ${this.variablesByC.size}\n`; this.lines.forEach(e => { out += e.toString() + "\n"; From 7205aa1087defc090e7b014acf5d4bdf3b5b5f99 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 12 Nov 2025 17:50:11 +0100 Subject: [PATCH 23/70] Fix source-map computation for nested subprograms --- CHANGELOG.md | 1 + src/mi2.ts | 27 ++++++++++++++++++--------- src/parser.c.ts | 31 +++++++++++++++---------------- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24ca879..6009c8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Fix handling of nested subprograms [PR #18](https://github.com/ocamlpro/superbol-vscode-debug/pull/18) * Add support for dynamically loaded sub-modules (e.g, via CALL + literal) [PR #17](https://github.com/ocamlpro/superbol-vscode-debug/pull/17) * Enable launching a debug session outside a workspace [PR #16](https://github.com/ocamlpro/superbol-vscode-debug/pull/16) * Set `gdbtty` to `false` by default [PR #15](https://github.com/ocamlpro/superbol-vscode-debug/pull/15) diff --git a/src/mi2.ts b/src/mi2.ts index afa8bb8..d1d1a0d 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -74,14 +74,12 @@ export class MI2 extends EventEmitter implements IDebugger { let target_no_ext = target.split('.').slice(0, -1).join('.'); this.gcovFiles.add(target_no_ext); try { - this.map = new SourceMap(cwd, [target].concat(group)); + this.map = new SourceMap(cwd, [target].concat(group), ((l: any) => this.debug (l))); } catch (e) { this.log('stderr', (e).toString()); } - if (this.verbose) { - this.log("stderr", this.map.toString("created")); - } + this.debug(() => this.map.toString("created")); target = path.resolve(cwd, path.basename(target)); target = target.split('.').slice(0, -1).join('.'); @@ -128,7 +126,7 @@ export class MI2 extends EventEmitter implements IDebugger { } try { - this.map = new SourceMap(cwd, [target].concat(group)); + this.map = new SourceMap(cwd, [target].concat(group), ((l: any) => this.debug (l))); } catch (e) { this.log('stderr', (e).toString()); } @@ -954,19 +952,30 @@ export class MI2 extends EventEmitter implements IDebugger { this.emit("msg", type, msg[msg.length - 1] == '\n' ? msg : (msg + "\n")); } - private debug (...msg: (string | (() => (string | string[])))[]) { + private debug(...msg: (string | (() => (string | string[])))[]) { if (this.verbose) { - this.log ("stderr", msg.flatMap (f => { + this.log("stderr", msg.flatMap(f => { if (typeof (f) == "string") { return [f]; } else { - const r = f (); + const r = f(); return (typeof (r) == "string") ? [r] : r; } - }).join (' ')); + }).join(' ')); } } + private info(...msg: (string | (() => (string | string[])))[]) { + this.log("stdout", msg.flatMap(f => { + if (typeof (f) == "string") { + return [f]; + } else { + const r = f(); + return (typeof (r) == "string") ? [r] : r; + } + }).join(' ')); + } + sendUserInput(command: string, threadId: number = 0, frameLevel: number = 0): Thenable { return new Promise((resolve, reject) => { this.stdin(command, resolve); diff --git a/src/parser.c.ts b/src/parser.c.ts index 2d830a3..1483bdf 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -35,7 +35,6 @@ const versionRegex = /\/\*\sGenerated by\s+cobc\s([0-9a-z\-\.]+)\s+\*\//i; const subroutineRegex = /\sPerform\s/i; const frame_ptrFindRegex = /frame\_ptr\-\-\;/; const fixOlderFormat = /cob\_trace\_stmt/; -const programExit = /\/\*\sProgram\s\exit\s+\*\//i; globalThis.varOccurs = []; @@ -54,16 +53,17 @@ export class Line { public lineCobol: number, public fileC: string, public rootFileC: string, - public lineC: number) { + public lineC: number, + public functionName: string) { this.endPerformLine = -1; // 002 - stepOver in routines with "perform" } public toString(): string { - return `${this.fileCobol}:${this.lineCobol} > ${this.fileC}:${this.lineC}`; + return `${this.fileCobol}:${this.lineCobol} > ${this.fileC}:${this.lineC} | (${this.functionName})`; } } -const dummyLine = new Line('', 0, '', '', 0); +const dummyLine = new Line('', 0, '', '', 0, ''); export class SourceMap { private cwd: string; @@ -77,7 +77,7 @@ export class SourceMap { private performLine: number = -1; // 002 - stepOver in routines with "perform" private isVersion2_2_or_3_1_1: boolean = false; - constructor(cwd: string, filesCobol: string[]) { + constructor(cwd: string, filesCobol: string[], private log: Function) { this.cwd = fs.realpathSync(nativePathFromPath.resolve(cwd)); filesCobol.forEach(e => { this.register (cFile (e)); @@ -131,21 +131,20 @@ export class SourceMap { } private register (givenFileC: string) : void { - this.parse (givenFileC); // just parse the file. + void this.parse (givenFileC); // just parse the file. } private parse (givenFileC: string, prevLine: string | undefined = undefined, - rootFileC: string | undefined = undefined) : void { + rootFileC: string | undefined = undefined, + functionName: string | undefined = undefined) : string { const [natFileC, fileC, cleanedFile] = this.ensureAbsolute (givenFileC); rootFileC = rootFileC ?? fileC; - let hasProgramExit = false; let lineNumber = 0; let row: false | Buffer; let fileCobol: string; - let functionName: string; const reader = new readline(natFileC); while (row = reader.next()) { @@ -171,15 +170,17 @@ export class SourceMap { this.performLine=-2; // must find line of frame_ptr else this.performLine=-1; - this.lines.push(new Line(fileCobol, parseInt(match[1]), fileC, rootFileC, lineNumber + 2)); + this.lines.push(new Line(fileCobol, parseInt(match[1]), fileC, rootFileC, lineNumber + 2, functionName)); } // fix new codegen match = procedureFixRegex.exec(line); - if (match && this.lines.length > 0 && !hasProgramExit) { + if (match && this.lines.length > 0) { let isOldFormat = fixOlderFormat.exec(prevLine); if(fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? let line = this.lines.pop(); + // this.log (`Fixing line: ${line.toString ()}`); line.lineC = parseInt(match[1]); + // this.log (`New line: ${line.toString ()}`); this.lines.push(line); } } @@ -218,7 +219,7 @@ export class SourceMap { } match = fileIncludeRegex.exec(line); if (match) { - this.parse(match[1], prevLine, rootFileC); + functionName = this.parse(match[1], prevLine, rootFileC, functionName); } match = versionRegex.exec(line); if (match) { @@ -233,13 +234,11 @@ export class SourceMap { this.lines.push(line); } } - match = programExit.exec(line); - if (match) { - hasProgramExit=true;; - } lineNumber++; prevLine = line; } + + return functionName; } public getVariablesByC(): IterableIterator { From 44ad4c119188ab47b426de8af5a30c96dd27ba33 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 14 Nov 2025 09:50:17 +0100 Subject: [PATCH 24/70] Fix detection of attach target given as a PID --- CHANGELOG.md | 1 + src/mi2.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6009c8d..63e99dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Fix detection of attach target that is given as a PID [PR #21](https://github.com/ocamlpro/superbol-vscode-debug/pull/21) * Fix handling of nested subprograms [PR #18](https://github.com/ocamlpro/superbol-vscode-debug/pull/18) * Add support for dynamically loaded sub-modules (e.g, via CALL + literal) [PR #17](https://github.com/ocamlpro/superbol-vscode-debug/pull/17) * Enable launching a debug session outside a workspace [PR #16](https://github.com/ocamlpro/superbol-vscode-debug/pull/16) diff --git a/src/mi2.ts b/src/mi2.ts index d1d1a0d..0735203 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -399,7 +399,7 @@ export class MI2 extends EventEmitter implements IDebugger { } this.once("ui-break-done", () => { if (!!attachTarget) { - if (/^d+$/.test(attachTarget)) { + if (/^\d+$/.test(attachTarget)) { command = `target-attach ${attachTarget}`; expectingResultClass = "done"; } else { From 8e2ad84ccf4c3b4b1051087a533f41fc58a0def5 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 14 Nov 2025 11:50:12 +0100 Subject: [PATCH 25/70] Fix first line of subprograms in source mapping --- CHANGELOG.md | 1 + src/parser.c.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63e99dc..b8716f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Fix first line of subprograms in source mapping [PR #22](https://github.com/ocamlpro/superbol-vscode-debug/pull/22) * Fix detection of attach target that is given as a PID [PR #21](https://github.com/ocamlpro/superbol-vscode-debug/pull/21) * Fix handling of nested subprograms [PR #18](https://github.com/ocamlpro/superbol-vscode-debug/pull/18) * Add support for dynamically loaded sub-modules (e.g, via CALL + literal) [PR #17](https://github.com/ocamlpro/superbol-vscode-debug/pull/17) diff --git a/src/parser.c.ts b/src/parser.c.ts index 1483bdf..74b1b2f 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -174,7 +174,7 @@ export class SourceMap { } // fix new codegen match = procedureFixRegex.exec(line); - if (match && this.lines.length > 0) { + if (match && this.lines.length > 0 && this.lines[this.lines.length - 1].functionName == functionName) { let isOldFormat = fixOlderFormat.exec(prevLine); if(fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? let line = this.lines.pop(); From 2e56a5ecfe0e05212c2ac73d99a0cec5b9ecec96 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 14 Nov 2025 14:19:54 +0100 Subject: [PATCH 26/70] Avoid forcing a prelaunch task on attach mode --- CHANGELOG.md | 1 + src/extension.ts | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63e99dc..45e4e8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Avoid forcing a prelaunch task on attach mode [PR #23](https://github.com/ocamlpro/superbol-vscode-debug/pull/23) * Fix detection of attach target that is given as a PID [PR #21](https://github.com/ocamlpro/superbol-vscode-debug/pull/21) * Fix handling of nested subprograms [PR #18](https://github.com/ocamlpro/superbol-vscode-debug/pull/18) * Add support for dynamically loaded sub-modules (e.g, via CALL + literal) [PR #17](https://github.com/ocamlpro/superbol-vscode-debug/pull/17) diff --git a/src/extension.ts b/src/extension.ts index 78d2882..538e059 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -41,7 +41,9 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.request === undefined) { config.request = "launch"; } - if (config.preLaunchTask === undefined && workspaceFolder != undefined) { + if (workspaceFolder != undefined && + config.request != "attach" && + config.preLaunchTask === undefined) { config.preLaunchTask = "SuperBOL: build (debug)"; } else if (config.preLaunchTask === "none" || config.preLaunchTask === "") { From 86b381b468305a1029131b2d46e53984f7261152 Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Fri, 14 Nov 2025 16:57:43 +0100 Subject: [PATCH 27/70] Debug module running with `cobcrun` (#19) --- src/extension.ts | 3 +++ src/gdb.ts | 32 +++++++++++++++++++++++++++++--- src/mi2.ts | 21 +++++++++++++++------ src/parser.c.ts | 3 +++ src/settings.ts | 4 ++++ 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 538e059..d5aacdb 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -64,6 +64,9 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.libcobpath === undefined) { config.libcobpath = settings.libcobpath; } + if (config.cobcrunPath === undefined) { + config.cobcrunPath = settings.cobcrunPath; + } if (config.env === undefined) { config.env = { ["LD_LIBRARY_PATH"] : config.libcobpath }; } else { diff --git a/src/gdb.ts b/src/gdb.ts index 9571de9..f1e825a 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -39,6 +39,8 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum verbose: boolean; coverage: boolean; gdbtty: boolean; + cobcrunPath: string; + useCobcrun: boolean; } export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { @@ -80,7 +82,17 @@ export class GDBDebugSession extends DebugSession { this.started = false; this.attached = false; - this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, args.noDebug, args.gdbtty); + this.miDebugger = + new MI2( + args.gdbpath, + args.gdbargs, + args.env, + args.verbose, + args.noDebug, + args.gdbtty, + args.cobcrunPath, + args.useCobcrun, + ); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); @@ -122,7 +134,11 @@ export class GDBDebugSession extends DebugSession { protected attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments): void { if (!args.pid && !args.remoteDebugger) { - this.sendErrorResponse(response, 100, `Failed to start MI Debugger: PID or remote-debugger argument required`); + this.sendErrorResponse( + response, + 100, + `Failed to start MI Debugger: PID or remote-debugger argument required` + ); return; } @@ -130,7 +146,17 @@ export class GDBDebugSession extends DebugSession { this.attached = true; this.started = false; - this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, false, false); + this.miDebugger = + new MI2( + args.gdbpath, + args.gdbargs, + args.env, + args.verbose, + false, + false, + "", + false + ); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); diff --git a/src/mi2.ts b/src/mi2.ts index 0735203..9eddbb2 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -40,7 +40,7 @@ export class MI2 extends EventEmitter implements IDebugger { private hasCobGetFieldStringFunction = true; private hasCobPutFieldStringFunction = true; - constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean | null, public gdbtty: boolean | null) { + constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean) { super(); if (procEnv) { const env = {}; @@ -101,7 +101,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.process.stderr.on("data", (data: string) => { this.log("stderr", data); }); this.process.on("exit", (() => { this.emit("quit"); })); this.process.on("error", (err) => { this.emit("launcherror", err); }); - const promises = this.initCommands(target, targetargs, cwd); + const promises = this.initCommands(target, targetargs, cwd, this.useCobcrun); // 001-gdbtty - additional parameters for gdb for (let item of gdbttyParameters) promises.push(this.sendCommand("gdb-set " + item, false)); @@ -147,7 +147,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.process.stderr.on("data", (data: string) => { this.log("stderr", data); }); this.process.on("exit", () => { this.emit("quit"); }); this.process.on("error", (err) => { this.emit("launcherror", err); }); - const promises = this.initCommands(target, targetargs, cwd); + const promises = this.initCommands(target, targetargs, cwd, false); Promise.all(promises).then(() => { this.emit("debug-ready"); resolve(true); @@ -156,7 +156,7 @@ export class MI2 extends EventEmitter implements IDebugger { }); } - protected initCommands(target: string, targetargs: string, cwd: string) { + protected initCommands(target: string, targetargs: string, cwd: string, useCobcrun: boolean) { if (!path.isAbsolute(target)) { target = path.join(cwd, target); } @@ -164,15 +164,24 @@ export class MI2 extends EventEmitter implements IDebugger { cwd = path.dirname(target); } + let target_exec_symbol = escape(target); + let target_args = targetargs; + let search_dir = path.dirname(target_exec_symbol); + if (useCobcrun) { + target_args = `-m ${target_exec_symbol} ${target_args}` + target_exec_symbol = this.cobcrunPath; + } + const cmds = [ this.sendCommand("gdb-set mi-async on", false), this.sendCommand("gdb-set print repeats 1000", false), - this.sendCommand("gdb-set args " + targetargs, false), + this.sendCommand("gdb-set args " + target_args, false), this.sendCommand("gdb-set charset UTF-8", false), this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), - this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\"", false), + this.sendCommand("file-exec-and-symbols \"" + target_exec_symbol + "\"", false), this.sendCommand("gdb-set stop-on-solib-events 1", false), ]; + return cmds; } diff --git a/src/parser.c.ts b/src/parser.c.ts index 74b1b2f..55a6782 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -310,6 +310,9 @@ export class SourceMap { } public getLineCobol(fileC: string, lineC: number): Line { + if (!fileC) { + return dummyLine; + } if (!nativePath.isAbsolute(fileC)) { fileC = nativePath.join(this.cwd, fileC); } diff --git a/src/settings.ts b/src/settings.ts index db845fd..ce70f0b 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -24,4 +24,8 @@ export class DebuggerSettings { return this.debugSettings.get("gdbtty"); } + public get cobcrunPath(): string { + return this.debugSettings.get("cobcrunPath"); + } + } From 246a7d0d5e4220cad48db9c1c43e755acc39fec1 Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Thu, 13 Nov 2025 11:59:21 +0100 Subject: [PATCH 28/70] Debug module running with `cobcrun` --- src/gdb.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gdb.ts b/src/gdb.ts index f1e825a..2aea596 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -39,8 +39,12 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum verbose: boolean; coverage: boolean; gdbtty: boolean; +<<<<<<< HEAD cobcrunPath: string; useCobcrun: boolean; +======= + module: boolean; +>>>>>>> f574cf6 (Debug module running with `cobcrun`) } export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { From 2ef11faedea6f7262a4b38a7b42c5e5dcb8c3ba1 Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Fri, 14 Nov 2025 15:25:59 +0100 Subject: [PATCH 29/70] Remove unnecessary gdb commands --- src/mi2.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mi2.ts b/src/mi2.ts index 9eddbb2..d3c84cf 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -40,7 +40,19 @@ export class MI2 extends EventEmitter implements IDebugger { private hasCobGetFieldStringFunction = true; private hasCobPutFieldStringFunction = true; +<<<<<<< HEAD constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean) { +======= + constructor( + public gdbpath: string, + public gdbArgs: string[], + procEnv: NodeJS.ProcessEnv, + public verbose: boolean, + public noDebug: boolean, + public gdbtty: boolean, + public module: boolean, + ) { +>>>>>>> aaddf11 (Remove unnecessary gdb commands) super(); if (procEnv) { const env = {}; From 8122588dd55d1ae26c1349950bd925fad337c0e6 Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Fri, 14 Nov 2025 16:13:25 +0100 Subject: [PATCH 30/70] Revert last changes of `src/settings.ts` --- src/settings.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/settings.ts b/src/settings.ts index ce70f0b..3aa8c38 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -27,5 +27,4 @@ export class DebuggerSettings { public get cobcrunPath(): string { return this.debugSettings.get("cobcrunPath"); } - } From 2052d6abded25653139d8e8de58f93a6bb17a878 Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Fri, 14 Nov 2025 16:40:15 +0100 Subject: [PATCH 31/70] Move cobcrunPath to debugger settings namespace --- src/extension.ts | 3 +++ src/gdb.ts | 4 ---- src/mi2.ts | 12 ------------ src/settings.ts | 1 + 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index d5aacdb..170c4b6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -78,6 +78,9 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.gdbtty === undefined) { config.gdbtty = false; } + if (config.cobcrunPath === undefined) { + config.cobcrunPath = settings.cobcrunPath; + } return config; } diff --git a/src/gdb.ts b/src/gdb.ts index 2aea596..f1e825a 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -39,12 +39,8 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum verbose: boolean; coverage: boolean; gdbtty: boolean; -<<<<<<< HEAD cobcrunPath: string; useCobcrun: boolean; -======= - module: boolean; ->>>>>>> f574cf6 (Debug module running with `cobcrun`) } export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { diff --git a/src/mi2.ts b/src/mi2.ts index d3c84cf..9eddbb2 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -40,19 +40,7 @@ export class MI2 extends EventEmitter implements IDebugger { private hasCobGetFieldStringFunction = true; private hasCobPutFieldStringFunction = true; -<<<<<<< HEAD constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean) { -======= - constructor( - public gdbpath: string, - public gdbArgs: string[], - procEnv: NodeJS.ProcessEnv, - public verbose: boolean, - public noDebug: boolean, - public gdbtty: boolean, - public module: boolean, - ) { ->>>>>>> aaddf11 (Remove unnecessary gdb commands) super(); if (procEnv) { const env = {}; diff --git a/src/settings.ts b/src/settings.ts index 3aa8c38..ce70f0b 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -27,4 +27,5 @@ export class DebuggerSettings { public get cobcrunPath(): string { return this.debugSettings.get("cobcrunPath"); } + } From 7117ef0615e4fa957321cf8739088e9ac97a3521 Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Thu, 13 Nov 2025 17:19:03 +0100 Subject: [PATCH 32/70] Allow specification of c sources directory --- package.json | 284 ----------------------------------------------- src/extension.ts | 10 +- src/gdb.ts | 14 ++- src/mi2.ts | 32 +++++- src/parser.c.ts | 169 +++++++++++++++++++--------- 5 files changed, 167 insertions(+), 342 deletions(-) delete mode 100644 package.json diff --git a/package.json b/package.json deleted file mode 100644 index 5756267..0000000 --- a/package.json +++ /dev/null @@ -1,284 +0,0 @@ -{ - "name": "superbol-vscode-debug", - "displayName": "SuperBOL Debugger for GnuCOBOL", - "description": "Debug or execute COBOL code. No mainframe required.", - "keywords": [ - "cobol", - "gnucobol", - "debugger", - "debug", - "code coverage" - ], - "version": "3.32.0", - "publisher": "OCamlPro SAS", - "contributors": [ - { - "name": "Emilien Lemaire", - "email": "emilien.lemaire@ocamlpro.com" - }, - { - "name": "Olegs Kunicins", - "email": "olegs.kunicins@gmail.com" - } - ], - "license": "GPL-3.0", - "icon": "icon.png", - "engines": { - "vscode": "^1.44.0" - }, - "main": "./out/src/extension", - "activationEvents": [ - "onDebugResolve", - "onDebugInitialConfigurations" - ], - "categories": [ - "Debuggers" - ], - "repository": { - "type": "git", - "url": "https://github.com/OCamlPro/superbol-vscode-debug.git" - }, - "capabilities": { - "untrustedWorkspaces": { - "supported": true - } - }, - "contributes": { - "breakpoints": [ - { - "language": "cobol" - } - ], - "debuggers": [ - { - "type": "superbol-gdb", - "languages": ["cobol", "COBOL"], - "program": "./out/src/gdb.js", - "runtime": "node", - "label": "SuperBOL Debugger for GnuCOBOL", - "configurationAttributes": { - "launch": { - "required": [], - "properties": { - "target": { - "type": "string", - "description": "Path to executable", - "default": "${file}" - }, - "arguments": { - "type": "string", - "description": "Extra arguments for executable", - "default": null - }, - "cwd": { - "type": "string", - "description": "Path to project", - "default": "${workspaceRoot}" - }, - "gdbpath": { - "type": "string", - "description": "Path to gdb", - "default": "gdb" - }, - "libcobpath": { - "type": "string", - "description": "Path to libcob", - "default": null - }, - "group": { - "type": "array", - "description": "Compilation Group for executable", - "default": [] - }, - "env": { - "type": "object", - "description": "Environment variables", - "default": null - }, - "coverage": { - "type": "boolean", - "description": "Enable code coverage", - "default": false - }, - "verbose": { - "type": "boolean", - "description": "Debug GDB", - "default": false - }, - "gdbtty": { - "type": [ - "boolean", - "string" - ], - "description": "Enable external display for debug", - "default": false, - "enum": [ - true, - false, - "vscode", - "xterm", - "gnome-terminal", - "xfce4-terminal", - "konsole", - "external" - ] - } - } - }, - "attach": { - "required": [], - "properties": { - "target": { - "type": "string", - "description": "Path to executable", - "default": "${file}" - }, - "arguments": { - "type": "string", - "description": "Extra arguments for executable", - "default": null - }, - "cwd": { - "type": "string", - "description": "Path to project", - "default": "${workspaceRoot}" - }, - "gdbpath": { - "type": "string", - "description": "Path to gdb", - "default": "gdb" - }, - "libcobpath": { - "type": "string", - "description": "Path to libcob", - "default": null - }, - "group": { - "type": "array", - "description": "Compilation Group for executable", - "default": [] - }, - "env": { - "type": "object", - "description": "Environment variables", - "default": null - }, - "verbose": { - "type": "boolean", - "description": "Debug GDB", - "default": false - }, - "pid": { - "type": "string", - "description": "PID of the executable", - "default": null - }, - "remoteDebugger": { - "type": "string", - "description": "GDB Server host:port", - "default": null - } - } - } - }, - "configurationSnippets": [ - { - "label": "SuperBOL: debug launch", - "description": "New SuperBOL launch request", - "body": { - "name": "${2:SuperBOL: debug launch}", - "type": "superbol-gdb", - "request": "launch", - "target": "$${_:{file}}", - "arguments": "", - "cwd": "$${_:{workspaceRoot}}", - "group": [], - "coverage": false, - "verbose": false, - "gdbtty": false - } - }, - { - "label": "SuperBOL: debug attach local", - "description": "New SuperBOL attach local request", - "body": { - "name": "${2:SuperBOL: debug attach local}", - "type": "superbol-gdb", - "request": "attach", - "pid": "${3:0}", - "target": "$${_:{file}}", - "arguments": "", - "cwd": "$${_:{workspaceRoot}}", - "group": [], - "verbose": false - } - }, - { - "label": "SuperBOL: debug attach remote", - "description": "New SuperBOL attach remote request", - "body": { - "name": "${2:SuperBOL: debug attach remote}", - "type": "superbol-gdb", - "request": "attach", - "remoteDebugger": "${3:host:port}", - "target": "$${_:{file}}", - "arguments": "", - "cwd": "$${_:{workspaceRoot}}", - "group": [], - "verbose": false - } - } - ] - } - ], - "configuration": { - "title": "SuperBOL Debugger", - "properties": { - "superbol-vscode-debug.displayVariableAttributes": { - "type": "boolean", - "default": false, - "description": "Displaying Data Storages and Fields attributes (e.g. size of Alphanumerics or digits and scale of numerics).", - "scope": "resource" - }, - "superbol-vscode-debug.pathToGDB": { - "type": "string", - "description": "Path to the `gdb` command", - "default": "gdb", - "scope": "application" - }, - "superbol-vscode-debug.pathToLibCob": { - "type": "string", - "description": "Path to the folder containing `libcob`", - "default": "/usr/local/gnucobol/lib", - "scope": "application" - } - } - } - }, - "scripts": { - "prepare": "tsc -p ./", - "compile": "tsc -p ./", - "watch": "tsc -w -p ./", - "test": "mocha -u tdd ./out/test/", - "lint": "eslint -c .eslintrc.js --ext .ts ./" - }, - "devDependencies": { - "@types/mocha": "^10.0.1", - "@types/node": "^20.6.3", - "@types/vscode": "^1.44.0", - "@typescript-eslint/eslint-plugin": "^6.7.2", - "@typescript-eslint/parser": "^6.7.2", - "@vscode/test-electron": "^2.3.4", - "eslint": "^8.50.0", - "eslint_d": "^12.2.1", - "mocha": "^10.2.0", - "typescript": "^5.2.2", - "@vscode/debugadapter-testsupport": "^1.51.0" - }, - "dependencies": { - "n-readlines": "^1.0.1", - "package_name": "^1.0.0", - "@vscode/debugprotocol": "^1.51.0", - "@vscode/debugadapter": "^1.51.0" - } -} diff --git a/src/extension.ts b/src/extension.ts index 170c4b6..fbc5642 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -29,7 +29,12 @@ export function deactivate() { } class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { - public resolveDebugConfiguration(workspaceFolder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { + public resolveDebugConfiguration( + workspaceFolder: vscode.WorkspaceFolder | undefined, + config: vscode.DebugConfiguration, + _token?: vscode.CancellationToken) + : vscode.ProviderResult + { config.gdbargs = ["-q", "--interpreter=mi2"]; const settings = new DebuggerSettings(); if (config.name === undefined) { @@ -81,6 +86,9 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.cobcrunPath === undefined) { config.cobcrunPath = settings.cobcrunPath; } + if (config.cSourcesDirs === undefined) { + config.cSourcesDirs = []; + } return config; } diff --git a/src/gdb.ts b/src/gdb.ts index f1e825a..2d0bf26 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -39,8 +39,13 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum verbose: boolean; coverage: boolean; gdbtty: boolean; +<<<<<<< HEAD cobcrunPath: string; useCobcrun: boolean; +======= + module: boolean; + cSourcesDirs: string[]; +>>>>>>> 52fa0cb (Allow specification of c sources directory) } export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { @@ -54,6 +59,7 @@ export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArgum verbose: boolean; pid: string; remoteDebugger: string; + cSourcesDirs: string[]; } export class GDBDebugSession extends DebugSession { @@ -92,6 +98,7 @@ export class GDBDebugSession extends DebugSession { args.gdbtty, args.cobcrunPath, args.useCobcrun, + args.cSourcesDirs, ); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); @@ -154,8 +161,13 @@ export class GDBDebugSession extends DebugSession { args.verbose, false, false, +<<<<<<< HEAD "", false +======= + false, + args.cSourcesDirs, +>>>>>>> 52fa0cb (Allow specification of c sources directory) ); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); @@ -254,7 +266,7 @@ export class GDBDebugSession extends DebugSession { protected launchError(err: Error) { this.handleMsg("stderr", "Could not start debugger process\n"); - this.handleMsg("stderr", err.toString() + "\n"); + this.handleMsg("stderr", err.toString() + "\n" + err.stack + "\n"); this.quitEvent(); } diff --git a/src/mi2.ts b/src/mi2.ts index 9eddbb2..e0a47af 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -40,7 +40,7 @@ export class MI2 extends EventEmitter implements IDebugger { private hasCobGetFieldStringFunction = true; private hasCobPutFieldStringFunction = true; - constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean) { + constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean, public cSourcesDirs: string[]) { super(); if (procEnv) { const env = {}; @@ -74,7 +74,11 @@ export class MI2 extends EventEmitter implements IDebugger { let target_no_ext = target.split('.').slice(0, -1).join('.'); this.gcovFiles.add(target_no_ext); try { - this.map = new SourceMap(cwd, [target].concat(group), ((l: any) => this.debug (l))); + this.map = new SourceMap( + cwd, + [target].concat(group), + this.cSourcesDirs, + ((l: any) => this.debug (l))); } catch (e) { this.log('stderr', (e).toString()); } @@ -126,7 +130,13 @@ export class MI2 extends EventEmitter implements IDebugger { } try { - this.map = new SourceMap(cwd, [target].concat(group), ((l: any) => this.debug (l))); + this.map = + new SourceMap( + cwd, + [target].concat(group), + this.cSourcesDirs, + ((l: any) => this.debug (l)) + ); } catch (e) { this.log('stderr', (e).toString()); } @@ -167,11 +177,13 @@ export class MI2 extends EventEmitter implements IDebugger { let target_exec_symbol = escape(target); let target_args = targetargs; let search_dir = path.dirname(target_exec_symbol); + let search_dir_src = this.map.getSourcePath(target_exec_symbol); if (useCobcrun) { target_args = `-m ${target_exec_symbol} ${target_args}` target_exec_symbol = this.cobcrunPath; } + const cmds = [ this.sendCommand("gdb-set mi-async on", false), this.sendCommand("gdb-set print repeats 1000", false), @@ -180,8 +192,16 @@ export class MI2 extends EventEmitter implements IDebugger { this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), this.sendCommand("file-exec-and-symbols \"" + target_exec_symbol + "\"", false), this.sendCommand("gdb-set stop-on-solib-events 1", false), + this.sendCommand("gdb-set debug-file-directory " + search_dir_src, false), + this.sendCommand("gdb-set solib-search-path " + search_dir, false), ]; + if (search_dir !== search_dir_src) { + cmds.push( + this.sendCommand(`gdb-set substitute-path ${search_dir} ${search_dir_src}`, false) + ); + } + return cmds; } @@ -343,6 +363,7 @@ export class MI2 extends EventEmitter implements IDebugger { // Possibly unreachable if `stop-on-solib-events` is on; still handle in case. let libname = record.output.find((e) => e[0] == "target-name")?.[1]; if (this.map.addLib (libname)) { + this.debug(() => `Added library to map: ${libname}`); this.debug (() => this.map.toString ("updated")); this.reloadBreakPoints (); } @@ -361,7 +382,10 @@ export class MI2 extends EventEmitter implements IDebugger { }); handled = true; } - if (parsed.token == undefined && parsed.resultRecords == undefined && parsed.outOfBandRecord.length == 0) { + if (parsed.token == undefined + && parsed.resultRecords == undefined + && parsed.outOfBandRecord.length == 0) + { handled = true; } if (!handled) { diff --git a/src/parser.c.ts b/src/parser.c.ts index 55a6782..778d969 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -1,26 +1,10 @@ import readline from "n-readlines"; -import * as nativePathFromPath from "path"; +import * as path from "path"; import * as fs from "fs"; import {DebuggerVariable, Attribute, VariableType} from "./debugger"; -const nativePath = { - resolve: function (...args: string[]): string { - const nat = nativePathFromPath.resolve(...args); - return nat; - }, - basename: function (path: string): string { - return nativePathFromPath.basename(path); - }, - isAbsolute: function (path: string): boolean { - return nativePathFromPath.isAbsolute(path); - }, - join: function (...args: string[]) { - return nativePathFromPath.join(...args); - } -}; - function cFile (filename: string) : string { - return nativePath.basename(filename.split('.').slice(0, -1).join('.') + '.c'); + return path.basename(filename.split('.').slice(0, -1).join('.') + '.c'); } const procedureRegex = /\/\*\sLine:\s([0-9]+)(\s+:\sEntry\s)?/i; @@ -67,6 +51,7 @@ const dummyLine = new Line('', 0, '', '', 0, ''); export class SourceMap { private cwd: string; + private cSourcesDirs: string[] = []; private lines: Line[] = new Array(); private variablesByCobol = new Map(); private variablesByC = new Map(); @@ -77,24 +62,51 @@ export class SourceMap { private performLine: number = -1; // 002 - stepOver in routines with "perform" private isVersion2_2_or_3_1_1: boolean = false; - constructor(cwd: string, filesCobol: string[], private log: Function) { - this.cwd = fs.realpathSync(nativePathFromPath.resolve(cwd)); + constructor(cwd: string, filesCobol: string[], cSourcesDirs: string[], private log: Function) { + this.cwd = fs.realpathSync(path.resolve(cwd)); + this.log(`Source dir arr: ${cSourcesDirs}`); + for (const cSourceDir of cSourcesDirs) { + this.log(`Trying to resolve ${cSourceDir}`); + let resolved_path = path.resolve(this.cwd, cSourceDir); + this.log(`Checking for ${resolved_path}`); + if (fs.existsSync(resolved_path)) { + this.cSourcesDirs.push(fs.realpathSync(resolved_path)); + this.log(`It's here`); + } + } + + this.cSourcesDirs.push(this.cwd); + filesCobol.forEach(e => { - this.register (cFile (e)); + let c_file = cFile(e); + for (const dir of this.cSourcesDirs) { + let c_file_path = path.join(dir, c_file); + if (fs.existsSync(c_file_path)) { + this.register (c_file_path); + break; + } + } }); + + this.log(`Resolved source dir: ${this.cSourcesDirs}`); } public addLib (libFile: string) : boolean { + this.log(`Loading ${libFile}`); if (this.loadedLibs.has (libFile)) { return false; } this.loadedLibs.add (libFile); - const c = nativePath.resolve (this.cwd, cFile (libFile)); - if (!fs.existsSync (c)) { - return false; + for (const src of this.cSourcesDirs) { + const c = path.resolve (src, cFile (libFile)); + this.log(`Checking for source candidate: ${c}`); + if (fs.existsSync (c)) { + this.log(`Loaded with sources: ${c}`); + this.register (c); + return true; + } } - this.register (c); - return true; + return false; } public remLib (libFile: string) : boolean { @@ -102,10 +114,23 @@ export class SourceMap { return false; } this.loadedLibs.delete (libFile); - this.unregister (nativePath.resolve (this.cwd, cFile (libFile))); + this.unregister (path.resolve (this.cwd, cFile (libFile))); return true; } + public getSourcePath (target: string) : string | null { + let basename = path.basename(target) + ".c"; + this.log(`Getting source file for ${basename}`); + for (const cSourceDir of this.cSourcesDirs) { + let candidate = path.join(cSourceDir, basename); + this.log(`Candidate ${candidate}`); + if (fs.existsSync(candidate)) { + return cSourceDir; + } + } + return null + } + private unregister (givenFileC: string) : void { const [natFileC, fileC, cleanedFile] = this.ensureAbsolute (givenFileC); this.lines = this.lines.filter (line => line.rootFileC != fileC) ?? []; @@ -119,18 +144,19 @@ export class SourceMap { private ensureAbsolute (fileC: string) : [string, string, string] { let nat = fileC; - if (!nativePath.isAbsolute(fileC)) { - nat = nativePathFromPath.resolve(this.cwd, fileC); - fileC = nativePath.resolve(this.cwd, fileC); + if (!path.isAbsolute(fileC)) { + nat = path.resolve(this.cwd, fileC); + fileC = path.resolve(this.cwd, fileC); } - const basename = nativePath.basename(fileC); + const basename = path.basename(fileC); const cleanedFile = basename.substring(0, basename.lastIndexOf(".c")); return [process.platform === "win32" ? nat : fileC, fileC, cleanedFile]; } private register (givenFileC: string) : void { + // this.log(`Parsing ${givenFileC}`); void this.parse (givenFileC); // just parse the file. } @@ -151,8 +177,8 @@ export class SourceMap { const line = row.toString(); let match = fileCobolRegex.exec(line); if (match) { - if (!nativePath.isAbsolute(match[1])) { - fileCobol = nativePath.resolve(this.cwd, match[1]); + if (!path.isAbsolute(match[1])) { + fileCobol = path.resolve(this.cwd, match[1]); } else { fileCobol = match[1]; } @@ -163,20 +189,34 @@ export class SourceMap { } match = procedureRegex.exec(line); if (match && !match[2]) { - if (this.lines.length > 0 && fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && this.lines[this.lines.length - 1].lineCobol === parseInt(match[1])) { + if (this.lines.length > 0 + && fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) + && this.lines[this.lines.length - 1].lineCobol === parseInt(match[1])) + { this.lines.pop(); } + if(subroutineRegex.exec(line)) this.performLine=-2; // must find line of frame_ptr else this.performLine=-1; - this.lines.push(new Line(fileCobol, parseInt(match[1]), fileC, rootFileC, lineNumber + 2, functionName)); + + this.lines.push( + new Line(fileCobol, + parseInt(match[1]), + fileC, + rootFileC, + lineNumber + 2, + functionName)); } // fix new codegen match = procedureFixRegex.exec(line); if (match && this.lines.length > 0 && this.lines[this.lines.length - 1].functionName == functionName) { let isOldFormat = fixOlderFormat.exec(prevLine); - if(fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? + if( + fileNameCompare( this.lines[this.lines.length - 1].fileCobol, fileCobol) + && (this.isVersion2_2_or_3_1_1 || !isOldFormat)) // Is it in the old format? + { let line = this.lines.pop(); // this.log (`Fixing line: ${line.toString ()}`); line.lineC = parseInt(match[1]); @@ -186,7 +226,14 @@ export class SourceMap { } match = attributeRegex.exec(line); if (match) { - const attribute = new Attribute(match[1], VariableType[match[2]], parseInt(match[3]), parseInt(match[4]), match[5]); + const attribute = + new Attribute( + match[1], + VariableType[match[2]], + parseInt(match[3]), + parseInt(match[4]), + match[5] + ); this.attributes.set(`${cleanedFile}.${match[1]}`, attribute); } match = dataStorageRegex.exec(line); @@ -199,7 +246,8 @@ export class SourceMap { new Attribute(null, VariableType[match[1]], 0, 0), size); this.dataStorages.set(`${functionName}.${dataStorage.cName}`, dataStorage); this.variablesByC.set(`${functionName}.${dataStorage.cName}`, dataStorage); - this.variablesByCobol.set(`${functionName}.${dataStorage.cobolName.toUpperCase()}`, dataStorage); + this.variablesByCobol.set( + `${functionName}.${dataStorage.cobolName.toUpperCase()}`, dataStorage); } match = fieldRegex.exec(line); if (match) { @@ -212,19 +260,36 @@ export class SourceMap { if (dataStorage) { dataStorage.addChild(field); - this.variablesByCobol.set(`${functionName}.${dataStorage.cobolName.toUpperCase()}.${field.cobolName.toUpperCase()}`, field); + this.variablesByCobol.set( + functionName + + dataStorage.cobolName.toUpperCase() + + field.cobolName.toUpperCase(), + field + ); } else { - this.variablesByCobol.set(`${functionName}.${field.cobolName.toUpperCase()}`, field); + this.variablesByCobol.set( + `${functionName}.${field.cobolName.toUpperCase()}`, + field + ); } } match = fileIncludeRegex.exec(line); if (match) { - functionName = this.parse(match[1], prevLine, rootFileC, functionName); + let include_file_path = match[1]; + for (const cSourceDir of this.cSourcesDirs) { + let candidate = path.join(cSourceDir, match[1]); + if (fs.existsSync(candidate)) { + include_file_path = candidate; + break; + } + } + functionName = this.parse(include_file_path, prevLine, rootFileC, functionName); } match = versionRegex.exec(line); if (match) { this.version = match[1]; - if(this.version.startsWith("2.2") || this.version.startsWith("3.1.1")) this.isVersion2_2_or_3_1_1 = true; + if(this.version.startsWith("2.2") || this.version.startsWith("3.1.1")) + this.isVersion2_2_or_3_1_1 = true; } if(this.performLine == -2){ match = frame_ptrFindRegex.exec(line); @@ -279,8 +344,8 @@ export class SourceMap { public hasLineCobol(fileC: string, lineC: number): boolean { if(!fileC || !lineC) return false; - if (!nativePath.isAbsolute(fileC)) { - fileC = nativePath.join(this.cwd, fileC); + if (!path.isAbsolute(fileC)) { + fileC = path.join(this.cwd, fileC); } return this.lines.some(e => e.fileC === fileC && e.lineC === lineC); } @@ -288,23 +353,23 @@ export class SourceMap { // 002 - stepOver in routines with "perform" public hasLineSubroutine(fileC: string, lineC: number): number { if(!fileC || !lineC) return -1; - if (!nativePath.isAbsolute(fileC)) { - fileC = nativePath.join(this.cwd, fileC); + if (!path.isAbsolute(fileC)) { + fileC = path.join(this.cwd, fileC); } return this.lines.find(e => e.fileC === fileC && e.lineC === lineC)?.endPerformLine ?? -1; } // 002 public hasLineC(fileCobol: string, lineCobol: number): boolean { - if (!nativePath.isAbsolute(fileCobol)) { - fileCobol = nativePath.join(this.cwd, fileCobol); + if (!path.isAbsolute(fileCobol)) { + fileCobol = path.join(this.cwd, fileCobol); } return this.lines.some(e => fileNameCompare(e.fileCobol, fileCobol) && e.lineCobol === lineCobol); } public getLineC(fileCobol: string, lineCobol: number): Line { - if (!nativePath.isAbsolute(fileCobol)) { - fileCobol = nativePath.join(this.cwd, fileCobol); + if (!path.isAbsolute(fileCobol)) { + fileCobol = path.join(this.cwd, fileCobol); } return this.lines.find(e => fileNameCompare(e.fileCobol, fileCobol) && e.lineCobol === lineCobol) ?? dummyLine; } @@ -313,8 +378,8 @@ export class SourceMap { if (!fileC) { return dummyLine; } - if (!nativePath.isAbsolute(fileC)) { - fileC = nativePath.join(this.cwd, fileC); + if (!path.isAbsolute(fileC)) { + fileC = path.join(this.cwd, fileC); } return this.lines.find(e => e.fileC === fileC && e.lineC === lineC) ?? dummyLine; } From fe2afa00cca9582067b4238fee20b22c947271c5 Mon Sep 17 00:00:00 2001 From: Emilien Lemaire Date: Fri, 14 Nov 2025 17:23:49 +0100 Subject: [PATCH 33/70] Fix after rebase --- src/extension.ts | 4 +--- src/gdb.ts | 16 ++++------------ src/mi2.ts | 6 +++--- src/parser.c.ts | 22 +++++++++++----------- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index fbc5642..fb7edd7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -86,9 +86,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.cobcrunPath === undefined) { config.cobcrunPath = settings.cobcrunPath; } - if (config.cSourcesDirs === undefined) { - config.cSourcesDirs = []; - } + config.sourcesDirs = config.sourcesDirs ?? []; return config; } diff --git a/src/gdb.ts b/src/gdb.ts index 2d0bf26..3a38132 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -39,13 +39,9 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum verbose: boolean; coverage: boolean; gdbtty: boolean; -<<<<<<< HEAD cobcrunPath: string; useCobcrun: boolean; -======= - module: boolean; - cSourcesDirs: string[]; ->>>>>>> 52fa0cb (Allow specification of c sources directory) + sourcesDirs: string[]; } export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { @@ -59,7 +55,7 @@ export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArgum verbose: boolean; pid: string; remoteDebugger: string; - cSourcesDirs: string[]; + sourcesDirs: string[]; } export class GDBDebugSession extends DebugSession { @@ -98,7 +94,7 @@ export class GDBDebugSession extends DebugSession { args.gdbtty, args.cobcrunPath, args.useCobcrun, - args.cSourcesDirs, + args.sourcesDirs, ); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); @@ -161,13 +157,9 @@ export class GDBDebugSession extends DebugSession { args.verbose, false, false, -<<<<<<< HEAD "", - false -======= false, - args.cSourcesDirs, ->>>>>>> 52fa0cb (Allow specification of c sources directory) + args.sourcesDirs, ); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); diff --git a/src/mi2.ts b/src/mi2.ts index e0a47af..2e401cf 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -40,7 +40,7 @@ export class MI2 extends EventEmitter implements IDebugger { private hasCobGetFieldStringFunction = true; private hasCobPutFieldStringFunction = true; - constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean, public cSourcesDirs: string[]) { + constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean, public sourcesDirs: string[]) { super(); if (procEnv) { const env = {}; @@ -77,7 +77,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.map = new SourceMap( cwd, [target].concat(group), - this.cSourcesDirs, + this.sourcesDirs, ((l: any) => this.debug (l))); } catch (e) { this.log('stderr', (e).toString()); @@ -134,7 +134,7 @@ export class MI2 extends EventEmitter implements IDebugger { new SourceMap( cwd, [target].concat(group), - this.cSourcesDirs, + this.sourcesDirs, ((l: any) => this.debug (l)) ); } catch (e) { diff --git a/src/parser.c.ts b/src/parser.c.ts index 778d969..2877eb6 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -51,7 +51,7 @@ const dummyLine = new Line('', 0, '', '', 0, ''); export class SourceMap { private cwd: string; - private cSourcesDirs: string[] = []; + private sourcesDirs: string[] = []; private lines: Line[] = new Array(); private variablesByCobol = new Map(); private variablesByC = new Map(); @@ -62,24 +62,24 @@ export class SourceMap { private performLine: number = -1; // 002 - stepOver in routines with "perform" private isVersion2_2_or_3_1_1: boolean = false; - constructor(cwd: string, filesCobol: string[], cSourcesDirs: string[], private log: Function) { + constructor(cwd: string, filesCobol: string[], sourcesDirs: string[], private log: Function) { this.cwd = fs.realpathSync(path.resolve(cwd)); - this.log(`Source dir arr: ${cSourcesDirs}`); - for (const cSourceDir of cSourcesDirs) { + this.log(`Source dir arr: ${sourcesDirs}`); + for (const cSourceDir of sourcesDirs) { this.log(`Trying to resolve ${cSourceDir}`); let resolved_path = path.resolve(this.cwd, cSourceDir); this.log(`Checking for ${resolved_path}`); if (fs.existsSync(resolved_path)) { - this.cSourcesDirs.push(fs.realpathSync(resolved_path)); + this.sourcesDirs.push(fs.realpathSync(resolved_path)); this.log(`It's here`); } } - this.cSourcesDirs.push(this.cwd); + this.sourcesDirs.push(this.cwd); filesCobol.forEach(e => { let c_file = cFile(e); - for (const dir of this.cSourcesDirs) { + for (const dir of this.sourcesDirs) { let c_file_path = path.join(dir, c_file); if (fs.existsSync(c_file_path)) { this.register (c_file_path); @@ -88,7 +88,7 @@ export class SourceMap { } }); - this.log(`Resolved source dir: ${this.cSourcesDirs}`); + this.log(`Resolved source dir: ${this.sourcesDirs}`); } public addLib (libFile: string) : boolean { @@ -97,7 +97,7 @@ export class SourceMap { return false; } this.loadedLibs.add (libFile); - for (const src of this.cSourcesDirs) { + for (const src of this.sourcesDirs) { const c = path.resolve (src, cFile (libFile)); this.log(`Checking for source candidate: ${c}`); if (fs.existsSync (c)) { @@ -121,7 +121,7 @@ export class SourceMap { public getSourcePath (target: string) : string | null { let basename = path.basename(target) + ".c"; this.log(`Getting source file for ${basename}`); - for (const cSourceDir of this.cSourcesDirs) { + for (const cSourceDir of this.sourcesDirs) { let candidate = path.join(cSourceDir, basename); this.log(`Candidate ${candidate}`); if (fs.existsSync(candidate)) { @@ -276,7 +276,7 @@ export class SourceMap { match = fileIncludeRegex.exec(line); if (match) { let include_file_path = match[1]; - for (const cSourceDir of this.cSourcesDirs) { + for (const cSourceDir of this.sourcesDirs) { let candidate = path.join(cSourceDir, match[1]); if (fs.existsSync(candidate)) { include_file_path = candidate; From 93a35e0146722fec2b27f132b2a5a3599c6877ea Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 14 Nov 2025 21:33:31 +0100 Subject: [PATCH 34/70] Restore some unneeded changes --- package.json | 284 +++++++++++++++++++++++++++++++++++++++++++++++ src/extension.ts | 10 +- src/gdb.ts | 26 +---- src/mi2.ts | 20 +--- src/parser.c.ts | 115 +++++++++---------- 5 files changed, 340 insertions(+), 115 deletions(-) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..5756267 --- /dev/null +++ b/package.json @@ -0,0 +1,284 @@ +{ + "name": "superbol-vscode-debug", + "displayName": "SuperBOL Debugger for GnuCOBOL", + "description": "Debug or execute COBOL code. No mainframe required.", + "keywords": [ + "cobol", + "gnucobol", + "debugger", + "debug", + "code coverage" + ], + "version": "3.32.0", + "publisher": "OCamlPro SAS", + "contributors": [ + { + "name": "Emilien Lemaire", + "email": "emilien.lemaire@ocamlpro.com" + }, + { + "name": "Olegs Kunicins", + "email": "olegs.kunicins@gmail.com" + } + ], + "license": "GPL-3.0", + "icon": "icon.png", + "engines": { + "vscode": "^1.44.0" + }, + "main": "./out/src/extension", + "activationEvents": [ + "onDebugResolve", + "onDebugInitialConfigurations" + ], + "categories": [ + "Debuggers" + ], + "repository": { + "type": "git", + "url": "https://github.com/OCamlPro/superbol-vscode-debug.git" + }, + "capabilities": { + "untrustedWorkspaces": { + "supported": true + } + }, + "contributes": { + "breakpoints": [ + { + "language": "cobol" + } + ], + "debuggers": [ + { + "type": "superbol-gdb", + "languages": ["cobol", "COBOL"], + "program": "./out/src/gdb.js", + "runtime": "node", + "label": "SuperBOL Debugger for GnuCOBOL", + "configurationAttributes": { + "launch": { + "required": [], + "properties": { + "target": { + "type": "string", + "description": "Path to executable", + "default": "${file}" + }, + "arguments": { + "type": "string", + "description": "Extra arguments for executable", + "default": null + }, + "cwd": { + "type": "string", + "description": "Path to project", + "default": "${workspaceRoot}" + }, + "gdbpath": { + "type": "string", + "description": "Path to gdb", + "default": "gdb" + }, + "libcobpath": { + "type": "string", + "description": "Path to libcob", + "default": null + }, + "group": { + "type": "array", + "description": "Compilation Group for executable", + "default": [] + }, + "env": { + "type": "object", + "description": "Environment variables", + "default": null + }, + "coverage": { + "type": "boolean", + "description": "Enable code coverage", + "default": false + }, + "verbose": { + "type": "boolean", + "description": "Debug GDB", + "default": false + }, + "gdbtty": { + "type": [ + "boolean", + "string" + ], + "description": "Enable external display for debug", + "default": false, + "enum": [ + true, + false, + "vscode", + "xterm", + "gnome-terminal", + "xfce4-terminal", + "konsole", + "external" + ] + } + } + }, + "attach": { + "required": [], + "properties": { + "target": { + "type": "string", + "description": "Path to executable", + "default": "${file}" + }, + "arguments": { + "type": "string", + "description": "Extra arguments for executable", + "default": null + }, + "cwd": { + "type": "string", + "description": "Path to project", + "default": "${workspaceRoot}" + }, + "gdbpath": { + "type": "string", + "description": "Path to gdb", + "default": "gdb" + }, + "libcobpath": { + "type": "string", + "description": "Path to libcob", + "default": null + }, + "group": { + "type": "array", + "description": "Compilation Group for executable", + "default": [] + }, + "env": { + "type": "object", + "description": "Environment variables", + "default": null + }, + "verbose": { + "type": "boolean", + "description": "Debug GDB", + "default": false + }, + "pid": { + "type": "string", + "description": "PID of the executable", + "default": null + }, + "remoteDebugger": { + "type": "string", + "description": "GDB Server host:port", + "default": null + } + } + } + }, + "configurationSnippets": [ + { + "label": "SuperBOL: debug launch", + "description": "New SuperBOL launch request", + "body": { + "name": "${2:SuperBOL: debug launch}", + "type": "superbol-gdb", + "request": "launch", + "target": "$${_:{file}}", + "arguments": "", + "cwd": "$${_:{workspaceRoot}}", + "group": [], + "coverage": false, + "verbose": false, + "gdbtty": false + } + }, + { + "label": "SuperBOL: debug attach local", + "description": "New SuperBOL attach local request", + "body": { + "name": "${2:SuperBOL: debug attach local}", + "type": "superbol-gdb", + "request": "attach", + "pid": "${3:0}", + "target": "$${_:{file}}", + "arguments": "", + "cwd": "$${_:{workspaceRoot}}", + "group": [], + "verbose": false + } + }, + { + "label": "SuperBOL: debug attach remote", + "description": "New SuperBOL attach remote request", + "body": { + "name": "${2:SuperBOL: debug attach remote}", + "type": "superbol-gdb", + "request": "attach", + "remoteDebugger": "${3:host:port}", + "target": "$${_:{file}}", + "arguments": "", + "cwd": "$${_:{workspaceRoot}}", + "group": [], + "verbose": false + } + } + ] + } + ], + "configuration": { + "title": "SuperBOL Debugger", + "properties": { + "superbol-vscode-debug.displayVariableAttributes": { + "type": "boolean", + "default": false, + "description": "Displaying Data Storages and Fields attributes (e.g. size of Alphanumerics or digits and scale of numerics).", + "scope": "resource" + }, + "superbol-vscode-debug.pathToGDB": { + "type": "string", + "description": "Path to the `gdb` command", + "default": "gdb", + "scope": "application" + }, + "superbol-vscode-debug.pathToLibCob": { + "type": "string", + "description": "Path to the folder containing `libcob`", + "default": "/usr/local/gnucobol/lib", + "scope": "application" + } + } + } + }, + "scripts": { + "prepare": "tsc -p ./", + "compile": "tsc -p ./", + "watch": "tsc -w -p ./", + "test": "mocha -u tdd ./out/test/", + "lint": "eslint -c .eslintrc.js --ext .ts ./" + }, + "devDependencies": { + "@types/mocha": "^10.0.1", + "@types/node": "^20.6.3", + "@types/vscode": "^1.44.0", + "@typescript-eslint/eslint-plugin": "^6.7.2", + "@typescript-eslint/parser": "^6.7.2", + "@vscode/test-electron": "^2.3.4", + "eslint": "^8.50.0", + "eslint_d": "^12.2.1", + "mocha": "^10.2.0", + "typescript": "^5.2.2", + "@vscode/debugadapter-testsupport": "^1.51.0" + }, + "dependencies": { + "n-readlines": "^1.0.1", + "package_name": "^1.0.0", + "@vscode/debugprotocol": "^1.51.0", + "@vscode/debugadapter": "^1.51.0" + } +} diff --git a/src/extension.ts b/src/extension.ts index fb7edd7..ec3f41f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -29,12 +29,7 @@ export function deactivate() { } class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { - public resolveDebugConfiguration( - workspaceFolder: vscode.WorkspaceFolder | undefined, - config: vscode.DebugConfiguration, - _token?: vscode.CancellationToken) - : vscode.ProviderResult - { + public resolveDebugConfiguration(workspaceFolder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken) : vscode.ProviderResult { config.gdbargs = ["-q", "--interpreter=mi2"]; const settings = new DebuggerSettings(); if (config.name === undefined) { @@ -83,9 +78,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.gdbtty === undefined) { config.gdbtty = false; } - if (config.cobcrunPath === undefined) { - config.cobcrunPath = settings.cobcrunPath; - } config.sourcesDirs = config.sourcesDirs ?? []; return config; } diff --git a/src/gdb.ts b/src/gdb.ts index 3a38132..2c13dad 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -84,18 +84,7 @@ export class GDBDebugSession extends DebugSession { this.started = false; this.attached = false; - this.miDebugger = - new MI2( - args.gdbpath, - args.gdbargs, - args.env, - args.verbose, - args.noDebug, - args.gdbtty, - args.cobcrunPath, - args.useCobcrun, - args.sourcesDirs, - ); + this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, args.noDebug, args.gdbtty, args.cobcrunPath, args.useCobcrun, args.sourcesDirs); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); @@ -149,18 +138,7 @@ export class GDBDebugSession extends DebugSession { this.attached = true; this.started = false; - this.miDebugger = - new MI2( - args.gdbpath, - args.gdbargs, - args.env, - args.verbose, - false, - false, - "", - false, - args.sourcesDirs, - ); + this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, false, false, "", false, args.sourcesDirs); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); diff --git a/src/mi2.ts b/src/mi2.ts index 2e401cf..249892f 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -74,11 +74,7 @@ export class MI2 extends EventEmitter implements IDebugger { let target_no_ext = target.split('.').slice(0, -1).join('.'); this.gcovFiles.add(target_no_ext); try { - this.map = new SourceMap( - cwd, - [target].concat(group), - this.sourcesDirs, - ((l: any) => this.debug (l))); + this.map = new SourceMap(cwd, [target].concat(group), this.sourcesDirs, ((l: any) => this.debug (l))); } catch (e) { this.log('stderr', (e).toString()); } @@ -130,13 +126,7 @@ export class MI2 extends EventEmitter implements IDebugger { } try { - this.map = - new SourceMap( - cwd, - [target].concat(group), - this.sourcesDirs, - ((l: any) => this.debug (l)) - ); + this.map = new SourceMap(cwd, [target].concat(group), this.sourcesDirs, ((l: any) => this.debug (l))); } catch (e) { this.log('stderr', (e).toString()); } @@ -183,7 +173,6 @@ export class MI2 extends EventEmitter implements IDebugger { target_exec_symbol = this.cobcrunPath; } - const cmds = [ this.sendCommand("gdb-set mi-async on", false), this.sendCommand("gdb-set print repeats 1000", false), @@ -382,10 +371,7 @@ export class MI2 extends EventEmitter implements IDebugger { }); handled = true; } - if (parsed.token == undefined - && parsed.resultRecords == undefined - && parsed.outOfBandRecord.length == 0) - { + if (parsed.token == undefined && parsed.resultRecords == undefined && parsed.outOfBandRecord.length == 0) { handled = true; } if (!handled) { diff --git a/src/parser.c.ts b/src/parser.c.ts index 2877eb6..adff807 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -1,10 +1,26 @@ import readline from "n-readlines"; -import * as path from "path"; +import * as nativePathFromPath from "path"; import * as fs from "fs"; import {DebuggerVariable, Attribute, VariableType} from "./debugger"; +const nativePath = { + resolve: function (...args: string[]): string { + const nat = nativePathFromPath.resolve(...args); + return nat; + }, + basename: function (path: string): string { + return nativePathFromPath.basename(path); + }, + isAbsolute: function (path: string): boolean { + return nativePathFromPath.isAbsolute(path); + }, + join: function (...args: string[]) { + return nativePathFromPath.join(...args); + } +}; + function cFile (filename: string) : string { - return path.basename(filename.split('.').slice(0, -1).join('.') + '.c'); + return nativePath.basename(filename.split('.').slice(0, -1).join('.') + '.c'); } const procedureRegex = /\/\*\sLine:\s([0-9]+)(\s+:\sEntry\s)?/i; @@ -63,11 +79,11 @@ export class SourceMap { private isVersion2_2_or_3_1_1: boolean = false; constructor(cwd: string, filesCobol: string[], sourcesDirs: string[], private log: Function) { - this.cwd = fs.realpathSync(path.resolve(cwd)); - this.log(`Source dir arr: ${sourcesDirs}`); + this.cwd = fs.realpathSync(nativePathFromPath.resolve(cwd)); + this.log(`Source dirs: ${sourcesDirs}`); for (const cSourceDir of sourcesDirs) { this.log(`Trying to resolve ${cSourceDir}`); - let resolved_path = path.resolve(this.cwd, cSourceDir); + let resolved_path = nativePathFromPath.resolve(this.cwd, cSourceDir); this.log(`Checking for ${resolved_path}`); if (fs.existsSync(resolved_path)) { this.sourcesDirs.push(fs.realpathSync(resolved_path)); @@ -80,7 +96,7 @@ export class SourceMap { filesCobol.forEach(e => { let c_file = cFile(e); for (const dir of this.sourcesDirs) { - let c_file_path = path.join(dir, c_file); + let c_file_path = nativePathFromPath.join(dir, c_file); if (fs.existsSync(c_file_path)) { this.register (c_file_path); break; @@ -88,7 +104,7 @@ export class SourceMap { } }); - this.log(`Resolved source dir: ${this.sourcesDirs}`); + this.log(`Resolved source dirs: ${this.sourcesDirs}`); } public addLib (libFile: string) : boolean { @@ -98,7 +114,7 @@ export class SourceMap { } this.loadedLibs.add (libFile); for (const src of this.sourcesDirs) { - const c = path.resolve (src, cFile (libFile)); + const c = nativePathFromPath.resolve (src, cFile (libFile)); this.log(`Checking for source candidate: ${c}`); if (fs.existsSync (c)) { this.log(`Loaded with sources: ${c}`); @@ -114,7 +130,7 @@ export class SourceMap { return false; } this.loadedLibs.delete (libFile); - this.unregister (path.resolve (this.cwd, cFile (libFile))); + this.unregister (nativePath.resolve (this.cwd, cFile (libFile))); return true; } @@ -122,7 +138,7 @@ export class SourceMap { let basename = path.basename(target) + ".c"; this.log(`Getting source file for ${basename}`); for (const cSourceDir of this.sourcesDirs) { - let candidate = path.join(cSourceDir, basename); + let candidate = nativePath.join(cSourceDir, basename); this.log(`Candidate ${candidate}`); if (fs.existsSync(candidate)) { return cSourceDir; @@ -144,12 +160,12 @@ export class SourceMap { private ensureAbsolute (fileC: string) : [string, string, string] { let nat = fileC; - if (!path.isAbsolute(fileC)) { - nat = path.resolve(this.cwd, fileC); - fileC = path.resolve(this.cwd, fileC); + if (!nativePath.isAbsolute(fileC)) { + nat = nativePathFromPath.resolve(this.cwd, fileC); + fileC = nativePath.resolve(this.cwd, fileC); } - const basename = path.basename(fileC); + const basename = nativePath.basename(fileC); const cleanedFile = basename.substring(0, basename.lastIndexOf(".c")); return [process.platform === "win32" ? nat : fileC, fileC, cleanedFile]; @@ -177,8 +193,8 @@ export class SourceMap { const line = row.toString(); let match = fileCobolRegex.exec(line); if (match) { - if (!path.isAbsolute(match[1])) { - fileCobol = path.resolve(this.cwd, match[1]); + if (!nativePath.isAbsolute(match[1])) { + fileCobol = nativePath.resolve(this.cwd, match[1]); } else { fileCobol = match[1]; } @@ -189,34 +205,20 @@ export class SourceMap { } match = procedureRegex.exec(line); if (match && !match[2]) { - if (this.lines.length > 0 - && fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) - && this.lines[this.lines.length - 1].lineCobol === parseInt(match[1])) - { + if (this.lines.length > 0 && fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && this.lines[this.lines.length - 1].lineCobol === parseInt(match[1])) { this.lines.pop(); } - if(subroutineRegex.exec(line)) this.performLine=-2; // must find line of frame_ptr else this.performLine=-1; - - this.lines.push( - new Line(fileCobol, - parseInt(match[1]), - fileC, - rootFileC, - lineNumber + 2, - functionName)); + this.lines.push(new Line(fileCobol, parseInt(match[1]), fileC, rootFileC, lineNumber + 2, functionName)); } // fix new codegen match = procedureFixRegex.exec(line); if (match && this.lines.length > 0 && this.lines[this.lines.length - 1].functionName == functionName) { let isOldFormat = fixOlderFormat.exec(prevLine); - if( - fileNameCompare( this.lines[this.lines.length - 1].fileCobol, fileCobol) - && (this.isVersion2_2_or_3_1_1 || !isOldFormat)) // Is it in the old format? - { + if(fileNameCompare( this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? let line = this.lines.pop(); // this.log (`Fixing line: ${line.toString ()}`); line.lineC = parseInt(match[1]); @@ -226,14 +228,7 @@ export class SourceMap { } match = attributeRegex.exec(line); if (match) { - const attribute = - new Attribute( - match[1], - VariableType[match[2]], - parseInt(match[3]), - parseInt(match[4]), - match[5] - ); + const attribute = new Attribute(match[1], VariableType[match[2]], parseInt(match[3]), parseInt(match[4]), match[5]); this.attributes.set(`${cleanedFile}.${match[1]}`, attribute); } match = dataStorageRegex.exec(line); @@ -246,8 +241,7 @@ export class SourceMap { new Attribute(null, VariableType[match[1]], 0, 0), size); this.dataStorages.set(`${functionName}.${dataStorage.cName}`, dataStorage); this.variablesByC.set(`${functionName}.${dataStorage.cName}`, dataStorage); - this.variablesByCobol.set( - `${functionName}.${dataStorage.cobolName.toUpperCase()}`, dataStorage); + this.variablesByCobol.set(`${functionName}.${dataStorage.cobolName.toUpperCase()}`, dataStorage); } match = fieldRegex.exec(line); if (match) { @@ -260,17 +254,9 @@ export class SourceMap { if (dataStorage) { dataStorage.addChild(field); - this.variablesByCobol.set( - functionName - + dataStorage.cobolName.toUpperCase() - + field.cobolName.toUpperCase(), - field - ); + this.variablesByCobol.set(`${functionName}.${dataStorage.cobolName.toUpperCase()}.${field.cobolName.toUpperCase()}`, field); } else { - this.variablesByCobol.set( - `${functionName}.${field.cobolName.toUpperCase()}`, - field - ); + this.variablesByCobol.set(`${functionName}.${field.cobolName.toUpperCase()}`, field); } } match = fileIncludeRegex.exec(line); @@ -288,8 +274,7 @@ export class SourceMap { match = versionRegex.exec(line); if (match) { this.version = match[1]; - if(this.version.startsWith("2.2") || this.version.startsWith("3.1.1")) - this.isVersion2_2_or_3_1_1 = true; + if(this.version.startsWith("2.2") || this.version.startsWith("3.1.1")) this.isVersion2_2_or_3_1_1 = true; } if(this.performLine == -2){ match = frame_ptrFindRegex.exec(line); @@ -344,8 +329,8 @@ export class SourceMap { public hasLineCobol(fileC: string, lineC: number): boolean { if(!fileC || !lineC) return false; - if (!path.isAbsolute(fileC)) { - fileC = path.join(this.cwd, fileC); + if (!nativePath.isAbsolute(fileC)) { + fileC = nativePath.join(this.cwd, fileC); } return this.lines.some(e => e.fileC === fileC && e.lineC === lineC); } @@ -353,23 +338,23 @@ export class SourceMap { // 002 - stepOver in routines with "perform" public hasLineSubroutine(fileC: string, lineC: number): number { if(!fileC || !lineC) return -1; - if (!path.isAbsolute(fileC)) { - fileC = path.join(this.cwd, fileC); + if (!nativePath.isAbsolute(fileC)) { + fileC = nativePath.join(this.cwd, fileC); } return this.lines.find(e => e.fileC === fileC && e.lineC === lineC)?.endPerformLine ?? -1; } // 002 public hasLineC(fileCobol: string, lineCobol: number): boolean { - if (!path.isAbsolute(fileCobol)) { - fileCobol = path.join(this.cwd, fileCobol); + if (!nativePath.isAbsolute(fileCobol)) { + fileCobol = nativePath.join(this.cwd, fileCobol); } return this.lines.some(e => fileNameCompare(e.fileCobol, fileCobol) && e.lineCobol === lineCobol); } public getLineC(fileCobol: string, lineCobol: number): Line { - if (!path.isAbsolute(fileCobol)) { - fileCobol = path.join(this.cwd, fileCobol); + if (!nativePath.isAbsolute(fileCobol)) { + fileCobol = nativePath.join(this.cwd, fileCobol); } return this.lines.find(e => fileNameCompare(e.fileCobol, fileCobol) && e.lineCobol === lineCobol) ?? dummyLine; } @@ -378,8 +363,8 @@ export class SourceMap { if (!fileC) { return dummyLine; } - if (!path.isAbsolute(fileC)) { - fileC = path.join(this.cwd, fileC); + if (!nativePath.isAbsolute(fileC)) { + fileC = nativePath.join(this.cwd, fileC); } return this.lines.find(e => e.fileC === fileC && e.lineC === lineC) ?? dummyLine; } From adccfb1ea9e4ba1a23350e0a06c91214d7f12ff6 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 14 Nov 2025 23:19:05 +0100 Subject: [PATCH 35/70] Fix and simplify handling of user-given source directories --- src/gdb.ts | 2 +- src/mi2.ts | 28 +++++++------------ src/parser.c.ts | 71 ++++++++++++++++++++++--------------------------- 3 files changed, 43 insertions(+), 58 deletions(-) diff --git a/src/gdb.ts b/src/gdb.ts index 2c13dad..fc1dac1 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -103,7 +103,7 @@ export class GDBDebugSession extends DebugSession { this.crashed = false; this.debugReady = false; this.useVarObjects = false; - // Run in the target executables' directory, unless specificed. + // Run in the target executables' directory, unless specificed; becomes '.' if target is a module name. let cwd = args.cwd ?? path.dirname (args.target); this.miDebugger.load(cwd, args.target, args.arguments, args.group, args.gdbtty).then( /*onfulfilled:*/ () => { diff --git a/src/mi2.ts b/src/mi2.ts index 249892f..a629941 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -81,8 +81,10 @@ export class MI2 extends EventEmitter implements IDebugger { this.debug(() => this.map.toString("created")); - target = path.resolve(cwd, path.basename(target)); - target = target.split('.').slice(0, -1).join('.'); + if (fs.existsSync (target)) { // assume module name otherwise... + target = path.resolve(cwd, path.basename(target)); + target = target.split('.').slice(0, -1).join('.'); + } // FIXME: the following should prefix "cobcrun.exe" if in "module mode", see #13 // FIXME: if we need this code twice then add a comment why, otherwise move to a new function if (process.platform === "win32") { @@ -164,33 +166,23 @@ export class MI2 extends EventEmitter implements IDebugger { cwd = path.dirname(target); } - let target_exec_symbol = escape(target); - let target_args = targetargs; - let search_dir = path.dirname(target_exec_symbol); - let search_dir_src = this.map.getSourcePath(target_exec_symbol); + let targetExec = escape(target); if (useCobcrun) { - target_args = `-m ${target_exec_symbol} ${target_args}` - target_exec_symbol = this.cobcrunPath; + targetargs = `-m ${targetExec} ${targetargs}` + targetExec = this.cobcrunPath; } const cmds = [ this.sendCommand("gdb-set mi-async on", false), this.sendCommand("gdb-set print repeats 1000", false), - this.sendCommand("gdb-set args " + target_args, false), + this.sendCommand("gdb-set args " + targetargs, false), this.sendCommand("gdb-set charset UTF-8", false), this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), - this.sendCommand("file-exec-and-symbols \"" + target_exec_symbol + "\"", false), + this.sendCommand("file-exec-and-symbols \"" + targetExec + "\"", false), this.sendCommand("gdb-set stop-on-solib-events 1", false), - this.sendCommand("gdb-set debug-file-directory " + search_dir_src, false), - this.sendCommand("gdb-set solib-search-path " + search_dir, false), + this.sendCommand("gdb-set directories \"" + this.map.sourcesDirs.join('" "') + "\"", false) ]; - if (search_dir !== search_dir_src) { - cmds.push( - this.sendCommand(`gdb-set substitute-path ${search_dir} ${search_dir_src}`, false) - ); - } - return cmds; } diff --git a/src/parser.c.ts b/src/parser.c.ts index adff807..ced3829 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -67,7 +67,7 @@ const dummyLine = new Line('', 0, '', '', 0, ''); export class SourceMap { private cwd: string; - private sourcesDirs: string[] = []; + public sourcesDirs: string[] = []; private lines: Line[] = new Array(); private variablesByCobol = new Map(); private variablesByC = new Map(); @@ -87,40 +87,42 @@ export class SourceMap { this.log(`Checking for ${resolved_path}`); if (fs.existsSync(resolved_path)) { this.sourcesDirs.push(fs.realpathSync(resolved_path)); - this.log(`It's here`); } } this.sourcesDirs.push(this.cwd); filesCobol.forEach(e => { - let c_file = cFile(e); - for (const dir of this.sourcesDirs) { - let c_file_path = nativePathFromPath.join(dir, c_file); - if (fs.existsSync(c_file_path)) { - this.register (c_file_path); - break; - } + let c_file = this.lookupSourceFile (cFile (e)); + if (c_file) { + this.register (c_file); } }); this.log(`Resolved source dirs: ${this.sourcesDirs}`); } + private lookupSourceFile (file: string) : string | undefined { + for (const dir of this.sourcesDirs) { + const filePath = nativePath.join (dir, file); + if (fs.existsSync (filePath)) { + return filePath; + } + } + return; + } + public addLib (libFile: string) : boolean { this.log(`Loading ${libFile}`); if (this.loadedLibs.has (libFile)) { return false; } this.loadedLibs.add (libFile); - for (const src of this.sourcesDirs) { - const c = nativePathFromPath.resolve (src, cFile (libFile)); - this.log(`Checking for source candidate: ${c}`); - if (fs.existsSync (c)) { - this.log(`Loaded with sources: ${c}`); - this.register (c); - return true; - } + const c = this.lookupSourceFile (cFile (libFile)); + if (c) { + this.log(`Loaded with sources: ${c}`); + this.register (c); + return true; } return false; } @@ -130,21 +132,18 @@ export class SourceMap { return false; } this.loadedLibs.delete (libFile); - this.unregister (nativePath.resolve (this.cwd, cFile (libFile))); - return true; + const c = this.lookupSourceFile (cFile (libFile)); + if (c) { + this.unregister (c); + return true; + } + return false; } - public getSourcePath (target: string) : string | null { - let basename = path.basename(target) + ".c"; + public getSourcePath (target: string) : string | undefined { + let basename = nativePath.basename(target) + ".c"; this.log(`Getting source file for ${basename}`); - for (const cSourceDir of this.sourcesDirs) { - let candidate = nativePath.join(cSourceDir, basename); - this.log(`Candidate ${candidate}`); - if (fs.existsSync(candidate)) { - return cSourceDir; - } - } - return null + return nativePathFromPath.dirname (this.lookupSourceFile (basename)); } private unregister (givenFileC: string) : void { @@ -194,7 +193,7 @@ export class SourceMap { let match = fileCobolRegex.exec(line); if (match) { if (!nativePath.isAbsolute(match[1])) { - fileCobol = nativePath.resolve(this.cwd, match[1]); + fileCobol = nativePath.resolve(nativePathFromPath.dirname (fileC), match[1]); } else { fileCobol = match[1]; } @@ -261,15 +260,9 @@ export class SourceMap { } match = fileIncludeRegex.exec(line); if (match) { - let include_file_path = match[1]; - for (const cSourceDir of this.sourcesDirs) { - let candidate = path.join(cSourceDir, match[1]); - if (fs.existsSync(candidate)) { - include_file_path = candidate; - break; - } - } - functionName = this.parse(include_file_path, prevLine, rootFileC, functionName); + // Note: we assume the included file is in the same dir as the current file. + const filename = nativePath.resolve (nativePathFromPath.dirname (rootFileC), match[1]); + functionName = this.parse(filename, prevLine, rootFileC, functionName); } match = versionRegex.exec(line); if (match) { From 17c67db29167ac2f5e34ef2fa7672dff08293c30 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 14 Nov 2025 23:28:28 +0100 Subject: [PATCH 36/70] Rename configuration entry --- src/extension.ts | 2 +- src/gdb.ts | 8 ++++---- src/mi2.ts | 8 ++++---- src/parser.c.ts | 16 ++++++++-------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index ec3f41f..a45ac11 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -78,7 +78,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.gdbtty === undefined) { config.gdbtty = false; } - config.sourcesDirs = config.sourcesDirs ?? []; + config.sourceDirs = config.sourceDirs ?? []; return config; } diff --git a/src/gdb.ts b/src/gdb.ts index fc1dac1..d088da7 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -41,7 +41,7 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum gdbtty: boolean; cobcrunPath: string; useCobcrun: boolean; - sourcesDirs: string[]; + sourceDirs: string[]; } export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { @@ -55,7 +55,7 @@ export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArgum verbose: boolean; pid: string; remoteDebugger: string; - sourcesDirs: string[]; + sourceDirs: string[]; } export class GDBDebugSession extends DebugSession { @@ -84,7 +84,7 @@ export class GDBDebugSession extends DebugSession { this.started = false; this.attached = false; - this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, args.noDebug, args.gdbtty, args.cobcrunPath, args.useCobcrun, args.sourcesDirs); + this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, args.noDebug, args.gdbtty, args.cobcrunPath, args.useCobcrun, args.sourceDirs); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); @@ -138,7 +138,7 @@ export class GDBDebugSession extends DebugSession { this.attached = true; this.started = false; - this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, false, false, "", false, args.sourcesDirs); + this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, false, false, "", false, args.sourceDirs); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); diff --git a/src/mi2.ts b/src/mi2.ts index a629941..4a5a8c1 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -40,7 +40,7 @@ export class MI2 extends EventEmitter implements IDebugger { private hasCobGetFieldStringFunction = true; private hasCobPutFieldStringFunction = true; - constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean, public sourcesDirs: string[]) { + constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean, public sourceDirs: string[]) { super(); if (procEnv) { const env = {}; @@ -74,7 +74,7 @@ export class MI2 extends EventEmitter implements IDebugger { let target_no_ext = target.split('.').slice(0, -1).join('.'); this.gcovFiles.add(target_no_ext); try { - this.map = new SourceMap(cwd, [target].concat(group), this.sourcesDirs, ((l: any) => this.debug (l))); + this.map = new SourceMap(cwd, [target].concat(group), this.sourceDirs, ((l: any) => this.debug (l))); } catch (e) { this.log('stderr', (e).toString()); } @@ -128,7 +128,7 @@ export class MI2 extends EventEmitter implements IDebugger { } try { - this.map = new SourceMap(cwd, [target].concat(group), this.sourcesDirs, ((l: any) => this.debug (l))); + this.map = new SourceMap(cwd, [target].concat(group), this.sourceDirs, ((l: any) => this.debug (l))); } catch (e) { this.log('stderr', (e).toString()); } @@ -180,7 +180,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), this.sendCommand("file-exec-and-symbols \"" + targetExec + "\"", false), this.sendCommand("gdb-set stop-on-solib-events 1", false), - this.sendCommand("gdb-set directories \"" + this.map.sourcesDirs.join('" "') + "\"", false) + this.sendCommand("gdb-set directories \"" + this.map.sourceDirs.join('" "') + "\"", false) ]; return cmds; diff --git a/src/parser.c.ts b/src/parser.c.ts index ced3829..3a0e831 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -67,7 +67,7 @@ const dummyLine = new Line('', 0, '', '', 0, ''); export class SourceMap { private cwd: string; - public sourcesDirs: string[] = []; + public sourceDirs: string[] = []; private lines: Line[] = new Array(); private variablesByCobol = new Map(); private variablesByC = new Map(); @@ -78,19 +78,19 @@ export class SourceMap { private performLine: number = -1; // 002 - stepOver in routines with "perform" private isVersion2_2_or_3_1_1: boolean = false; - constructor(cwd: string, filesCobol: string[], sourcesDirs: string[], private log: Function) { + constructor(cwd: string, filesCobol: string[], sourceDirs: string[], private log: Function) { this.cwd = fs.realpathSync(nativePathFromPath.resolve(cwd)); - this.log(`Source dirs: ${sourcesDirs}`); - for (const cSourceDir of sourcesDirs) { + this.log(`Source dirs: ${sourceDirs}`); + for (const cSourceDir of sourceDirs) { this.log(`Trying to resolve ${cSourceDir}`); let resolved_path = nativePathFromPath.resolve(this.cwd, cSourceDir); this.log(`Checking for ${resolved_path}`); if (fs.existsSync(resolved_path)) { - this.sourcesDirs.push(fs.realpathSync(resolved_path)); + this.sourceDirs.push(fs.realpathSync(resolved_path)); } } - this.sourcesDirs.push(this.cwd); + this.sourceDirs.push(this.cwd); filesCobol.forEach(e => { let c_file = this.lookupSourceFile (cFile (e)); @@ -99,11 +99,11 @@ export class SourceMap { } }); - this.log(`Resolved source dirs: ${this.sourcesDirs}`); + this.log(`Resolved source dirs: ${this.sourceDirs}`); } private lookupSourceFile (file: string) : string | undefined { - for (const dir of this.sourcesDirs) { + for (const dir of this.sourceDirs) { const filePath = nativePath.join (dir, file); if (fs.existsSync (filePath)) { return filePath; From 9cd5ffbc5dae089d2d63ee9363c63deef6d01b7d Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 14 Nov 2025 23:34:49 +0100 Subject: [PATCH 37/70] Rid of some log messages --- src/extension.ts | 2 +- src/parser.c.ts | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index a45ac11..6b41df7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -29,7 +29,7 @@ export function deactivate() { } class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { - public resolveDebugConfiguration(workspaceFolder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken) : vscode.ProviderResult { + public resolveDebugConfiguration(workspaceFolder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { config.gdbargs = ["-q", "--interpreter=mi2"]; const settings = new DebuggerSettings(); if (config.name === undefined) { diff --git a/src/parser.c.ts b/src/parser.c.ts index 3a0e831..8ebd60c 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -113,14 +113,13 @@ export class SourceMap { } public addLib (libFile: string) : boolean { - this.log(`Loading ${libFile}`); if (this.loadedLibs.has (libFile)) { return false; } this.loadedLibs.add (libFile); + // this.log(`Loading ${libFile}`); const c = this.lookupSourceFile (cFile (libFile)); if (c) { - this.log(`Loaded with sources: ${c}`); this.register (c); return true; } @@ -132,6 +131,9 @@ export class SourceMap { return false; } this.loadedLibs.delete (libFile); + // this.log(`Unloading ${libFile}`); + // Note: assumes there was no FS changes in the meantime. + // Cleaner way would be to record a mapping between libs and source files. const c = this.lookupSourceFile (cFile (libFile)); if (c) { this.unregister (c); @@ -217,7 +219,7 @@ export class SourceMap { match = procedureFixRegex.exec(line); if (match && this.lines.length > 0 && this.lines[this.lines.length - 1].functionName == functionName) { let isOldFormat = fixOlderFormat.exec(prevLine); - if(fileNameCompare( this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? + if(fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? let line = this.lines.pop(); // this.log (`Fixing line: ${line.toString ()}`); line.lineC = parseInt(match[1]); From 5710fa00c79ce41003c84002a55a19da8a1f1cd2 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 14 Nov 2025 23:37:21 +0100 Subject: [PATCH 38/70] Rid of one more unused method --- src/parser.c.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/parser.c.ts b/src/parser.c.ts index 8ebd60c..4500bce 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -142,12 +142,6 @@ export class SourceMap { return false; } - public getSourcePath (target: string) : string | undefined { - let basename = nativePath.basename(target) + ".c"; - this.log(`Getting source file for ${basename}`); - return nativePathFromPath.dirname (this.lookupSourceFile (basename)); - } - private unregister (givenFileC: string) : void { const [natFileC, fileC, cleanedFile] = this.ensureAbsolute (givenFileC); this.lines = this.lines.filter (line => line.rootFileC != fileC) ?? []; From 6ab1813a0e8847271494bb99448db7cdab304bed Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Sat, 15 Nov 2025 17:54:56 +0100 Subject: [PATCH 39/70] Add missing entries in `CHANGELOG.md` --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4126a92..daddaca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Next +* Enable specification of directories where COBOL and C source files are to be found (option `sourceDirs`) [PR #20](https://github.com/ocamlpro/superbol-vscode-debug/pull/20) +* Enable use of `cobcrun` module loaded [PR #19](https://github.com/ocamlpro/superbol-vscode-debug/pull/19) * Avoid forcing a prelaunch task on attach mode [PR #23](https://github.com/ocamlpro/superbol-vscode-debug/pull/23) * Fix first line of subprograms in source mapping [PR #22](https://github.com/ocamlpro/superbol-vscode-debug/pull/22) * Fix detection of attach target that is given as a PID [PR #21](https://github.com/ocamlpro/superbol-vscode-debug/pull/21) From af11ff2547bef4caaf6695863d0a155994da50f1 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Sat, 15 Nov 2025 17:55:19 +0100 Subject: [PATCH 40/70] Fix a likely bug on win32 platforms --- src/mi2.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mi2.ts b/src/mi2.ts index 4a5a8c1..083ff76 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -81,14 +81,14 @@ export class MI2 extends EventEmitter implements IDebugger { this.debug(() => this.map.toString("created")); - if (fs.existsSync (target)) { // assume module name otherwise... + if (!this.useCobcrun) { target = path.resolve(cwd, path.basename(target)); target = target.split('.').slice(0, -1).join('.'); - } - // FIXME: the following should prefix "cobcrun.exe" if in "module mode", see #13 - // FIXME: if we need this code twice then add a comment why, otherwise move to a new function - if (process.platform === "win32") { - target = target + '.exe'; + // FIXME: the following should prefix "cobcrun.exe" if in "module mode", see #13 + // FIXME: if we need this code twice then add a comment why, otherwise move to a new function + if (process.platform === "win32") { + target = target + '.exe'; + } } // 001-gdbtty - Extension for debugging on a separate tty using xterm - start From 8b3fb802e454d8705f56dd88c373164eaf766f67 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Sun, 16 Nov 2025 14:42:24 +0100 Subject: [PATCH 41/70] Fix evaluation of expressions with binary-typed fields --- CHANGELOG.md | 1 + src/gdb.ts | 4 +++- src/mi2.ts | 5 +---- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daddaca..a688f98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Fix evaluation of expressions with binary-typed fields [PR #26](https://github.com/ocamlpro/superbol-vscode-debug/pull/26) * Enable specification of directories where COBOL and C source files are to be found (option `sourceDirs`) [PR #20](https://github.com/ocamlpro/superbol-vscode-debug/pull/20) * Enable use of `cobcrun` module loaded [PR #19](https://github.com/ocamlpro/superbol-vscode-debug/pull/19) * Avoid forcing a prelaunch task on attach mode [PR #23](https://github.com/ocamlpro/superbol-vscode-debug/pull/23) diff --git a/src/gdb.ts b/src/gdb.ts index d088da7..961d11c 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -571,7 +571,8 @@ export class GDBDebugSession extends DebugSession { this.miDebugger.evalExpression(args.expression, threadId, level).then((res) => { response.body = { variablesReference: 0, - result: !!res ? res : "not available" + presentationHint: { kind: 'data' }, + result: res ?? "not available" }; this.sendResponse(response); }, (msg: Error) => { @@ -587,6 +588,7 @@ export class GDBDebugSession extends DebugSession { else response.body = { result: JSON.stringify(output), + // presentationHint: { kind: 'data' }, variablesReference: 0 }; this.sendResponse(response); diff --git a/src/mi2.ts b/src/mi2.ts index 083ff76..9e7bf9f 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -885,10 +885,7 @@ export class MI2 extends EventEmitter implements IDebugger { try { const result = Function(`"use strict"; ${finalExpression}`)(); - if (/[^0-9.\-+]/g.test(result)) { - return `"${result}"`; - } - return result; + return JSON.stringify(result); // deals with escapes. } catch (e) { this.log("stderr", e.message); return `Failed to evaluate ${expression}`; From 526eeb8a50bbfb3cb702408690eba91b33fd0ccd Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Sun, 16 Nov 2025 12:44:02 +0100 Subject: [PATCH 42/70] Silence errors that may occur during asynchronous data requests --- CHANGELOG.md | 1 + src/gdb.ts | 8 +++- src/mi2.ts | 129 +++++++++++++++++++++++++-------------------------- 3 files changed, 72 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daddaca..553630f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Silence some errors due to requests that are handled while the program is running [PR #25](https://github.com/ocamlpro/superbol-vscode-debug/pull/25) * Enable specification of directories where COBOL and C source files are to be found (option `sourceDirs`) [PR #20](https://github.com/ocamlpro/superbol-vscode-debug/pull/20) * Enable use of `cobcrun` module loaded [PR #19](https://github.com/ocamlpro/superbol-vscode-debug/pull/19) * Avoid forcing a prelaunch task on attach mode [PR #23](https://github.com/ocamlpro/superbol-vscode-debug/pull/23) diff --git a/src/gdb.ts b/src/gdb.ts index d088da7..b591d1c 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -440,6 +440,9 @@ export class GDBDebugSession extends DebugSession { const variables: DebugProtocol.Variable[] = []; const [threadId, level] = this.frameIdToThreadAndLevel(id); const stackVariables = await this.miDebugger.getStackVariables(threadId, level); + if (stackVariables === undefined) { + this.sendResponse(response); + } globalThis.varGlobal = []; for (const stackVariable of stackVariables) { let reference = 0; @@ -482,6 +485,9 @@ export class GDBDebugSession extends DebugSession { try { // TODO: this evals on an (effectively) unknown thread for multithreaded programs. const stackVariable = await this.miDebugger.evalCobField(id, 0, 0); + if (stackVariable === undefined) { + this.sendResponse(response); // fail early and silently + } let variables: DebugProtocol.Variable[] = []; @@ -499,7 +505,7 @@ export class GDBDebugSession extends DebugSession { let value = child.displayableType; if (!this.showVariableDetails) { const evaluatedChild = await this.miDebugger.evalCobField(childId, 0, 0); - value = evaluatedChild.value || "null"; + value = evaluatedChild !== undefined ? (evaluatedChild.value || "null") : "?"; } variables.push({ diff --git a/src/mi2.ts b/src/mi2.ts index 083ff76..cd5bb27 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -25,6 +25,8 @@ export function couldBeOutput(line: string) { return !nonOutput.exec(line); } +enum failure_handling { Report_n_reject, Suppress, Silence } + export class MI2 extends EventEmitter implements IDebugger { private map: SourceMap; private gcovFiles: Set = new Set(); @@ -106,7 +108,7 @@ export class MI2 extends EventEmitter implements IDebugger { const promises = this.initCommands(target, targetargs, cwd, this.useCobcrun); // 001-gdbtty - additional parameters for gdb for (let item of gdbttyParameters) - promises.push(this.sendCommand("gdb-set " + item, false)); + promises.push(this.sendCommand("gdb-set " + item)); //001 Promise.all(promises).then(() => { this.emit("debug-ready"); @@ -173,14 +175,14 @@ export class MI2 extends EventEmitter implements IDebugger { } const cmds = [ - this.sendCommand("gdb-set mi-async on", false), - this.sendCommand("gdb-set print repeats 1000", false), - this.sendCommand("gdb-set args " + targetargs, false), - this.sendCommand("gdb-set charset UTF-8", false), - this.sendCommand("environment-directory \"" + escape(cwd) + "\"", false), - this.sendCommand("file-exec-and-symbols \"" + targetExec + "\"", false), - this.sendCommand("gdb-set stop-on-solib-events 1", false), - this.sendCommand("gdb-set directories \"" + this.map.sourceDirs.join('" "') + "\"", false) + this.sendCommand("gdb-set mi-async on"), + this.sendCommand("gdb-set print repeats 1000"), + this.sendCommand("gdb-set args " + targetargs), + this.sendCommand("gdb-set charset UTF-8"), + this.sendCommand("environment-directory \"" + escape(cwd) + "\""), + this.sendCommand("file-exec-and-symbols \"" + targetExec + "\""), + this.sendCommand("gdb-set stop-on-solib-events 1"), + this.sendCommand("gdb-set directories \"" + this.map.sourceDirs.join('" "') + "\"") ]; return cmds; @@ -572,9 +574,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async changeVariable(name: string, rawValue: string): Promise { - if (this.verbose) { - this.log("stderr", "changeVariable"); - } + this.debug("changeVariable"); const functionName = await this.getCurrentFunctionName(); @@ -607,9 +607,7 @@ export class MI2 extends EventEmitter implements IDebugger { } loadBreakPoints(breakpoints: Breakpoint[]): Thenable<[boolean, Breakpoint][]> { - if (this.verbose) { - this.log("stderr", "loadBreakPoints"); - } + this.debug("loadBreakPoints"); const promisses = []; breakpoints.forEach(breakpoint => { promisses.push(this.addBreakPoint(breakpoint)); @@ -627,16 +625,12 @@ export class MI2 extends EventEmitter implements IDebugger { } setBreakPointCondition(bkptNum: number, condition: string): Thenable { - if (this.verbose) { - this.log("stderr", "setBreakPointCondition"); - } + this.debug("setBreakPointCondition"); return this.sendCommand("break-condition " + bkptNum.toString() + " " + condition); } addBreakPoint(breakpoint: Breakpoint): Thenable<[boolean, Breakpoint]> { - if (this.verbose) { - this.log("stderr", "addBreakPoint "); - } + this.debug("addBreakPoint"); return new Promise((resolve, reject) => { if (this.breakpoints.has(breakpoint)) { @@ -704,9 +698,7 @@ export class MI2 extends EventEmitter implements IDebugger { } removeBreakPoint(breakpoint: Breakpoint): Thenable { - if (this.verbose) { - this.log("stderr", "removeBreakPoint"); - } + this.debug("removeBreakPoint"); return new Promise((resolve, _reject) => { if (!this.breakpoints.has(breakpoint)) { if (this.ignoredBreakpoints.has(breakpoint)) { @@ -726,9 +718,7 @@ export class MI2 extends EventEmitter implements IDebugger { } clearBreakPoints(): Thenable { - if (this.verbose) { - this.log("stderr", "clearBreakPoints"); - } + this.debug("clearBreakPoints"); return new Promise((resolve, _reject) => { this.sendCommand("break-delete").then((result) => { if (result.resultRecords.resultClass == "done") { @@ -745,9 +735,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async getThreads(): Promise { - if (this.verbose) { - this.log("stderr", "getThreads"); - } + this.debug("getThreads"); return new Promise((resolve, reject) => { if (!!this.noDebug) { return; @@ -769,9 +757,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async getStack(maxLevels: number, thread: number): Promise { - if (this.verbose) { - this.log("stderr", "getStack"); - } + this.debug("getStack"); let command = "stack-list-frames"; if (thread != 0) { command += ` --thread ${thread}`; @@ -779,7 +765,9 @@ export class MI2 extends EventEmitter implements IDebugger { if (maxLevels) { command += " 0 " + maxLevels.toString(); } - const result = await this.sendCommand(command); + const result = await this.sendCommand(command, failure_handling.Silence); + if (result === undefined) + return; const stack = result.result("stack"); return stack.map(element => { const level = MINode.valueOf(element, "@frame.level"); @@ -811,21 +799,24 @@ export class MI2 extends EventEmitter implements IDebugger { } async getCurrentFunctionName(): Promise { - if (this.verbose) { - this.log("stderr", "getCurrentFunctionName"); - } - const response = await this.sendCommand("stack-info-frame"); - return response.result("frame.func").toLowerCase(); + this.debug("getCurrentFunctionName"); + const response = await this.sendCommand("stack-info-frame", failure_handling.Silence); + if (response === undefined) + return; + return response.result("frame.func")?.toLowerCase(); } async getStackVariables(thread: number, frame: number): Promise { - if (this.verbose) { - this.log("stderr", "getStackVariables"); - } + this.debug("getStackVariables"); const functionName = await this.getCurrentFunctionName(); + if (functionName === undefined) + return; + + const variablesResponse = await this.sendCommand(`stack-list-variables --thread ${thread} --frame ${frame} --all-values`, failure_handling.Silence); + if (variablesResponse === undefined) + return; - const variablesResponse = await this.sendCommand(`stack-list-variables --thread ${thread} --frame ${frame} --all-values`); const variables = variablesResponse.result("variables"); const currentFrameVariables = new Set(); @@ -865,11 +856,11 @@ export class MI2 extends EventEmitter implements IDebugger { } async evalExpression(expression: string, thread: number, frame: number): Promise { - const functionName = await this.getCurrentFunctionName(); + this.debug("evalExpression", expression); - if (this.verbose) { - this.log("stderr", "evalExpression"); - } + const functionName = await this.getCurrentFunctionName(); + if (functionName === undefined) + return; let [finalExpression, variableNames] = parseExpression(expression, functionName, this.map); finalExpression = `return ${finalExpression};`; @@ -890,17 +881,17 @@ export class MI2 extends EventEmitter implements IDebugger { } return result; } catch (e) { - this.log("stderr", e.message); + this.debug(e.message); return `Failed to evaluate ${expression}`; } } async evalCobField(name: string, thread: number, frame: number): Promise { - const functionName = await this.getCurrentFunctionName(); + this.debug("evalCobField", name); - if (this.verbose) { - this.log("stderr", "evalCobField"); - } + const functionName = await this.getCurrentFunctionName(); + if (functionName === undefined) + return; try { const variable = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); @@ -913,9 +904,7 @@ export class MI2 extends EventEmitter implements IDebugger { } private async evalVariable(variable: DebuggerVariable, thread: number, frame: number): Promise { - if (this.verbose) { - this.log("stderr", "evalVariable"); - } + this.debug("evalVariable", variable.cName); let command = "data-evaluate-expression "; if (thread != 0) { @@ -933,10 +922,12 @@ export class MI2 extends EventEmitter implements IDebugger { let dataResponse; let value = null; try { - dataResponse = await this.sendCommand(command); - value = dataResponse.result("value"); - if (value === "0x0") { - value = null; + dataResponse = await this.sendCommand(command, failure_handling.Silence); + if (dataResponse !== undefined) { + value = dataResponse.result("value"); + if (value === "0x0") { + value = null; + } } } catch (error) { if (error.message.includes("No symbol \"cob_get_field_str_buffered\"")) { @@ -993,16 +984,24 @@ export class MI2 extends EventEmitter implements IDebugger { }); } - private sendCommand(command: string, suppressFailure: boolean = false): Thenable { + private sendCommand(command: string, on_failure: failure_handling = undefined): Thenable { return new Promise((resolve, reject) => { const sel = this.currentToken++; this.handlers[sel] = (node: MINode) => { if (node && node.resultRecords && node.resultRecords.resultClass === "error") { - if (suppressFailure) { - this.log("stderr", `WARNING: Error executing command '${command}'`); - resolve(node); - } else - reject(new MIError(node.result("msg") || "Internal error", command)); + switch (on_failure) { + case failure_handling.Suppress: + this.log("stderr", `WARNING: Error executing command '${command}'`); + resolve(node); + break; + case failure_handling.Silence: + resolve(undefined); + break; + default: + case failure_handling.Report_n_reject: + reject(new MIError(node.result("msg") || "Internal error", command)); + break; + } } else resolve(node); }; From 41d77a2a191e49d3fbeb53e38d9b8171294be81a Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Sun, 16 Nov 2025 14:51:32 +0100 Subject: [PATCH 43/70] Remove unneeded fields from auto-generated configurations --- CHANGELOG.md | 1 + src/extension.ts | 14 +++----------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daddaca..611050d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Remove unneeded fields from auto-generated configurations [PR #27](https://github.com/ocamlpro/superbol-vscode-debug/pull/27) * Enable specification of directories where COBOL and C source files are to be found (option `sourceDirs`) [PR #20](https://github.com/ocamlpro/superbol-vscode-debug/pull/20) * Enable use of `cobcrun` module loaded [PR #19](https://github.com/ocamlpro/superbol-vscode-debug/pull/19) * Avoid forcing a prelaunch task on attach mode [PR #23](https://github.com/ocamlpro/superbol-vscode-debug/pull/23) diff --git a/src/extension.ts b/src/extension.ts index 6b41df7..6708f0f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -92,11 +92,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { request: "launch", preLaunchTask: "SuperBOL: build (debug)", target: "${file}", - arguments: "", - group: [], - coverage: false, - verbose: false, - gdbtty: false + arguments: "" }; const attachLocalConfiguration: vscode.DebugConfiguration = { @@ -105,9 +101,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { request: "attach", pid: "${input:pid}", target: "${file}", - arguments: "", - group: [], - verbose: false + arguments: "" }; const attachRemoteConfiguration: vscode.DebugConfiguration = { @@ -116,9 +110,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { request: "attach", remoteDebugger: "${input:remoteDebugger}", target: "${file}", - arguments: "", - group: [], - verbose: false + arguments: "" } return [ From 9e58e010e0d29b97ebac5bb7bec4aea1a76abbef Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Sun, 16 Nov 2025 15:59:44 +0100 Subject: [PATCH 44/70] Drop unneeded argument setting for default attach configurations --- CHANGELOG.md | 2 +- package.json | 2 -- src/extension.ts | 6 ++---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ad9fdc..7ec3953 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Next -* Remove unneeded fields from auto-generated configurations [PR #27](https://github.com/ocamlpro/superbol-vscode-debug/pull/27) +* Remove unneeded fields from auto-generated configurations [PR #27](https://github.com/ocamlpro/superbol-vscode-debug/pull/27) [PR #28](https://github.com/ocamlpro/superbol-vscode-debug/pull/28) * Fix evaluation of expressions with binary-typed fields [PR #26](https://github.com/ocamlpro/superbol-vscode-debug/pull/26) * Silence some errors due to requests that are handled while the program is running [PR #25](https://github.com/ocamlpro/superbol-vscode-debug/pull/25) * Enable specification of directories where COBOL and C source files are to be found (option `sourceDirs`) [PR #20](https://github.com/ocamlpro/superbol-vscode-debug/pull/20) diff --git a/package.json b/package.json index 5756267..0d61747 100644 --- a/package.json +++ b/package.json @@ -207,7 +207,6 @@ "request": "attach", "pid": "${3:0}", "target": "$${_:{file}}", - "arguments": "", "cwd": "$${_:{workspaceRoot}}", "group": [], "verbose": false @@ -222,7 +221,6 @@ "request": "attach", "remoteDebugger": "${3:host:port}", "target": "$${_:{file}}", - "arguments": "", "cwd": "$${_:{workspaceRoot}}", "group": [], "verbose": false diff --git a/src/extension.ts b/src/extension.ts index 6708f0f..2b30ddb 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -100,8 +100,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { type: "superbol-gdb", request: "attach", pid: "${input:pid}", - target: "${file}", - arguments: "" + target: "${file}" }; const attachRemoteConfiguration: vscode.DebugConfiguration = { @@ -109,8 +108,7 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { type: "superbol-gdb", request: "attach", remoteDebugger: "${input:remoteDebugger}", - target: "${file}", - arguments: "" + target: "${file}" } return [ From c7ed8269a1d5f37c31c25e962fcd866c96660f3d Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 17 Nov 2025 09:25:31 +0100 Subject: [PATCH 45/70] Support COBOL and C source code in distinct directories --- CHANGELOG.md | 1 + src/parser.c.ts | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ec3953..8911e0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Support cases where the COBOL source code and the corresponding C files are in distinct directories [PR #29](https://github.com/ocamlpro/superbol-vscode-debug/pull/29) * Remove unneeded fields from auto-generated configurations [PR #27](https://github.com/ocamlpro/superbol-vscode-debug/pull/27) [PR #28](https://github.com/ocamlpro/superbol-vscode-debug/pull/28) * Fix evaluation of expressions with binary-typed fields [PR #26](https://github.com/ocamlpro/superbol-vscode-debug/pull/26) * Silence some errors due to requests that are handled while the program is running [PR #25](https://github.com/ocamlpro/superbol-vscode-debug/pull/25) diff --git a/src/parser.c.ts b/src/parser.c.ts index 4500bce..f734c73 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -188,10 +188,21 @@ export class SourceMap { const line = row.toString(); let match = fileCobolRegex.exec(line); if (match) { - if (!nativePath.isAbsolute(match[1])) { - fileCobol = nativePath.resolve(nativePathFromPath.dirname (fileC), match[1]); + const filename = match[1]; + const filebase = nativePath.basename (filename); + if (!nativePath.isAbsolute(filename)) { + fileCobol = nativePath.resolve(nativePathFromPath.dirname (fileC), filename); + if (!fs.existsSync(fileCobol)) { + fileCobol = nativePath.resolve(nativePathFromPath.dirname (fileC), filebase); + } + if (!fs.existsSync(fileCobol)) { + fileCobol = this.lookupSourceFile (filename); + } } else { - fileCobol = match[1]; + fileCobol = filename; + } + if (!fs.existsSync(fileCobol)) { + fileCobol = this.lookupSourceFile (filebase) } } match = functionRegex.exec(line); From fd75b25aa066ffd5132a4ba29d2ecb041401d8dd Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 21 Nov 2025 21:37:38 +0100 Subject: [PATCH 46/70] Restore ability to debug and run extension tests --- .vscode-test.js | 11 + .vscode/launch.json | 10 +- package.json | 45 +- src/parser.c.ts | 2 +- test/suite/functions.test.ts | 4 +- test/suite/index.ts | 4 +- test/suite/parser.c.test.ts | 18 +- tsconfig.json | 2 +- yarn.lock | 1722 ++++++++++++++++++++++++---------- 9 files changed, 1273 insertions(+), 545 deletions(-) create mode 100644 .vscode-test.js diff --git a/.vscode-test.js b/.vscode-test.js new file mode 100644 index 0000000..b9ad718 --- /dev/null +++ b/.vscode-test.js @@ -0,0 +1,11 @@ +const { defineConfig } = require('@vscode/test-cli'); + +module.exports = defineConfig([ + { + files: 'out/test/**/*.test.js', + mocha: { + ui: 'tdd', + timeout: 20000 + } + } +]); diff --git a/.vscode/launch.json b/.vscode/launch.json index 6d9d584..2cf08a3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,13 +7,12 @@ "request": "launch", "runtimeExecutable": "${execPath}", "args": [ - "--extensionDevelopmentPath=${workspaceRoot}", + "--extensionDevelopmentPath=${workspaceFolder}", "--trace-deprecation" ], - "stopOnEntry": false, "sourceMaps": true, "outFiles": [ - "${workspaceRoot}/out/**/*.js" + "${workspaceFolder}/out/test/**/*.js" ], "preLaunchTask": "npm", "internalConsoleOptions": "openOnSessionStart" @@ -28,11 +27,12 @@ "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" ], + "sourceMaps": true, "outFiles": [ - "${workspaceRoot}/out/**/*.js" + "${workspaceFolder}/out/test/**/*.js" ], "preLaunchTask": "npm", "internalConsoleOptions": "openOnSessionStart" } ] -} \ No newline at end of file +} diff --git a/package.json b/package.json index 0d61747..c2f543a 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,14 @@ "version": "3.32.0", "publisher": "OCamlPro SAS", "contributors": [ - { - "name": "Emilien Lemaire", - "email": "emilien.lemaire@ocamlpro.com" - }, - { - "name": "Olegs Kunicins", - "email": "olegs.kunicins@gmail.com" - } + { + "name": "Emilien Lemaire", + "email": "emilien.lemaire@ocamlpro.com" + }, + { + "name": "Olegs Kunicins", + "email": "olegs.kunicins@gmail.com" + } ], "license": "GPL-3.0", "icon": "icon.png", @@ -52,7 +52,10 @@ "debuggers": [ { "type": "superbol-gdb", - "languages": ["cobol", "COBOL"], + "languages": [ + "cobol", + "COBOL" + ], "program": "./out/src/gdb.js", "runtime": "node", "label": "SuperBOL Debugger for GnuCOBOL", @@ -257,26 +260,30 @@ "prepare": "tsc -p ./", "compile": "tsc -p ./", "watch": "tsc -w -p ./", - "test": "mocha -u tdd ./out/test/", + "test": "npm run compile && npm exec vscode-test", "lint": "eslint -c .eslintrc.js --ext .ts ./" }, "devDependencies": { - "@types/mocha": "^10.0.1", + "@types/expect": "^1.20.4", + "@types/mocha": "^10.0.10", "@types/node": "^20.6.3", - "@types/vscode": "^1.44.0", + "@types/vscode": "^1.64.0", "@typescript-eslint/eslint-plugin": "^6.7.2", "@typescript-eslint/parser": "^6.7.2", - "@vscode/test-electron": "^2.3.4", + "@vscode/debugadapter-testsupport": "^1.51.0", + "@vscode/test-cli": "^0.0.12", + "@vscode/test-electron": "^2.5.2", "eslint": "^8.50.0", "eslint_d": "^12.2.1", - "mocha": "^10.2.0", - "typescript": "^5.2.2", - "@vscode/debugadapter-testsupport": "^1.51.0" + "mocha": "^10.8.2", + "ts-mocha": "^11.1.0", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.2.2" }, "dependencies": { - "n-readlines": "^1.0.1", - "package_name": "^1.0.0", + "@vscode/debugadapter": "^1.51.0", "@vscode/debugprotocol": "^1.51.0", - "@vscode/debugadapter": "^1.51.0" + "n-readlines": "^1.0.1" } } diff --git a/src/parser.c.ts b/src/parser.c.ts index f734c73..bdac531 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -78,7 +78,7 @@ export class SourceMap { private performLine: number = -1; // 002 - stepOver in routines with "perform" private isVersion2_2_or_3_1_1: boolean = false; - constructor(cwd: string, filesCobol: string[], sourceDirs: string[], private log: Function) { + constructor(cwd: string, filesCobol: string[], sourceDirs: string[], private log: Function = (_ => {})) { this.cwd = fs.realpathSync(nativePathFromPath.resolve(cwd)); this.log(`Source dirs: ${sourceDirs}`); for (const cSourceDir of sourceDirs) { diff --git a/test/suite/functions.test.ts b/test/suite/functions.test.ts index 4805c71..a87999f 100644 --- a/test/suite/functions.test.ts +++ b/test/suite/functions.test.ts @@ -6,8 +6,8 @@ import { parseExpression, cleanRawValue } from '../../src/functions'; suite("Useful functions", () => { const cwd = nativePath.resolve(__dirname, '../../../test/resources'); const c = nativePath.resolve(cwd, 'petstore.c'); - const parsed = new SourceMap(cwd, [c]); - console.log(parsed.toString()); + const parsed = new SourceMap(cwd, [c], [cwd]); + //console.log(parsed.toString()); const functionName = "petstore_"; test("it can parse expressions", () => { diff --git a/test/suite/index.ts b/test/suite/index.ts index b1df30c..7c9f287 100644 --- a/test/suite/index.ts +++ b/test/suite/index.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +import Mocha from 'mocha'; +import glob from 'glob'; export function run(): Promise { // Create the mocha test diff --git a/test/suite/parser.c.test.ts b/test/suite/parser.c.test.ts index 3f5a621..04e133b 100644 --- a/test/suite/parser.c.test.ts +++ b/test/suite/parser.c.test.ts @@ -6,8 +6,8 @@ suite("C code parse", () => { const cwd = nativePath.resolve(__dirname, '../../../test/resources'); test("Minimal", () => { const c = nativePath.resolve(cwd, 'hello.c'); - const cobol = '/home/olegs/projects/gnucobol-debug/test/resources/hello.cbl'; - const parsed = new SourceMap(cwd, [c]); + const cobol = nativePath.resolve(cwd, 'hello.cbl'); + const parsed = new SourceMap(cwd, [c], [cwd]); assert.equal(3, parsed.getLinesCount()); assert.equal(3, parsed.getVariablesCount()); @@ -24,8 +24,8 @@ suite("C code parse", () => { }); test("GnuCOBOL 3.1.1", () => { const c = nativePath.resolve(cwd, 'hello3.c'); - const cobol = '/home/olegs/projects/gnucobol-debug/test/resources/hello3.cbl'; - const parsed = new SourceMap(cwd, [c]); + const cobol = nativePath.resolve(cwd, 'hello3.cbl'); + const parsed = new SourceMap(cwd, [c], [cwd]); assert.equal(3, parsed.getLinesCount()); assert.equal(3, parsed.getVariablesCount()); @@ -47,7 +47,7 @@ suite("C code parse", () => { const cSample = nativePath.resolve(cwd, 'sample.c'); const cSubSample = nativePath.resolve(cwd, 'subsample.c'); const cSubSubSample = nativePath.resolve(cwd, 'subsubsample.c'); - const parsed = new SourceMap(cwd, [cSample, cSubSample, cSubSubSample]); + const parsed = new SourceMap(cwd, [cSample, cSubSample, cSubSubSample], [cwd]); assert.equal(7, parsed.getLinesCount()); assert.equal(14, parsed.getVariablesCount()); @@ -65,7 +65,7 @@ suite("C code parse", () => { }); test("Variables Hierarchy", () => { const c = nativePath.resolve(cwd, 'petstore.c'); - const parsed = new SourceMap(cwd, [c]); + const parsed = new SourceMap(cwd, [c], [cwd]); assert.equal('b_14', parsed.getVariableByCobol('petstore_.WS-BILL').cName); assert.equal('f_15', parsed.getVariableByCobol('petstore_.WS-BILL.TOTAL-QUANTITY').cName); @@ -74,7 +74,7 @@ suite("C code parse", () => { }); test("Find variables by function and COBOL name", () => { const c = nativePath.resolve(cwd, 'petstore.c'); - const parsed = new SourceMap(cwd, [c]); + const parsed = new SourceMap(cwd, [c], [cwd]); assert.equal('f_15', parsed.findVariableByCobol('petstore_', 'TOTAL-QUANTITY').cName); assert.equal('f_15', parsed.findVariableByCobol('petstore_', 'WS-BILL.TOTAL-QUANTITY').cName); @@ -85,7 +85,7 @@ suite("C code parse", () => { }); test("Attributes", () => { const c = nativePath.resolve(cwd, 'datatypes.c'); - const parsed = new SourceMap(cwd, [c]); + const parsed = new SourceMap(cwd, [c], [cwd]); for (let variable of parsed.getVariablesByCobol()) { assert.notEqual(variable.attribute, null); @@ -108,7 +108,7 @@ suite("C code parse", () => { }); test("Multiple Functions", () => { const c = nativePath.resolve(cwd, 'func.c'); - const parsed = new SourceMap(cwd, [c]); + const parsed = new SourceMap(cwd, [c], [cwd]); const f_6 = parsed.getVariableByC('func_.f_6'); assert.equal('argA', f_6.cobolName); diff --git a/tsconfig.json b/tsconfig.json index 7990b0b..d8793b8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,7 @@ "rootDir": ".", "esModuleInterop": true, }, - "include": ["src"], + "include": ["src", "test"], "exclude": [ "node_modules", ".vscode-test" diff --git a/yarn.lock b/yarn.lock index abc796a..10c1f99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,31 +2,38 @@ # yarn lockfile v1 -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== +"@bcoe/v8-coverage@^1.0.1": + version "1.0.2" + resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz" + integrity sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA== -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== dependencies: - eslint-visitor-keys "^3.3.0" + "@jridgewell/trace-mapping" "0.3.9" -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.9.0" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz" + integrity sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g== + dependencies: + eslint-visitor-keys "^3.4.3" -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.12.2" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz" + integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.5.2" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -34,185 +41,317 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.43.0": - version "8.43.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0" - integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg== +"@eslint/js@8.57.1": + version "8.57.1" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz" + integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== -"@humanwhocodes/config-array@^0.11.10": - version "0.11.10" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" - integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== +"@humanwhocodes/config-array@^0.13.0": + version "0.13.0" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz" + integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" + "@humanwhocodes/object-schema" "^2.0.3" + debug "^4.3.1" minimatch "^3.0.5" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/object-schema@^2.0.3": + version "2.0.3" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": + version "0.1.3" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.5" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + +"@jridgewell/trace-mapping@^0.3.12": + version "0.3.31" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@types/json-schema@^7.0.9": - version "7.0.12" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" - integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== - -"@types/mocha@^10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" - integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== - -"@types/node@^20.3.2": - version "20.3.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.2.tgz#fa6a90f2600e052a03c18b8cb3fd83dd4e599898" - integrity sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw== - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@types/vscode@^1.44.0": - version "1.79.1" - resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.79.1.tgz#ab568315f9c844a8f4fa8f168b2d6dbf1f58dd02" - integrity sha512-Ikwc4YbHABzqthrWfeAvItaAIfX9mdjMWxqNgTpGjhgOu0TMRq9LzyZ2yBK0JhYqoSjEubEPawf6zJgnl6Egtw== - -"@typescript-eslint/eslint-plugin@^5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz#81382d6ecb92b8dda70e91f9035611cb2fecd1c3" - integrity sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.60.1" - "@typescript-eslint/type-utils" "5.60.1" - "@typescript-eslint/utils" "5.60.1" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@tsconfig/node10@^1.0.7": + version "1.0.12" + resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz" + integrity sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@types/expect@^1.20.4": + version "1.20.4" + resolved "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz" + integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== + +"@types/istanbul-lib-coverage@^2.0.1": + version "2.0.6" + resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/json-schema@^7.0.12": + version "7.0.15" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/mocha@^10.0.10": + version "10.0.10" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz" + integrity sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q== + +"@types/node@*", "@types/node@^20.6.3": + version "20.19.25" + resolved "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz" + integrity sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ== + dependencies: + undici-types "~6.21.0" + +"@types/semver@^7.5.0": + version "7.7.1" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz" + integrity sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA== + +"@types/vscode@^1.64.0": + version "1.64.0" + resolved "https://registry.npmjs.org/@types/vscode/-/vscode-1.64.0.tgz" + integrity sha512-bSlAWz5WtcSL3cO9tAT/KpEH9rv5OBnm93OIIFwdCshaAiqr2bp1AUyEwW9MWeCvZBHEXc3V0fTYVdVyzDNwHA== + +"@typescript-eslint/eslint-plugin@^6.7.2": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz" + integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/type-utils" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.60.1.tgz#0f2f58209c0862a73e3d5a56099abfdfa21d0fd3" - integrity sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q== - dependencies: - "@typescript-eslint/scope-manager" "5.60.1" - "@typescript-eslint/types" "5.60.1" - "@typescript-eslint/typescript-estree" "5.60.1" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha", "@typescript-eslint/parser@^6.7.2": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz" + integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== + dependencies: + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz#35abdb47f500c68c08f2f2b4f22c7c79472854bb" - integrity sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ== +"@typescript-eslint/scope-manager@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz" + integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== dependencies: - "@typescript-eslint/types" "5.60.1" - "@typescript-eslint/visitor-keys" "5.60.1" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" -"@typescript-eslint/type-utils@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz#17770540e98d65ab4730c7aac618003f702893f4" - integrity sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A== +"@typescript-eslint/type-utils@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz" + integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== dependencies: - "@typescript-eslint/typescript-estree" "5.60.1" - "@typescript-eslint/utils" "5.60.1" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/utils" "6.21.0" debug "^4.3.4" - tsutils "^3.21.0" + ts-api-utils "^1.0.1" -"@typescript-eslint/types@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.60.1.tgz#a17473910f6b8d388ea83c9d7051af89c4eb7561" - integrity sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg== +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== -"@typescript-eslint/typescript-estree@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz#8c71824b7165b64d5ebd7aa42968899525959834" - integrity sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw== +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== dependencies: - "@typescript-eslint/types" "5.60.1" - "@typescript-eslint/visitor-keys" "5.60.1" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz" + integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== + dependencies: + "@typescript-eslint/types" "6.21.0" + eslint-visitor-keys "^3.4.1" -"@typescript-eslint/utils@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.60.1.tgz#6861ebedbefba1ac85482d2bdef6f2ff1eb65b80" - integrity sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.60.1" - "@typescript-eslint/types" "5.60.1" - "@typescript-eslint/typescript-estree" "5.60.1" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz#19a877358bf96318ec35d90bfe6bd1445cce9434" - integrity sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw== - dependencies: - "@typescript-eslint/types" "5.60.1" - eslint-visitor-keys "^3.3.0" - -"@vscode/debugadapter@^1.40.0": - version "1.61.0" - resolved "https://registry.yarnpkg.com/@vscode/debugadapter/-/debugadapter-1.61.0.tgz#5e40595ee2e699b5fd447f3ea3c961a8e8573bc3" - integrity sha512-VDGLUFDVAdnftUebZe4uQCIFUbJ7rTc2Grps4D/CXl+qyzTZSQLv5VADEOZ6kBYG4SvlnMLql5vPQ0G6XvUCvQ== - dependencies: - "@vscode/debugprotocol" "1.61.0" - -"@vscode/debugprotocol@1.61.0", "@vscode/debugprotocol@^1.40.0": - version "1.61.0" - resolved "https://registry.yarnpkg.com/@vscode/debugprotocol/-/debugprotocol-1.61.0.tgz#82bbcaba5a925f1f58246c9f50b669855c9f23f9" - integrity sha512-K/kF27jIStVFqlmUaGc2u+Dj8IR7YdEiSqShWr7MWhDudqpAW7uu7XMwoFwjpuC9LSaVwJMIX7EFC5OJ/RmnDQ== +"@ungap/structured-clone@^1.2.0": + version "1.3.0" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" + integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== + +"@vscode/debugadapter-testsupport@^1.51.0": + version "1.68.0" + resolved "https://registry.npmjs.org/@vscode/debugadapter-testsupport/-/debugadapter-testsupport-1.68.0.tgz" + integrity sha512-UpbaPsCGMKyjIvJFtqFKDD1MVvME50xuOtRBPrqY1WdhAOLjWQN7FcKEoHv3X85twfNL21jW2M54FYwEdEQv4Q== + dependencies: + "@vscode/debugprotocol" "1.68.0" + +"@vscode/debugadapter@^1.51.0": + version "1.68.0" + resolved "https://registry.npmjs.org/@vscode/debugadapter/-/debugadapter-1.68.0.tgz" + integrity sha512-D6gk5Fw2y4FV8oYmltoXpj+VAZexxJFopN/mcZ6YcgzQE9dgq2L45Aj3GLxScJOD6GeLILcxJIaA8l3v11esGg== + dependencies: + "@vscode/debugprotocol" "1.68.0" + +"@vscode/debugprotocol@^1.51.0", "@vscode/debugprotocol@1.68.0": + version "1.68.0" + resolved "https://registry.npmjs.org/@vscode/debugprotocol/-/debugprotocol-1.68.0.tgz" + integrity sha512-2J27dysaXmvnfuhFGhfeuxfHRXunqNPxtBoR3koiTOA9rdxWNDTa1zIFLCFMSHJ9MPTPKFcBeblsyaCJCIlQxg== + +"@vscode/test-cli@^0.0.12": + version "0.0.12" + resolved "https://registry.npmjs.org/@vscode/test-cli/-/test-cli-0.0.12.tgz" + integrity sha512-iYN0fDg29+a2Xelle/Y56Xvv7Nc8Thzq4VwpzAF/SIE6918rDicqfsQxV6w1ttr2+SOm+10laGuY9FG2ptEKsQ== + dependencies: + "@types/mocha" "^10.0.10" + c8 "^10.1.3" + chokidar "^3.6.0" + enhanced-resolve "^5.18.3" + glob "^10.3.10" + minimatch "^9.0.3" + mocha "^11.7.4" + supports-color "^10.2.2" + yargs "^17.7.2" + +"@vscode/test-electron@^2.5.2": + version "2.5.2" + resolved "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.5.2.tgz" + integrity sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg== + dependencies: + http-proxy-agent "^7.0.2" + https-proxy-agent "^7.0.5" + jszip "^3.10.1" + ora "^8.1.0" + semver "^7.6.2" acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.8.0: - version "8.9.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" - integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== +acorn-walk@^8.1.1: + version "8.3.4" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" + +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0: + version "8.15.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== -ajv@^6.10.0, ajv@^6.12.4: +agent-base@^7.1.0, agent-base@^7.1.2: + version "7.1.4" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz" + integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== + +ajv@^6.12.4: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -220,100 +359,137 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-colors@^4.1.3: + version "4.1.3" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.2.2" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz" + integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== + ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.3" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz" + integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== + anymatch@~3.1.2: version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + version "1.1.12" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + version "2.0.2" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== dependencies: balanced-match "^1.0.0" -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +braces@^3.0.3, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" -browser-stdout@1.3.1: +browser-stdout@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== +c8@^10.1.3: + version "10.1.3" + resolved "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz" + integrity sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA== + dependencies: + "@bcoe/v8-coverage" "^1.0.1" + "@istanbuljs/schema" "^0.1.3" + find-up "^5.0.0" + foreground-child "^3.1.1" + istanbul-lib-coverage "^3.2.0" + istanbul-lib-report "^3.0.1" + istanbul-reports "^3.1.6" + test-exclude "^7.0.1" + v8-to-istanbul "^9.0.0" + yargs "^17.7.2" + yargs-parser "^21.1.1" + callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase@^6.0.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +chalk@^5.3.0: + version "5.6.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz" + integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== + +chokidar@^3.5.3, chokidar@^3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -325,141 +501,220 @@ chokidar@3.5.3: optionalDependencies: fsevents "~2.3.2" +chokidar@^4.0.1: + version "4.0.3" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz" + integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== + dependencies: + readdirp "^4.0.1" + +cli-cursor@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz" + integrity sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw== + dependencies: + restore-cursor "^5.0.0" + +cli-spinners@^2.9.2: + version "2.9.2" + resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + cliui@^7.0.2: version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + core_d@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/core_d/-/core_d-5.0.1.tgz#695c9c9baa483d7321db47a452887738048a1822" + resolved "https://registry.npmjs.org/core_d/-/core_d-5.0.1.tgz" integrity sha512-37lZyhJY1hzgFbfU4LzY4zL09QPwPfV2W/3YBOtN7mkdvVaeP1OVnDZI6zxggtlPwG/BuE5wIr0xptlVJk5EPA== dependencies: supports-color "^8.1.0" -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.2, cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" which "^2.0.1" -debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== +debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@4: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: - ms "2.1.2" + ms "^2.1.3" decamelize@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== deep-is@^0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diff@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== + +diff@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz" + integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw== dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +emoji-regex@^10.3.0: + version "10.6.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz" + integrity sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A== + emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +enhanced-resolve@^5.18.3: + version "5.18.3" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz" + integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: +escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== +eslint_d@^12.2.1: + version "12.2.1" + resolved "https://registry.npmjs.org/eslint_d/-/eslint_d-12.2.1.tgz" + integrity sha512-qOJ9cTi5AaH5bOgEoCkv41DJ637mHgzffbOLojwU4wadwC6qbR+OxVJRvVzH0v2XYmQOvw4eiJK7ivrr5SvzsA== dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" + core_d "^5.0.1" + eslint "^8.12.0" + nanolru "^1.0.0" + optionator "^0.9.1" -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@^8.12.0, eslint@^8.43.0: - version "8.43.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.43.0.tgz#3e8c6066a57097adfd9d390b8fc93075f257a094" - integrity sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q== +"eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.12.0, eslint@^8.50.0: + version "8.57.1" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz" + integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.43.0" - "@humanwhocodes/config-array" "^0.11.10" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.57.1" + "@humanwhocodes/config-array" "^0.13.0" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.5.2" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -469,7 +724,6 @@ eslint@^8.12.0, eslint@^8.43.0: globals "^13.19.0" graphemer "^1.4.0" ignore "^5.2.0" - import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" @@ -479,67 +733,51 @@ eslint@^8.12.0, eslint@^8.43.0: lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" + optionator "^0.9.3" strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" text-table "^0.2.0" -eslint_d@^12.2.1: - version "12.2.1" - resolved "https://registry.yarnpkg.com/eslint_d/-/eslint_d-12.2.1.tgz#e5faf55acdc74d0e6e4f13ade464421f1f8e4152" - integrity sha512-qOJ9cTi5AaH5bOgEoCkv41DJ637mHgzffbOLojwU4wadwC6qbR+OxVJRvVzH0v2XYmQOvw4eiJK7ivrr5SvzsA== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - core_d "^5.0.1" - eslint "^8.12.0" - nanolru "^1.0.0" - optionator "^0.9.1" - -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== - dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" esquery@^1.4.2: version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.9: version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -550,38 +788,38 @@ fast-glob@^3.2.9: fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" -find-up@5.0.0, find-up@^5.0.0: +find-up@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -589,7 +827,7 @@ find-up@5.0.0, find-up@^5.0.0: flat-cache@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: flatted "^3.1.0" @@ -597,58 +835,85 @@ flat-cache@^3.0.4: flat@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.1.0: version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +foreground-child@^3.1.0, foreground-child@^3.1.1: + version "3.3.1" + resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz" + integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== + dependencies: + cross-spawn "^7.0.6" + signal-exit "^4.0.1" + fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -glob-parent@^5.1.2, glob-parent@~5.1.2: +get-east-asian-width@^1.0.0: + version "1.4.0" + resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz" + integrity sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q== + +glob-parent@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" + is-glob "^4.0.1" + +glob@^10.3.10, glob@^10.4.5: + version "10.5.0" + resolved "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz" + integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + +glob@^10.4.1: + version "10.5.0" + resolved "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz" + integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" glob@^7.1.3: version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -658,16 +923,27 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + globals@^13.19.0: version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== dependencies: type-fest "^0.20.2" globby@^11.1.0: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -677,34 +953,60 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graceful-fs@^4.2.4: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== graphemer@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -he@1.2.0: +he@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + +https-proxy-agent@^7.0.5: + version "7.0.6" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz" + integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== + dependencies: + agent-base "^7.1.2" + debug "4" + +ignore@^5.2.0, ignore@^5.2.4: + version "5.3.2" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -712,520 +1014,910 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" -inherits@2: +inherits@~2.0.3, inherits@2: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" +is-interactive@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz" + integrity sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ== + is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-path-inside@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-plain-obj@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-unicode-supported@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz" + integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== + +is-unicode-supported@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz" + integrity sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-report@^3.0.0, istanbul-lib-report@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-reports@^3.1.6: + version "3.2.0" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz" + integrity sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +js-yaml@^4.1.0: + version "4.1.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== dependencies: argparse "^2.0.1" json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json5@^2.2.2: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jszip@^3.10.1: + version "3.10.1" + resolved "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" type-check "~0.4.0" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -log-symbols@4.1.0: +log-symbols@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" is-unicode-supported "^0.1.0" -lru-cache@^6.0.0: +log-symbols@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz" + integrity sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw== + dependencies: + chalk "^5.3.0" + is-unicode-supported "^1.3.0" + +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== dependencies: - yallist "^4.0.0" + semver "^7.5.3" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" -minimatch@5.0.1: +mimic-function@^5.0.0: version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + resolved "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz" + integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== + +minimatch@^3.0.5: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: - brace-expansion "^2.0.1" + brace-expansion "^1.1.7" -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.1.1: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -mocha@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3: +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1, minimatch@^5.1.6: + version "5.1.6" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.3, minimatch@^9.0.4, minimatch@^9.0.5: + version "9.0.5" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + +mocha@^10.8.2, "mocha@^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X": + version "10.8.2" + resolved "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz" + integrity sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg== + dependencies: + ansi-colors "^4.1.3" + browser-stdout "^1.3.1" + chokidar "^3.5.3" + debug "^4.3.5" + diff "^5.2.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + glob "^8.1.0" + he "^1.2.0" + js-yaml "^4.1.0" + log-symbols "^4.1.0" + minimatch "^5.1.6" + ms "^2.1.3" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^6.5.1" + yargs "^16.2.0" + yargs-parser "^20.2.9" + yargs-unparser "^2.0.0" + +mocha@^11.7.4: + version "11.7.5" + resolved "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz" + integrity sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig== + dependencies: + browser-stdout "^1.3.1" + chokidar "^4.0.1" + debug "^4.3.5" + diff "^7.0.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + glob "^10.4.5" + he "^1.2.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + log-symbols "^4.1.0" + minimatch "^9.0.5" + ms "^2.1.3" + picocolors "^1.1.1" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^9.2.0" + yargs "^17.7.2" + yargs-parser "^21.1.1" + yargs-unparser "^2.0.0" + +ms@^2.1.3: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -n-readlines@^1.0.0: +n-readlines@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/n-readlines/-/n-readlines-1.0.1.tgz#bbb7364d38bc31a170a199f986fcacfa76b95f6e" + resolved "https://registry.npmjs.org/n-readlines/-/n-readlines-1.0.1.tgz" integrity sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ== -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - nanolru@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/nanolru/-/nanolru-1.0.0.tgz#0a5679cd4e4578c4ca3741e610b71c4c9b5afaf8" + resolved "https://registry.npmjs.org/nanolru/-/nanolru-1.0.0.tgz" integrity sha512-GyQkE8M32pULhQk7Sko5raoIbPalAk90ICG+An4fq6fCsFHsP6fB2K46WGXVdoJpy4SGMnZ/EKbo123fZJomWg== -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== once@^1.3.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" -optionator@^0.9.1: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== +onetime@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz" + integrity sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ== + dependencies: + mimic-function "^5.0.0" + +optionator@^0.9.1, optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" + word-wrap "^1.2.5" + +ora@^8.1.0: + version "8.2.0" + resolved "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz" + integrity sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw== + dependencies: + chalk "^5.3.0" + cli-cursor "^5.0.0" + cli-spinners "^2.9.2" + is-interactive "^2.0.0" + is-unicode-supported "^2.0.0" + log-symbols "^6.0.0" + stdin-discarder "^0.2.2" + string-width "^7.2.0" + strip-ansi "^7.1.0" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + punycode@^2.1.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" +readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@^4.0.1: + version "4.1.2" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz" + integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== + readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +restore-cursor@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz" + integrity sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA== + dependencies: + onetime "^7.0.0" + signal-exit "^4.1.0" + reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" -safe-buffer@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -semver@^7.3.7: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== - dependencies: - lru-cache "^6.0.0" +semver@^7.5.3, semver@^7.5.4, semver@^7.6.2: + version "7.7.3" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +signal-exit@^4.0.1, signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -string-width@^4.1.0, string-width@^4.2.0: +stdin-discarder@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz" + integrity sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ== + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string-width@^7.2.0: + version "7.2.0" + resolved "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz" + integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== + dependencies: + emoji-regex "^10.3.0" + get-east-asian-width "^1.0.0" + strip-ansi "^7.1.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-ansi@^7.0.1: + version "7.1.2" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz" + integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== + dependencies: + ansi-regex "^6.0.1" + +strip-ansi@^7.1.0: + version "7.1.2" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz" + integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== + dependencies: + ansi-regex "^6.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1, supports-color@^8.1.0: +supports-color@^10.2.2: + version "10.2.2" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz" + integrity sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.1.0: version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" +tapable@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== + +test-exclude@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz" + integrity sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^10.4.1" + minimatch "^9.0.4" + text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +ts-api-utils@^1.0.1: + version "1.4.3" + resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz" + integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" +ts-mocha@^11.1.0: + version "11.1.0" + resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-11.1.0.tgz" + integrity sha512-yT7FfzNRCu8ZKkYvAOiH01xNma/vLq6Vit7yINKYFNVP8e5UyrYXSOMIipERTpzVKJQ4Qcos5bQo1tNERNZevQ== + +ts-node@^10.9.2, "ts-node@^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X": + version "10.9.2" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +tsconfig-paths@^4.2.0, tsconfig-paths@^4.X.X: + version "4.2.0" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -typescript@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" - integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +typescript@^5.2.2, typescript@>=2.7, typescript@>=4.2.0: + version "5.9.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== + +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" -vscode-debugadapter-testsupport@^1.40.3: - version "1.51.0" - resolved "https://registry.yarnpkg.com/vscode-debugadapter-testsupport/-/vscode-debugadapter-testsupport-1.51.0.tgz#d60c4d9e2b70d094d9449abffdf3745898e698a4" - integrity sha512-rb8tfn7J3kxLi1rRhEyG5ggGkFcJH2WrYYrq6Vb1tDAcHoFXF580M1dAA2jPOrc0I14GuWxMnndvfGkfG10VxA== - dependencies: - vscode-debugprotocol "1.51.0" +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -vscode-debugprotocol@1.51.0: - version "1.51.0" - resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.51.0.tgz#c03168dac778b6c24ce17b3511cb61e89c11b2df" - integrity sha512-dzKWTMMyebIMPF1VYMuuQj7gGFq7guR8AFya0mKacu+ayptJfaRuM0mdHCqiOth4FnRP8mPhEroFPx6Ift8wHA== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +v8-to-istanbul@^9.0.0: + version "9.3.0" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz" + integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +workerpool@^6.5.1: + version "6.5.1" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz" + integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== + +workerpool@^9.2.0: + version "9.3.4" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz" + integrity sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: +yargs-parser@^20.2.2, yargs-parser@^20.2.9: version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-unparser@2.0.0: +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs-unparser@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== dependencies: camelcase "^6.0.0" @@ -1233,9 +1925,9 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@16.2.0: +yargs@^16.2.0: version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" @@ -1246,7 +1938,25 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 5698eba0305ffead83a52748ffb20457917c8d94 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 24 Nov 2025 16:23:40 +0100 Subject: [PATCH 47/70] Fix some errors in `src/extension.ts` --- src/extension.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 2b30ddb..258f962 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -14,15 +14,13 @@ export function activate(context: vscode.ExtensionContext) { const factory = new GdbAdapterDescriptorFactory(new CoverageStatus(), new GDBDebugSession()); context.subscriptions.push( vscode.debug.registerDebugConfigurationProvider('superbol-gdb', provider), - vscode.debug.registerDebugAdapterDescriptorFactory('superbol-gdb', factory, vscode.DebugConfigurationProviderTriggerKind.Dynamic), + vscode.debug.registerDebugAdapterDescriptorFactory('superbol-gdb', factory), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL31', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL3.1', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL32', new GnuCOBOLEvalExpressionFactory()), vscode.languages.registerEvaluatableExpressionProvider('GnuCOBOL3.2', new GnuCOBOLEvalExpressionFactory()), - vscode.languages.registerEvaluatableExpressionProvider('COBOL', new GnuCOBOLEvalExpressionFactory()), - factory, - ); + vscode.languages.registerEvaluatableExpressionProvider('COBOL', new GnuCOBOLEvalExpressionFactory())); } export function deactivate() { From e97fda2719e9077a07d42649648110abab1b1a68 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 24 Nov 2025 16:14:08 +0100 Subject: [PATCH 48/70] Add a CI workflow for testing the extension --- .github/workflows/ci.yml | 35 + .github/workflows/nodejs.yml | 23 - package-lock.json | 3945 ++++++++++++++++++++++++++++++++++ package.json | 9 +- test/suite/index.ts | 10 +- 5 files changed, 3992 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/nodejs.yml create mode 100644 package-lock.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f5e6c88 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,35 @@ +name: Run VSCode Extension Tests + +on: + push: + branches: + - superbol-vscode-debug + pull_request: + branches: + - superbol-vscode-debug + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup Node.js environment + uses: actions/setup-node@v6 + with: + node-version-file: 'package.json' + + - name: Install dependencies + run: npm install + + - name: Compile + run: npm run compile + + - name: Run tests + run: xvfb-run -a npm test + if: runner.os == 'Linux' + + - name: Run tests + run: npm test + if: runner.os != 'Linux' diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml deleted file mode 100644 index 7be86bc..0000000 --- a/.github/workflows/nodejs.yml +++ /dev/null @@ -1,23 +0,0 @@ -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - -name: Node.js CI - -on: - push: - branches: - - '*' - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Use Node.js - uses: actions/setup-node@v1 - with: - node-version: '14.x' - - run: npm install - - run: npm run build --if-present - - run: npm test diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..92b83a3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3945 @@ +{ + "name": "superbol-vscode-debug", + "version": "3.32.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "superbol-vscode-debug", + "version": "3.32.0", + "license": "GPL-3.0", + "dependencies": { + "@vscode/debugadapter": "^1.51.0", + "@vscode/debugprotocol": "^1.51.0", + "n-readlines": "^1.0.1" + }, + "devDependencies": { + "@types/expect": "^1.20.4", + "@types/mocha": "^10.0.10", + "@types/node": "^20.6.3", + "@types/vscode": "^1.64.0", + "@typescript-eslint/eslint-plugin": "^6.7.2", + "@typescript-eslint/parser": "^6.7.2", + "@vscode/debugadapter-testsupport": "^1.51.0", + "@vscode/test-cli": "^0.0.12", + "@vscode/test-electron": "^2.5.2", + "eslint": "^8.50.0", + "eslint_d": "^12.2.1", + "mocha": "^10.8.2", + "ts-mocha": "^11.1.0", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.2.2" + }, + "engines": { + "node": ">=20", + "vscode": "^1.44.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/expect": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", + "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/vscode": { + "version": "1.106.1", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.106.1.tgz", + "integrity": "sha512-R/HV8u2h8CAddSbX8cjpdd7B8/GnE4UjgjpuGuHcbp1xV6yh4OeqU4L1pKjlwujCrSFS0MOpwJAIs/NexMB1fQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vscode/debugadapter": { + "version": "1.68.0", + "resolved": "https://registry.npmjs.org/@vscode/debugadapter/-/debugadapter-1.68.0.tgz", + "integrity": "sha512-D6gk5Fw2y4FV8oYmltoXpj+VAZexxJFopN/mcZ6YcgzQE9dgq2L45Aj3GLxScJOD6GeLILcxJIaA8l3v11esGg==", + "license": "MIT", + "dependencies": { + "@vscode/debugprotocol": "1.68.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@vscode/debugadapter-testsupport": { + "version": "1.68.0", + "resolved": "https://registry.npmjs.org/@vscode/debugadapter-testsupport/-/debugadapter-testsupport-1.68.0.tgz", + "integrity": "sha512-UpbaPsCGMKyjIvJFtqFKDD1MVvME50xuOtRBPrqY1WdhAOLjWQN7FcKEoHv3X85twfNL21jW2M54FYwEdEQv4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/debugprotocol": "1.68.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@vscode/debugprotocol": { + "version": "1.68.0", + "resolved": "https://registry.npmjs.org/@vscode/debugprotocol/-/debugprotocol-1.68.0.tgz", + "integrity": "sha512-2J27dysaXmvnfuhFGhfeuxfHRXunqNPxtBoR3koiTOA9rdxWNDTa1zIFLCFMSHJ9MPTPKFcBeblsyaCJCIlQxg==", + "license": "MIT" + }, + "node_modules/@vscode/test-cli": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@vscode/test-cli/-/test-cli-0.0.12.tgz", + "integrity": "sha512-iYN0fDg29+a2Xelle/Y56Xvv7Nc8Thzq4VwpzAF/SIE6918rDicqfsQxV6w1ttr2+SOm+10laGuY9FG2ptEKsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^10.0.10", + "c8": "^10.1.3", + "chokidar": "^3.6.0", + "enhanced-resolve": "^5.18.3", + "glob": "^10.3.10", + "minimatch": "^9.0.3", + "mocha": "^11.7.4", + "supports-color": "^10.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "vscode-test": "out/bin.mjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@vscode/test-cli/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/@vscode/test-cli/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/test-cli/node_modules/mocha": { + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@vscode/test-cli/node_modules/mocha/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@vscode/test-cli/node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@vscode/test-cli/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@vscode/test-cli/node_modules/workerpool": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@vscode/test-electron": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.5.2.tgz", + "integrity": "sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "jszip": "^3.10.1", + "ora": "^8.1.0", + "semver": "^7.6.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/c8": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz", + "integrity": "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.1", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^7.0.1", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "monocart-coverage-reports": "^2" + }, + "peerDependenciesMeta": { + "monocart-coverage-reports": { + "optional": true + } + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core_d": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/core_d/-/core_d-5.0.1.tgz", + "integrity": "sha512-37lZyhJY1hzgFbfU4LzY4zL09QPwPfV2W/3YBOtN7mkdvVaeP1OVnDZI6zxggtlPwG/BuE5wIr0xptlVJk5EPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "supports-color": "^8.1.0" + } + }, + "node_modules/core_d/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint_d": { + "version": "12.2.1", + "resolved": "https://registry.npmjs.org/eslint_d/-/eslint_d-12.2.1.tgz", + "integrity": "sha512-qOJ9cTi5AaH5bOgEoCkv41DJ637mHgzffbOLojwU4wadwC6qbR+OxVJRvVzH0v2XYmQOvw4eiJK7ivrr5SvzsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core_d": "^5.0.1", + "eslint": "^8.12.0", + "nanolru": "^1.0.0", + "optionator": "^0.9.1" + }, + "bin": { + "eslint_d": "bin/eslint_d.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/n-readlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/n-readlines/-/n-readlines-1.0.1.tgz", + "integrity": "sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ==", + "license": "MIT", + "engines": { + "node": ">=6.x.x" + } + }, + "node_modules/nanolru": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nanolru/-/nanolru-1.0.0.tgz", + "integrity": "sha512-GyQkE8M32pULhQk7Sko5raoIbPalAk90ICG+An4fq6fCsFHsP6fB2K46WGXVdoJpy4SGMnZ/EKbo123fZJomWg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-mocha": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-11.1.0.tgz", + "integrity": "sha512-yT7FfzNRCu8ZKkYvAOiH01xNma/vLq6Vit7yINKYFNVP8e5UyrYXSOMIipERTpzVKJQ4Qcos5bQo1tNERNZevQ==", + "dev": true, + "license": "MIT", + "bin": { + "ts-mocha": "bin/ts-mocha" + }, + "engines": { + "node": ">= 6.X.X" + }, + "peerDependencies": { + "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X", + "ts-node": "^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X", + "tsconfig-paths": "^4.X.X" + }, + "peerDependenciesMeta": { + "tsconfig-paths": { + "optional": true + } + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index c2f543a..f6d5ee2 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "license": "GPL-3.0", "icon": "icon.png", "engines": { - "vscode": "^1.44.0" + "vscode": "^1.44.0", + "node": ">=20" }, "main": "./out/src/extension", "activationEvents": [ @@ -285,5 +286,11 @@ "@vscode/debugadapter": "^1.51.0", "@vscode/debugprotocol": "^1.51.0", "n-readlines": "^1.0.1" + }, + "devEngines": { + "packageManager": { + "name": "npm", + "onFail": "error" + } } } diff --git a/test/suite/index.ts b/test/suite/index.ts index 7c9f287..6351958 100644 --- a/test/suite/index.ts +++ b/test/suite/index.ts @@ -1,20 +1,18 @@ import * as path from 'path'; import Mocha from 'mocha'; -import glob from 'glob'; +import { glob } from 'glob'; export function run(): Promise { // Create the mocha test const mocha = new Mocha({ - ui: 'tdd' + ui: 'tdd', + timeout: 20000 }); const testsRoot = path.resolve(__dirname, '..'); return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } + glob('**/**.test.js', { cwd: testsRoot }).then (files => { // Add files to the test suite files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); From 05c4819ab9ec76e59985367aeac002978ceee787 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 24 Nov 2025 16:58:27 +0100 Subject: [PATCH 49/70] Centralize some test specifications into `.vscode-test.js` --- .vscode-test.js | 2 ++ .vscode/launch.json | 14 ++------------ test/suite/index.ts | 35 ----------------------------------- 3 files changed, 4 insertions(+), 47 deletions(-) delete mode 100644 test/suite/index.ts diff --git a/.vscode-test.js b/.vscode-test.js index b9ad718..4dcd102 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -3,6 +3,8 @@ const { defineConfig } = require('@vscode/test-cli'); module.exports = defineConfig([ { files: 'out/test/**/*.test.js', + extensionDevelopmentPath: __dirname, + sourceMap: true, mocha: { ui: 'tdd', timeout: 20000 diff --git a/.vscode/launch.json b/.vscode/launch.json index 2cf08a3..4d75302 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -21,18 +21,8 @@ "name": "Tests", "type": "extensionHost", "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--disable-extensions", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" - ], - "sourceMaps": true, - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ], - "preLaunchTask": "npm", - "internalConsoleOptions": "openOnSessionStart" + "testConfiguration": "${workspaceFolder}/.vscode-test.js", + "preLaunchTask": "npm" } ] } diff --git a/test/suite/index.ts b/test/suite/index.ts deleted file mode 100644 index 6351958..0000000 --- a/test/suite/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as path from 'path'; -import Mocha from 'mocha'; -import { glob } from 'glob'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'tdd', - timeout: 20000 - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }).then (files => { - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} From 4f731994384fb6651e4c3f620db3ac85b04745a4 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 24 Nov 2025 17:07:51 +0100 Subject: [PATCH 50/70] Try caching VSCode's test directory --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5e6c88..cd7aef7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,12 @@ jobs: with: node-version-file: 'package.json' + - name: Cache VSCode test directory + uses: actions/cache@v4 + with: + path: .vscode-test + key: ${{ runner.os }}-vscode-test-${{ hashFiles('package-lock.json') }} + - name: Install dependencies run: npm install From ae5db117e9bf132dcbafb1ea9ecf29aca0b4d675 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 25 Nov 2025 12:17:20 +0100 Subject: [PATCH 51/70] Run the CI on multiple versions of Node --- .github/workflows/ci.yml | 19 +++++- package-lock.json | 7 --- yarn.lock | 129 ++++++++++++++++++++------------------- 3 files changed, 81 insertions(+), 74 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd7aef7..a6b8fbb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,19 @@ on: jobs: test: - runs-on: ubuntu-latest + strategy: + matrix: + os: + - ubuntu-latest + - macos-latest + # - windows-latest + node: + - 20 + include: + - { os: ubuntu-latest, node: 22 } + - { os: ubuntu-latest, node: 24 } + runs-on: ${{ matrix.os }} + name: Test with Node ${{ matrix.node }} on ${{ matrix.os }} steps: - name: Checkout code uses: actions/checkout@v2 @@ -18,13 +30,14 @@ jobs: - name: Setup Node.js environment uses: actions/setup-node@v6 with: - node-version-file: 'package.json' + node-version: ${{ matrix.node }} + # node-version-file: 'package.json' - name: Cache VSCode test directory uses: actions/cache@v4 with: path: .vscode-test - key: ${{ runner.os }}-vscode-test-${{ hashFiles('package-lock.json') }} + key: ${{ runner.os }}-${{ matrix.node }}-vscode-test-${{ hashFiles('package-lock.json') }} - name: Install dependencies run: npm install diff --git a/package-lock.json b/package-lock.json index 92b83a3..7b6293a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -404,7 +404,6 @@ "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -465,7 +464,6 @@ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -823,7 +821,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1422,7 +1419,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -3537,7 +3533,6 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -3592,7 +3587,6 @@ "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -3634,7 +3628,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/yarn.lock b/yarn.lock index 10c1f99..7452e69 100644 --- a/yarn.lock +++ b/yarn.lock @@ -187,9 +187,9 @@ integrity sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA== "@types/vscode@^1.64.0": - version "1.64.0" - resolved "https://registry.npmjs.org/@types/vscode/-/vscode-1.64.0.tgz" - integrity sha512-bSlAWz5WtcSL3cO9tAT/KpEH9rv5OBnm93OIIFwdCshaAiqr2bp1AUyEwW9MWeCvZBHEXc3V0fTYVdVyzDNwHA== + version "1.106.1" + resolved "https://registry.npmjs.org/@types/vscode/-/vscode-1.106.1.tgz" + integrity sha512-R/HV8u2h8CAddSbX8cjpdd7B8/GnE4UjgjpuGuHcbp1xV6yh4OeqU4L1pKjlwujCrSFS0MOpwJAIs/NexMB1fQ== "@typescript-eslint/eslint-plugin@^6.7.2": version "6.21.0" @@ -415,9 +415,9 @@ balanced-match@^1.0.0: integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + version "2.3.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== brace-expansion@^1.1.7: version "1.1.12" @@ -661,9 +661,9 @@ enhanced-resolve@^5.18.3: tapable "^2.2.0" escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + version "3.2.0" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-string-regexp@^4.0.0: version "4.0.0" @@ -747,9 +747,9 @@ espree@^9.6.0, espree@^9.6.1: eslint-visitor-keys "^3.4.1" esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + version "1.6.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" @@ -776,15 +776,15 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + version "3.3.3" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz" + integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.4" + micromatch "^4.0.8" fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -797,9 +797,9 @@ fast-levenshtein@^2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.19.1" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz" + integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== dependencies: reusify "^1.0.4" @@ -826,11 +826,12 @@ find-up@^5.0.0: path-exists "^4.0.0" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.2.0" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: - flatted "^3.1.0" + flatted "^3.2.9" + keyv "^4.5.3" rimraf "^3.0.2" flat@^5.0.2: @@ -838,10 +839,10 @@ flat@^5.0.2: resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flatted@^3.2.9: + version "3.3.3" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz" + integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== foreground-child@^3.1.0, foreground-child@^3.1.1: version "3.3.1" @@ -866,7 +867,7 @@ get-east-asian-width@^1.0.0: resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz" integrity sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q== -glob-parent@^5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -880,26 +881,7 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^10.3.10, glob@^10.4.5: - version "10.5.0" - resolved "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz" - integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== - dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" - -glob@^10.4.1: +glob@^10.3.10, glob@^10.4.1, glob@^10.4.5: version "10.5.0" resolved "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz" integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== @@ -935,9 +917,9 @@ glob@^8.1.0: once "^1.3.0" globals@^13.19.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + version "13.24.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" @@ -1005,9 +987,9 @@ immediate@~3.0.5: integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + version "3.3.1" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz" + integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -1137,6 +1119,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" @@ -1162,6 +1149,13 @@ jszip@^3.10.1: readable-stream "~2.3.6" setimmediate "^1.0.5" +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + levn@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" @@ -1227,7 +1221,7 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micromatch@^4.0.4: +micromatch@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== @@ -1268,7 +1262,14 @@ minimatch@^5.0.1, minimatch@^5.1.6: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.3, minimatch@^9.0.4, minimatch@^9.0.5: +minimatch@^9.0.3, minimatch@^9.0.5: + version "9.0.5" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.4: version "9.0.5" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz" integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== @@ -1491,9 +1492,9 @@ process-nextick-args@~2.0.0: integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== queue-microtask@^1.2.2: version "1.2.3" @@ -1551,9 +1552,9 @@ restore-cursor@^5.0.0: signal-exit "^4.1.0" reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + version "1.1.0" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz" + integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== rimraf@^3.0.2: version "3.0.2" @@ -1634,7 +1635,7 @@ string_decoder@~1.1.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.1.0: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -1643,7 +1644,7 @@ string-width@^4.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== From bc63d340fe2c097137f1037695d6f44049a964de Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 25 Nov 2025 14:23:09 +0100 Subject: [PATCH 52/70] Fix Windows support --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6b8fbb..9340188 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: os: - ubuntu-latest - macos-latest - # - windows-latest + - windows-latest node: - 20 include: From 47fc36376b8bfebb2c33f040333f364a32b79a71 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 25 Nov 2025 17:18:25 +0100 Subject: [PATCH 53/70] Get rid of weird path module imports --- src/parser.c.ts | 100 +++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 57 deletions(-) diff --git a/src/parser.c.ts b/src/parser.c.ts index bdac531..eb4cef4 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -1,26 +1,19 @@ import readline from "n-readlines"; -import * as nativePathFromPath from "path"; +import * as path from "path"; import * as fs from "fs"; import {DebuggerVariable, Attribute, VariableType} from "./debugger"; -const nativePath = { - resolve: function (...args: string[]): string { - const nat = nativePathFromPath.resolve(...args); - return nat; - }, - basename: function (path: string): string { - return nativePathFromPath.basename(path); - }, - isAbsolute: function (path: string): boolean { - return nativePathFromPath.isAbsolute(path); - }, - join: function (...args: string[]) { - return nativePathFromPath.join(...args); +function normalizeExistingFileName(f: string): string { + if (f != undefined && process.platform === "win32") { + const lc = f.toLowerCase(); + const uc = f.toUpperCase(); + return (!fs.existsSync(lc) || !fs.existsSync(uc)) ? f : lc; } -}; + return f; +} function cFile (filename: string) : string { - return nativePath.basename(filename.split('.').slice(0, -1).join('.') + '.c'); + return path.basename(filename.split('.').slice(0, -1).join('.') + '.c'); } const procedureRegex = /\/\*\sLine:\s([0-9]+)(\s+:\sEntry\s)?/i; @@ -79,14 +72,14 @@ export class SourceMap { private isVersion2_2_or_3_1_1: boolean = false; constructor(cwd: string, filesCobol: string[], sourceDirs: string[], private log: Function = (_ => {})) { - this.cwd = fs.realpathSync(nativePathFromPath.resolve(cwd)); + this.cwd = fs.realpathSync(path.resolve(cwd)); this.log(`Source dirs: ${sourceDirs}`); for (const cSourceDir of sourceDirs) { this.log(`Trying to resolve ${cSourceDir}`); - let resolved_path = nativePathFromPath.resolve(this.cwd, cSourceDir); + let resolved_path = path.resolve(this.cwd, cSourceDir); this.log(`Checking for ${resolved_path}`); if (fs.existsSync(resolved_path)) { - this.sourceDirs.push(fs.realpathSync(resolved_path)); + this.sourceDirs.push(normalizeExistingFileName(fs.realpathSync(resolved_path))); } } @@ -104,9 +97,9 @@ export class SourceMap { private lookupSourceFile (file: string) : string | undefined { for (const dir of this.sourceDirs) { - const filePath = nativePath.join (dir, file); + const filePath = path.join (dir, file); if (fs.existsSync (filePath)) { - return filePath; + return normalizeExistingFileName (filePath); } } return; @@ -143,7 +136,7 @@ export class SourceMap { } private unregister (givenFileC: string) : void { - const [natFileC, fileC, cleanedFile] = this.ensureAbsolute (givenFileC); + const [fileC, cleanedFile] = this.ensureAbsolute (givenFileC); this.lines = this.lines.filter (line => line.rootFileC != fileC) ?? []; for (const [k, v] of this.variablesByC) { if (v.rootFileC == fileC) this.variablesByC.delete(k); @@ -153,17 +146,16 @@ export class SourceMap { } } - private ensureAbsolute (fileC: string) : [string, string, string] { + private ensureAbsolute (fileC: string) : [string, string] { let nat = fileC; - if (!nativePath.isAbsolute(fileC)) { - nat = nativePathFromPath.resolve(this.cwd, fileC); - fileC = nativePath.resolve(this.cwd, fileC); + if (!path.isAbsolute(fileC)) { + fileC = path.resolve(this.cwd, fileC); } - const basename = nativePath.basename(fileC); + const basename = path.basename(fileC); const cleanedFile = basename.substring(0, basename.lastIndexOf(".c")); - return [process.platform === "win32" ? nat : fileC, fileC, cleanedFile]; + return [normalizeExistingFileName(fileC), cleanedFile]; } private register (givenFileC: string) : void { @@ -176,24 +168,24 @@ export class SourceMap { rootFileC: string | undefined = undefined, functionName: string | undefined = undefined) : string { - const [natFileC, fileC, cleanedFile] = this.ensureAbsolute (givenFileC); + const [fileC, cleanedFile] = this.ensureAbsolute (givenFileC); rootFileC = rootFileC ?? fileC; let lineNumber = 0; let row: false | Buffer; let fileCobol: string; - const reader = new readline(natFileC); + const reader = new readline(fileC); while (row = reader.next()) { const line = row.toString(); let match = fileCobolRegex.exec(line); if (match) { const filename = match[1]; - const filebase = nativePath.basename (filename); - if (!nativePath.isAbsolute(filename)) { - fileCobol = nativePath.resolve(nativePathFromPath.dirname (fileC), filename); + const filebase = path.basename (filename); + if (!path.isAbsolute(filename)) { + fileCobol = path.resolve(path.dirname (fileC), filename); if (!fs.existsSync(fileCobol)) { - fileCobol = nativePath.resolve(nativePathFromPath.dirname (fileC), filebase); + fileCobol = path.resolve(path.dirname (fileC), filebase); } if (!fs.existsSync(fileCobol)) { fileCobol = this.lookupSourceFile (filename); @@ -202,8 +194,9 @@ export class SourceMap { fileCobol = filename; } if (!fs.existsSync(fileCobol)) { - fileCobol = this.lookupSourceFile (filebase) + fileCobol = this.lookupSourceFile (filebase); } + fileCobol = normalizeExistingFileName (fileCobol); } match = functionRegex.exec(line); if (match) { @@ -211,7 +204,7 @@ export class SourceMap { } match = procedureRegex.exec(line); if (match && !match[2]) { - if (this.lines.length > 0 && fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && this.lines[this.lines.length - 1].lineCobol === parseInt(match[1])) { + if (this.lines.length > 0 && this.lines[this.lines.length - 1].fileCobol === fileCobol && this.lines[this.lines.length - 1].lineCobol === parseInt(match[1])) { this.lines.pop(); } if(subroutineRegex.exec(line)) @@ -224,7 +217,7 @@ export class SourceMap { match = procedureFixRegex.exec(line); if (match && this.lines.length > 0 && this.lines[this.lines.length - 1].functionName == functionName) { let isOldFormat = fixOlderFormat.exec(prevLine); - if(fileNameCompare(this.lines[this.lines.length - 1].fileCobol, fileCobol) && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? + if(this.lines[this.lines.length - 1].fileCobol === fileCobol && (this.isVersion2_2_or_3_1_1 || !isOldFormat)){ // Is it in the old format? let line = this.lines.pop(); // this.log (`Fixing line: ${line.toString ()}`); line.lineC = parseInt(match[1]); @@ -268,7 +261,7 @@ export class SourceMap { match = fileIncludeRegex.exec(line); if (match) { // Note: we assume the included file is in the same dir as the current file. - const filename = nativePath.resolve (nativePathFromPath.dirname (rootFileC), match[1]); + const filename = path.resolve (path.dirname (rootFileC), match[1]); functionName = this.parse(filename, prevLine, rootFileC, functionName); } match = versionRegex.exec(line); @@ -329,8 +322,8 @@ export class SourceMap { public hasLineCobol(fileC: string, lineC: number): boolean { if(!fileC || !lineC) return false; - if (!nativePath.isAbsolute(fileC)) { - fileC = nativePath.join(this.cwd, fileC); + if (!path.isAbsolute(fileC)) { + fileC = path.join(this.cwd, fileC); } return this.lines.some(e => e.fileC === fileC && e.lineC === lineC); } @@ -338,33 +331,33 @@ export class SourceMap { // 002 - stepOver in routines with "perform" public hasLineSubroutine(fileC: string, lineC: number): number { if(!fileC || !lineC) return -1; - if (!nativePath.isAbsolute(fileC)) { - fileC = nativePath.join(this.cwd, fileC); + if (!path.isAbsolute(fileC)) { + fileC = path.join(this.cwd, fileC); } return this.lines.find(e => e.fileC === fileC && e.lineC === lineC)?.endPerformLine ?? -1; } // 002 public hasLineC(fileCobol: string, lineCobol: number): boolean { - if (!nativePath.isAbsolute(fileCobol)) { - fileCobol = nativePath.join(this.cwd, fileCobol); + if (!path.isAbsolute(fileCobol)) { + fileCobol = path.join(this.cwd, fileCobol); } - return this.lines.some(e => fileNameCompare(e.fileCobol, fileCobol) && e.lineCobol === lineCobol); + return this.lines.some(e => e.fileCobol === fileCobol && e.lineCobol === lineCobol); } public getLineC(fileCobol: string, lineCobol: number): Line { - if (!nativePath.isAbsolute(fileCobol)) { - fileCobol = nativePath.join(this.cwd, fileCobol); + if (!path.isAbsolute(fileCobol)) { + fileCobol = path.join(this.cwd, fileCobol); } - return this.lines.find(e => fileNameCompare(e.fileCobol, fileCobol) && e.lineCobol === lineCobol) ?? dummyLine; + return this.lines.find(e => e.fileCobol === fileCobol && e.lineCobol === lineCobol) ?? dummyLine; } public getLineCobol(fileC: string, lineC: number): Line { if (!fileC) { return dummyLine; } - if (!nativePath.isAbsolute(fileC)) { - fileC = nativePath.join(this.cwd, fileC); + if (!path.isAbsolute(fileC)) { + fileC = path.join(this.cwd, fileC); } return this.lines.find(e => e.fileC === fileC && e.lineC === lineC) ?? dummyLine; } @@ -392,10 +385,3 @@ export class SourceMap { } } - -function fileNameCompare(fileNameOne: string, fileNameTwo: string): boolean { - if(process.platform === "win32") - return fileNameOne.toUpperCase() === fileNameTwo.toUpperCase(); - else - return fileNameOne === fileNameTwo; -} From 4a035d282a874665fd2369ae78008848869e6312 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 26 Nov 2025 10:12:18 +0100 Subject: [PATCH 54/70] Run tests with old versions of VSCode in the CI The oldest version found that passes the current tests is 1.66.0. --- .github/workflows/ci.yml | 25 ++++++++++++++----------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9340188..9cb8ad9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,11 +18,14 @@ jobs: - windows-latest node: - 20 + code-version: + - stable + - 1.66.0 include: - - { os: ubuntu-latest, node: 22 } - - { os: ubuntu-latest, node: 24 } + - { os: ubuntu-latest, node: 22, code-version: stable } + - { os: ubuntu-latest, node: 24, code-version: stable } runs-on: ${{ matrix.os }} - name: Test with Node ${{ matrix.node }} on ${{ matrix.os }} + name: Test with Node ${{ matrix.node }} and VSCode ${{ matrix.code-version }} on ${{ matrix.os }} steps: - name: Checkout code uses: actions/checkout@v2 @@ -33,22 +36,22 @@ jobs: node-version: ${{ matrix.node }} # node-version-file: 'package.json' - - name: Cache VSCode test directory - uses: actions/cache@v4 - with: - path: .vscode-test - key: ${{ runner.os }}-${{ matrix.node }}-vscode-test-${{ hashFiles('package-lock.json') }} - - name: Install dependencies run: npm install - name: Compile run: npm run compile + - name: Cache VSCode test directory + uses: actions/cache@v4 + with: + path: .vscode-test + key: ${{ runner.os }}-${{ matrix.node }}-${{ matrix.code-version }}-vscode-test-${{ hashFiles('package-lock.json') }} + - name: Run tests - run: xvfb-run -a npm test + run: xvfb-run -a npm test -- --code-version ${{ matrix.code-version }} if: runner.os == 'Linux' - name: Run tests - run: npm test + run: npm test -- --code-version ${{ matrix.code-version }} if: runner.os != 'Linux' diff --git a/package.json b/package.json index f6d5ee2..fc137f5 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "license": "GPL-3.0", "icon": "icon.png", "engines": { - "vscode": "^1.44.0", + "vscode": "^1.66.0", "node": ">=20" }, "main": "./out/src/extension", @@ -261,7 +261,7 @@ "prepare": "tsc -p ./", "compile": "tsc -p ./", "watch": "tsc -w -p ./", - "test": "npm run compile && npm exec vscode-test", + "test": "npm run compile && vscode-test", "lint": "eslint -c .eslintrc.js --ext .ts ./" }, "devDependencies": { From 9da38b48a05b962c4e142e68226027c0ec57f145 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 26 Nov 2025 11:26:02 +0100 Subject: [PATCH 55/70] Do not enforce a default `preLaunchTask` that is not available --- .gitignore | 2 + .vscode-test-workspace/.dummy | 0 .vscode/launch.json | 14 ++- CHANGELOG.md | 1 + src/extension.ts | 178 ++++++++++++++++++---------------- 5 files changed, 110 insertions(+), 85 deletions(-) create mode 100644 .vscode-test-workspace/.dummy diff --git a/.gitignore b/.gitignore index e4224ff..ea4ab8f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ hello hello3 .idea/ .vscode-test/ +.vscode-test-workspace/* +!.vscode-test-workspace/.dummy diff --git a/.vscode-test-workspace/.dummy b/.vscode-test-workspace/.dummy new file mode 100644 index 0000000..e69de29 diff --git a/.vscode/launch.json b/.vscode/launch.json index 4d75302..1b77ffd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,15 +7,21 @@ "request": "launch", "runtimeExecutable": "${execPath}", "args": [ + "--profile-temp", + "--new-window", + "--transient", + // "--extensions-dir=${workspaceFolder}/.vscode-test/extensions", + // "--user-data-dir=${workspaceFolder}/.vscode-test/user-data", "--extensionDevelopmentPath=${workspaceFolder}", - "--trace-deprecation" + "--trace-deprecation", + "${workspaceFolder}/.vscode-test-workspace", ], + "autoAttachChildProcesses": true, "sourceMaps": true, "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" + "${workspaceFolder}/out/**/*.js" ], - "preLaunchTask": "npm", - "internalConsoleOptions": "openOnSessionStart" + "preLaunchTask": "npm" }, { "name": "Tests", diff --git a/CHANGELOG.md b/CHANGELOG.md index 8911e0b..eb50257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Fix enforcement of a default `preLaunchTask` that is not available [PR #34](https://github.com/ocamlpro/superbol-vscode-debug/pull/34) * Support cases where the COBOL source code and the corresponding C files are in distinct directories [PR #29](https://github.com/ocamlpro/superbol-vscode-debug/pull/29) * Remove unneeded fields from auto-generated configurations [PR #27](https://github.com/ocamlpro/superbol-vscode-debug/pull/27) [PR #28](https://github.com/ocamlpro/superbol-vscode-debug/pull/28) * Fix evaluation of expressions with binary-typed fields [PR #26](https://github.com/ocamlpro/superbol-vscode-debug/pull/26) diff --git a/src/extension.ts b/src/extension.ts index 258f962..672e9c5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -9,6 +9,20 @@ const MAX_COLUMN_INDEX = 300; /** Array of COBOL Reserved words */ const COBOL_RESERVED_WORDS = ["perform", "move", "to", "set", "add", "subtract", "call", "inquire", "modify", "invoke", "if", "not", "end-if", "until", "varying", "evaluate", "true", "when", "false", "go", "thru", "zeros", "spaces", "zero", "space", "inspect", "tallying", "exit", "paragraph", "method", "cycle", "from", "by", "and", "or", "of", "length", "function", "program", "synchronized", "end-synchronized", "string", "end-string", "on", "reference", "value", "returning", "giving", "replacing", "goback", "all", "open", "i-o", "input", "output", "close", "compute", "unstring", "using", "delete", "start", "read", "write", "rewrite", "with", "lock", "else", "upper-case", "lower-case", "display", "accept", "at", "clear-screen", "initialize", "line", "col", "key", "is", "self", "null", "stop", "run", "upon", "environment-name", "environment-value"] +const superbolConsts = { + taskType: "superbol", + taskSource: "SuperBOL", + debugBuildTaskName: "build (debug)", +} +const defaultDebugBuildTask = `${superbolConsts.taskSource}: ${superbolConsts.debugBuildTaskName}`; + +async function checkForSuperBOLBuildTask () { + return vscode.tasks.fetchTasks({ type: superbolConsts.taskType }).then((tasks) => + tasks.find(task => task.source == superbolConsts.taskSource && + task.name == superbolConsts.debugBuildTaskName) != undefined + ); +} + export function activate(context: vscode.ExtensionContext) { const provider = new GdbConfigurationProvider(); const factory = new GdbAdapterDescriptorFactory(new CoverageStatus(), new GDBDebugSession()); @@ -30,90 +44,92 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { public resolveDebugConfiguration(workspaceFolder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { config.gdbargs = ["-q", "--interpreter=mi2"]; const settings = new DebuggerSettings(); - if (config.name === undefined) { - config.name = "SuperBOL: default debug"; - } - if (config.type === undefined) { - config.type = "superbol-gdb"; - } - if (config.request === undefined) { - config.request = "launch"; - } - if (workspaceFolder != undefined && - config.request != "attach" && - config.preLaunchTask === undefined) { - config.preLaunchTask = "SuperBOL: build (debug)"; - } else if (config.preLaunchTask === "none" || - config.preLaunchTask === "") { - delete config.preLaunchTask; - } - if (config.target === undefined) { - config.target = "${file}"; - } - if (config.arguments === undefined) { - config.arguments = ""; - } - if (config.group === undefined) { - config.group = []; - } - if (config.gdbpath === undefined) { - config.gdbpath = settings.gdbpath; - } - if (config.libcobpath === undefined) { - config.libcobpath = settings.libcobpath; - } - if (config.cobcrunPath === undefined) { - config.cobcrunPath = settings.cobcrunPath; - } - if (config.env === undefined) { - config.env = { ["LD_LIBRARY_PATH"] : config.libcobpath }; - } else { - config.env.LD_LIBRARY_PATH = config.libcobpath + ";" + config.env.LD_LIBRARY_PATH; - } - if (config.coverage === undefined) { - config.coverage = false; - } - if (config.gdbtty === undefined) { - config.gdbtty = false; - } - config.sourceDirs = config.sourceDirs ?? []; - return config; + return checkForSuperBOLBuildTask().then(haveSuperBOLBuildTask => { + if (config.name === undefined && haveSuperBOLBuildTask) { + config.name = "SuperBOL: default debug"; + } + if (config.type === undefined) { + config.type = "superbol-gdb"; + } + if (config.request === undefined) { + config.request = "launch"; + } + if (haveSuperBOLBuildTask && + workspaceFolder != undefined && + config.request != "attach" && + config.preLaunchTask === undefined) { + config.preLaunchTask = defaultDebugBuildTask; + } else if (config.preLaunchTask === "") { + delete config.preLaunchTask; + } + if (config.target === undefined) { + config.target = "${file}"; + } + if (config.arguments === undefined) { + config.arguments = ""; + } + if (config.group === undefined) { + config.group = []; + } + if (config.gdbpath === undefined) { + config.gdbpath = settings.gdbpath; + } + if (config.libcobpath === undefined) { + config.libcobpath = settings.libcobpath; + } + if (config.cobcrunPath === undefined) { + config.cobcrunPath = settings.cobcrunPath; + } + if (config.env === undefined) { + config.env = { ["LD_LIBRARY_PATH"]: config.libcobpath }; + } else { + config.env.LD_LIBRARY_PATH = config.libcobpath + ";" + config.env.LD_LIBRARY_PATH; + } + if (config.coverage === undefined) { + config.coverage = false; + } + if (config.gdbtty === undefined) { + config.gdbtty = false; + } + config.sourceDirs = config.sourceDirs ?? []; + return config; + }); } - public provideDebugConfigurations( - _folder: vscode.WorkspaceFolder, - _token?: vscode.CancellationToken): - vscode.ProviderResult { - const launchConfigDefault: vscode.DebugConfiguration = { - name: "SuperBOL: debug (launch)", - type: "superbol-gdb", - request: "launch", - preLaunchTask: "SuperBOL: build (debug)", - target: "${file}", - arguments: "" - }; - - const attachLocalConfiguration: vscode.DebugConfiguration = { - name: "SuperBOL: debug (attach local)", - type: "superbol-gdb", - request: "attach", - pid: "${input:pid}", - target: "${file}" - }; - - const attachRemoteConfiguration: vscode.DebugConfiguration = { - name: "SuperBOL: debug (attach remote)", - type: "superbol-gdb", - request: "attach", - remoteDebugger: "${input:remoteDebugger}", - target: "${file}" - } + public provideDebugConfigurations(_folder: vscode.WorkspaceFolder, _token?: vscode.CancellationToken) + : vscode.ProviderResult { + return checkForSuperBOLBuildTask().then(haveSuperBOLBuildTask => { + const launchConfigDefault: vscode.DebugConfiguration = { + name: "SuperBOL: debug (launch)", + type: "superbol-gdb", + request: "launch", + preLaunchTask: haveSuperBOLBuildTask ? defaultDebugBuildTask : undefined, + target: "${file}", + arguments: "" + }; + + const attachLocalConfiguration: vscode.DebugConfiguration = { + name: "SuperBOL: debug (attach local)", + type: "superbol-gdb", + request: "attach", + pid: "${input:pid}", + target: "${file}" + }; + + const attachRemoteConfiguration: vscode.DebugConfiguration = { + name: "SuperBOL: debug (attach remote)", + type: "superbol-gdb", + request: "attach", + remoteDebugger: "${input:remoteDebugger}", + target: "${file}" + } - return [ - launchConfigDefault, - attachLocalConfiguration, - attachRemoteConfiguration - ]; + return [ + launchConfigDefault, + attachLocalConfiguration, + attachRemoteConfiguration + ]; + }); } } From 802899507a551723449c24f9a22a3ed299609382 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Thu, 27 Nov 2025 11:45:40 +0100 Subject: [PATCH 56/70] Add a test with COBOL and C source files in distinct directories --- src/parser.c.ts | 13 +- .../distinct-sources/c/subsubsample.c | 232 ++++++++++++++++++ .../distinct-sources/c/subsubsample.c.h | 21 ++ .../distinct-sources/c/subsubsample.c.l.h | 49 ++++ .../distinct-sources/c/subsubsample.i | 15 ++ .../distinct-sources/c/subsubsample.o | Bin 0 -> 118160 bytes .../distinct-sources/cbl/subsubsample.cbl | 14 ++ test/suite/parser.c.test.ts | 39 +-- 8 files changed, 367 insertions(+), 16 deletions(-) create mode 100644 test/resources/distinct-sources/c/subsubsample.c create mode 100644 test/resources/distinct-sources/c/subsubsample.c.h create mode 100644 test/resources/distinct-sources/c/subsubsample.c.l.h create mode 100644 test/resources/distinct-sources/c/subsubsample.i create mode 100644 test/resources/distinct-sources/c/subsubsample.o create mode 100644 test/resources/distinct-sources/cbl/subsubsample.cbl diff --git a/src/parser.c.ts b/src/parser.c.ts index eb4cef4..6c990f8 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -71,7 +71,7 @@ export class SourceMap { private performLine: number = -1; // 002 - stepOver in routines with "perform" private isVersion2_2_or_3_1_1: boolean = false; - constructor(cwd: string, filesCobol: string[], sourceDirs: string[], private log: Function = (_ => {})) { + constructor(cwd: string, filesCobol: string[], sourceDirs: string[] = [], private log: Function = (_ => {})) { this.cwd = fs.realpathSync(path.resolve(cwd)); this.log(`Source dirs: ${sourceDirs}`); for (const cSourceDir of sourceDirs) { @@ -300,6 +300,15 @@ export class SourceMap { return this.variablesByC.size; } + public findVariableByC(functionName: string, cName: string): DebuggerVariable { + for (const key of this.variablesByC.keys()) { + if (key.startsWith(`${functionName}.`) && key.endsWith(`.${cName}`)) { + return this.variablesByC.get(key); + } + } + return null; + } + public getVariableByC(varC: string): DebuggerVariable { if (this.variablesByC.has(varC)) { return this.variablesByC.get(varC); @@ -309,7 +318,7 @@ export class SourceMap { public findVariableByCobol(functionName: string, name: string): DebuggerVariable { for (const key of this.variablesByCobol.keys()) { - if (key.startsWith(functionName) && key.endsWith(`.${name.toUpperCase()}`)) { + if (key.startsWith(`${functionName}.`) && key.endsWith(`.${name.toUpperCase()}`)) { return this.variablesByCobol.get(key); } } diff --git a/test/resources/distinct-sources/c/subsubsample.c b/test/resources/distinct-sources/c/subsubsample.c new file mode 100644 index 0000000..6356571 --- /dev/null +++ b/test/resources/distinct-sources/c/subsubsample.c @@ -0,0 +1,232 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from distinct-sources/cbl/subsubsample.cbl */ +/* Generated at Nov 27 2025 11:03:15 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -x -g -save-temps=distinct-sources/c distinct-sources/cbl/subsubsample.cbl */ + +#include /* for memcpy, memcmp and friends */ +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "distinct-sources/cbl/subsubsample.cbl" +#define COB_PACKAGE_VERSION "3.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "Nov 27 2025 11:03:15" +#define COB_MODULE_DATE 20251127 +#define COB_MODULE_TIME 110315 + +/* Global variables */ +#include "subsubsample.c.h" + +/* Function prototypes */ + +static int subsubsample (); +static int subsubsample_ (const int); +static void subsubsample_module_init (cob_module *module); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (subsubsample ()); +} + +/* Functions */ + +static void gc_module_so_init () __attribute__ ((constructor)); +static void gc_module_so_init () +{ + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); +} + +/* PROGRAM-ID 'subsubsample' */ + +/* ENTRY 'subsubsample' */ + +static int +subsubsample () +{ + return subsubsample_ (0); +} + +static int +subsubsample_ (const int entry) +{ + /* Program local variables */ + #include "subsubsample.c.l.h" + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -10) + goto P_dump; + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + frame_ptr->return_address_ptr = &&P_cgerror; + frame_overflow = frame_ptr + 255 - 1; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 13 : Entry subsubsample : distinct-sources/cbl/subsubsample.cbl */ + l_2:; +#line 13 "distinct-sources/cbl/subsubsample.cbl" + ENTRY_SUBSUBSAMPLE: cob_nop (); +#line 105 "subsubsample.c" + + /* Line: 13 : DISPLAY : distinct-sources/cbl/subsubsample.cbl */ +#line 13 "distinct-sources/cbl/subsubsample.cbl" + cob_nop (); +#line 110 "subsubsample.c" + cob_display (0, 1, 1, &f_22); + + /* Program exit */ + + exit_program: + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + P_cgerror: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + subsubsample_module_init (module); + + module->collating_sequence = NULL; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->xml_code = NULL; + module->xml_event = NULL; + module->xml_information = NULL; + module->xml_namespace = NULL; + module->xml_namespace_prefix = NULL; + module->xml_nnamespace = NULL; + module->xml_nnamespace_prefix = NULL; + module->xml_ntext = NULL; + module->xml_text = NULL; + module->json_code = NULL; + module->json_status = NULL; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + /* initialize field RETURN-CODE */ + b_2 = 0; + + /* initialize field WS-GROUP-NUMERIC */ +#line 7 "distinct-sources/cbl/subsubsample.cbl" + cob_nop (); +#line 163 "subsubsample.c" + memset (b_17, (unsigned char)'0', 12); + /* initialize field WS-GROUP-ALPHABETIC */ +#line 10 "distinct-sources/cbl/subsubsample.cbl" + cob_nop (); +#line 168 "subsubsample.c" + memset (b_17 + 12, (unsigned char)' ', 11); + + + if (0 == 1) goto P_cgerror; + initialized = 1; + goto P_ret_initialize; + + P_dump: + return 0; + + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) + return 0; + if (module && module->module_active) + cob_fatal_error (COB_FERROR_CANCEL); + + initialized = 0; + + P_clear_decimal: + return 0; + +} + +/* End PROGRAM-ID 'subsubsample' */ + +/* Initialize module structure for subsubsample */ +static void subsubsample_module_init (cob_module *module) +{ + module->module_name = "subsubsample"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->gc_version = COB_PACKAGE_VERSION; + module->module_entry.funcptr = (void *(*)())subsubsample; + module->module_cancel.funcptr = (void *(*)())subsubsample_; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + module->flag_debug_trace = 0; + module->flag_dump_ready = 0; + module->xml_mode = 1; + module->module_stmt = 0; + module->module_sources = NULL; +} + +/* End functions */ + diff --git a/test/resources/distinct-sources/c/subsubsample.c.h b/test/resources/distinct-sources/c/subsubsample.c.h new file mode 100644 index 0000000..53680ba --- /dev/null +++ b/test/resources/distinct-sources/c/subsubsample.c.h @@ -0,0 +1,21 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from distinct-sources/cbl/subsubsample.cbl */ +/* Generated at Nov 27 2025 11:03:15 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -x -g -save-temps=distinct-sources/c distinct-sources/cbl/subsubsample.cbl */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x0000, NULL}; + + +#define cob_nop if (!module) cob_nop + diff --git a/test/resources/distinct-sources/c/subsubsample.c.l.h b/test/resources/distinct-sources/c/subsubsample.c.l.h new file mode 100644 index 0000000..6564b87 --- /dev/null +++ b/test/resources/distinct-sources/c/subsubsample.c.l.h @@ -0,0 +1,49 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from distinct-sources/cbl/subsubsample.cbl */ +/* Generated at Nov 27 2025 11:03:15 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -x -g -save-temps=distinct-sources/c distinct-sources/cbl/subsubsample.cbl */ + +/* Program local variables for 'subsubsample' */ + +/* Module initialization indicator */ +static unsigned int initialized = 0; + +/* Module structure pointer */ +static cob_module *module = NULL; + +/* Global variable pointer */ +cob_global *cob_glob_ptr; + + +/* LINKAGE SECTION (Items not referenced by USING clause) */ +static unsigned char *b_9 = NULL; /* XML-NAMESPACE */ +static unsigned char *b_10 = NULL; /* XML-NAMESPACE-PREFIX */ +static unsigned char *b_11 = NULL; /* XML-NNAMESPACE */ +static unsigned char *b_12 = NULL; /* XML-NNAMESPACE-PREFIX */ +static unsigned char *b_13 = NULL; /* XML-NTEXT */ +static unsigned char *b_14 = NULL; /* XML-TEXT */ + + +/* Call parameters */ +cob_field *cob_procedure_params[1]; + +/* Perform frame stack */ +struct cob_frame *frame_overflow; +struct cob_frame *frame_ptr; +struct cob_frame frame_stack[255]; + + +/* Data storage */ +static int b_2; /* RETURN-CODE */ +static cob_u8_t b_17[23] __attribute__((aligned)); /* WS-GROUP */ + +/* End of local data storage */ + + +/* Fields (local) */ +static cob_field f_22 = {5, b_17 + 18, &a_1}; /* WS-GROUP-ALPHANUMERIC */ + +/* End of fields */ + diff --git a/test/resources/distinct-sources/c/subsubsample.i b/test/resources/distinct-sources/c/subsubsample.i new file mode 100644 index 0000000..c8277bf --- /dev/null +++ b/test/resources/distinct-sources/c/subsubsample.i @@ -0,0 +1,15 @@ +#line 1 "distinct-sources/cbl/subsubsample.cbl" + IDENTIFICATION DIVISION. + PROGRAM-ID. subsubsample. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 WS-GROUP. + 05 WS-GROUP-NUMERIC PIC 9(2). + 05 WS-GROUP-SIGNED-DECIMAL PIC S9(3)V9(2). + 05 WS-GROUP-UNSIGNED-DECIMAL PIC 9(3)V9(2). + 05 WS-GROUP-ALPHABETIC PIC A(6). + 05 WS-GROUP-ALPHANUMERIC PIC X(5). + PROCEDURE DIVISION. + DISPLAY WS-GROUP-ALPHANUMERIC. + END PROGRAM subsubsample. diff --git a/test/resources/distinct-sources/c/subsubsample.o b/test/resources/distinct-sources/c/subsubsample.o new file mode 100644 index 0000000000000000000000000000000000000000..01687d8599f4e373944a3c1e939d84ff5636b6b3 GIT binary patch literal 118160 zcmeFad3>E!oj-olo13N-+Oo-}a0^0HXxh7FL%`l9H_f$a5_1zMI?g3cZrVtiWO9?z zIxdU|f~bI^BC@%RIy$Jcint*vxQ*M4`-YB;=(syBqmF*x@6Y?3=Xvf;0>#(w_n(12 zpL@=;o#!l{{qs35DD?NPYG{c0zlPXFv9RQ8W3e0G9oBBQ>g};Tu}kdQvr#?=|9HhF z{A+Q)Hv^vQexC=p#r&qkY#s+;`OvH(d9; z-}ha&_|v}YM}K;K0YATZ-Gh(dbnG4;9^sd|3f^!pEBjuSFmT-i!7tr%?9;}bl#VGmaUcdb^dw47sC%e9S(7J_J`xC*i z+CWG~mNz7ML(S7Up5OoO|NZfgH`?d@ci~1qc@|fzCL2C-;biw) zV|~;IdABt_Y^vS#aa&7$*FDc>ET$>0!;6P7J8agvA|4klCTof}{*?FVg1x`z{2yv@ z#c>r=R(x>#kUg&EQG0mm!R?p%GY@W`_;o{DgKGEx_d6Qw$q#Oy4lkJVKOflsTs!-~ z_UCQo4G(O8{*wh?u*Kk&SK?B8)&p1mP5ASL;m@n^Q_r~aMPcpL;m>Qr3tk-ld`bB8 zy71?3@KY_n@};cBADhwl;FUM36a(&ZzZ}?DTa0D55~Igr6I0cNshRPG)`iM}x$3s@ zz0=#Oi+lP1*nzp}%2rgwq7|`$*@MYUM>3Pjv?bH&^HbUL)1(9Sf5AkpJMo1l#A1n9 zLo=&S;o(U!J$i+v6M zezxk1I0A$EV}t!(WyiQ38||2|W0M_M+p*b>YwUQG9oO3NXgeNb$8~mGA6qwx=QlT6 zp;Ycsrh8#}n=N1UsH&$CK@NiXBh2<7sw$q8*=P z$J6b2h8>f3+-S!$?Rb_QpKQmo?RbtIH`%epj+^axt{u;_;}$!%+HtELx7jge$Fvw%f78j-7Vwvg7%7e2N_}u;YbxyvUAEwc~a>=Iyw{j@@?bv17rGy>{Gb z$38n2?f5i1?y_UQ9e3Mtz>b4<9J1rn?Ko`5k{w6vIBLg>?RbeD_t^1LJ3hmX&$Q!T z*zs9*{7XBQ?Rc3T$LzS*j^lQmuw%uJlXl!^$NhGkvg5Puc)1;??RdbBGj^P{<6P`0 zE|caRjT=6SIZI3)>uy}l-zxMpuI5r}j5Rkj@#H$5A{B`hY?iP49Ln~L4aLR{DXc_$ z#?u;)<8Kvqsj$k<^fzwkz?nuX?ADp4^>b6>v4O^uFT$DTSo12a_*J&z<6rl09BlkH zey;1rMfS#%ON|?@MZq35(zw>Jn-xYIkK>7ED_q=o@@rAp5R1Re>I@I9$%+Z@GDg~I`+h7yRGF#jm_O?x7~Ji^tNlF zx4qciW|v*7!Uii`*SL=NpKOKeRY=C-pTd_nvCVsMay9YdYN65Q_-h*1zY&#eU+k8~ zweRr1U)y-pz5e&Djq5+-f4{DA&A0sT+guAz()}6tIBpc!nHg5P3`r1C^V~r>Aw+bI`T>k(H>cCGluIKma z<3Fi_KK@fGB<%tJ)_B}^aaoHMKCME^3ZH2_>63U`rxiZixQ;E|ZiUaO&}W6uHy-<0 zTsCBde{bCI1r+vJ;R}r$IG&eT;fpFvSm8@5?6<;~RhYKIS5%m@!dF#Tu)^0Go7pvo ztniJ-V>xEewZb=5c%Bu$rNZ;A@Q?~Gu)=p#xY7#$slwk_;kzol&!XH$4s}=sJ!n>>xOW0uDV}%A4?z6%w6+UK#xC)=OLZb>_wnCE% z4_RTg3XfP}O~O{uPpz;vVWaSy<1sF=^@)>zfbWSlSn0Tg&Aw)pj#p`eN+%>v{2nem zxgi$+3FcIs6Dxi*7XYVAoU_(eBp+uh5|!V>XLtNuQ=JR)cn_pf>cYpx5qB9LtBb*wY3Q zM-jKAtT3oTrxk`0ws5yw;psZlXNBQ};qoCXlvLPbg%K4lTR%Aw8%@|s+ixc>(HLuW z?or`@ow-zn87n+Pg;^^+Q-wJz{DlgCWrb&{FmHvwRH15x%T&->A5&q`&g@m;pcTed zxWWn(Djc#xMTNswm{j38R@kS)Ut3{H1!0b7C)Sc?3Rzs9IGTkk*H4a5#115mYlgUg zt=%)5SholB;YKU`RbuTiICF~?=2f^W$@vnmCJf;PgOX|3O`d}trdQ*g4W9~R5-@Y{ErIjtnf<})?49MDr~UAuT?nK3cpd| zI4k_G3ddXFw<>7$#n;%!ooHv)s_+CW9Ie7hRyan5ldZ5$g;T6>yb7mU;RF>R_ zg>5S2tdP=W?N&&u&}oH?E<4`}S)IAS3ON-nvO=3)s%71-Lf+1F=&~JF=u|^{)>mfd zVqH2jync3WA$IxoVQB1KtR=7Zgzp%oEDqLoTi*%33_EXn1{}vx7 z#ISwMhCU#_EA6tp3R*5ZRM2wiUbE^8c+V|%STe% z+0we_l%@^0;lu5wQ=5)?5>BXaTGRU90#!HLnI|?GS<>`BFoTI{JR@kJ%ek-)7FlU8xnrBt}mE=xBVHWKfWQQ=xUlT|_7Moxtr?M!=`b@pa8?%9-mLo2byj=iCI?ORb;rw`^&dru(sIxI2H zNdH^sd)IJrSshkga2~&Pe&?D+e;x}l`rFRO`5{O5t>HSfhhTvQjl^#~q_~Dl)6Qef z2Iuix=byIbtNuKeac~~L?YvD9B2w#=W7MO+_2mYYj{>J@=TC}Zy~kpSqfR96xCXOL zf2uv^7|IP{?MY+hbS!b~lPIHxwI}nIYnz^hXC|oTianW!rVH1xZO>yZe8L=7mkizP`5R`)iK<0BcIPBs^@0oy`Ztn^zxyj{SIk(*{2L=e*Po zzplNh;RIgJ7sY>%GjU?H_;*le4Y|GP*fViKf*qg(Ul+5lx~3`1Q&wRYKd0%~r}>%$ zf5qaQ2Ag{5qAt^p4YyVWU>vG^FCj6)ezvU|eBZm!&L$rC9ai}V;iHN#Kfw%|v4(WbKobw~ui>^< z1Dk?Z+N8EKG=9b!POrHy%{u%w+-8&G^tJ5ORX0tmbTX&ns+%su`D0@7b?0x4KPAz% zws?FesQaoG)I5=7etm51#^xd>Mq|xInBa*RtD71cipNvXT)h$HZMdcR$+5L-FIpR4 zhe65l!E2wgmd{;<)p6AE4e@nr*SdG{wzW?P-n}u-2OfP=1Ky}BHm>3&#~kIKvN28u zcilPm=JjZhyUw+G1J~cNTN|EwO7J z&R%!?+V~l#opEf#ajQ3+boiuL>{ROj*GI9~X|DIMK%a=dM}I!)B=y-^4iDdW`iTt$ zXINh*@M>3|wC}NE@%UrbUXBmiczgqTJGkOZ6eBmBg;%rbHtaybuHn{}O{Wx(SJ$1r zHD(=Z*RelgnGdeSt>KlMwxXr#icR>|<5q7!`8n46EzuLj<8|t}c4~99`#9syjn0{C z8`g5#oQE0U`j``7%T_-jF!26iu~=(Z9ae4)nuH`)@uQB_^BP^HZrbQdjR`}k@uQAQU~*vrKPm2hoKkcB zL#vMW7o3nVgb+W~y|yua`iZXUq$jv{B@CD73GwTjPKrO=aI$Ma{2!X#qvKyc`cz%- z?>d@INEo_G03YBt2p^7y(Go@-<0mBavc~xNs~a0(VdMY2=+DPL_rRZf;Lknq=N|ZT z5B#|Y{@eq9?tvrd0pp(_9e{r_MMq+j{Z84@n79PBamHSW0Zf=LQ+QvKth7zC&o;?2 z+a$ealdQ2#*O=jZ8SxZObF4FY!yyjQ>+{bGq18Z)1GiNH+)w+P&6!1@H@ zIywu23693RTI~a-1W0^Z;9-HE8ff}ImHr^`LOtLrfvXMJBaG=@bym4N6l;32J>H~y zsk;(%M2;o$cHCjdK|2oF@#%IPwj=$wVu|P3(G(d84Ov1%me3$2)aMEHc|v`caNTr= zI_Av+ZxQ&hy5c7SzZ3Yqz^(eW*9*K+;LQSW5qO)xI|M!=K=%(c_6q{v68JBH9}4_Z z;8y~!6RB6ieXkO@Q{e3a{~&OWz=s4rVW8>rD*d~_*9Cqo@DqXG2>e0dj{>)v@R9gC zfwu|JUjzz|kE-->12&R3n@dsRRRXUTc#Xg<0i@|wZIH7Zjv5>%*A_}&bBT!)ml@x{oZNcSG3=|?YHJ!$$py}Eb*82`!XIA z6ZU(`ejnh`+F}xLA{mt5qv>?7fLnv_Q|bKz9}sX0^FEb6ByhjLhXp<&@KJ#W1RfOl zn83#cK5L-qM*=r!I^ArbNz>O_EA(jU)r9qhUpB&Y31K?Fh=l19!gL8?x`Z%YLYOY$ zFrAi^dwt@1Et{7LyiDNb0yhZUDB$qWD^z-=z|8`$5_q-1YXls|daX*g8fbcpz&8Yz z`}n3i)gyNa{H=k=_?=_J8SS0TR--;T&wg*Qqp+6g9~0+W%~R}np&gCbBu4D_s2wl1 z<0W?7W5-MF7@1#*vejH>$1ywZwd1%QZQdm+_IuKf`|YTi_-y-qxgDqNXmhjaFn>2a z$But($LHG7FlUo6r%ZW%3b^rgMC6T{S8p<4J!QR{FpOd4@2SEe&R?nI5a-qE=W7IB zEO4#BbpkIDc%6X5t#44tq1ZR6eF7Wl2e?*wYm_LYW{6IThmNZ@LLYXuaYk$8zp3J*xUR3$}+Bwnu44FWd` z+$``afmaLMBJf%PM>Jli(rp5_3)~@ar@&nTuNQcOz#9eLB=BZ|w+hq}qPMH^ZUMSG zqU-)qfS!&h{jh$Sy9MqMc#i-*Byq!g1>Ps{et{1N+$ZoMf%^qMEbtKlM-(4W zNdXjzkEtX|nJ`zeSmKka{FK0_1wJQ04@|V>3j$vh_>#bv1->fq4S|OQzAf+_f&Ucv zuE6&M9ufF~zz+p}WT5F9(bE?P^t9;))f@puzg1V(681Y(d8feZ1?~}ekAS20?^Wr2 z0`C|2fWUnM_X~Vj;3EPb6Zp8mCj>qz@F{^$3pm!{n<_aD;vtp3E%30w_XHew@qLwk zAn@M;KNR?pz>fufF7OM1{}K45z^?>;E$|zG{}uSH!0!cKwA#l0YJqD6UMz5}z;yyI z6L`764FWd`+$8V{fmaILEbuCUR|~vG;1+?`3fwC2I)U2+ZWp*i;7)P+17J;`4{GGtt1l}(2PJw?B_*a2<3%p0*UV--tyief$0v{0gpul|s_X~VP z;7bBu7Wj(5R|UQ%@O6Q22z*oETLKRWd|Ti<0{ z1+EpiPT(a1*9*K<;AH|Y7q~&-MuD3IULo*Gftv+hCGcv2*9hDq@LGXe1zsm`o51Y? zcL>}maF@XA1>Pv|w*qe#c#FVW1>RvG2ISZD&#HO1z&!%@3cOd~=WA?X{zBlTM_K9Z z0v|BICpldLEwC|Z6cVTLx1GC1wx8Du+$wOLOhGRd_>oLPKNk3jz)uB!Ch&8C{}K45 zz^?>;E$|zG{}uSH!0!ZpFYtc?e-QYiz?Ei-O8kw$3k9wcc#*)>0@nzBLZAGTz`X+hEKj zp90?%cv#?j0*?s%K;XXxekkxGfgcO}MBsMu6yc(uT5 z1a1?!UEmIZI|be-@Fs!36?n72TLj)J@HTKjp90?%cpW@@ z@U^!I+%9m3z?}kj3A|q54FYcx_*;QD3%o_(?*!f^@OFW_1>Pa>PJwp`{DZ(h3jCA6 zzX<%Rz`F(R5qOWly#ntQc)!301U@KmpTLI%?icv5z()i=D)4~7g90BD__)9)1U@P7 zDS>|z__V-h1U@V9d4Ycy_zwZb=MsMkd`aNT0$&mMs=(I-zAo?$fo}?YOW+}aZySjH z3uO5OyhI+v3mO_4ez)!z0%`*A4?oT@;>g!O+TW^%Gghq^RSYgOZGveEOm4S&6K%s^ zCZt%MWL}<;;1c{YF2)XZ*BJ@7gS{hifG4j4g!z#8=?#ha!_CLXRy8&>-H~W$`s+k| zSE8Z$<2{L^0PjT9PV*^=CZ4`GvHH?aBoZG_tS+l!)#l?8Yj-8qygrd!NE~x@;`F-{ z8}CjW_oc+@ujqm=CgQJ5tT`)j@*RozRO70|N%6a1khC}5n}`F(oA%(?*mN)69sf2W z1CLpC7G8D-UwsPhd3NHc?vq|CKm>A+hGF#1kUN6Y%@) z#EEu1&5ozo5e-BAsdn6GM_m)W{-lLO{GEx_kD!6^_z#|chZ@Kx-PW+DaaH_#&u@NV zSa(Omp2Yg*YZCE06N&iEFW8efI{uSb60N-X1q+GQ@t@;&(41CVri6`M>{SRDr+TDp0?BY|ulxTQ(6)Oo@9G2d2TYD%6JePpWQn(GqupNIf-B8%AtkI{7jiO$(GHr?!g`9r8W|ielt%_H$>WBd!-f1vVK~{6 zPF`?9vTJi}cW=43x7<_c&5!nvBvY~ZO0_b7urgt{4i|<7heyi&#Q{8XH=bSS!JVVL zHJjQTD~;?PDd+p~Jolpf$Y`mY%9Tr_-Q9&!sazcB9^5_DUl=JQbFuOz-F^At@(5ps z2lgcS?(SZ8C^|EBD4mK84wZKnMv4QygD9s`sdjwrzUisG ze{IG`*VHCe9c}nQHY!Rp3m)SIzDno5saE`-?le(NX9`w6a_p$q%Cgc9#1Jc@Axn-M70iFp}p) zNyero4h^6|{goNqi#bx}tW2lMg*`)<2HDQo^z8WM`SAt!VvKeVn|Lw$vp3({6`P%_ z%sIXO+3>QZV<$Nz*T^`BruuBTLSbxus;y`~P*D|>|*@C~x&Ckp}i$jjNzBzdg zFYCqF;BRyCxx4}wWbA@;d(8#m>9n2hjGWau+?jfod*tTLv7SPA{{SZINHRKz-Gc)o z!-M_h-oZiZnVR8Dr#GV`M$v!e{zASqlFgJyE*&bMFBWI2Q~PEr6Gr+MD(4H$_QtTP&!yWCp*j{#DY3ex@P3Z370#;>V_h>&BO?d#5sD*7LzwQ}=}afOE!{DSH&4#aFHB7yE>A8Z-v)*$ zS@y_cZ2F3^!&Tsn>8Y6ts)PAn9^)-j<5OePSkn$Sly?^g!jW%j&8E;0Taj4(_}q&J zcNK7Leq?Yr+R+EBFkE046_V*}I@OVheqsOMCBzBKd>k+Ytg0i!Jw;#%&b2Z=q+_!7 zuiv+6Pkp0uU0Dne=9;0m!O@YSQ6L#EgLJI7yQh3Hre1q)2aqHYn?n#9KMk9f2i9A; zSm-Xdr`p=O%Dtll-6hQUk#ct?8{=SE8C-Av^`Eq#r%nQygv~hS)MUKf5ryImzEi`>i)&&av0DJTVQp`1e&7Dl-RL z4vA8zltdACXs%eJbW2NXdpeid96K;}Xt*-2Wsgzp#kh_PC!=$ujPWa%rz>NV%M+FHsRO|B z)%{rWwFt>Rl(eb8r{&<5Lt74Sc@D7c!L3!`p5%qeLtByuw@!>LjN$iT{^l^?_j9%+ z&pAkZvlr;i29=+*$X{rPC$MGVPc+i#aVDV0J)=YYMRrY6%fIk+^sRkxVW>QS6=h%B zoyQ9f%=Hq>kuc`_Nk%R$clQsLK(;q!HraUC*kH8s{RNSV$<3`7v7N0KRYCqLn9q}3 z4nqs`vGU~;dkvOLePAd&#!a^i3#p;GEEW{#)xaQlguwyu3|V|sX#{u_Y{o#T7%uAK z0GOg-c0Q*q=Mk8O;y`iaQoF`_*L{7v9y&4%tidlQPhsn}fTs?O^hK8Mma*xnv1)V? zCo#XP2k=ZREyn;PTh7vDWC}+5h6gW+&CLQ?Rp!f`dk=#-SpXr}!Vlk!At!?W>m;j^ z=guw6ms$Um>TVFD%wmytvqd z@13uVTR)E2|f}b7( z_N^QmugsC6l}W#1)x!t&&Q8bj;slLj;)KKu>rCNsnyaK?=-k$zY!s$7X;fXD-|XIJ zb5URbfL_bxy|Yyg#;n7Z=q*0OBgz zV0o|-LI&UmjDlR8?=SXX>foZC-QAv|juc9ql|5y$n3!D!T;?!U6oc&?9vmG44svq^ zJj7CzIWxPke}47~!`qy?y+u izRy$y};SOT-pNaVNPWNeN=$J0)7U7lMrU7kBoJ zEJw-H+0C&TNF~t)mu<7P1`1gMp3Jtzs+EOjADC+abwXFGkhBt-@A|ZcY<6u;cV^pi zUG3?%j;^kBCY^3;Po>&A+CVQmQn}8Ku3WYqWHY@Zm_yl&gqoW5S~q{H3uDMbRsr9J z22buUW8p-bo$J7A2O|M$IZy;b%5~J_CIg2Ag6~+C8cdkZmBE6P2YbuA3YV6L^8-7< z4CU<6`EvIlC{4}SkRO_!0PV6dF`)|+qc~FH`blQnH9PV>J?Nc)0mZb7V7H<2#NvTD z@hCHu%0#t1Gi_@Y=;Av*7ZLuX zCrQlElQOwKy-k6*Vqe$!r#{F(#y;+%i;{ohgTlx72mNW^7JZI?(x1}bwa@WS!W_WF z7t^!5SnB3a&hcKzSeR>G5~!5}CMQRoDBzHVrHiB|NZ6;9ZJf&q#Ntf`rUmH7n-0+j7TMmogi*&G)h*rra$2rl9W zt~7?ke-9-a)Zt5kK)fV5Jv+0{Ns*Mei(obaSwtF{D@f4G5f!KswlG<3v>7L&yq*x@>zUoyw+jS$uM;E8CW8&)~m~4vauH zlkRBCw5KT4Wi!1L&5YPz(g%ruaHP-aw4PBI9xRl=0uS{;-7^B#f5)Xz1@spNc8>I+ z@t!)Ho-E%VsF|o0Fv(O{e*qay7N!nVs$k&eDxhxCuQ|HCqdz|YX~N{5%iQhmWeIkAzCPbO3dZSMGU6SMhMcuEfZTD8`BFC z4DN=yhzuVH@>_NKR7lC?>i9fvp9cR&%p?ZV(^|J~-1ilRq30+U2A5UXm`bAranGqn zTo0PQVMhu49J(#kQreQq(2NaP8wPX+1Bz-Bpab27$Q{)Cl;qG=&XhPcr6l1Vz@H+6{?b{o`-&LcBTct zHXD0BRHW9hMlEJs=5h-%1Nj7!*zEj78HyP^nMx0ezAXo;`zWP^T9Y!hGCVysvk%X= z3yiWt&$m$agk!%XIjlO5z-71yjo>T@;u_a{^dSR$k>_^+FBAS?8+zahMW@{#s%0bbV!=we0 z&SJK9<~lO%S!&!m)9pE6>q=|7z2B=f_n;3<3X=+T3VJB^vn|1DwPkF}>=p>`>U>v; z*NtsS&TdIot(Z&g_)9c_YfR!M?OAASID2QoR87y0 zO^jj0FnBme$=Xp^FLbBdvz;ceo8onJq_+&ZB*uv7%=Gejo9}nyu{dx2GIcDAir`sz zj>;{+6r|`n*VqKwlOS#9i?B)ULXV#oH zas`V}%8pG;aFLpv934HONeo4_l1s1*v_%YR8VAriTNg=vXQ_}M?(PG}(;vKXXs}c? z^OL>SG=`=NM0*OHrM>x1qfzSJwC4aExd3)rN-eBwZPK{O8#3xP1sxM@N?Gw(z5V%} z>;Ozv*z>?CIzwc;*%u<5Y!)^!$FO6tXozcZ`c+OWmZ5ClLba-~C&_cq-TWMm3ukuw zQtsZkxV@EqQ#0k+Nkgi*mT2#>#2{SK>4~5{1exqWai9<8lD5zBqP+i>G_+T2GquNH zd?M^q6^0=xmB9s7Dl_DP_&FFvs9MPuO@pgsmDAxsgXk4FyskQS5Lz8t8LYcXBTnH9 z@-KZ7N3lzqhCRDs*31usgTk+YQpvXttRY+O)XKRWMuVpC@*p(dut{H%%;kb91LaEi z+@8F;7i)Ssl^oC^`ci0#EaHNFnZph;l$N0ksyJTM5J_lIIdov!w5rv)v2oCR=<}uy ziS<4(HZ`NZrWK(qE}IN}y}FvCQ-v8a7?VG$i% zS(u*1B$2`i_^6vp7!(@%9pH1Ka4;$2Lom~5+mA4bX(-aVKvG~}0!aa>>1c0DWzryq zoo(4vHU({3CJj|AMHSkgY#d}K0n0lG{M|En$-uI#iYY|Z#D#^!ZjnR9UWm<3PNLPb zPHtk0mJw~aDv0l+%s-nEp;tRD9m->tqz>g$Kq1a}d~l1Ik7eP#5L4NkjRm;pY*ltxQ92E+JeBuNa|5%Sfn0H-2CAPxt}&2u=OvmA}C)6oI=bI_A!xmB75 zvldy?a4hLx?y@#R`o@0*RQB=6*+y{LBO}G#urNTC4GXHXlRNJK%^)yXCE7bePEdL$ zcp^ZGp?NBLPAo2tb9f{(=nx zUug)zrm8JpL+q>*#V}UQu47}tb(U!gD(^0g^bPhH#^L-+lyQwka$C>{R z$0SrL@`>i)U_KI@p}4)f-xE~$PIxUNdH#S6&){?Te9{#*z{?A+97+se2sjdt2iLwoT9-X;#CfDAU z%aO{q!$_6sZ12ou($L3NTA`mcVQzeJ-aA}CtbxX&+~?&VQ!my@TH!n8M_`x~oDz)P zj$JRnn}U1;kpv8ipde`K^wi~*>BCx2dl#psu?Y_hlyjBwg_ai2#ctlX5f^MprXdKM ze-bnaHqJINV6Pkvz1y(BISS5ik3M7+lN_gP(udqUAePC-*_O2%j2qP&L(BXPwG3Z2 z4GK$+71lzkz^L{!{Y^H&ASHM`#m1_1yuv7OQd4x;gWnVcy?a6*hsadRe;Nlw8v~XZ z5N@beNEce$d#Gf>i>QzAsCcQXk{6@kxf7X*p{L=2vGMs?ud!)?%CW-xT@94)pLDsUn;IOPO0 zsit!tmm&hnQTDg*gF12~GM>$qcMO6iL6R!N;3C~p5=N2(Q`PZabNyi3O7Izjp9EPb z`X~CCfqCYTNVOh|te_q=fe$#uWNCgXRXO$sb59)_9_%ZEAc1HHmTf0?KL)*&@oH2@^r(IbF)ceSP@)>gZaRKbojjJDxf}&? z=40z%a2!%q^Cf{!g>qKF!31(@Kvys&=@pktWjZt2Ts!5EOlN0XS7(}PFIfF^op6|I zhw6@cWpB0;>6DSYo{OHC+BdaOHF~}b$qRh?G$$f1V03gV?!at;V-?4Gz_g&CZ)EnU z*7e+7X>fGdw3uGe>yRrAXz+L5eATt44-szEnRjk4N`u3zA_EIsn%n_lOUo=jsp#RB&X`fzw&-7C}~w9_@zs9R}Q z5zaF-36?S;zS8>Ml-tBwiFh;tBsX`{c5;o^iw8lq9a6Eue*2ZA*!>fSMSB-F}AUs@1ZNa8MpCNuiEjH(sK)V z1F;K?r%s|Qqwg_sDu)o@fez&^9;jx|)q?Ls_A zq#xV(PFk4Cv@sp(Y^VDV73;qGaI`NoIdg0BR2}a6b{(uk9_gE*=-k*OY>1UIRr{0E zvsd8Bo_F@fR9GA}1@>@pWp>$f%x}WE)SKNR!r;+!8o?Tzoo=duXD$X~27E;=-2$jB z9!#Ih$#D?B8X}8HTrLNWa5#qvM}H(-iF@EkdC0yT+?y?UIe@`e1WvbxbKp|0<-yeg zg&3V3%=6b!nyJP;=SLTlNH2>G(F%^}mmhNtN3M12NmOeGgnW3on2FnPtB(|LIv{7G z27+JN44*}pS#M&%LvK*1~HOo~$~6O{$BsVQpt80qvz;UEnz$}@Sj zAJnCW>wQ>3qq_$v=)x0gxmQ{@GR7ckTVZ)Q+lmD*Ow-MlZLvA)c?L=XZKUu!MoG-+ z3FLfhNZyU4A*^m}{xB3dc)GK3NRJel;2cY>iNN8t^B7{X)Fybi<F<7ruG&yAT57tZ@T_}U^eFhvgPr$cYe{NOLfsq)b?vNzh={Qu+Q|0st5=~=tBic7VHn-m_ zXXsmUoQ~Lc?kN>xaB(a#w8@xD9?waZQ3p2?8%g_(^AP95@DO%da#LCiu`?28Az50~ z2s9Em;=iwWeUB3awpj&>7(qK#RF#ThFcg54N4Pmkz7(?7kpx<)q zc8R$#T#zPJxR_&_T(P()T)@mRvv{B~50|WJg|l#BR<8Y~fOL34UM^NsWBYO*z~KpA z5B+8sU|3|_FgQVZaf#UhCR>)-kpd=UcC0LR$UDsI5_Yrab87gNN4djsIL4}gmqR4c-LjaLGk5vepnw3b#saypyOhUgZ>=(5wAPOPf+1{QmXED5~8205N z@w9sl`(KjBRJHXM^t`R0nc4E(emWD3&5YaCjvX~pCa^02W+uGeTEg!LDDE&8ZMd+UQLx;7X}3{2EmqJzZ_u!1 zo7!rer(eB%ueE)2VAlX`;CwUsYZvsD2+wxWW9-TjYRNpaYaQV>2C#;D2ahv@4jz_C zQI`RfAki`)KTw=w(aWtO5D5b(3$Fu&Hv*WDIq z(T7I7?1hIS(WO8<&hG=wotf;VuE&k9>0R@evf59YTn*>XJBsgwPSLWE}{z5NS zOxp4!&{Y(D7ahN3dAS&G8BuF4lzUdWe+aCs7yG^S8GKAN%LBc@sx)8B%+Aa#!r93> zI&g%vgbDr}p5jkO{5MFe>AnFDrMkG6|BoG*16iJ{%wyTg8^^i_FEM_tCbr>mgicd@ zEfsdc7Ghet(6~GYT@~6Eonz__ov;b-mSC;WVp5n%UiB&*Z}jLlBxmd0%N#=xicM#b zhF6`;%g)7zP7RPEggCJ*3Z`Io{IJ6ra@dn=E80Z)K@4funbOQgY{~&rFU{mf;gEwX zIZw^#Gceq|&+bvGM zg&Ep)i7ht%j+JN>#Ih^)ko;I|u(v)5TaU&L9IP7J!846ho*ds#N>nv*+sL4O528W` z81BmDsnSl{NP9UEX zi*wUclznMp2+Tb#y+pb}u}qJrUN$_c!hjMjb>)~UUBQH9OtS>l?#~2c~=r4W=$6atMsUGh2tqSF#HddSrFaIugxo&01s7#JNkfn-VxLLE;pe-E@k6OJsS}=#+ah`oAB=DQ zH?>*>6Q(2C4ZLL(TE}Fh8bv&q{0$U>d%8M3vszs^u%KpBc<3V^1py0}LViN(1Zw(R zT7tvYp|qNtI>gN9iZvVY=tIF zstH@w$b&I0eE}Nd=8pAt`&NYaA>yeW5hN@ARa)B^ea;ylr0*&t14^>J4bHZ)XIGK2 zz)}GaZ-m07_s{fD_R5BlFk55H378W-gcT7`hy}eP$385IQo{oul!Z7@*`s5tk8xNdTM( z>?g5_HY9=2rqslCdt+$GNz?oZ5BpiD4i8wLIW1pX*61y@4W*>>C=2MV1#>$T?d{H{ zqiiFsfS%fv6m1spX*$qAhbFZ?#B=FkxV(5ls7J$4o9@hzgbVye&(f1U;u*FTVPzS( z&vzj5nh8&GS>!zFKp0nND%IKEh1^aZX~dazxx`LR6d--uLn*;4kX`B@8G@~$a>0!% zYimMXd^=57YuLkUA3X8(J?kN&=WU(@0T>u9i>V696K7$6!Bl#wbS{;nNQL+UGN*J@ zfD^PmflBY85gQ}qK+-CsBP-*bk~3~rLOGM%43XQ-Y@64X%?*=yC6ODG-c4!eIt#r{ z5Eo;w2C*l5CUM3X-9KATHMSy6;>)MsFCTUdj|VUTn}tCX@$hC zonRm=93Xb%I?qOvfmQSX-$E-8rgU#{=O`lzvYC!{vtNiV1t{QAs8XBkr=d`1xFAF` zmXnWMGzQODJ+AKMlI*cLG@~$w4I0T%1!L$j6JWsVGjY>ak5h%>krsLc)scI=%?&6x zYH+{9m_kaAHxNnKhB4YSWC~k><28S2ND7#{u*@mkz$Qd;QEhneIry zQg20UW2Bu9WaluV;g_?(o1d0*K#(yS6F@FM)TB<9Ga#vp^VQk;^4x5db0I`iCijDk zm|e(^zadU2i;g&Fh7Uv|0f+S14LOwpq3a>@(=zTj(D!fx*GPChgQM(Ih<7>4IuV9u zB}T`4=s9kUstO#Bqegw+)8rLP~jLzk=a}WIScNBy4ed!dE0NPZ*;38@W zmq5x?Kr^N@-PQ5~^nZ8rnb~3k?FGNkL@MXLWw3Nb|Lh+Cq<-vtzC-S+L_WUK5-3ymDq<0&XJgv1@&bfPZ|g;U z>C%$dwV0h-@hl28f$^qDtql{ZNwPf07!%$%tB8~AwpwPO@h{*NFkk%hyYI0zeX0;8JwxwlbCDYUyGlymi#i`qmR4aeAh=3<5RZSPXBsNet!F>i-Pz*-n?Q56h>E`5P#vT_rrM$68 zmp?XK)d!|#TzDRP-f;t_IR$G7@=5n!$B3lCs~Pd4UO=WgPvJqH(S_t(_k!H;kme!7 zLzahJjYZTu_8I=LyaVRajO#k0NXdD)XtkNX8aY4_$0!*Jd=YPjY|GwaFf;{@QZfvB zphudtB9IqpdB+7nt06Xrk~!VxJbK-yyQoO_$&3W`Zaw2&T}W77IW#tpOgRU~rly(8 z1=Ap$u`Zwnv@Qo)2Ldz#X+#Z4u1^|Kqm_*&jqs$-X>FYR zg^-K6IsXZ6fyoLjpAHjkoY=Gk(?zvLmMeWZzXqK!){l~GT~^JdnpfChxOWBuBr%_) z((xLRK>a}!B&|dcV84u@;CYWFS_xoDL(*h4FghU(4Yf?f*cO-Wwe^U=HDN_d-5Eo; z0mcF3UMugNn4Dg$!i^zh>mg$XY`s!c$vet5-NlkpW4hFo5Q;c;{*z7?_s-px?J`2X z=?86u7l+o1EUEf=&c!gy#u2z4f|@@ynNFUcL<(EP7Gk#)Adr$_Lr8yaV-pKWH`}Z8 zzzDLwz|E`#nY83&kTBMRF^wndavWv>*$ zR6H}C-J02&!UtO>{?ICp*aG;Ha2+H={}Q|tE2=k1Hd0$sXhBLTY@S2pKb)YDNz-`< zjGH+UC6TJljIu7LCWs?+w@DI7z>pl)j483GeNZr-j>`vL$$7j;5!4335j5wkIIM*6&RG%CpNuZN zUCyl;*!{6L1)t$6EW`&X(;_1XKV;MVlt87JaiTqvZ7(nnJ6RZ=yi(-53)AuPV=BP6 z-X39Tc4=YahCp@wXly=w3>FVz0L9-f33m&*ncgB62fU(sVv~V;8nKGcCJEo3rP$YH zS}G@*MlCX|1BIOtfg@urfe;1zzjKWM0+CH0xmAlyWrj3xCOKdQhv>ln0n$OXGYj!RT2S&9Aq6mxXEBi`bEB0LQKSLR^?8za$4!tvsU{7Mt5sI!zhzZi|N)ny1=L~G;2zF(zKo}~t zl5e48Mxqc1UQSS5>MV{Cal4PyAkCV6D^id%{KgfjVCM>loP0k724HkVh@wJrVpc<( zz#7IJh~%hJfVf*PIT#AvRxK8blXLSa;0*$iaC!_fJE+Ti<*!-}j6Hh`q-iC=jZjH4 zoOoY7T8*M7gfbd4Z~GnniJPYkP~AK?MfYDW2s2pOs*tJDRz+p+_ykn~Oe+)41Bgta+N93(fu zMrW|t+fXSa-N#{%KqiVHiioUkdC0vVGYw9-5l+lurzkfj_ahnTe#~x(UhKY_>RU4e z@q=M415eQjkVzrAG|~{JGBAK5c{;KrVdofZ?ZMo)#%J!ES!6y7hkWtTVLm3)lyIWd zq-b==FO)8rvjmgCxiwf9N}VSwgkLLOIEpT17YDu^f1P$ovCNijTHrtp!(MYL0IxI$ zqO3E}l`^2n-QZ>{;X8v;P1)WJ3#X(4=cF)(&D@Yt5MttgNQoLYJZBDWZO$w!F7X#y?lIo&hBti$*C?rXl!TAQ`RHn;S z=0>(L$J!5fOyjm^#*Hy{0WbAI7cPZ+tvwgs@Cyi9*HZ9_7{UbBE~dj0`8nNe@|n-# z^kb@6h!Vqvr-y`@nK7Ir2i&r#+oFcjYJjUPtL#N|Is_%RWDL5Zg+!eL<~J_Io*~SQ zyCvAsREl1x`>h@Y0*dbX{C8J=hvycodg1Q9b2AXFYNFp$$GD zN)*gh2p^g@W{^f+R;AasBpnM=6NlYS5By0he<)6<=PzT|v^j>PaAre?;>D-CqxS1^(*om%jTz){ zEGJ85PaQSalf9c;A)JZq=}1A?UpUkJ)JNb>RgJ;ohNloGi|i=~cpwb>uJX{f`HAp~@c*$47-57EQ2{#~>?##L zm>qDPG6W&RA-;M5@tG7cQrd$~YlYtObgnRAm=7_!ZRlHc8zQ12_;<^Ig8p~SJo0R1 zHPgbYMKEdo9+jo%SWAuaSUfpgE`=aBMxJ8jVgIx0lHILyD4V& zbi&g=Oig8vcXGJpPLk!y0&l$4%18!jyoMTWmH@zB^)n6mBWEgpSD1(b3!Sd5QsEbf z8#$bE?9it z>~7!d(%mDAz@<=J#OimVgHhCrjrvZUHJF^;z1d`Ibz$Pdaop32;C&8hD@{FoaTQf^TxvC? zW9#Ht_3+F%__dkY#cJ!~%oS5J6RpTFF%2ZZ-md-NZY-tH11aOb*=_t3y&*dFsFH?| zlA-p`ToFS0Iu_Z8I2k3pF3u}*+GvlLS;h01V9~a<3wwUF=W-n#ZP_mD@v&U!My0ir zt|&I=Oz4mBR7Wb-kpDuu0poOyE&(SyqD`c13eONjrjOK3Jlqz68AR(`bewgRY@W!? z(+V7Xg}VjBuz7U5zVAtLq&(zDlyi-tCY z(SqKH>{f`8_d)8zO+PkKvAFIQ2e-h-Y5AZ(zr{o{xHJ;;7vb3yCT`Y17fik^+ZMen z%DEA@Ir~{uQ6n9fY>XW4z{4a^&{9z;901Rd?gI4?j;l9nMwZ^ql1TIws04f4mYr$T0jZ{CIBxqT)oWq1ndVtjGi)J_@rFi>?9q_ zDP)IkXMJ+Wz_~@h5bKAQsTL-H1Gu2c~z;i#3M4X zqhms~duWZm%~-Id-Uy38rAMA!IpzHSeV2r0Ra+oZ88WbcC6yt4E=aB;&MTZyL9!-M zH*R$st;Ad^Q)_8qabTDs@a|N6cY&K`gqZih*x|huzy0=dmO-~OH~0Q#i=kW+WyW%c z2dYR)lj0LmOLTQwHX_SnPqzq z8!m8io8}ey)QDQOi>+Y}A$hIY^b7WsB{m6n65Fe+vL>U@WUzm%>NCyCE~DWvUb5ER z)qgwvwwQ{a2;gbh-AIl%%W-oqt1oCW!bU9wnKRCOY3htDz!upWGfSv*LeLc6h_v`K z)&ALi(jrYy!Bi1o7%$-1JaWn?*jz4NPQ8|O$j3Rt!<`bL2()HEy$W$=VD?}#(_y<# zCe!KjQ`z&=ZM2!{>y{OCsgc9)4)o>0+O=Y<7c^`*qs&};W9D#JHco= zyy89;UjxN%M>?eq`l>eJYUY_&1lr^BrS2l^a~3>hjYrl2(rA)~bZln23UinXsSR}& z;FS2PYi5sma3PBH}s9by-}(8KF_HLq3dewIFBc zJZRf+Qn^cC7n&kLA}J&G7JQ}!ZVo_lL2(IR>{Ci|?{CYiwQSNJkstOcxA1nU30%=~ z6L73Omy*u#b71aNdYGlrZE1#9dKTUsCu|BN3z1?3*d+Ar;Ff7MDr0Xo6+6BpF>e9N8s|v~i?F#T z%jg&J8z5&$%1$w_UO=4EMy|}Cpe;SZ{0aO3qiBP@y+G|wDHfF?F}RE_a7?^OM}aHf zk=tLuxOo1GI)^%mq|3ZbX9Dw!kUDUTtt+;#W!gfTBN{HSn44Qdg%^vH7hHhE-^jo= zy*WmE2-!V+og!oni#XSg8l5534a?{Z)tA_(*=AsUkJ6pcauZrhUBDvWP#eSODBt*g zr#2)NG!Yr9LtgDrUqrhi#!Ze6X{d2{m1jnVprOF?J(loirOR%^e)G^}<9W zaUh9H^`87T(puQnlm0ie062ig{iM{-Ixun0u#%vm7u$Mt~Ub9h;M z9g~xAIz;(y;s+>;)B%_>HFlvR-tPlwMfA*eT9Jy?sp%*S#^~>;sjkV~g`K<+(we^* zuF;k@vrAv0(J2fv-M-VvBC8-qpky0duvQPRA=J+OGh(6k#%U>Rh~c0IoRms~>TFFk zV~2@+!Y;1mz-3`H^y#^!v`70=dWXx$F(nWu(=pPt7!;T0;)vxLan?JZw1u7Sf=`&| zlw;zzP_#@L!ES$uB?As&M5nC`vhLQ6Tm?+W+dW(yLe@08!cc2Klf4U4b6SX+cteE{ z22r{~Aj*TdY@7ynqj$qgWPas*cY(YrIAfjXz0UM1Vi$Kc^GjWqBC?PG0k zhh3XI6P}CkY9C){g|InS-8Q~=dRsKZ+*VX@P`npSE%OU+)ywz|haS&CXr!Tj8kf8K5Gx&3NjtlW#g#dfh!i-yKFUi+70ITB3t1_+xGy4* z2I4x{#VH7b%ZUe(vraS!BaK`%hG{wZUY+5jS`upHE?r9SqS{<;EmtdA_U&s|?n#E_KM?5oDkyIs!V+XT+$KeUL1(AGs|XfLbg_!_Xle zMFZ{yzqLycaEe=lcx&ij71NoQHaho?>kx-Gp^)eR3E^@&USE9B%_O|#IxMi z+mRScZNBYViavJAV|lI6n~n3r=|wE_FBA{hL)>k<8ruhVA++3b`UOf~ygsVL4pcH! z`eG3&xHRxBat^gMQBxtdgQCZ9lWDUf3V%EY8%6_9A$Pz0dYyy0ZO~z&qAeooqxlKY zM;ecTuJu-p)FI?l6XS`gf^QGzfs3b2hE+K0N&60DiIj%O(9glK`6=62Tn1fxnPpt1 z?L_^pVz_gm*BlY$gq~wT&NkE21f5yaT0;V|%fMjZ!T=HE$1ik_3gkYahsUljq;!b& zf{wwga6U`=4mf*rml_M#D`Ux_6Q_Xe5n6{2_C*eq`G5sFxn+n_sE?})W&z4$laMW% z?tLzD3`@`Vp=)_Zt-tPwa?HEk&?%+ZQ>5DI&kyYK>3uCHEg16UJJKl_nfeY_NS272 z$PiTw-5C^Ta0y(&p`g;*L2+WA+e0ouJ(QMUJM|b^m=!Ov3=#8{gR_@c90x^qzr=;; z8L9mUkxOy~c)e?&*@x=pQMdL2*G-iH=O|DHw*gZ6N(^np(t=lcWZ@kgJcOfzO%Q1A z5Cml2mpcmBE1+!Y+MQFN3nB5*D)|UmYHXd>46TJ9*E9RkLD=Tc_xK`(3glJ zR47Q(h{Rk{FkKXeFVTLswGp54aPSTe0fvaqcx-Ujl|ha$sEe^JH+*5UDWrMo=;+F2 zu#ae0rX$NeLy7L=?TA_T@I+;L>Hq~T z3%rGA`7-=UWIjcdV;0+vS>?J_nW`8N(mPSE!waCiRYYd@!Vwcd>+=1F8<$LnK_SrJzSz-^V@uD)wqyQ(oS+=m@ki zjlJ*CZgX3LrpH>{+YX;4_;3w^lk?s>z~?5UQNr_D$wHU*FogvRdG>r{1`|P(fp&80 z?EKU|DnY30Gv?g(-0(E#(XtG$NOMeGPv!@<6YA?~@IZs*_*=Hay8qtyPO9Ap zHx;4P(T|py0ET}Acbak?nHW-!or(cu%v0l~!-IJu{=`hY6a&f=a6iQzP%hEGU3me) zO7JV4bbw)mfIxpI*b9<&AZf6EP=;Lw5SV=FNs^P;oVLrf$G}gc%d5Mz&SAy@LxtA> zHE~B71j{L^l*evo8VamABW&s1#t>+mhs_81VCgi9h4 z+l$R<;lpfO)JCt+{E1wL3SMM$iCPpjE-)fIu6zJtp1fovXI?0RLBavoO`($%s~4;V z90Osd%U~PQ@hN!wAkUcii;(BBP+G@iI~NMtA|>P-=Ubx|u!#GfoGmh|SjMWw3`4^I|NM00_?GHIq`j1laWX$pc7~ zTy7cLvUj=ANOv73BzbywF@jOIB=>T9E@dnYi5ecVwiA;lt?~S2t%nRoF{ExbUFx`J zNJvPehOER$h?I>Xp@J8tIgSxs`r~j5wkBaubIa?^T{o=v@jMzpYnZVhIlI*6N{w$? zHhy>+i+z)dm_Y&_sFu&^*>(7Gf4WIov<*Yg(a?X&qjU%(o``OW7B zmzHetlg**mSSU8tAa!F^qQPUB_8I4(D?OE2v!F75Oz%p6p_{(c3Wb_xB>%OAgxWf4 zNCzUWU)x2Tc28YML|-e~LMf%SSoZ)VzupBrjP3Q7iREOKPrJI8L zD-@jc1)ZAFYNcnh<7GyQyv$T5CNc&J;XoKPuXpFw0kjTV9Xx07MEZ54+IhFWsLqVn zMK;{{3gLf?HX?BcTy;jv^n!)d*Y-#VWzj*~gYfF*Yi!Wkd^f}uA> z%%f)y54py`J`jAgXNvMBTGBY0tf9v(EfCTx*lL-fHk@g&A_L>XA z(@6BQQUYou1_}~TdpQd}J{Q;fJ@k5&0`eQtx5UyLEmEyO`aon3PUc9{!}iLF!iTWp zA;jQbsj`%|`LzJ@>#W9Rs>kFYD;eEEh$cSU8qxDsoH33`9{_oaP8yf7VI}4XYsYRj ze|gg?!Hq~+YabJ-*IrK4Zk7f_BbBlA$n%AdMy|^G=fUSy)8B=-I6tbfX}gWY7{MPV zOJ!1SCra&cs(@9DV}yyiVGf(Dfy#(Z$iEC$BC7}E5_WoRs7I7B=mdJf zLiG{QSvn`7mE1%J>0prkDJ!nR@}}iAqbXyAyetHB@ zC_W|myd?HsDPY3x;N2D-8swV8x+E7xxzAYz+}@H5w}jV(>Aa!T=*3npNQF-CNo;&y zYk-e!+dq4tvTbH+e0JLv&^K?JuOM6Wwz;v1y|dHX<`(y2^*kx;e0j7HdjH9~s zV3pA%t!4(@hFz%^aF>rn{QvrSOI-+J+ZLyV zZ8cH96;7Gk(pi6f&CNB1rFZR}TBtt8B~?Vx*EDCztMU5BxPq_QM(2}i{n*qERc&$a zG?2&v$Yfjh!<~Nu$$Z8g$;?c(D7jVU7 zWemJcr5gF!O4o??9BMFKCMcocC+pnLaXgLJ6N$7cR2?N+d01-@k#D@f299-=1$eC1 z{E!btO}1m4XUf2Rv~{y-l|$o|Iflq>#S6ny>(s1O1ddi#auNe>i@}g`ezK*fvUh51 z#>MEh!W+>2jJdxP9Bg>baIE3bhKAFQUfq0SLo9YO>YwP&r3v%vHe9o+`ZE#djg8}tNsav8wO8)HBF z<1(jW@z{yWRipmoCG~7~L!_SH#lIx}vEG*(S?T`bu~Yod0H*M(AyRMsfw~<2twMV) zc31lPysNi9$8YOjz>=$<1mvIf8{ioJu|58N->%DDz5g=b&cjykM^@vEs@RoQe{wM9 z{`zZB&vw3ni^l*_tn+E z*VPZz)!*;x_te#Y+|^%JSI=TRcDk#r1@Yjk>g&&{t#GAyZ1)QFgDceg*4Lhn2cunI zzp1vumEy6@E7YI2LVfEB_1jjc_p`9}bUc==t#GAytZjw*juq;=R;Yi<3iTJRQ2*2w z>baVh{>5Y6ODj74afSL_OX@#kH4RJZe`PhRmeikTm%2q4Ir|q@?^kDd z;s&cvgca`Bhpe7hyY}ywR=>Ko5~Z`PDSmZ^r!ThpHDQJOb*-iXt3Q58{fn&L zQ_b-7yHS5!gueKd^FGusZA~op(G}`Hze4?YSE&E}3iXYc3d_BB!wU5qSEx^|P~Wja zeH~+F;$Pqcv9RCDmL`i!NtYss zbV6Oy3lN(0BE5@bce4vf2@nvF-UJLt7m!{hbOAv`ML`9`hKgcA1ipv`uwX$E{ol#^ z&UJky&l7+D`#j0be)gR+bLY;SnRBwGAOG|3d>vv~NTlX*UKZ?p4U8wj`6%-!Py9cN z&|Ic1^9kmjxXcec_rzv?__-&>oT5CLpMoCg$^1n02#@)6^h8fY*ytfKo(NA$OhRHx zgfA*8&Ur;dAn1<`rugEb5}ijWDbddNO=QZPt*PJcF+Guqo`eKP6-GqgyH-zBv?tN|y0++GLZUYqpW^c-IBC)7nAn(@M4vA*#ut&8 zl3C#IjjE}`>-EJ&$H%9{`%)qjobURHh)am@Igfo_=k<3f&ZnfB_W!+o^~89hA`_xw zov(;XOpNsgV-gY~{3*eRfHx}2o01sq^+jnVP76Fi=S3h90e?cAKQidNHpF>VRJ1qB z=Tzm53&g}E1TxETJM4*y@Wce1k8=uogXS~Tq9P-Ffkb~GHqPshaLPM%{8JyFkl+b8 zp9B>dofzqlN=ZnJOGyaE2IJ%Xv0mqc6B2!K-ssEQ#1YHVEMiA;!f zUhM6Qi-`(E`u!`{IK>=bQL=If!ID(TSco=f8Myu?c>EoX;QQ zkM}1;$Ht^MUrC%8i1Eh8$H$|C83TEoHhF`Iu@V0G*tqCGM2tT%C6MCuZqWJCKW}VI z(CL%R0-;fa^9dbszDQ@Z1cTAeXmN&SqH{Z9qI?lfUwDH)=eJZ6o9OXH#X48wi}5AI zc%9K6?{!`w6q690;!AK|7L*u|(Pcw3=axACfC?r=M#Mx0Vj{c=-iVl3Z(PtHbd30% zJ`5xVy#K5tG9o_CU>#<`J~fK-)6p% z$~@1kRjB`SJ{}mKo0s`AX8Z9*_zoIVBpCATukH@oaqnSf_wmPHIP4D2aI-hI-0qCb z@@iIlyTaO?i{*CZvO7~_$LwOPomZW|&0+Lr$+ULfG|)MWzK!!^_2&(A4%Ju8++Y07 zZN2q`Tl;OZ;N8egy=GTs>%~6kZ~N9xFbn;V5c_5qVC~Ef(YFiXCI&W#Uf1d@_|7c& z{t){nO0f05AbK08of2;KXN249y_^OAB@2Fsxgh7z>$*D&UM&lrkOgm(1%EILJ~RtH zISalp3%)T6zCR0oJPZCw7W@La8HW!zKlZ+SC3-u~vCsW?Ki>+m6FQy?W$sV^*4qfZ zB)O^A%voD+Inmqk5FVlrweJyqb;p)D8i(jZ?Y9uU-Ag_s++Oc6;kG^Fv*2^d&2@Ej ze(ZHE61}bWnGkOLo6RGQJ2-5NGUW+WFsEK%{>nv@BDHO8<7}ZE|cI_N&aoQjeyFK+jiO_ zHAD1eEp*PF5N^vFWFvdqo-dn0*d#=6+L^Qoz^p;$u==fRY#(5kpI!^#6FzMuK!4$* z%;0s7M{siO1h)gQn_NC=EBI8=Z&(a4OL$F_P;-taaB}UuvKD~FTt2)V_*0@^%)}Rq zx%$IQd2AN_$^ZZ_!`1)wDEJ=HCmUzu9M9q8>VH@W@RIN{=>V?^Z!{3#4dGRW0K6-F zGdt#U;ooKed?maw^}h<=)D_^C@M47ka+v|^9CrL<@V?{|zJT|)u<$XapmUTE-l7(G zS>e^EfZP3vt@jV!uW-?ym;`+t;rZ8sM+>i!2A(Lq@fPq#!hb3N-duPh9h}`4*>+ay z1brvbKiv_$hwvnhpT5FZj)C4UeAo`~fx=hJ1Wy&-k=Hv)_)MmX#tFYZ5q72sztRJI zrtsDc!RHFEH4J=_@C(K{ImdG0r^bP=5niq~_$J|-7lCgR-jELO8R4fnP7Vm~KtK7S z@IOrg-8qg5U&RINgz(FBgzpG%IU9CP3$Ok#_@}~84gfzd{L41rc0Xyy+vO_YS4Dqs z4e;y2^U=<4!Y{BN{t`ZO73|o3sjYW)U+@BE(RB{XqpRX^QQ<>}gO?J1tO9sB;pe-7 zR~G&u=V=Y$r&dB=SNP0I;IYE*uMA#a__t4jHxb@rGI&ej!|BJ`3qQ~GqKoj2xnZZ5 z@c#50{e&lVfj%I-Ip_5t;l+6Wh6|4`1v{gK=j{hRLHO_7j7$^0x(W2Ng->I9<_Yif zF!W1=pDzx+LU;-G+dARnxG8&DcoN&cL-?QdVSlgiJ$HZ~6yBo|_+jBU=7GN^{55WH zP6~fxKJ=%Aw^|PVk??5xtFyvi=Xky-{D%dw^R@6I4Zyz>-jePAS$OH*(BBjuLqC>- z`*1t27Zim)kMI(lrv-%^sDy^|9lSYv=+Xa`_B%-51XWdb958FcLjJK;hT1Ydxf{(1>RqH zQ?_S_@Rr=4qzNy`^>nQ8#X;DgBs{=<%M9T=cwOnjQwGD%0^xpc*p~|5R0;ak!c%zP zw+XMy{n&HD8{Z8($A#ykKY34h<*CqL5Z*E!{5#<}!@>U${>#(g`RLc}e3|P3FDd*8 z?_;#^dU>I*C%pA`@Mgjft^w~Vd|3x@ukf$vw}%Sf{{-~ogm0qXm@oWdY3SDoU(*tN zyYO>Qfj=Ysx2E7P314(C_(|dKjQ~F*eDGHAuY`ZX>-|}{wV#vgfW2SVeqrI({=LFK zq5r8N{Q6R~Crf;htvP|7rvkCMVj!{Twf*$pT>P=y6`DJ)VoypP9{Gt36JAC z{=M)KoJW5NKXMoB-$i@2KlA&+?-721_pzGr4P5V{g-_);Y%DyT*V|tBB*sm>g%_hg z=`TFMcxR;Wz1`9NDZ=YC27f|$4f@p;!b|abw+J7>{ob>}FL8Z8B79dn)ccO`c3ek3 z6JDPE|F!T8w&xe&kEX(Yt~@x~`&ecJ9v2Z_t0s6k;VqNEYYIQh_QVTMV_e@%_z>6*f}V?R15Ie zgkBWO4Bkq3QZ#rs;UBdH_X!_75Ij}*V^4#R7v3fre75i+^v_F$Tfee-pmG4eZ=$ZlH76`j+P-3tmrnVcxHn z!uL;rK3VuduA4)IFRujsqr&gzIGHItdI+1R znUCLNf-Vi{n85IOL)Jw2=8I{A;MP`MSG45 zzg!ahwD64&fL{>4XASsw!e8gS{zG_e2;MF zi!Cyb!@}!xU;U==U_0nP7XH?B@Gpg@a({AN_?bb_htdDp`*?HmHZa?tO!Y6S4_7naBm$Tln!l$-_{l|pYV?44*_@t+yUn@KZ z@7E6D(@lps$MeFYxX(By{6H7zKM>x4`t!m&OoslN@DjW)H-*339{S>iaklsC1IA^Q zg`e|47a_bY_2;C)FK{sR5OGU4NS zzcvZ~U>@x65x#)?pTojC_JsaT;T7nAJ{EpoGW1^xpWO%iy6~f%r}hOa_I`~k34OsL zI9py}2OgIZUY2&kg+KEk^fAJJ+zH-9_-l+u9uVG|IVw9`l-UL{t4k$zh1c2?-XwJM}%Ab+rq8B0RPWv`)zY6^kZrA z9L_^-^)jERD0(~JJ)-9@3~Ls`xin_lX)ku{>$M&d{#9?ZXQJ?L=7Y}{exxG!df`d* zw}*vq?hgHN;e*P9=ixrZ_RroS;FX0ht_L0?{B`=zj>3Q8{-FoC>1X2_?E55#ivIG$ zuy6NGwmo)#HcRXTArD(4cE)l)yi@q*x+ric#E!Y|4CBIH6}@fGDbdp%g?%FWebKQ0 zi}17T2m971dtDdE^Orz5%P*7PE&K}keZqeruP)r?|Ko+9h(diWgxkDaH{na?KtF=q z&KDEIn`4~l?@7+YVY5YF0XS@-=y!5_t_ji81!k7mBKjDvcRNG$W?XgUBt9Venw+RF zihc$4uZw;Tj$+t)??PxOr*h5j4Sziv9#Ij)O7Vy5 z>Q{^YsV#USL-dq~y&(D|j@vhcx8nZF`f78%)(03{c7EIbwDx)XGxLyTEp*Oy9WZvd zRn2^s?lx0jK16TljnP*K;Y?#?>W!vVXFOSl8l$hszs-qh)=Yh+5YBYNzc|A!*M6yi zDAa{zjeS$^>s0`Hh49M!+njtMoYG7(D1?W$=aCR@?2p+9Fg}FaYd2_i2(QM!&1pdh zXULjKm{!ibuIkj7(;EJ5uB!(BHYbKFZa+N7e%?)u?T1st0S*dp+7sZF5MGmio71rn zUMqy33gM<74lM-uM0g+ip9>*8v_G$gaARj$Z-Adecy0b|PPan1(O-A>7Vs^NhY8xDs!yz8<*YW3Z#I2fj-G zsjmmVX9o28df;b^f$QsmBcBBC9nwzIKP{Vp-+_}mPM#*PVWAx-o|zC975$a%0Nif6 zb}G<$loNgD!2ouyS^Imsg4;1{d3*(MdoL`X%z+$>r`>vg8~{*X_$B&zUbd_Ml}@Xr z=$F$mv=`ov?NonqX&!{3{>1ci>~e5!U)*~4v%>;nzcRCeTd!kdf%2=#~Neih(+yeaxK+z;dsKahL}gn5MD#eGXb;Wy|+iwi%}2zKrf z{zwLRdEs}A0uS}8ru`>NfQR~3!z<1Qj}$vM?gzK~MC%{+1;LX74D~h=r4TNQ_v3)K8PExG~wqtkH!jrj_b%I z;mdQu{tV$WV!+ddzsGfaf$$Zak4uF=LqESt_>xJmzd?Az#^4#kd(m&~5^m$Z z55n7Vq5f6))|#mImhkFqPp+JJ-j3TFx$!uk@K@MBg@xy&-zy=!Sw7e)EBtC>@QT9s z^Zwe`C))O$91DFN(a)uSh!%d3>wco}Gf}Y9Nca$L5Sk1Ba~depmIc$=Z%YlP=#5V=YC@mitdluMAfH5*}U( z`a4*Uop;5nfEN(HV<31@;e%OkDdCr9LvP=oZtZVi|5q0M`p(eT5Z;*^?YhGKC83WM z{xREGU-(NL&rO7Prn-v<7X z@Xt4ZpB0`?eo^?t41m5CzTGsyIrM!ZkGBE;S@b!Jf!`GVD*G)5*LizgPws|3kMO}O z!3zrS77kuq_+pOFdxW386MB5U+TX8l{5=-Ds_0j*2d^c3whuf~c(2F7)yV z_%7j98Gk)1ye<3lknjRYu=9%WHe8pF3IBrY)LX*0bAR~0@E&tv|6}2k7=N7;-nupP zmxNE`IQ&-lQTl-&gjeA@_^a?4ZDIeG@U6YUb209>ejtkXC7rS-rWo2MDQFsLXPb1+aIj))uKM@BzZH51j z`nfErWf(@M`qi1BIU(4t=WdB(8U(gilxt{W#%&H36R@yeQY5 znZiG)1pQp$qv`h+37^Grwp{p;fv~eixbrP_na3vKkFbBX39r}(`e%gqd;%BDOh>3hz7){Dkmu_Rl-Qe}4q})54q91OHU`(kbBQg}=o8%wo*Kl~*}jg|-rsLhp`RxD4EE=2;icC?KTo)Q z-SZORJs*Q!-=CP*3%*YDXPLixTKEfG-**WAWfSb|6>i@*drrtYr=n? z1^r3kA2NPCCA?Jy=syzvA;+!V|JwfF*a7;BqJN$9R^LZCiGJfd(HBgCou7pd1`fL^ z{F4fJB1ayaZF}x}3Xk&$Z^V8mDEuYHcg2O*3&74j!mo2*R9?8h7xYzycb^AdOSpag zM5OSI^ppC2&yC$+CrR`f91r&kzjYV%t%c8N4BkO_2FGnT;p1yT-$(cdjK{sgpPmnW zf8ps5fe#UWJsCVr_>ubHV}-Y)Kb#~yo%?ouUur7-VY=u?wt@Wx!soLemI|N8b#|5T zn~Py*gYf;c!83%9Ne15~d@=|6v%j)o5e-$k}B@OLK6h40-cq8Fg z={K4SFU0&$Tj4qBA36yyJ{tCW2+uzUysz*V`h)w0k17p5Q24c0;QD^#My0?ax=?VQ5;S0G=%@lr|{XAEAB@gT@5?-?f_;TSB`+%=e&Uv&+_^+JT+k_Wn9{w5O z&(ohA5WX)r>U~l8MUIoB!uQmL{)F%Zt{3kJ|8x}er-cvWeEC#(80YDE;Wv7~&Sl}p z7J^?D{v`Jy*M-+-y}t?XvK@B*65fpS>yCVQ-ui(@=m!c2zn5`nQQ@!Bzm*ccVG!(= z6P~&eyt42|qrqzkxBj=T@Pwt%#|mFs2fTh3oZBon|4^Cx1TJGPpUQE?<;3M3*bkh3 zF8^>U>Sfx(LC?k9T zc}3w5a^6)JUbhASr;TfWIpc9|uU%e><0?t)6ybfRJ9hQ=(Vw&x{Ue-5+)larx42$& zTj}zv^fSp~=P37?bjPl~MPCTHEV=xXdf=S)E-rku53v6?3x9`xc!%)q-0$rZUY-4XNcdTH*b(9VX9JuNzJ>kyuJ8of z`AGP#2LL`7?t28_lJFzEQCEb|;P|;N{EmzKZ`k9Z}Z+D8FeRL!Rg|FmzxLf#i{vW5T@EES|m4q+t2*By> zwtv@JaJmVXm*9kp7dx-*1ZXI{%?tqTpS&Z$|J4s&z}4T{&zUVJ_VZ5%U^lt#e3=IH zy6OysUj5iic6_YZKa>DaUwA`0U`~6t-WK$4Ek)my4zj)Qh_wK`Y}ZbW-r(xr;)j7J z^>?pZd2h$G7M`nThZJJi2*UJJeYw{SL4 z{aY$0&}I~K+h3+Mfcm$WYJsbN>qdW~{%uz>^y=SIM}wch$*uQ9K7eaXeLd$Fyk7e~ zBl#Vf>EfU0AN*qHGdhfih1cS|7%sdX>m4Kf1}B`pZZnM&?lI9{;5udBw`AMdJU6au zvFMX~fUgjq_5k>L;e|Ot_4S!kmqWi>^ci))4+w9{3H_4rd34yX2@le7vb)`R*Ci45 z3*zK*`}u&n4*pOKLR|-ovp*||oqJjX)DZq1+oS7Xu_X}3i$3r$fUbjQ8h|$!{W(_H zPWWmMfUXN)37HEvC)e=_VyDbP0A1fJ z2EcXy6UA|;>wXhM6l(+#=((30~}_btU_^%0eYS9rRRg|eBZi z-n%cjj-Ov>U&qglaOibD<{1diZK7-cAje^OJnizW9B3TYF8^~Hgq%(;uRR<*M(lWp z0qDH@U=cW%f7i}{)!@85moMjabrkz;=>U2NKh68~knpz$0|bQI`^Bf-dhaO)VVdaI z<^`Y|a`k0;f=>~BoiPBjgr8)?=Lx^W{&`aP6TJXd3IApez((O;bAoOYZug6Ogzx8# zIw-t72hPjF>(>A{CcGyd=i9>1aYCOKUXT;+GvSLlJ}(MC&T;sSa67+#5N_w!4dHfv z{U!WV1%Nwq;B5DkLC!~gUs%)X(CIv#(iL3i>DP4FI!|v#L0<|dcU&!D|CbZqW(NS> zpR1og0-U$Uax7h$Xulue5A0+yBeE@V@uKnGdD5FJxlntC9{2=cOhoft!A32-l z^1ZyjI^QdD0bC;XFD?e)Ww>^FCxCN#bNQ-b;7^O4fn@>MeXhPL{l;F=zgQbU{XoIC z;D<$jD-qx|;a@)pa8h`Cw&#@cod6#Rzs>=ER(N^}z(wJ^c*DOIeu0kpJK;aA0{B^Y ztMvdkg~x0K$SM9|M-q5G;V*NX7ZE;=``c2&$8x;gC%gsQsqY(oXEN$l|Ff(CcmbT; z`~E2hxb8F0(BBpmed)&m=(b!t^|(Rc?R5F@bm(=Tc_Rb7hS-0Z3uA=vGLr$~g`L9RJNl@5=?iY38=G;V5wRKV9k1b)UI=3iMvFpIQoFfbiyx08)ilYzv_K%;d)4 z6GZ#b$^fX}h^1pYBl_T70Oy3Sq+j|{_>B<&SA~yey*~;6bPa&| zhfSOp>K{&W{;GfYo{nGrgLf(HtAAMe6u9~aHZM&5!(ooM+Bu*w%j><)Pu|IR94$P9 z3%LEBVyoZ94Q3P3|IYDgKbOer>x_l{4x&HN3%tAV=yBkEg%9LJPZ6Gz`}{$|ALacW zA^hY5*w^=o-@|owvgo%?g?^^+KAi7Q2=B^qzC?HrI<}R-^f0F+2YvKLc z!2b8b2bw|Z9Qyw5rjLXFDf-ViuI|W*=k0Zsqkp?g_;dF|S6q0()!=1>H|+tg@8dq2 z23}qC9q1?P3a^qI`Z(d$i-RW#AD;)jnegP+;QD^;X7S*iMgIrqS1;k0cwdr*Kerin z`U@X74BUQiwe9Bub;0$0+3zHSj~6?4vpv&Mgzw_G)%RZ? z;zq!J?znA#g^{qcL+p$z2fj~u6|Q%OgkS3h{So0?xlZZ(tOrLz|E}micnn;>&#ujV z;Gc`WH0RwV;f*Une?|EF6~XoW)cebW|1SDej^`Y?@VxD}G;Ub(3jc(Dtg!IMxFNFN z>uv39*bck;zUkWZ&sD@u=625}tGfMae9M6fudnLh6W8t?F!1evncXk1PK=kG7 zfOivqS3Yq2`GWR(4|>4;qW_cq@UZZm0qFI8(1V76j}iTMeZeOQulo@AW5V<80-r1V ze^tR33-84ZroP{~H|L}M98i0`x#)*8#LhJK+iv0Q^P=7Z!jEzMyd=Cmj*I7<8m;b~Bp2j6bWNUH!h=uuu2x^3P_2 zbGdc-=PSXReC8v3<3x%E!x4dK%+FTr(Razda-RJ-lD%gy&cU@TKtQ;sCA+U!DQ* zlkoevPq-<(!CU~1ch0o{*LdfC_JhVd6FWh#@y>*BaE*69c>-MHor=_JytAGCsqxP9 z!(m6`othoMHQu?_8C>I?*Etb2-WkE`)p+Lx`c;j0>THI6jdwQD0cgB4_Acl(-f37A zT;rYKAaIR$cF^ByyklS2qVY}~@0Z3q_Isx^-l@j*NaLMVTxT`j`EV)PsqxMMI&6)1 zIt+wf7aH#r-VMFRJ4>R#HQxD-4pQTtpXmoQ-Z@G?sqxM+-Y<=JT1TQ@jdyC) z2iJJ#(fQyS?>spaT;rYUobMX%bk7I9#yh#W57c<)NiGN)?<}naI~wmyC2CZ3y%l?|jR3P2-)H*>4)}TrLGW8t=@h0Iu;) zvAN(H@Ay678t>eg0-;q1cza*?aE|{^gb(Tt`{#vMgmQ?`9sUnD8w*px4i3dYbEX1<`-X_Jj*hd>D2-!e=ush!sAO z>qP_M(;tH!{rsipmw>ks{Sfv`C*jxILElsOR<2+DgmTzruN^-+NxVDfIezO6$ghuNFJ6^1f^mzHKJ-`aS6jlfn0j z{yo}%UU(_`AN|~^l_5rVflgr;N4Zv-L%Zt!&#EZTN?a&>#`ffEL z)I3J&Jn%cjPASGI1%&@e14V@&SpmRh!>#uvFSz#S-j3kfpTBXxt^IlIap<)_e_al) z{rN+2aP7|=L2&KQF`dD+KTGg>wLf$9gkJme_!@A!54Rs;x`A_h>hhU$!5Q|r{73H3 z*?lhmh5Lj7DCY8h(*RP1UnPG;cq-#}%?o+i0n%i%@Tz;180&kDY zC)S02Elw_9OwR3~%Q>9Gc8dP!4uEHcm#7c$g79BBo{tJYL;V}V53u4>!iP=)I3xT{ z4ybd&<9GwV6uz0`@T&0Z+<*Qgyf?@5P2p+H05mVuls8=SLc=-UG%qxzEbM4r$iEp} z^Fn2eV{{J93w5L;(Y#Qn_RwoyC_k@P^Foocpx3-me#SeR7iz`+(Y#O&4jj!3g*^=W znio32xKHy!H#$JCd7(HuNX-ki8x6hYg?9D_*Syd#jLS4Hw67xcniu+(?bN(bK2A{0 z3q8Scu6dykVLnXrLho??YF;S+1{Bb|(B3lOniu*r4P5g=_H&UmFI0*1Me{=G+`nmF zsD4e@*St`Tdf=KD8dn)y^Fs5Mfoopq9QPrb7wXCVgXV<}F^}XzS6BkU)3$+>sz2=1maXr$!(9e%SuX&;F zQ@}MZl$;E%d7+Wjz%?(_kMl_LLWL_ruX&+8yTLUt^bYs=nisk{9(v6SZK9vlyinh^ z&}&{O-~-pZ&=>2$H7_)Z@r&k##tejB^Fn^kcg+he?*qN&g%Wy$YhLK1j^LUXD!mO{ z^Fp^c{xvVu+Yi0wg;JV;YhLK9oZy-ly2$oxUZ^VXujYmPIbcWgLalgTG%qx&74(`H zn#Mpy^Fp1ufz`aw{CTjWd7t z&}&}kDb5Sc3)%14)x1#M>ae4Eq04!|H80d}D!Ar_TG0<^UZ~?N=ru3&s}EfBLUp;m zXkO^GLC|Yn=)`^Cnine0^EOye_&ozZV&+!&1ygU6vg7A&J?~R17=Xh%&yl7*zr@ioN zY=2kbg_)P=BYZFCmrr=!Rt&NOlCN@v0)F2 z-j3Jt!h?Kl``_BP@oJbSZS0VdUY~OwIRfVa_OB6v!CueEz?hL?o)qs$Z3e?;o2VeFj$kJAmOEVs!2u+o^1?&7(db2h#&Hy_(`R^_d~ z3N3F!Z(Giuvnt<{^@Nr;TYp>5p0g^Sa+~rdw6*2zIji!vYeVZdKHiqI=d8-xaU5FS zY^`iLd(Nu7^=F~w6aGW_#g5h-q2;O&smj!?l$Ec{D<M{ZDB5`~O4v(zmI<*?%ZsJ;-==&8hZ!lilg?i_B3QoI z9hTrs>_W5cH)El(OYldLJW$SJdE-AzI6rx*E6uanml|a*KDH+tkJ!idto7G+o-j7G zyp2x=*n&J4k;i5|Ha5+=8hY6B4~0VKZ!K@;L?P!#>)*`|wbyIS*vIy4eNtm9;CUGb zknJbae`TB>Th4M5Cf~0AYz96NSjiDPN8@}r+uvE%FXe|NLHT_Zlr;5Mb$+s2|3v0ns@sZr&Tjq5J}Bq2 zoT=ZWc(YsoX4YSX|I+^z_>aFWA@|>y%Kb{KZ%Pef_k9B^sTmJ^u-;?F-DZBO08U|%Y7BKaj_#?aZ-(>y&*ZF^DI4TaE z|7NYvZv6#VaJ9W~p0j)XdHI5}BAl1z`c3?i-TE_Fe=(_09%ecIOOJ#y)c=_HBfIq< zVxpv`R45O#tpDZFP);_BqjQ++H}OYy>%U}zedqYU-v7qqQGe+DZ{pa?Zv8*A{x|5q zGaKXl%I@_KWBuRXg_7p_jW5k^{fAAk?;KyV|L`dL^(W6pOOLYyP5mbR$Zq{x%wTm6 zvp)?zvU~m2pMvsx7B=;_bbhj1|BtNS?0G|v?ABkJA6%Zy!lwS#&QEshFJyv!=diDH z#G~x@{}|R^y%b8C`rA4`T7QPa^qNeG_nVsEVPOYlU03Z!M`MOaW9KLISi1*G`#K*} zzxfx1*8i--jMB~%=g-Vzju|Y@acnov_P4Fyo?mvJxLx@!zo5jQS+w7le>aQroqj|4 z3OKpHZ8>}X*m=hO?TVZ~hO>MqGk>f08ksaRYz)gkCkAZ)S^Ty0$L;#R^nTPdhCTk*TKNC8?^!iQi^>*dw Nv;BYBf;?;a{|8(hG=Bg9 literal 0 HcmV?d00001 diff --git a/test/resources/distinct-sources/cbl/subsubsample.cbl b/test/resources/distinct-sources/cbl/subsubsample.cbl new file mode 100644 index 0000000..b831948 --- /dev/null +++ b/test/resources/distinct-sources/cbl/subsubsample.cbl @@ -0,0 +1,14 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. subsubsample. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 WS-GROUP. + 05 WS-GROUP-NUMERIC PIC 9(2). + 05 WS-GROUP-SIGNED-DECIMAL PIC S9(3)V9(2). + 05 WS-GROUP-UNSIGNED-DECIMAL PIC 9(3)V9(2). + 05 WS-GROUP-ALPHABETIC PIC A(6). + 05 WS-GROUP-ALPHANUMERIC PIC X(5). + PROCEDURE DIVISION. + DISPLAY WS-GROUP-ALPHANUMERIC. + END PROGRAM subsubsample. diff --git a/test/suite/parser.c.test.ts b/test/suite/parser.c.test.ts index 04e133b..e8f9b61 100644 --- a/test/suite/parser.c.test.ts +++ b/test/suite/parser.c.test.ts @@ -7,12 +7,13 @@ suite("C code parse", () => { test("Minimal", () => { const c = nativePath.resolve(cwd, 'hello.c'); const cobol = nativePath.resolve(cwd, 'hello.cbl'); - const parsed = new SourceMap(cwd, [c], [cwd]); + const parsed = new SourceMap(cwd, [cobol]); assert.equal(3, parsed.getLinesCount()); assert.equal(3, parsed.getVariablesCount()); assert.equal('b_6', parsed.getVariableByCobol('hello_.MYVAR').cName); assert.equal('f_6', parsed.getVariableByCobol('hello_.MYVAR.MYVAR').cName); + assert.equal('hello_', parsed.getVariableByCobol('hello_.MYVAR').functionName); assert.equal('MYVAR', parsed.getVariableByC('hello_.b_6').cobolName); assert.equal('MYVAR', parsed.getVariableByC('hello_.f_6').cobolName); assert.equal(105, parsed.getLineC(cobol, 8).lineC); @@ -25,7 +26,7 @@ suite("C code parse", () => { test("GnuCOBOL 3.1.1", () => { const c = nativePath.resolve(cwd, 'hello3.c'); const cobol = nativePath.resolve(cwd, 'hello3.cbl'); - const parsed = new SourceMap(cwd, [c], [cwd]); + const parsed = new SourceMap(cwd, [cobol]); assert.equal(3, parsed.getLinesCount()); assert.equal(3, parsed.getVariablesCount()); @@ -44,10 +45,7 @@ suite("C code parse", () => { assert.equal('3.1.1.0', parsed.getVersion()); }); test("Compilation Group", () => { - const cSample = nativePath.resolve(cwd, 'sample.c'); - const cSubSample = nativePath.resolve(cwd, 'subsample.c'); - const cSubSubSample = nativePath.resolve(cwd, 'subsubsample.c'); - const parsed = new SourceMap(cwd, [cSample, cSubSample, cSubSubSample], [cwd]); + const parsed = new SourceMap(cwd, ['sample.cbl', 'subsample.cbl', 'subsubsample.cbl']); assert.equal(7, parsed.getLinesCount()); assert.equal(14, parsed.getVariablesCount()); @@ -64,8 +62,7 @@ suite("C code parse", () => { assert.equal('2.2.0', parsed.getVersion()); }); test("Variables Hierarchy", () => { - const c = nativePath.resolve(cwd, 'petstore.c'); - const parsed = new SourceMap(cwd, [c], [cwd]); + const parsed = new SourceMap(cwd, ['petstore.cbl']); assert.equal('b_14', parsed.getVariableByCobol('petstore_.WS-BILL').cName); assert.equal('f_15', parsed.getVariableByCobol('petstore_.WS-BILL.TOTAL-QUANTITY').cName); @@ -73,8 +70,7 @@ suite("C code parse", () => { assert.equal('TOTAL-QUANTITY', parsed.getVariableByC('petstore_.f_15').cobolName); }); test("Find variables by function and COBOL name", () => { - const c = nativePath.resolve(cwd, 'petstore.c'); - const parsed = new SourceMap(cwd, [c], [cwd]); + const parsed = new SourceMap(cwd, ['petstore.cbl']); assert.equal('f_15', parsed.findVariableByCobol('petstore_', 'TOTAL-QUANTITY').cName); assert.equal('f_15', parsed.findVariableByCobol('petstore_', 'WS-BILL.TOTAL-QUANTITY').cName); @@ -84,8 +80,7 @@ suite("C code parse", () => { assert.equal('3.1-dev.0', parsed.getVersion()); }); test("Attributes", () => { - const c = nativePath.resolve(cwd, 'datatypes.c'); - const parsed = new SourceMap(cwd, [c], [cwd]); + const parsed = new SourceMap(cwd, ['datatypes.cbl']); for (let variable of parsed.getVariablesByCobol()) { assert.notEqual(variable.attribute, null); @@ -107,8 +102,7 @@ suite("C code parse", () => { assert.equal('3.1-dev.0', parsed.getVersion()); }); test("Multiple Functions", () => { - const c = nativePath.resolve(cwd, 'func.c'); - const parsed = new SourceMap(cwd, [c], [cwd]); + const parsed = new SourceMap(cwd, ['func.cbl']); const f_6 = parsed.getVariableByC('func_.f_6'); assert.equal('argA', f_6.cobolName); @@ -133,4 +127,21 @@ suite("C code parse", () => { assert.equal('2.2.0', parsed.getVersion()); }); + test("Split Sources", () => { + const srcDirs = nativePath.resolve(cwd, 'distinct-sources'); + const cDirs = nativePath.resolve(srcDirs, 'c'); + const cblDirs = nativePath.resolve(srcDirs, 'cbl'); + const parsed = new SourceMap(cwd, ['subsubsample.cbl'], [cDirs, cblDirs]); + console.log (parsed.toString()); + + assert.equal(1, parsed.getLinesCount()); + assert.equal(3, parsed.getVariablesCount()); + + const alnumGroup = parsed.findVariableByCobol('subsubsample_', 'WS-GROUP-ALPHANUMERIC'); + assert.equal('WS-GROUP-ALPHANUMERIC', alnumGroup.cobolName); + + const alnumGroup_ = parsed.findVariableByC('subsubsample_', alnumGroup.cName); + assert.equal(alnumGroup_.cobolName, alnumGroup.cobolName); + assert.equal(alnumGroup_.rootFileC, alnumGroup.rootFileC); + }); }); From 68a09582e1d29554ab146327d2cf87c473e7f5e2 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Thu, 27 Nov 2025 16:24:27 +0100 Subject: [PATCH 57/70] Clarify some configuration settings --- .vscode/launch.json | 5 +++ CHANGELOG.md | 1 + package.json | 89 ++++++++++++++++++++++----------------------- src/extension.ts | 10 ----- src/gdb.ts | 12 +++--- src/settings.ts | 12 +++--- 6 files changed, 60 insertions(+), 69 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 1b77ffd..024d6c9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -28,6 +28,11 @@ "type": "extensionHost", "request": "launch", "testConfiguration": "${workspaceFolder}/.vscode-test.js", + "sourceMaps": true, + "outFiles": [ + "${workspaceFolder}/**/*.(m|c|)js", + "!**/node_modules/**" + ], "preLaunchTask": "npm" } ] diff --git a/CHANGELOG.md b/CHANGELOG.md index eb50257..305903a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Remove `gdbpath` and `libcobpath` from launch configurations (these are provided in extension settings) [PR #36](https://github.com/ocamlpro/superbol-vscode-debug/pull/36) * Fix enforcement of a default `preLaunchTask` that is not available [PR #34](https://github.com/ocamlpro/superbol-vscode-debug/pull/34) * Support cases where the COBOL source code and the corresponding C files are in distinct directories [PR #29](https://github.com/ocamlpro/superbol-vscode-debug/pull/29) * Remove unneeded fields from auto-generated configurations [PR #27](https://github.com/ocamlpro/superbol-vscode-debug/pull/27) [PR #28](https://github.com/ocamlpro/superbol-vscode-debug/pull/28) diff --git a/package.json b/package.json index fc137f5..6c74d87 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "properties": { "target": { "type": "string", - "description": "Path to executable", + "description": "Path to the executable, or name of the module to launch", "default": "${file}" }, "arguments": { @@ -77,17 +77,7 @@ "cwd": { "type": "string", "description": "Path to project", - "default": "${workspaceRoot}" - }, - "gdbpath": { - "type": "string", - "description": "Path to gdb", - "default": "gdb" - }, - "libcobpath": { - "type": "string", - "description": "Path to libcob", - "default": null + "default": "${workspaceFolder}" }, "group": { "type": "array", @@ -106,7 +96,7 @@ }, "verbose": { "type": "boolean", - "description": "Debug GDB", + "description": "Debug interactions with gdb", "default": false }, "gdbtty": { @@ -126,6 +116,16 @@ "konsole", "external" ] + }, + "useCobcrun": { + "type": "boolean", + "markdownDescription": "Debug the target as a module of `cobcrun`", + "default": false + }, + "sourceDirs": { + "type": "array", + "markdownDescription": "Where to find the source code, in addition to the current directory.\n\nExample: `[ \"/usr/share/cobol/sources\" ]`", + "default": [] } } }, @@ -139,23 +139,13 @@ }, "arguments": { "type": "string", - "description": "Extra arguments for executable", + "description": "Extra arguments (only used when the program is restarted)", "default": null }, "cwd": { "type": "string", "description": "Path to project", - "default": "${workspaceRoot}" - }, - "gdbpath": { - "type": "string", - "description": "Path to gdb", - "default": "gdb" - }, - "libcobpath": { - "type": "string", - "description": "Path to libcob", - "default": null + "default": "${workspaceFolder}" }, "group": { "type": "array", @@ -169,7 +159,7 @@ }, "verbose": { "type": "boolean", - "description": "Debug GDB", + "description": "Debug interactions with gdb", "default": false }, "pid": { @@ -181,6 +171,11 @@ "type": "string", "description": "GDB Server host:port", "default": null + }, + "sourceDirs": { + "type": "array", + "markdownDescription": "Where to find the source code, in addition to the current directory.\n\nExample: `[ \"/usr/share/cobol/sources\" ]`", + "default": [] } } } @@ -196,10 +191,7 @@ "target": "$${_:{file}}", "arguments": "", "cwd": "$${_:{workspaceRoot}}", - "group": [], - "coverage": false, - "verbose": false, - "gdbtty": false + "gdbtty": true } }, { @@ -211,9 +203,7 @@ "request": "attach", "pid": "${3:0}", "target": "$${_:{file}}", - "cwd": "$${_:{workspaceRoot}}", - "group": [], - "verbose": false + "cwd": "$${_:{workspaceRoot}}" } }, { @@ -225,9 +215,7 @@ "request": "attach", "remoteDebugger": "${3:host:port}", "target": "$${_:{file}}", - "cwd": "$${_:{workspaceRoot}}", - "group": [], - "verbose": false + "cwd": "$${_:{workspaceRoot}}" } } ] @@ -242,17 +230,28 @@ "description": "Displaying Data Storages and Fields attributes (e.g. size of Alphanumerics or digits and scale of numerics).", "scope": "resource" }, - "superbol-vscode-debug.pathToGDB": { + "superbol-vscode-debug.gdbPath": { "type": "string", - "description": "Path to the `gdb` command", - "default": "gdb", - "scope": "application" - }, - "superbol-vscode-debug.pathToLibCob": { + "title": "GNU Debugger Executable", + "markdownDescription": "Path to the GNU debugger executable.\n", + "default": "gdb", + "scope": "machine-overridable" + }, + "superbol-vscode-debug.cobcrunPath": { + "title": "GnuCOBOL module loader", + "markdownDescription": "Path to `cobcrun`, the GnuCOBOL module loader.\n", "type": "string", - "description": "Path to the folder containing `libcob`", - "default": "/usr/local/gnucobol/lib", - "scope": "application" + "default": "cobcrun", + "scope": "machine-overridable" + }, + "superbol-vscode-debug.libcobPath": { + "title": "GnuCOBOL Runtime Library", + "type": [ + "string", + "null" + ], + "description": "Path to the GnuCOBOL runtime library file.", + "scope": "machine-overridable" } } } diff --git a/src/extension.ts b/src/extension.ts index 672e9c5..e4db6c4 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -43,7 +43,6 @@ export function deactivate() { class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { public resolveDebugConfiguration(workspaceFolder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult { config.gdbargs = ["-q", "--interpreter=mi2"]; - const settings = new DebuggerSettings(); return checkForSuperBOLBuildTask().then(haveSuperBOLBuildTask => { if (config.name === undefined && haveSuperBOLBuildTask) { config.name = "SuperBOL: default debug"; @@ -71,15 +70,6 @@ class GdbConfigurationProvider implements vscode.DebugConfigurationProvider { if (config.group === undefined) { config.group = []; } - if (config.gdbpath === undefined) { - config.gdbpath = settings.gdbpath; - } - if (config.libcobpath === undefined) { - config.libcobpath = settings.libcobpath; - } - if (config.cobcrunPath === undefined) { - config.cobcrunPath = settings.cobcrunPath; - } if (config.env === undefined) { config.env = { ["LD_LIBRARY_PATH"]: config.libcobpath }; } else { diff --git a/src/gdb.ts b/src/gdb.ts index 18d85f6..e99c125 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -32,14 +32,12 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum cwd: string | null; target: string; arguments: string; - gdbpath: string; gdbargs: string[]; env: NodeJS.ProcessEnv; group: string[]; verbose: boolean; coverage: boolean; gdbtty: boolean; - cobcrunPath: string; useCobcrun: boolean; sourceDirs: string[]; } @@ -48,7 +46,6 @@ export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArgum cwd: string | null; target: string; arguments: string; - gdbpath: string; gdbargs: string[]; env: NodeJS.ProcessEnv; group: string[]; @@ -58,6 +55,8 @@ export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArgum sourceDirs: string[]; } +const settings = new DebuggerSettings(); + export class GDBDebugSession extends DebugSession { protected variableHandles = new Handles(VAR_HANDLES_START); protected variableHandlesReverse: { [id: string]: number } = {}; @@ -71,7 +70,6 @@ export class GDBDebugSession extends DebugSession { protected miDebugger: MI2; coverageStatus: CoverageStatus; private showVariableDetails: boolean; - private settings = new DebuggerSettings(); private showCoverage: boolean = true; protected initializeRequest(response: DebugProtocol.InitializeResponse, _args: DebugProtocol.InitializeRequestArguments): void { @@ -84,7 +82,7 @@ export class GDBDebugSession extends DebugSession { this.started = false; this.attached = false; - this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, args.noDebug, args.gdbtty, args.cobcrunPath, args.useCobcrun, args.sourceDirs); + this.miDebugger = new MI2(settings.gdbPath, args.gdbargs, args.env, args.verbose, args.noDebug, args.gdbtty, settings.cobcrunPath, args.useCobcrun, args.sourceDirs); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); @@ -138,7 +136,7 @@ export class GDBDebugSession extends DebugSession { this.attached = true; this.started = false; - this.miDebugger = new MI2(args.gdbpath, args.gdbargs, args.env, args.verbose, false, false, "", false, args.sourceDirs); + this.miDebugger = new MI2(settings.gdbPath, args.gdbargs, args.env, args.verbose, false, false, "", false, args.sourceDirs); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); @@ -426,7 +424,7 @@ export class GDBDebugSession extends DebugSession { } protected async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise { - this.showVariableDetails = this.settings.displayVariableAttributes; + this.showVariableDetails = settings.displayVariableAttributes; let id: number | string | VariableObject | ExtendedVariable; if (args.variablesReference < VAR_HANDLES_START) { diff --git a/src/settings.ts b/src/settings.ts index ce70f0b..55b66bd 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -5,25 +5,23 @@ export class DebuggerSettings { constructor() { this.debugSettings = vscode.workspace.getConfiguration("superbol.debugger"); - //this.globalSettings = vscode.workspace.getConfiguration("superbol"); + if (!this.debugSettings.has("gdbPath")) { + this.debugSettings = vscode.workspace.getConfiguration("superbol-vscode-debug"); + } } public get displayVariableAttributes(): boolean { return this.debugSettings.get("displayVariableAttributes"); } - public get gdbpath(): string { + public get gdbPath(): string { return this.debugSettings.get("gdbPath"); } - public get libcobpath(): string { + public get libcobPath(): string { return this.debugSettings.get("libcobPath"); } - public get gdbtty(): string { - return this.debugSettings.get("gdbtty"); - } - public get cobcrunPath(): string { return this.debugSettings.get("cobcrunPath"); } From 9fc54b8b7eff053d8ef06d004969c0cf30c1cd4c Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Thu, 27 Nov 2025 16:37:05 +0100 Subject: [PATCH 58/70] Contribute a minimal COBOL language This minimal language definition seems necessary to insert beakpoints, and is hence required to test the extension independently. --- package.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/package.json b/package.json index 6c74d87..ddb5cd1 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,17 @@ "language": "cobol" } ], + "languages": [ + { + "id": "cobol", + "aliases": [ + "COBOL" + ], + "filenamePatterns": [ + "*.[cC]{ob,OB,bl,BL,py,PY,bx,BX,bsql}" + ] + } + ], "debuggers": [ { "type": "superbol-gdb", From fca3206d5f88c126491fa6d2a303b0e86409a5c5 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Thu, 27 Nov 2025 17:58:59 +0100 Subject: [PATCH 59/70] Move debug logs to a VSCode-managed channel --- src/gdb.ts | 19 +++++- src/log.ts | 33 +++++++++++ src/mi2.ts | 153 ++++++++++++++++-------------------------------- src/parser.c.ts | 17 +++--- 4 files changed, 108 insertions(+), 114 deletions(-) create mode 100644 src/log.ts diff --git a/src/gdb.ts b/src/gdb.ts index e99c125..230f6f0 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -19,6 +19,7 @@ import * as path from "path"; import {MI2} from './mi2'; import {CoverageStatus} from './coverage'; import {DebuggerSettings} from './settings'; +import * as log from './log'; const STACK_HANDLES_START = 1000; const VAR_HANDLES_START = 512 * 256 + 1000; @@ -42,7 +43,7 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum sourceDirs: string[]; } -export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArguments { +export interface AttachRequestArguments extends DebugProtocol.AttachRequestArguments { cwd: string | null; target: string; arguments: string; @@ -57,6 +58,14 @@ export interface AttachRequestArguments extends DebugProtocol.LaunchRequestArgum const settings = new DebuggerSettings(); +function initLogLevel(verbose: boolean) { + if (verbose) { + log.setLevel(log.Level.Debug); + } else { + log.setLevel(log.Level.Info); + } +} + export class GDBDebugSession extends DebugSession { protected variableHandles = new Handles(VAR_HANDLES_START); protected variableHandlesReverse: { [id: string]: number } = {}; @@ -78,11 +87,13 @@ export class GDBDebugSession extends DebugSession { } protected launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments): void { + initLogLevel(args.verbose); + this.showCoverage = args.coverage; this.started = false; this.attached = false; - this.miDebugger = new MI2(settings.gdbPath, args.gdbargs, args.env, args.verbose, args.noDebug, args.gdbtty, settings.cobcrunPath, args.useCobcrun, args.sourceDirs); + this.miDebugger = new MI2(settings.gdbPath, args.gdbargs, args.env, args.noDebug, args.gdbtty, settings.cobcrunPath, args.useCobcrun, args.sourceDirs); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); @@ -123,6 +134,8 @@ export class GDBDebugSession extends DebugSession { } protected attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments): void { + initLogLevel(args.verbose); + if (!args.pid && !args.remoteDebugger) { this.sendErrorResponse( response, @@ -136,7 +149,7 @@ export class GDBDebugSession extends DebugSession { this.attached = true; this.started = false; - this.miDebugger = new MI2(settings.gdbPath, args.gdbargs, args.env, args.verbose, false, false, "", false, args.sourceDirs); + this.miDebugger = new MI2(settings.gdbPath, args.gdbargs, args.env, false, false, "", false, args.sourceDirs); this.miDebugger.on("launcherror", (err: Error) => this.launchError(err)); this.miDebugger.on("quit", () => this.quitEvent()); this.miDebugger.on("exited-normally", () => this.quitEvent()); diff --git a/src/log.ts b/src/log.ts new file mode 100644 index 0000000..d5ba1e8 --- /dev/null +++ b/src/log.ts @@ -0,0 +1,33 @@ +import * as vscode from "vscode"; + +export enum Level { Debug, Info }; +export let level = Level.Info; +export function setLevel (l: Level): void { + level = l; +} + +const channel = vscode.window.createOutputChannel("SuperBOL Debugger"); + +export function emit(...msg: (string | (() => (string | string[])))[]) { + channel.appendLine(msg.flatMap(f => { + if (typeof (f) == "string") { + return [f]; + } else { + const r = f(); + return (typeof (r) == "string") ? [r] : r; + } + }).join(' ')); +} + +export const info = emit; + +export function debug(...msg: (string | (() => (string | string[])))[]) { + if (level == Level.Debug) { + emit(...msg); + } +} + +export function error(...msg) { + emit(...msg); + channel.show(); +} diff --git a/src/mi2.ts b/src/mi2.ts index ceff601..31b7fa0 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -7,6 +7,7 @@ import * as fs from "fs"; import { SourceMap } from "./parser.c"; import { parseExpression, cleanRawValue } from "./functions"; import * as vscode from 'vscode'; +import * as log from './log'; const nonOutput = /(^(?:\d*|undefined)[*+\-=~@&^])([^*+\-=~@&]{1,})/; const gdbRegex = /(?:\d*|undefined)\(gdb\)/; @@ -42,7 +43,7 @@ export class MI2 extends EventEmitter implements IDebugger { private hasCobGetFieldStringFunction = true; private hasCobPutFieldStringFunction = true; - constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public verbose: boolean, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean, public sourceDirs: string[]) { + constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean, public sourceDirs: string[]) { super(); if (procEnv) { const env = {}; @@ -76,12 +77,12 @@ export class MI2 extends EventEmitter implements IDebugger { let target_no_ext = target.split('.').slice(0, -1).join('.'); this.gcovFiles.add(target_no_ext); try { - this.map = new SourceMap(cwd, [target].concat(group), this.sourceDirs, ((l: any) => this.debug (l))); + this.map = new SourceMap(cwd, [target].concat(group), this.sourceDirs); } catch (e) { - this.log('stderr', (e).toString()); + log.error((e).toString()); } - this.debug(() => this.map.toString("created")); + log.debug(() => this.map.toString("created")); if (!this.useCobcrun) { target = path.resolve(cwd, path.basename(target)); @@ -102,7 +103,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.process = ChildProcess.spawn(this.gdbpath, this.gdbArgs, { cwd: cwd, env: this.procEnv }); this.process.stdout.on("data", (data: string) => this.stdout(data)); - this.process.stderr.on("data", (data: string) => { this.log("stderr", data); }); + this.process.stderr.on("data", (data: string) => this.stderr(data)); this.process.on("exit", (() => { this.emit("quit"); })); this.process.on("error", (err) => { this.emit("launcherror", err); }); const promises = this.initCommands(target, targetargs, cwd, this.useCobcrun); @@ -130,14 +131,12 @@ export class MI2 extends EventEmitter implements IDebugger { } try { - this.map = new SourceMap(cwd, [target].concat(group), this.sourceDirs, ((l: any) => this.debug (l))); + this.map = new SourceMap(cwd, [target].concat(group), this.sourceDirs); } catch (e) { - this.log('stderr', (e).toString()); + log.error((e).toString()); } - if (this.verbose) { - this.log("stderr", this.map.toString("created")); - } + log.debug(() => this.map.toString("created")); target = path.resolve(cwd, path.basename(target)); target = target.split('.').slice(0, -1).join('.'); @@ -148,7 +147,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.process = ChildProcess.spawn(this.gdbpath, this.gdbArgs, { cwd: cwd, env: this.procEnv }); this.process.stdout.on("data", (data: string) => this.stdout(data)); - this.process.stderr.on("data", (data: string) => { this.log("stderr", data); }); + this.process.stderr.on("data", (data: string) => this.stderr(data)); this.process.on("exit", () => { this.emit("quit"); }); this.process.on("error", (err) => { this.emit("launcherror", err); }); const promises = this.initCommands(target, targetargs, cwd, false); @@ -189,9 +188,7 @@ export class MI2 extends EventEmitter implements IDebugger { } stdout(data: string) { - if (this.verbose) { - this.log("stderr", "stdout: " + data); - } + log.debug("stdout: " + data); this.buffer += data; const end = this.buffer.lastIndexOf('\n'); if (end != -1) { @@ -206,9 +203,7 @@ export class MI2 extends EventEmitter implements IDebugger { } stderr(data: string) { - if (this.verbose) { - this.log("stderr", "stderr: " + data); - } + log.debug("stderr: " + data); this.errbuf += data; const end = this.errbuf.lastIndexOf('\n'); if (end != -1) { @@ -223,9 +218,7 @@ export class MI2 extends EventEmitter implements IDebugger { stdin(data: string, cb?: (_err: Error) => void) { if (this.isReady()) { - if (this.verbose) { - this.log("stderr", "stdin: " + data); - } + log.debug("stdin: " + data); this.process.stdin.write(data + "\n", cb); } } @@ -254,9 +247,9 @@ export class MI2 extends EventEmitter implements IDebugger { } } else { const parsed = parseMI(line); - if (this.verbose) { - this.log("stderr", "GDB -> App: " + JSON.stringify(parsed)); - } + // if (this.verbose) { + // this.log("stderr", "GDB -> App: " + JSON.stringify(parsed)); + // } let handled = false; if (parsed.token !== undefined) { if (this.handlers[parsed.token]) { @@ -282,9 +275,7 @@ export class MI2 extends EventEmitter implements IDebugger { this.emit("running", parsed); } else if (record.asyncClass == "stopped") { const reason = parsed.record("reason"); - if (this.verbose) { - this.log("stderr", "stop: " + reason); - } + log.debug("stop:", reason); if (reason == "breakpoint-hit") { if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { if(this.lastStepCommand==this.continue && parsed.record("disp")=="del") @@ -317,9 +308,7 @@ export class MI2 extends EventEmitter implements IDebugger { } else if (reason == "exited-normally") { this.emit("exited-normally", parsed); } else if (reason == "exited") { // exit with error code != 0 - if (this.verbose) { - this.log("stderr", "Program exited with code " + parsed.record("exit-code")); - } + log.info("Program exited with code " + parsed.record("exit-code")); this.emit("quit", parsed); } else if (reason == "solib-event") { this.onSolibEvent (parsed); @@ -328,14 +317,12 @@ export class MI2 extends EventEmitter implements IDebugger { if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { void this.continue(); } else { - if (this.verbose) { - this.log("stderr", "Not implemented stop reason (assuming exception): " + reason); - } + log.error("Not implemented stop reason (assuming exception):", reason); this.emit("stopped", parsed); } } } else { - this.debug (() => JSON.stringify(parsed)); + log.debug (() => JSON.stringify(parsed)); } } else if (record.type == "notify") { if (record.asyncClass == "thread-created") { @@ -346,19 +333,19 @@ export class MI2 extends EventEmitter implements IDebugger { // Possibly unreachable if `stop-on-solib-events` is on; still handle in case. let libname = record.output.find((e) => e[0] == "target-name")?.[1]; if (this.map.addLib (libname)) { - this.debug(() => `Added library to map: ${libname}`); - this.debug (() => this.map.toString ("updated")); + log.debug (() => `Added library to map: ${libname}`); + log.debug (() => this.map.toString ("updated")); this.reloadBreakPoints (); } } else if (record.asyncClass == "library-unloaded") { // Ditto: possibly unreachable if `stop-on-solib-events` is on; still handle in case. let libname = record.output.find((e) => e[0] == "target-name")?.[1]; if (this.map.remLib (libname)) { - this.debug (() => this.map.toString ("updated")); + log.debug (() => this.map.toString ("updated")); this.reloadBreakPoints (); } } else { - this.debug (() => JSON.stringify(parsed)); + log.debug (() => JSON.stringify(parsed)); } } } @@ -369,9 +356,7 @@ export class MI2 extends EventEmitter implements IDebugger { handled = true; } if (!handled) { - if (this.verbose) { - this.log("stderr", "Unhandled: " + JSON.stringify(parsed)); - } + log.error("Unhandled: " + JSON.stringify(parsed)); } } }); @@ -383,15 +368,15 @@ export class MI2 extends EventEmitter implements IDebugger { const isLib = (lib: [string, any]) => lib[0] == "library"; let libsChanged = false; libsChanged = added.filter(isLib).reduce((libsChanged, lib) => { - this.debug("loaded library:", lib[1]); + log.debug("loaded library:", lib[1]); return this.map.addLib(lib[1]) || libsChanged; }, libsChanged); libsChanged = removed.filter(isLib).reduce((libsChanged, lib) => { - this.debug("unloaded library:", lib[1]); + log.debug("unloaded library:", lib[1]); return this.map.remLib(lib[1]) || libsChanged; }, libsChanged); if (libsChanged) { - this.debug (() => this.map.toString ("updated")); + log.debug (() => this.map.toString ("updated")); this.reloadBreakPoints (); } } @@ -459,9 +444,7 @@ export class MI2 extends EventEmitter implements IDebugger { } interrupt(): Thenable { - if (this.verbose) { - this.log("stderr", "interrupt"); - } + log.debug("interrupt"); return new Promise((resolve, reject) => { this.sendCommand("exec-interrupt").then((info) => { resolve(info.resultRecords.resultClass == "done"); @@ -471,9 +454,7 @@ export class MI2 extends EventEmitter implements IDebugger { continue(): Thenable { this.lastStepCommand = () => this.continue(); - if (this.verbose) { - this.log("stderr", "continue"); - } + log.debug("continue"); return new Promise((resolve, reject) => { this.sendCommand("exec-continue").then((info) => { resolve(info.resultRecords.resultClass == "running"); @@ -497,9 +478,7 @@ export class MI2 extends EventEmitter implements IDebugger { // 002 - stepOver in routines with "perform" stepOver(): Thenable { this.lastStepCommand = () => this.stepOver(); - if (this.verbose) { - this.log("stderr", "stepOver"); - } + log.debug("stepOver"); if (subroutine >= 0) { return new Promise((resolve, reject) => { this.sendCommand("exec-until " + subroutine).then((info) => { @@ -522,9 +501,7 @@ export class MI2 extends EventEmitter implements IDebugger { */ stepInto(): Thenable { this.lastStepCommand = () => this.stepInto() ; - if (this.verbose) { - this.log("stderr", "stepInto"); - } + log.debug("stepInto"); // 002 - stepInto/setpOut in routines with "perform" if (subroutine >= 0) { return new Promise((resolve, reject) => { @@ -549,9 +526,7 @@ export class MI2 extends EventEmitter implements IDebugger { */ stepOut(): Thenable { this.lastStepCommand = () => this.stepOut() ; - if (this.verbose) { - this.log("stderr", "stepOut"); - } + log.debug("stepOut"); return new Promise((resolve, reject) => { this.sendCommand("exec-finish").then((info) => { resolve(info.resultRecords.resultClass == "running"); @@ -560,9 +535,7 @@ export class MI2 extends EventEmitter implements IDebugger { } goto(filename: string, line: number): Thenable { - if (this.verbose) { - this.log("stderr", "goto"); - } + log.debug("goto"); return new Promise((resolve, reject) => { const target: string = '"' + (filename ? escape(filename) + ":" : "") + line.toString() + '"'; this.sendCommand("break-insert -t " + target).then(() => { @@ -574,7 +547,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async changeVariable(name: string, rawValue: string): Promise { - this.debug("changeVariable"); + log.debug("changeVariable"); const functionName = await this.getCurrentFunctionName(); @@ -607,7 +580,7 @@ export class MI2 extends EventEmitter implements IDebugger { } loadBreakPoints(breakpoints: Breakpoint[]): Thenable<[boolean, Breakpoint][]> { - this.debug("loadBreakPoints"); + log.debug("loadBreakPoints"); const promisses = []; breakpoints.forEach(breakpoint => { promisses.push(this.addBreakPoint(breakpoint)); @@ -625,12 +598,12 @@ export class MI2 extends EventEmitter implements IDebugger { } setBreakPointCondition(bkptNum: number, condition: string): Thenable { - this.debug("setBreakPointCondition"); + log.debug("setBreakPointCondition"); return this.sendCommand("break-condition " + bkptNum.toString() + " " + condition); } addBreakPoint(breakpoint: Breakpoint): Thenable<[boolean, Breakpoint]> { - this.debug("addBreakPoint"); + log.debug("addBreakPoint"); return new Promise((resolve, reject) => { if (this.breakpoints.has(breakpoint)) { @@ -653,7 +626,7 @@ export class MI2 extends EventEmitter implements IDebugger { const map = this.map.getLineC(breakpoint.file, breakpoint.line); if (map.fileC === '' && map.lineC === 0) { - this.debug (() => [ + log.debug (() => [ "addBreakPoint: ignoring breakpoint for unknown source file:", JSON.stringify(breakpoint) ]); @@ -698,7 +671,7 @@ export class MI2 extends EventEmitter implements IDebugger { } removeBreakPoint(breakpoint: Breakpoint): Thenable { - this.debug("removeBreakPoint"); + log.debug("removeBreakPoint"); return new Promise((resolve, _reject) => { if (!this.breakpoints.has(breakpoint)) { if (this.ignoredBreakpoints.has(breakpoint)) { @@ -718,7 +691,7 @@ export class MI2 extends EventEmitter implements IDebugger { } clearBreakPoints(): Thenable { - this.debug("clearBreakPoints"); + log.debug("clearBreakPoints"); return new Promise((resolve, _reject) => { this.sendCommand("break-delete").then((result) => { if (result.resultRecords.resultClass == "done") { @@ -735,7 +708,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async getThreads(): Promise { - this.debug("getThreads"); + log.debug("getThreads"); return new Promise((resolve, reject) => { if (!!this.noDebug) { return; @@ -757,7 +730,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async getStack(maxLevels: number, thread: number): Promise { - this.debug("getStack"); + log.debug("getStack"); let command = "stack-list-frames"; if (thread != 0) { command += ` --thread ${thread}`; @@ -799,7 +772,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async getCurrentFunctionName(): Promise { - this.debug("getCurrentFunctionName"); + log.debug("getCurrentFunctionName"); const response = await this.sendCommand("stack-info-frame", failure_handling.Silence); if (response === undefined) return; @@ -807,7 +780,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async getStackVariables(thread: number, frame: number): Promise { - this.debug("getStackVariables"); + log.debug("getStackVariables"); const functionName = await this.getCurrentFunctionName(); if (functionName === undefined) @@ -845,9 +818,7 @@ export class MI2 extends EventEmitter implements IDebugger { } examineMemory(from: number, length: number): Thenable { - if (this.verbose) { - this.log("stderr", "examineMemory"); - } + log.debug("examineMemory"); return new Promise((resolve, reject) => { this.sendCommand("data-read-memory-bytes 0x" + from.toString(16) + " " + length).then((result) => { resolve(result.result("memory[0].contents")); @@ -856,7 +827,7 @@ export class MI2 extends EventEmitter implements IDebugger { } async evalExpression(expression: string, thread: number, frame: number): Promise { - this.debug("evalExpression", expression); + log.debug("evalExpression", expression); const functionName = await this.getCurrentFunctionName(); if (functionName === undefined) @@ -878,13 +849,13 @@ export class MI2 extends EventEmitter implements IDebugger { const result = Function(`"use strict"; ${finalExpression}`)(); return JSON.stringify(result); // deals with escapes. } catch (e) { - this.debug(e.message); + log.debug(e.message); return `Failed to evaluate ${expression}`; } } async evalCobField(name: string, thread: number, frame: number): Promise { - this.debug("evalCobField", name); + log.debug("evalCobField", name); const functionName = await this.getCurrentFunctionName(); if (functionName === undefined) @@ -901,7 +872,7 @@ export class MI2 extends EventEmitter implements IDebugger { } private async evalVariable(variable: DebuggerVariable, thread: number, frame: number): Promise { - this.debug("evalVariable", variable.cName); + log.debug("evalVariable", variable.cName); let command = "data-evaluate-expression "; if (thread != 0) { @@ -951,30 +922,6 @@ export class MI2 extends EventEmitter implements IDebugger { this.emit("msg", type, msg[msg.length - 1] == '\n' ? msg : (msg + "\n")); } - private debug(...msg: (string | (() => (string | string[])))[]) { - if (this.verbose) { - this.log("stderr", msg.flatMap(f => { - if (typeof (f) == "string") { - return [f]; - } else { - const r = f(); - return (typeof (r) == "string") ? [r] : r; - } - }).join(' ')); - } - } - - private info(...msg: (string | (() => (string | string[])))[]) { - this.log("stdout", msg.flatMap(f => { - if (typeof (f) == "string") { - return [f]; - } else { - const r = f(); - return (typeof (r) == "string") ? [r] : r; - } - }).join(' ')); - } - sendUserInput(command: string, threadId: number = 0, frameLevel: number = 0): Thenable { return new Promise((resolve, reject) => { this.stdin(command, resolve); diff --git a/src/parser.c.ts b/src/parser.c.ts index 6c990f8..e45fc05 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -2,6 +2,7 @@ import readline from "n-readlines"; import * as path from "path"; import * as fs from "fs"; import {DebuggerVariable, Attribute, VariableType} from "./debugger"; +import * as log from './log'; function normalizeExistingFileName(f: string): string { if (f != undefined && process.platform === "win32") { @@ -71,13 +72,13 @@ export class SourceMap { private performLine: number = -1; // 002 - stepOver in routines with "perform" private isVersion2_2_or_3_1_1: boolean = false; - constructor(cwd: string, filesCobol: string[], sourceDirs: string[] = [], private log: Function = (_ => {})) { + constructor(cwd: string, filesCobol: string[], sourceDirs: string[] = []) { this.cwd = fs.realpathSync(path.resolve(cwd)); - this.log(`Source dirs: ${sourceDirs}`); + log.debug(`Source dirs: ${sourceDirs}`); for (const cSourceDir of sourceDirs) { - this.log(`Trying to resolve ${cSourceDir}`); + log.debug(`Trying to resolve ${cSourceDir}`); let resolved_path = path.resolve(this.cwd, cSourceDir); - this.log(`Checking for ${resolved_path}`); + log.debug(`Checking for ${resolved_path}`); if (fs.existsSync(resolved_path)) { this.sourceDirs.push(normalizeExistingFileName(fs.realpathSync(resolved_path))); } @@ -92,7 +93,7 @@ export class SourceMap { } }); - this.log(`Resolved source dirs: ${this.sourceDirs}`); + log.info(`Resolved source dirs: ${this.sourceDirs}`); } private lookupSourceFile (file: string) : string | undefined { @@ -110,7 +111,7 @@ export class SourceMap { return false; } this.loadedLibs.add (libFile); - // this.log(`Loading ${libFile}`); + log.info(`Loading ${libFile}`); const c = this.lookupSourceFile (cFile (libFile)); if (c) { this.register (c); @@ -124,7 +125,7 @@ export class SourceMap { return false; } this.loadedLibs.delete (libFile); - // this.log(`Unloading ${libFile}`); + log.info(`Unloading ${libFile}`); // Note: assumes there was no FS changes in the meantime. // Cleaner way would be to record a mapping between libs and source files. const c = this.lookupSourceFile (cFile (libFile)); @@ -159,7 +160,6 @@ export class SourceMap { } private register (givenFileC: string) : void { - // this.log(`Parsing ${givenFileC}`); void this.parse (givenFileC); // just parse the file. } @@ -167,6 +167,7 @@ export class SourceMap { prevLine: string | undefined = undefined, rootFileC: string | undefined = undefined, functionName: string | undefined = undefined) : string { + log.debug(`Parsing ${givenFileC}`); const [fileC, cleanedFile] = this.ensureAbsolute (givenFileC); rootFileC = rootFileC ?? fileC; From 50a56ce406a5731cc89167ef5f8a0434ea36ffa6 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 28 Nov 2025 22:38:34 +0100 Subject: [PATCH 60/70] Show current COBOL statement in stack frame summary --- src/debugger.ts | 7 ++----- src/gdb.ts | 26 ++++++++++++-------------- src/mi2.ts | 8 +------- src/parser.c.ts | 22 ++++++++++++++++++++++ 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/debugger.ts b/src/debugger.ts index 4f6bcdf..2f87cd3 100644 --- a/src/debugger.ts +++ b/src/debugger.ts @@ -1,7 +1,7 @@ import {MINode} from "./parser.mi2"; import {DebugProtocol} from "@vscode/debugprotocol/lib/debugProtocol"; import {removeLeadingZeroes} from "./functions"; -import {SourceMap} from "./parser.c"; +import {SourceMap, Line} from "./parser.c"; export interface Breakpoint { file?: string; @@ -19,11 +19,8 @@ export interface Thread { export interface Stack { level: number; - address: string; function: string; - fileName: string; - file: string; - line: number; + line: Line; } const repeatTimeRegex = /(\"\,\s|^)\'(\s|0)\'\s\/i; diff --git a/src/gdb.ts b/src/gdb.ts index 230f6f0..b0150da 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -391,23 +391,21 @@ export class GDBDebugSession extends DebugSession { protected stackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments): void { this.miDebugger.getStack(args.levels, args.threadId).then(stack => { - const ret: StackFrame[] = []; - stack.forEach(element => { - let source: Source = undefined; - const file = element.file; - if (file) { - source = new Source(element.fileName, file); - } - - ret.push(new StackFrame( + const ret = stack.map(element => { + const file = element.line.fileCobol; + const fileBasename = path.basename(file); + const cobolLine = element.line.cobolLine?.trim(); + const frameDescr = cobolLine + ? `${element.function} (${cobolLine})` + : `${element.function}`; + return new StackFrame( this.threadAndLevelToFrameId(args.threadId, element.level), - element.function + "@" + element.address, - source, - element.line, - 0)); + frameDescr, // + "@" + element.address, + file ? new Source(fileBasename, file) : undefined, + element.line.lineCobol, 0); }); response.body = { - stackFrames: ret + stackFrames: Array.from(ret) }; this.sendResponse(response); }, (err: Error) => { diff --git a/src/mi2.ts b/src/mi2.ts index 31b7fa0..0a26388 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -744,9 +744,7 @@ export class MI2 extends EventEmitter implements IDebugger { const stack = result.result("stack"); return stack.map(element => { const level = MINode.valueOf(element, "@frame.level"); - const addr = MINode.valueOf(element, "@frame.addr"); const func = MINode.valueOf(element, "@frame.func"); - const filename = MINode.valueOf(element, "@frame.file"); let file: string = MINode.valueOf(element, "@frame.fullname"); if (file) { file = path.normalize(file); @@ -759,14 +757,10 @@ export class MI2 extends EventEmitter implements IDebugger { line = parseInt(lnstr); } - const map = this.map.getLineCobol(file, line); return { - address: addr, - fileName: path.basename(map.fileCobol), - file: map.fileCobol, function: func || from, level: level, - line: map.lineCobol + line: this.map.getLineCobol(file, line) }; }); } diff --git a/src/parser.c.ts b/src/parser.c.ts index e45fc05..8c44337 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -39,8 +39,29 @@ function cobEncodeInvalidChars (s: string): string { return s.replace("-","__"); } +// Minimalistic one-entry cache. +let currentCOBOLFileName: string = null; +let currentCOBOLFileContents: string[] = []; + +function lookupLineInCobolFile(fileCobol: string, lineCobol: number) : string | undefined { + if (fileCobol && currentCOBOLFileName != fileCobol) { + currentCOBOLFileName = fileCobol; + try { + currentCOBOLFileContents = fs.readFileSync(fileCobol).toString().split('\n'); + } catch (e) { + log.debug(e.message); + currentCOBOLFileContents = []; + } + } + if (currentCOBOLFileContents) { + return currentCOBOLFileContents[lineCobol - 1]; + } + return undefined; +} + export class Line { endPerformLine: number; // 002 - stepOver in routines with "perform" + public cobolLine: string | undefined; public constructor (public fileCobol: string, @@ -50,6 +71,7 @@ export class Line { public lineC: number, public functionName: string) { this.endPerformLine = -1; // 002 - stepOver in routines with "perform" + this.cobolLine = lookupLineInCobolFile (fileCobol, lineCobol); } public toString(): string { From e598b9287b0fcecc1f05d9fa96f4884fcb77e850 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 28 Nov 2025 22:39:46 +0100 Subject: [PATCH 61/70] Change build tasks to be less intrusive --- .vscode/tasks.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 54059ed..e255ae1 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,8 +6,9 @@ "command": "npm", "type": "shell", "presentation": { - "reveal": "always", - "panel": "new" + "reveal": "silent", + "revealProblems": "onProblem", + "panel": "dedicated" }, "args": [ "run", @@ -15,7 +16,7 @@ "--loglevel", "silent" ], - "isBackground": true, + "isBackground": false, "problemMatcher": "$tsc-watch", "group": { "kind": "build", From a34a9ac23530b71b6499f64d3fdb6755892a1e2a Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 8 Dec 2025 11:26:15 +0100 Subject: [PATCH 62/70] Fix vscode version in `package-lock.json` --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 7b6293a..ba0e4e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ }, "engines": { "node": ">=20", - "vscode": "^1.44.0" + "vscode": "^1.66.0" } }, "node_modules/@bcoe/v8-coverage": { From 6098232179251b3b177341e33bcfa0dc0da84491 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 8 Dec 2025 13:10:38 +0100 Subject: [PATCH 63/70] Minor simplifications in `src/mi2.ts` --- src/mi2.ts | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/mi2.ts b/src/mi2.ts index 0a26388..d879c5e 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -46,29 +46,11 @@ export class MI2 extends EventEmitter implements IDebugger { constructor(public gdbpath: string, public gdbArgs: string[], procEnv: NodeJS.ProcessEnv, public noDebug: boolean, public gdbtty: boolean, public cobcrunPath: string, public useCobcrun: boolean, public sourceDirs: string[]) { super(); if (procEnv) { - const env = {}; - // Duplicate process.env so we don't override it - for (const key in process.env) - if (key in process.env) { - env[key] = process.env[key]; - } - // Overwrite with user specified variables - for (const key in procEnv) { - if (key in procEnv) { - if (procEnv === null) { - delete env[key]; - } else { - env[key] = procEnv[key]; - } - } - } - this.procEnv = env; + this.procEnv = {...process.env, ...procEnv}; } } load(cwd: string, target: string, targetargs: string, group: string[], gdbtty: boolean): Thenable { - group.map(e => { path.join(cwd, e); }); - return new Promise(async (resolve, reject) => { if (!fs.existsSync(cwd)) { reject(new Error("cwd does not exist.")); @@ -123,7 +105,6 @@ export class MI2 extends EventEmitter implements IDebugger { if (!path.isAbsolute(target)) { target = path.join(cwd, target); } - group.map(e => { path.join(cwd, e) }); return new Promise((resolve, reject) => { if (!fs.existsSync(cwd)) { From d9a80314479ea0c95dc627bf6eb27baf692f12d0 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 8 Dec 2025 13:13:01 +0100 Subject: [PATCH 64/70] Run interactive extension tests with workspace in `test/resources` --- .vscode-test-workspace/.dummy | 0 .vscode/launch.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 .vscode-test-workspace/.dummy diff --git a/.vscode-test-workspace/.dummy b/.vscode-test-workspace/.dummy deleted file mode 100644 index e69de29..0000000 diff --git a/.vscode/launch.json b/.vscode/launch.json index 024d6c9..08d0d29 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,7 +14,7 @@ // "--user-data-dir=${workspaceFolder}/.vscode-test/user-data", "--extensionDevelopmentPath=${workspaceFolder}", "--trace-deprecation", - "${workspaceFolder}/.vscode-test-workspace", + "${workspaceFolder}/test/resources", ], "autoAttachChildProcesses": true, "sourceMaps": true, From 9fac41f175d410a8c70024ebf964b55eddc4da34 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 8 Dec 2025 13:22:14 +0100 Subject: [PATCH 65/70] Add missing entry in `CHANGELOG.md` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 305903a..29d5fb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Show COBOL statements in entries of stackframe summary [PR #38](https://github.com/ocamlpro/superbol-vscode-debug/pull/38) * Remove `gdbpath` and `libcobpath` from launch configurations (these are provided in extension settings) [PR #36](https://github.com/ocamlpro/superbol-vscode-debug/pull/36) * Fix enforcement of a default `preLaunchTask` that is not available [PR #34](https://github.com/ocamlpro/superbol-vscode-debug/pull/34) * Support cases where the COBOL source code and the corresponding C files are in distinct directories [PR #29](https://github.com/ocamlpro/superbol-vscode-debug/pull/29) From ae65af54f49f9d0bd57c983a2050cf7f8f2339cf Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 8 Dec 2025 15:26:50 +0100 Subject: [PATCH 66/70] Fix handling of signed numbers in standard output Before these changes, lines starting with signed numbers like `+0000` on stdout, were wrongly interpreted as MI2-related messages. --- CHANGELOG.md | 1 + src/mi2.ts | 218 ++++++++++++++++++++--------------------- test/suite/mi2.test.ts | 3 + 3 files changed, 113 insertions(+), 109 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29d5fb8..d757b22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Fixed a bug that made the extension hang when debugged programs displayed signed numbers [PR #39](https://github.com/ocamlpro/superbol-vscode-debug/pull/39) * Show COBOL statements in entries of stackframe summary [PR #38](https://github.com/ocamlpro/superbol-vscode-debug/pull/38) * Remove `gdbpath` and `libcobpath` from launch configurations (these are provided in extension settings) [PR #36](https://github.com/ocamlpro/superbol-vscode-debug/pull/36) * Fix enforcement of a default `preLaunchTask` that is not available [PR #34](https://github.com/ocamlpro/superbol-vscode-debug/pull/34) diff --git a/src/mi2.ts b/src/mi2.ts index d879c5e..6c01ee4 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -9,7 +9,7 @@ import { parseExpression, cleanRawValue } from "./functions"; import * as vscode from 'vscode'; import * as log from './log'; -const nonOutput = /(^(?:\d*|undefined)[*+\-=~@&^])([^*+\-=~@&]{1,})/; +const nonOutput = /(^(?:\d*|undefined)[*+\-=~@&^])([^*+\-=~@&]+[a-zA-Z]+)/; const gdbRegex = /(?:\d*|undefined)\(gdb\)/; const numRegex = /\d+/; const gcovRegex = /"([0-9a-z_\-/\s\\:]+\.o)"/gi; @@ -219,7 +219,7 @@ export class MI2 extends EventEmitter implements IDebugger { return false; } - onOutput(linesStr: string) { + private onOutput(linesStr: string) { const lines = linesStr.split('\n'); lines.forEach(line => { if (couldBeOutput(line)) { @@ -227,120 +227,120 @@ export class MI2 extends EventEmitter implements IDebugger { this.log("stdout", line); } } else { - const parsed = parseMI(line); - // if (this.verbose) { - // this.log("stderr", "GDB -> App: " + JSON.stringify(parsed)); - // } - let handled = false; - if (parsed.token !== undefined) { - if (this.handlers[parsed.token]) { - this.handlers[parsed.token](parsed); - delete this.handlers[parsed.token]; - handled = true; - } - } - if (!handled && parsed.resultRecords && parsed.resultRecords.resultClass == "error") { - this.log("stderr", parsed.result("msg") || line); - } - if (parsed.outOfBandRecord) { - parsed.outOfBandRecord.forEach(async record => { - if (record.isStream) { - this.log(record.type, record.content); - } else { - if (record.type == "exec") { - this.emit("exec-async-output", parsed); - // 002 - stepOver in routines with "perform" - subroutine = this.map.hasLineSubroutine(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line'))); - // 002 - if (record.asyncClass == "running") { - this.emit("running", parsed); - } else if (record.asyncClass == "stopped") { - const reason = parsed.record("reason"); - log.debug("stop:", reason); - if (reason == "breakpoint-hit") { - if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { - if(this.lastStepCommand==this.continue && parsed.record("disp")=="del") - void this.lastStepCommand(); - else - this.stepOver(); // 002 - stepInto/stepOut in routines with "perform" - } else { - this.emit("step-end", parsed); - } - } else if (reason == "location-reached") { // 002 - stepOver in routines with "perform" - if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { - this.stepOver(); - } else { - this.emit("step-end", parsed); - } - } else if (reason == "end-stepping-range") { - if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { - void this.lastStepCommand().then(); - } else { - this.emit("step-end", parsed); - } - } else if (reason == "function-finished") { - if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { - void this.lastStepCommand(); - } else { - this.emit("step-out-end", parsed); - } - } else if (reason == "signal-received") { - this.emit("signal-stop", parsed); - } else if (reason == "exited-normally") { - this.emit("exited-normally", parsed); - } else if (reason == "exited") { // exit with error code != 0 - log.info("Program exited with code " + parsed.record("exit-code")); - this.emit("quit", parsed); - } else if (reason == "solib-event") { - this.onSolibEvent (parsed); - this.resume (); - } else { - if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { - void this.continue(); - } else { - log.error("Not implemented stop reason (assuming exception):", reason); - this.emit("stopped", parsed); - } - } + this.onMINode(parseMI(line)); + } + }); + } + + private onMINode(parsed: MINode) { + let handled = false; + if (parsed && parsed.token !== undefined) { + if (this.handlers[parsed.token]) { + this.handlers[parsed.token](parsed); + delete this.handlers[parsed.token]; + handled = true; + } + } + if (!handled && parsed.resultRecords && parsed.resultRecords.resultClass == "error") { + this.log("stderr", parsed.result("msg")); + } + if (parsed.outOfBandRecord) { + parsed.outOfBandRecord.forEach(async record => { + if (record.isStream) { + this.log(record.type, record.content); + } else { + if (record.type == "exec") { + this.emit("exec-async-output", parsed); + // 002 - stepOver in routines with "perform" + subroutine = this.map.hasLineSubroutine(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line'))); + // 002 + if (record.asyncClass == "running") { + this.emit("running", parsed); + } else if (record.asyncClass == "stopped") { + const reason = parsed.record("reason"); + log.debug("stop:", reason); + if (reason == "breakpoint-hit") { + if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { + if (this.lastStepCommand == this.continue && parsed.record("disp") == "del") + void this.lastStepCommand(); + else + this.stepOver(); // 002 - stepInto/stepOut in routines with "perform" + } else { + this.emit("step-end", parsed); + } + } else if (reason == "location-reached") { // 002 - stepOver in routines with "perform" + if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { + this.stepOver(); + } else { + this.emit("step-end", parsed); + } + } else if (reason == "end-stepping-range") { + if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { + void this.lastStepCommand().then(); } else { - log.debug (() => JSON.stringify(parsed)); + this.emit("step-end", parsed); } - } else if (record.type == "notify") { - if (record.asyncClass == "thread-created") { - this.emit("thread-created", parsed); - } else if (record.asyncClass == "thread-exited") { - this.emit("thread-exited", parsed); - } else if (record.asyncClass == "library-loaded") { - // Possibly unreachable if `stop-on-solib-events` is on; still handle in case. - let libname = record.output.find((e) => e[0] == "target-name")?.[1]; - if (this.map.addLib (libname)) { - log.debug (() => `Added library to map: ${libname}`); - log.debug (() => this.map.toString ("updated")); - this.reloadBreakPoints (); - } - } else if (record.asyncClass == "library-unloaded") { - // Ditto: possibly unreachable if `stop-on-solib-events` is on; still handle in case. - let libname = record.output.find((e) => e[0] == "target-name")?.[1]; - if (this.map.remLib (libname)) { - log.debug (() => this.map.toString ("updated")); - this.reloadBreakPoints (); - } + } else if (reason == "function-finished") { + if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { + void this.lastStepCommand(); } else { - log.debug (() => JSON.stringify(parsed)); + this.emit("step-out-end", parsed); + } + } else if (reason == "signal-received") { + this.emit("signal-stop", parsed); + } else if (reason == "exited-normally") { + this.emit("exited-normally", parsed); + } else if (reason == "exited") { // exit with error code != 0 + log.info("Program exited with code " + parsed.record("exit-code")); + this.emit("quit", parsed); + } else if (reason == "solib-event") { + this.onSolibEvent(parsed); + this.resume(); + } else { + if (!this.map.hasLineCobol(parsed.record('frame.fullname'), parseInt(parsed.record('frame.line')))) { + void this.continue(); + } else { + log.error("Not implemented stop reason (assuming exception):", reason); + this.emit("stopped", parsed); } } + } else { + log.debug(() => JSON.stringify(parsed)); } - }); - handled = true; - } - if (parsed.token == undefined && parsed.resultRecords == undefined && parsed.outOfBandRecord.length == 0) { - handled = true; - } - if (!handled) { - log.error("Unhandled: " + JSON.stringify(parsed)); + } else if (record.type == "notify") { + if (record.asyncClass == "thread-created") { + this.emit("thread-created", parsed); + } else if (record.asyncClass == "thread-exited") { + this.emit("thread-exited", parsed); + } else if (record.asyncClass == "library-loaded") { + // Possibly unreachable if `stop-on-solib-events` is on; still handle in case. + let libname = record.output.find((e) => e[0] == "target-name")?.[1]; + if (this.map.addLib(libname)) { + log.debug(() => `Added library to map: ${libname}`); + log.debug(() => this.map.toString("updated")); + this.reloadBreakPoints(); + } + } else if (record.asyncClass == "library-unloaded") { + // Ditto: possibly unreachable if `stop-on-solib-events` is on; still handle in case. + let libname = record.output.find((e) => e[0] == "target-name")?.[1]; + if (this.map.remLib(libname)) { + log.debug(() => this.map.toString("updated")); + this.reloadBreakPoints(); + } + } else { + log.debug(() => JSON.stringify(parsed)); + } + } } - } - }); + }); + handled = true; + } + if (parsed.token == undefined && parsed.resultRecords == undefined && parsed.outOfBandRecord.length == 0) { + handled = true; + } + if (!handled) { + log.error("Unhandled: " + JSON.stringify(parsed)); + } } private onSolibEvent(node: MINode): void { diff --git a/test/suite/mi2.test.ts b/test/suite/mi2.test.ts index 51bbc24..bfc66d9 100644 --- a/test/suite/mi2.test.ts +++ b/test/suite/mi2.test.ts @@ -26,6 +26,9 @@ suite("GDB output", () => { test("++", () => { assert.equal(true, couldBeOutput('++')); }); + test("+0000", () => { + assert.equal(true, couldBeOutput('+0000')); + }); test("GDB done", () => { assert.equal(false, couldBeOutput('2^done')); }); From 9a6c581ea76e9240fa6efc184c4315eae955a79e Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 2 Dec 2025 16:41:48 +0100 Subject: [PATCH 67/70] Minor renaming in debugger API --- src/debugger.ts | 2 +- src/gdb.ts | 2 +- src/mi2.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debugger.ts b/src/debugger.ts index 2f87cd3..9262513 100644 --- a/src/debugger.ts +++ b/src/debugger.ts @@ -513,7 +513,7 @@ export interface IDebugger { sendUserInput(command: string, threadId: number, frameLevel: number): Thenable; - getSourceMap(): SourceMap; + sourceMap(): SourceMap; } export class VariableObject { diff --git a/src/gdb.ts b/src/gdb.ts index b0150da..d3ac5af 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -236,7 +236,7 @@ export class GDBDebugSession extends DebugSession { return; if (this.showCoverage) { - this.coverageStatus.show(this.miDebugger.getGcovFiles(), this.miDebugger.getSourceMap()).catch((err: Error) => console.log(err)); + this.coverageStatus.show(this.miDebugger.getGcovFiles(), this.miDebugger.sourceMap()).catch((err: Error) => console.log(err)); } else { this.coverageStatus.hide(); } diff --git a/src/mi2.ts b/src/mi2.ts index 6c01ee4..e10e065 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -936,7 +936,7 @@ export class MI2 extends EventEmitter implements IDebugger { return Array.from(this.gcovFiles); } - getSourceMap(): SourceMap { + sourceMap(): SourceMap { return this.map; } From 3c3934a29c5febef7c25a038158abb0c6173e5b6 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Thu, 27 Nov 2025 16:33:28 +0100 Subject: [PATCH 68/70] Show global data items in "Variables" panel --- CHANGELOG.md | 1 + src/debugger.ts | 21 ++- src/extension.ts | 9 +- src/gdb.ts | 199 ++++++++++++----------- src/mi2-decoder.ts | 19 +++ src/mi2.ts | 107 +++++++++---- src/parser.c.ts | 48 ++++-- test/resources/globals.c | 297 +++++++++++++++++++++++++++++++++++ test/resources/globals.c.h | 43 +++++ test/resources/globals.c.l.h | 52 ++++++ test/resources/globals.cbl | 21 +++ test/resources/globals.i | 22 +++ test/suite/parser.c.test.ts | 17 +- 13 files changed, 717 insertions(+), 139 deletions(-) create mode 100644 src/mi2-decoder.ts create mode 100644 test/resources/globals.c create mode 100644 test/resources/globals.c.h create mode 100644 test/resources/globals.c.l.h create mode 100644 test/resources/globals.cbl create mode 100644 test/resources/globals.i diff --git a/CHANGELOG.md b/CHANGELOG.md index d757b22..864650d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Next +* Show global data items in Variables panel [PR #39](https://github.com/ocamlpro/superbol-vscode-debug/pull/39) * Fixed a bug that made the extension hang when debugged programs displayed signed numbers [PR #39](https://github.com/ocamlpro/superbol-vscode-debug/pull/39) * Show COBOL statements in entries of stackframe summary [PR #38](https://github.com/ocamlpro/superbol-vscode-debug/pull/38) * Remove `gdbpath` and `libcobpath` from launch configurations (these are provided in extension settings) [PR #36](https://github.com/ocamlpro/superbol-vscode-debug/pull/36) diff --git a/src/debugger.ts b/src/debugger.ts index 9262513..12da206 100644 --- a/src/debugger.ts +++ b/src/debugger.ts @@ -23,6 +23,19 @@ export interface Stack { line: Line; } +export interface FileSymbols { + filename: string; + fullname: string; + symbols: Symbol[]; +} + +export interface Symbol { + line: number; + name: string; + type: string; + description: string; +} + const repeatTimeRegex = /(\"\,\s|^)\'(\s|0)\'\s\/i; export class CobolFieldDataParser { @@ -499,13 +512,17 @@ export interface IDebugger { getStackVariables(thread: number, frame: number): Thenable; - evalExpression(name: string, thread: number, frame: number): Thenable; + globalFileSymbols(nameFilterRegexp?: string): Thenable; + evalSymbol(s: Symbol): Promise; + evalExpression(name: string, thread: number, frame: number): Promise; evalCobField(name: string, thread: number, frame: number): Promise; + evalGlobalCobField(name: string): Promise; isReady(): boolean; - changeVariable(name: string, rawValue: string): Promise; + changeVariable(name: string, rawValue: string): Promise>; + changeGlobalVariable(name: string, rawValue: string): Promise>; examineMemory(from: number, to: number): Thenable; diff --git a/src/extension.ts b/src/extension.ts index e4db6c4..49b4815 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -155,10 +155,11 @@ class GnuCOBOLEvalExpressionFactory implements EvaluatableExpressionProvider { return undefined; } // TODO: Do not use a global variable - const variableName = globalThis.varGlobal.filter(it => it.children.toLowerCase() === txtToEval.toLowerCase()); - if(variableName && variableName.length>0){ - return new EvaluatableExpression(wordRange, variableName[0].father); - } + // Disabled for now... + // const variableName = globalThis.varGlobal.filter(it => it.children.toLowerCase() === txtToEval.toLowerCase()); + // if(variableName && variableName.length>0){ + // return new EvaluatableExpression(wordRange, variableName[0].father); + // } return wordRange ? new EvaluatableExpression(wordRange) : undefined; } diff --git a/src/gdb.ts b/src/gdb.ts index d3ac5af..ff18ba1 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -13,7 +13,7 @@ import { ThreadEvent } from '@vscode/debugadapter'; import {DebugProtocol} from '@vscode/debugprotocol'; -import {Breakpoint, VariableObject} from './debugger'; +import {Breakpoint, DebuggerVariable, FileSymbols, Symbol, VariableObject} from './debugger'; import {MINode} from './parser.mi2'; import * as path from "path"; import {MI2} from './mi2'; @@ -66,10 +66,10 @@ function initLogLevel(verbose: boolean) { } } +enum VarCat { Local, Global }; + export class GDBDebugSession extends DebugSession { - protected variableHandles = new Handles(VAR_HANDLES_START); - protected variableHandlesReverse: { [id: string]: number } = {}; - protected useVarObjects: boolean; + protected variableHandles = new Handles<[string, VarCat]>(VAR_HANDLES_START); protected quit: boolean; protected needContinue: boolean; protected started: boolean; @@ -78,7 +78,6 @@ export class GDBDebugSession extends DebugSession { protected debugReady: boolean; protected miDebugger: MI2; coverageStatus: CoverageStatus; - private showVariableDetails: boolean; private showCoverage: boolean = true; protected initializeRequest(response: DebugProtocol.InitializeResponse, _args: DebugProtocol.InitializeRequestArguments): void { @@ -111,8 +110,7 @@ export class GDBDebugSession extends DebugSession { this.needContinue = false; this.crashed = false; this.debugReady = false; - this.useVarObjects = false; - // Run in the target executables' directory, unless specificed; becomes '.' if target is a module name. + // Run in the target executables' directory, unless specified; becomes '.' if target is a module name. let cwd = args.cwd ?? path.dirname (args.target); this.miDebugger.load(cwd, args.target, args.arguments, args.group, args.gdbtty).then( /*onfulfilled:*/ () => { @@ -167,7 +165,6 @@ export class GDBDebugSession extends DebugSession { this.needContinue = true; this.crashed = false; this.debugReady = false; - this.useVarObjects = false; // Run in the target executables' directory, unless specificed. let cwd = args.cwd ?? path.dirname (args.target); this.miDebugger.attach(cwd, args.target, args.arguments, args.group).then(() => { @@ -260,26 +257,25 @@ export class GDBDebugSession extends DebugSession { } protected async setVariableRequest(response: DebugProtocol.SetVariableResponse, args: DebugProtocol.SetVariableArguments): Promise { + const showDetails = settings.displayVariableAttributes; + const [id, cat] = this.lookupVariable(args.variablesReference); try { - let id: number | string | VariableObject | ExtendedVariable; - if (args.variablesReference < VAR_HANDLES_START) { - id = args.variablesReference - STACK_HANDLES_START; - } else { - id = this.variableHandles.get(args.variablesReference); - } - let name = args.name; if (typeof id == "string") { name = `${id}.${args.name}`; - if (this.showVariableDetails && args.name === "value") { + if (showDetails && args.name === "value") { name = id; } } - if (!this.showVariableDetails || args.name === "value") { - await this.miDebugger.changeVariable(name, args.value); - response.body = { - value: args.value - }; + if (!showDetails || args.name === "value") { + const invalidatedAreas = (cat == VarCat.Global) ? + await this.miDebugger.changeGlobalVariable(name, args.value) : + await this.miDebugger.changeVariable(name, args.value); + response.body = { value: args.value }; + if (invalidatedAreas.length > 0) { + // Trigger an update of invalidated areas. + this.sendEvent(new DebugAdapter.InvalidatedEvent(invalidatedAreas)); + } } this.sendResponse(response); } catch (err) { @@ -424,96 +420,118 @@ export class GDBDebugSession extends DebugSession { this.sendResponse(response); } + // TODO: invalidate on some operations? + private globalSymbols: Symbol[] = []; + protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void { - const scopes = new Array(); - scopes.push(new Scope("Local", STACK_HANDLES_START + (args.frameId || 0), false)); + const scopes = [ + new Scope("Local", STACK_HANDLES_START + args.frameId, false) + ]; + this.miDebugger.globalFileSymbols("^b_[0-9]*$").then(globalsFileSymbols => { + this.globalSymbols = globalsFileSymbols.flatMap(fileSymbols => fileSymbols.symbols); + if (this.globalSymbols.length > 0) { + scopes.push(new Scope("Globals", 1, false)); + } + response.body = { scopes: scopes }; + this.sendResponse(response); + }); + } + + private debugProtocolVariable(dv: DebuggerVariable, varCat: VarCat) : DebugProtocol.Variable { + const showDetails = settings.displayVariableAttributes; + const reference = (showDetails || !!dv.children.size) + ? this.variableHandles.create([dv.cobolName, varCat]) + : 0; + const value = showDetails + ? `${dv.value || "null"} (${dv.displayableType})` + : dv.value || "null"; + return { + name: dv.cobolName, + evaluateName: dv.cobolName, + value: value, + type: dv.displayableType, + variablesReference: reference + }; + } + private async globalVariableRequest(response: DebugProtocol.VariablesResponse) : Promise { + Promise + .all(this.globalSymbols.map(s => this.miDebugger.evalSymbol(s))) + .then(debuggerVariables => + debuggerVariables.map(v => this.debugProtocolVariable(v, VarCat.Global))) + .then(variables => { + response.body = { variables: variables }; + this.sendResponse(response); + }); + } + + private async stackVariableRequest(response: DebugProtocol.VariablesResponse, id: number) : Promise { + const [threadId, level] = this.frameIdToThreadAndLevel(id); + const stackVariables = await this.miDebugger.getStackVariables(threadId, level); response.body = { - scopes: scopes + variables: (stackVariables ?? []).map(v => this.debugProtocolVariable(v, VarCat.Local)) }; this.sendResponse(response); } - protected async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise { - this.showVariableDetails = settings.displayVariableAttributes; - - let id: number | string | VariableObject | ExtendedVariable; - if (args.variablesReference < VAR_HANDLES_START) { - id = args.variablesReference - STACK_HANDLES_START; + private lookupVariable (ref: number) : [string | number, VarCat] { + let id: number | string; + let cat: VarCat = VarCat.Local; + if (ref < VAR_HANDLES_START) { + if (ref >= STACK_HANDLES_START) { + cat = VarCat.Local; + id = ref - STACK_HANDLES_START; + } else { + cat = VarCat.Global; + id = ref; + } } else { - id = this.variableHandles.get(args.variablesReference); + [id, cat] = this.variableHandles.get(ref); } + return [id, cat]; + } - if (typeof id == "number") { - try { - const variables: DebugProtocol.Variable[] = []; - const [threadId, level] = this.frameIdToThreadAndLevel(id); - const stackVariables = await this.miDebugger.getStackVariables(threadId, level); - if (stackVariables === undefined) { - this.sendResponse(response); - } - globalThis.varGlobal = []; - for (const stackVariable of stackVariables) { - let reference = 0; - if (this.showVariableDetails || !!stackVariable.children.size) { - reference = this.variableHandles.create(stackVariable.cobolName); - } - - let value = stackVariable.value || "null"; - if (this.showVariableDetails) { - value = stackVariable.displayableType; - } - - variables.push({ - name: stackVariable.cobolName, - evaluateName: stackVariable.cobolName, - value: value, - type: stackVariable.displayableType, - variablesReference: reference - }); - if(stackVariable.hasChildren){ - const child= stackVariable.children; - for (var childs of stackVariable.children.entries()) { - var key = childs[0]; - globalThis.varGlobal.push({ - "children": key, - "father": stackVariable.cobolName - }) - } - } + protected async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise { + const showDetails = settings.displayVariableAttributes; + const [id, cat] = this.lookupVariable(args.variablesReference); + try { + response.body = { variables: [] }; + if (typeof id == "number") { + if (cat == VarCat.Local) { + log.info('stack:', id.toString()); + this.stackVariableRequest(response, id); + } else { + log.info('global:', id.toString()); + this.globalVariableRequest(response); } - - response.body = { - variables: variables - }; - this.sendResponse(response); - } catch (err) { - this.sendErrorResponse(response, 1, `Could not expand variable: ${(err).toString()}`); - } - } else if (typeof id == "string") { - try { + } else if (typeof id == "string") { // TODO: this evals on an (effectively) unknown thread for multithreaded programs. - const stackVariable = await this.miDebugger.evalCobField(id, 0, 0); + const stackVariable = (cat == VarCat.Local) + ? await this.miDebugger.evalCobField(id) + : await this.miDebugger.evalGlobalCobField(id); if (stackVariable === undefined) { this.sendResponse(response); // fail early and silently } let variables: DebugProtocol.Variable[] = []; - if (this.showVariableDetails) { - variables = stackVariable.toDebugProtocolVariable(this.showVariableDetails); + if (showDetails) { + variables = stackVariable.toDebugProtocolVariable(showDetails); } for (const child of stackVariable.children.values()) { const childId = `${id}.${child.cobolName}`; let reference = 0; - if (this.showVariableDetails || !!child.children.size) { - reference = this.variableHandles.create(childId); + if (showDetails || !!child.children.size) { + reference = this.variableHandles.create([childId, cat]); } let value = child.displayableType; - if (!this.showVariableDetails) { - const evaluatedChild = await this.miDebugger.evalCobField(childId, 0, 0); + if (!showDetails) { + const evaluatedChild = (cat == VarCat.Local) + ? await this.miDebugger.evalCobField(childId) + : await this.miDebugger.evalGlobalCobField(childId); + // const evaluatedChild = await this.miDebugger.evalCobField(childId); value = evaluatedChild !== undefined ? (evaluatedChild.value || "null") : "?"; } @@ -529,14 +547,11 @@ export class GDBDebugSession extends DebugSession { variables: variables }; this.sendResponse(response); - } catch (err) { - this.sendErrorResponse(response, 1, `Could not expand variable: ${(err).toString()}`); + } else { + this.sendResponse(response); } - } else { - response.body = { - variables: [] - }; - this.sendResponse(response); + } catch (err) { + this.sendErrorResponse(response, 1, `Could not expand variable: ${(err).toString()}`); } } diff --git a/src/mi2-decoder.ts b/src/mi2-decoder.ts new file mode 100644 index 0000000..aa764a2 --- /dev/null +++ b/src/mi2-decoder.ts @@ -0,0 +1,19 @@ +import * as Debugger from './debugger'; +import {MINode} from './parser.mi2'; + +export function decodeFileSymbols(node: MINode): Debugger.FileSymbols { + return { + filename: MINode.valueOf(node, "filename"), + fullname: MINode.valueOf(node, "fullname"), + symbols: MINode.valueOf(node, "symbols").map(decodeSymbol), + } +} + +export function decodeSymbol(node: MINode): Debugger.Symbol { + return { + line: parseInt(MINode.valueOf(node, "line")), + name: MINode.valueOf(node, "name"), + type: MINode.valueOf(node, "type"), + description: MINode.valueOf(node, "description"), + } +} \ No newline at end of file diff --git a/src/mi2.ts b/src/mi2.ts index e10e065..df488e7 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -1,12 +1,14 @@ -import { Breakpoint, IDebugger, MIError, Stack, Thread, DebuggerVariable } from "./debugger"; +import { Breakpoint, IDebugger, MIError, Stack, Thread, DebuggerVariable, FileSymbols, Symbol } from "./debugger"; import * as ChildProcess from "child_process"; import { EventEmitter } from "events"; import { MINode, parseMI } from './parser.mi2'; +import * as MI2Decoder from './mi2-decoder'; import * as path from "path"; import * as fs from "fs"; import { SourceMap } from "./parser.c"; import { parseExpression, cleanRawValue } from "./functions"; import * as vscode from 'vscode'; +import {DebugProtocol} from '@vscode/debugprotocol'; import * as log from './log'; const nonOutput = /(^(?:\d*|undefined)[*+\-=~@&^])([^*+\-=~@&]+[a-zA-Z]+)/; @@ -527,37 +529,56 @@ export class MI2 extends EventEmitter implements IDebugger { }); } - async changeVariable(name: string, rawValue: string): Promise { + async changeVariable(name: string, rawValue: string): Promise> { log.debug("changeVariable"); - const functionName = await this.getCurrentFunctionName(); + try { + const v = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); + return this.setDebuggerVariable(v, rawValue); + } catch (e) { + this.log("stderr", `Failed to set cob field value on ${functionName}.${name}`); + this.log("stderr", (e).message); + throw e; + } + } - const cleanedRawValue = cleanRawValue(rawValue); - + async changeGlobalVariable(name: string, rawValue: string): Promise> { + log.debug("changeGobalVariable"); + const cobolName = name.toUpperCase(); try { - const variable = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); + const v = this.map.getGlobalByCobol(cobolName); + return this.setDebuggerVariable(v, rawValue); + } catch (e) { + this.log("stderr", `Failed to set cob field value on ${cobolName} (global)`); + this.log("stderr", (e).message); + throw e; + } + } - if (variable.attribute.type === "integer") { - await this.sendCommand(`gdb-set var ${variable.cName}=${cleanedRawValue}`); - } else if (this.hasCobPutFieldStringFunction && variable.cName.startsWith("f_")) { - await this.sendCommand(`data-evaluate-expression "(int)cob_put_field_str(&${variable.cName}, \\"${cleanedRawValue}\\")"`); + private async setDebuggerVariable(v: DebuggerVariable, rawValue: string) : Promise> { + const cleanedRawValue = cleanRawValue(rawValue); + try { + if (v.attribute.type === "integer") { + await this.sendCommand(`gdb-set var ${v.cName}=${cleanedRawValue}`); + } else if (this.hasCobPutFieldStringFunction && v.cName.startsWith("f_")) { + await this.sendCommand(`data-evaluate-expression "(int)cob_put_field_str(&${v.cName}, \\"${cleanedRawValue}\\")"`); } else { - const finalValue = variable.formatValue(cleanedRawValue); - let cName = variable.cName; - if (variable.cName.startsWith("f_")) { + const finalValue = v.formatValue(cleanedRawValue); + let cName = v.cName; + if (v.cName.startsWith("f_")) { cName += ".data"; } - await this.sendCommand(`data-evaluate-expression "(void)strncpy(${cName}, \\"${finalValue}\\", ${variable.size})"`); + await this.sendCommand(`data-evaluate-expression "(void)strncpy(${cName}, \\"${finalValue}\\", ${v.size})"`); } } catch (e) { if ((e).message.includes("No symbol \"cob_put_field_str\"")) { this.hasCobPutFieldStringFunction = false; - return this.changeVariable(name, rawValue); + return this.setDebuggerVariable(v, rawValue); } - this.log("stderr", `Failed to set cob field value on ${functionName}.${name}`); - this.log("stderr", (e).message); + this.log("stderr", `Failed to set cob field value on ${v.cName}`); throw e; } + return v.parent != null || v.hasChildren() ? ['variables'] : []; } loadBreakPoints(breakpoints: Breakpoint[]): Thenable<[boolean, Breakpoint][]> { @@ -746,6 +767,23 @@ export class MI2 extends EventEmitter implements IDebugger { }); } + async globalFileSymbols(nameFilterRegexp: string = null): Promise { + const nameFilterArg = nameFilterRegexp !== null + ? `--name "${nameFilterRegexp}"` + : ""; + const resp = await this.sendCommand(`symbol-info-variables ${nameFilterArg}`, + failure_handling.Silence); + if (resp?.resultRecords.resultClass !== "done") + return []; + return (resp.result("symbols.debug")).map(MI2Decoder.decodeFileSymbols); + } + + async evalSymbol(s: Symbol): Promise { + const v = this.map.getGlobalByC(s.name); + await this.updateVariable(v); + return v; + } + async getCurrentFunctionName(): Promise { log.debug("getCurrentFunctionName"); const response = await this.sendCommand("stack-info-frame", failure_handling.Silence); @@ -771,8 +809,6 @@ export class MI2 extends EventEmitter implements IDebugger { for (const element of variables) { const key = MINode.valueOf(element, "name"); const value = MINode.valueOf(element, "value"); - //console.log("Key="+key); - //console.log("Value="+value); if (key.startsWith("b_")) { const cobolVariable = this.map.getVariableByC(`${functionName}.${key}`); @@ -814,7 +850,7 @@ export class MI2 extends EventEmitter implements IDebugger { for (const variableName of variableNames) { const variable = this.map.getVariableByC(`${functionName}.${variableName}`); if (variable) { - await this.evalVariable(variable, thread, frame); + await this.updateVariable(variable, thread, frame); const value = variable.value; finalExpression = `const ${variableName}=${value};` + finalExpression; } @@ -829,7 +865,7 @@ export class MI2 extends EventEmitter implements IDebugger { } } - async evalCobField(name: string, thread: number, frame: number): Promise { + async evalCobField(name: string, thread: number = 0, frame: number = 0): Promise { log.debug("evalCobField", name); const functionName = await this.getCurrentFunctionName(); @@ -838,7 +874,8 @@ export class MI2 extends EventEmitter implements IDebugger { try { const variable = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); - return await this.evalVariable(variable, thread, frame); + await this.updateVariable(variable, thread, frame); + return variable; } catch (e) { this.log("stderr", `Failed to eval cob field value on ${functionName}.${name}`); this.log("stderr", e.message); @@ -846,8 +883,22 @@ export class MI2 extends EventEmitter implements IDebugger { } } - private async evalVariable(variable: DebuggerVariable, thread: number, frame: number): Promise { - log.debug("evalVariable", variable.cName); + async evalGlobalCobField(name: string): Promise { + log.debug("evalGlobalCobField", name); + + try { + const variable = this.map.getGlobalByCobol(name); + await this.updateVariable(variable); + return variable; + } catch (e) { + this.log("stderr", `Failed to eval cob field value on ${name}`); + this.log("stderr", e.message); + throw e; + } + } + + private async updateVariable(variable: DebuggerVariable, thread: number = 0, frame: number = 0): Promise { + log.debug("updateVariable", (() => `${variable.cName} (${variable.cobolName})`)); let command = "data-evaluate-expression "; if (thread != 0) { @@ -862,10 +913,9 @@ export class MI2 extends EventEmitter implements IDebugger { command += variable.cName; } - let dataResponse; let value = null; try { - dataResponse = await this.sendCommand(command, failure_handling.Silence); + let dataResponse = await this.sendCommand(command, failure_handling.Silence); if (dataResponse !== undefined) { value = dataResponse.result("value"); if (value === "0x0") { @@ -875,7 +925,8 @@ export class MI2 extends EventEmitter implements IDebugger { } catch (error) { if (error.message.includes("No symbol \"cob_get_field_str_buffered\"")) { this.hasCobGetFieldStringFunction = false; - return this.evalVariable(variable, thread, frame); + this.updateVariable(variable, thread, frame); + return; } this.log("stderr", error.message); } @@ -885,8 +936,6 @@ export class MI2 extends EventEmitter implements IDebugger { } else { variable.setValue(value); } - - return variable; } private logNoNewLine(type: string, msg: string): void { diff --git a/src/parser.c.ts b/src/parser.c.ts index 8c44337..f9dfb0a 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -30,8 +30,6 @@ const subroutineRegex = /\sPerform\s/i; const frame_ptrFindRegex = /frame\_ptr\-\-\;/; const fixOlderFormat = /cob\_trace\_stmt/; -globalThis.varOccurs = []; - function cobEncodeInvalidChars (s: string): string { // TODO: properly mimick `libcob:cob_encode_invalid_chars` // Meaning: Also replace any character in /[^a-zA-Z0-9-]/ into "_XX", where @@ -59,6 +57,9 @@ function lookupLineInCobolFile(fileCobol: string, lineCobol: number) : string | return undefined; } +const globalNamespace = "" +const globalNamespacePrefix = `${globalNamespace}.` + export class Line { endPerformLine: number; // 002 - stepOver in routines with "perform" public cobolLine: string | undefined; @@ -259,26 +260,28 @@ export class SourceMap { if (match[3].startsWith("[")) { size = parseInt(match[3].substring(1, match[3].length - 1)); } - const dataStorage = new DebuggerVariable(match[4], match[2], functionName, rootFileC, + const namespace = functionName ?? globalNamespace; + const dataStorage = new DebuggerVariable(match[4], match[2], namespace, rootFileC, new Attribute(null, VariableType[match[1]], 0, 0), size); - this.dataStorages.set(`${functionName}.${dataStorage.cName}`, dataStorage); - this.variablesByC.set(`${functionName}.${dataStorage.cName}`, dataStorage); - this.variablesByCobol.set(`${functionName}.${dataStorage.cobolName.toUpperCase()}`, dataStorage); + this.dataStorages.set(`${namespace}.${dataStorage.cName}`, dataStorage); + this.variablesByC.set(`${namespace}.${dataStorage.cName}`, dataStorage); + this.variablesByCobol.set(`${namespace}.${dataStorage.cobolName.toUpperCase()}`, dataStorage); } match = fieldRegex.exec(line); if (match) { + const namespace = functionName ?? globalNamespace; const attribute = this.attributes.get(`${cleanedFile}.${match[4]}`); - const dataStorage = this.dataStorages.get(`${functionName}.${match[3]}`); - const field = new DebuggerVariable(match[5], match[1], functionName, rootFileC, + const dataStorage = this.dataStorages.get(`${namespace}.${match[3]}`); + const field = new DebuggerVariable(match[5], match[1], namespace, rootFileC, attribute, parseInt(match[2])); - this.variablesByC.set(`${functionName}.${field.cName}`, field); + this.variablesByC.set(`${namespace}.${field.cName}`, field); if (dataStorage) { dataStorage.addChild(field); - this.variablesByCobol.set(`${functionName}.${dataStorage.cobolName.toUpperCase()}.${field.cobolName.toUpperCase()}`, field); + this.variablesByCobol.set(`${namespace}.${dataStorage.cobolName.toUpperCase()}.${field.cobolName.toUpperCase()}`, field); } else { - this.variablesByCobol.set(`${functionName}.${field.cobolName.toUpperCase()}`, field); + this.variablesByCobol.set(`${namespace}.${field.cobolName.toUpperCase()}`, field); } } match = fileIncludeRegex.exec(line); @@ -332,6 +335,25 @@ export class SourceMap { return null; } + public findGlobalByC(cName: string): DebuggerVariable { + for (const key of this.variablesByC.keys()) { + if (key.startsWith(globalNamespacePrefix) && key.endsWith(`.${cName}`)) { + return this.variablesByC.get(key); + } + } + return null; + } + + public globalCVariables() { + return Array.from(this.variablesByC.entries()) + .filter(([k,_]) => k.startsWith(globalNamespacePrefix)) + .map(([_,v]) => v); + } + + public getGlobalByC(varC: string): DebuggerVariable { + return this.getVariableByC(`${globalNamespacePrefix}${varC}`); + } + public getVariableByC(varC: string): DebuggerVariable { if (this.variablesByC.has(varC)) { return this.variablesByC.get(varC); @@ -352,6 +374,10 @@ export class SourceMap { return this.variablesByCobol.get(path); } + public getGlobalByCobol(name: string): DebuggerVariable { + return this.variablesByCobol.get(`${globalNamespacePrefix}${name}`); + } + public hasLineCobol(fileC: string, lineC: number): boolean { if(!fileC || !lineC) return false; if (!path.isAbsolute(fileC)) { diff --git a/test/resources/globals.c b/test/resources/globals.c new file mode 100644 index 0000000..55e6318 --- /dev/null +++ b/test/resources/globals.c @@ -0,0 +1,297 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from globals.cbl */ +/* Generated at Dec 05 2025 17:32:48 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -x -g globals.cbl */ + +#include /* for memcpy, memcmp and friends */ +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "globals.cbl" +#define COB_PACKAGE_VERSION "3.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "Dec 05 2025 17:32:48" +#define COB_MODULE_DATE 20251205 +#define COB_MODULE_TIME 173248 + +/* Global variables */ +#include "globals.c.h" + +/* Function prototypes */ + +static int globals (); +static int globals_ (const int); +static void globals_module_init (cob_module *module); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (globals ()); +} + +/* Functions */ + +static void gc_module_so_init () __attribute__ ((constructor)); +static void gc_module_so_init () +{ + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); +} + +/* PROGRAM-ID 'globals' */ + +/* ENTRY 'globals' */ + +static int +globals () +{ + return globals_ (0); +} + +static int +globals_ (const int entry) +{ + /* Program local variables */ + #include "globals.c.l.h" + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -10) + goto P_dump; + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + frame_ptr->return_address_ptr = &&P_cgerror; + frame_overflow = frame_ptr + 255 - 1; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 14 : Entry globals : globals.cbl */ + l_2:; +#line 14 "globals.cbl" + ENTRY_GLOBALS: cob_nop (); +#line 105 "globals.c" + + /* Line: 14 : MOVE : globals.cbl */ +#line 14 "globals.cbl" + cob_nop (); +#line 110 "globals.c" + *(b_18) = 51; + + /* Line: 15 : DISPLAY : globals.cbl */ +#line 15 "globals.cbl" + cob_nop (); +#line 116 "globals.c" + cob_display (0, 1, 1, &f_17); + + /* Line: 16 : DISPLAY : globals.cbl */ +#line 16 "globals.cbl" + cob_nop (); +#line 122 "globals.c" + cob_display (0, 1, 1, &f_19); + + /* Line: 17 : DISPLAY : globals.cbl */ +#line 17 "globals.cbl" + cob_nop (); +#line 128 "globals.c" + cob_display (0, 1, 1, &f_20); + + /* Line: 18 : DISPLAY : globals.cbl */ +#line 18 "globals.cbl" + cob_nop (); +#line 134 "globals.c" + cob_display (0, 1, 1, &f_22); + + /* Line: 19 : DISPLAY : globals.cbl */ +#line 19 "globals.cbl" + cob_nop (); +#line 140 "globals.c" + cob_display (0, 1, 1, &f_23); + + /* Line: 20 : DISPLAY : globals.cbl */ +#line 20 "globals.cbl" + cob_nop (); +#line 146 "globals.c" + cob_display (0, 1, 1, &f_24); + + /* Line: 21 : GOBACK : globals.cbl */ +#line 21 "globals.cbl" + cob_nop (); +#line 152 "globals.c" + goto exit_program; + + /* Program exit */ + + exit_program: + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + P_cgerror: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + globals_module_init (module); + + module->collating_sequence = NULL; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->xml_code = NULL; + module->xml_event = NULL; + module->xml_information = NULL; + module->xml_namespace = NULL; + module->xml_namespace_prefix = NULL; + module->xml_nnamespace = NULL; + module->xml_nnamespace_prefix = NULL; + module->xml_ntext = NULL; + module->xml_text = NULL; + module->json_code = NULL; + module->json_status = NULL; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + /* initialize field RETURN-CODE */ + b_2 = 0; + + /* initialize field FOO */ +#line 5 "globals.cbl" + cob_nop (); +#line 205 "globals.c" + memset (b_17, (unsigned char)'0', 3); + + /* initialize field BAR-1 */ +#line 7 "globals.cbl" + cob_nop (); +#line 211 "globals.c" + *(cob_u8_ptr)(b_18) = (unsigned char)'0'; + /* initialize field BAR-2 */ +#line 8 "globals.cbl" + cob_nop (); +#line 216 "globals.c" + memset (b_18 + 1, (unsigned char)' ', 3); + + /* initialize field BAZ-1 */ +#line 10 "globals.cbl" + cob_nop (); +#line 222 "globals.c" + *(cob_u8_ptr)(b_21) = (unsigned char)' '; + /* initialize field BAZ-2 */ +#line 11 "globals.cbl" + cob_nop (); +#line 227 "globals.c" + memset (b_21 + 1, 0x0, 2); + + /* initialize field FXX */ +#line 12 "globals.cbl" + cob_nop (); +#line 233 "globals.c" + memset (b_24, (unsigned char)'0', 3); + + + if (0 == 1) goto P_cgerror; + initialized = 1; + goto P_ret_initialize; + + P_dump: + return 0; + + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) + return 0; + if (module && module->module_active) + cob_fatal_error (COB_FERROR_CANCEL); + + initialized = 0; + + P_clear_decimal: + return 0; + +} + +/* End PROGRAM-ID 'globals' */ + +/* Initialize module structure for globals */ +static void globals_module_init (cob_module *module) +{ + module->module_name = "globals"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->gc_version = COB_PACKAGE_VERSION; + module->module_entry.funcptr = (void *(*)())globals; + module->module_cancel.funcptr = (void *(*)())globals_; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + module->flag_debug_trace = 0; + module->flag_dump_ready = 0; + module->xml_mode = 1; + module->module_stmt = 0; + module->module_sources = NULL; +} + +/* End functions */ + diff --git a/test/resources/globals.c.h b/test/resources/globals.c.h new file mode 100644 index 0000000..6f82c2a --- /dev/null +++ b/test/resources/globals.c.h @@ -0,0 +1,43 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from globals.cbl */ +/* Generated at Dec 05 2025 17:32:48 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -x -g globals.cbl */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Data storage */ + +/* PROGRAM-ID : globals */ +static cob_u8_t b_17[3] __attribute__((aligned)); /* FOO */ +static cob_u8_t b_18[4] __attribute__((aligned)); /* BAR */ + +/* End of data storage */ + + +/* Attributes */ + +static const cob_field_attr a_1 = {0x10, 3, 0, 0x0000, NULL}; +static const cob_field_attr a_2 = {0x10, 1, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_4 = {0x11, 4, 0, 0x0041, NULL}; + + +/* Fields */ + +/* PROGRAM-ID : globals */ +static cob_field f_17 = {3, b_17, &a_1}; /* FOO */ +static cob_field f_19 = {1, b_18, &a_2}; /* BAR-1 */ +static cob_field f_20 = {3, b_18 + 1, &a_3}; /* BAR-2 */ + +/* End of fields */ + + +#define cob_nop if (!module) cob_nop + diff --git a/test/resources/globals.c.l.h b/test/resources/globals.c.l.h new file mode 100644 index 0000000..9341ef6 --- /dev/null +++ b/test/resources/globals.c.l.h @@ -0,0 +1,52 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from globals.cbl */ +/* Generated at Dec 05 2025 17:32:48 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -x -g globals.cbl */ + +/* Program local variables for 'globals' */ + +/* Module initialization indicator */ +static unsigned int initialized = 0; + +/* Module structure pointer */ +static cob_module *module = NULL; + +/* Global variable pointer */ +cob_global *cob_glob_ptr; + + +/* LINKAGE SECTION (Items not referenced by USING clause) */ +static unsigned char *b_9 = NULL; /* XML-NAMESPACE */ +static unsigned char *b_10 = NULL; /* XML-NAMESPACE-PREFIX */ +static unsigned char *b_11 = NULL; /* XML-NNAMESPACE */ +static unsigned char *b_12 = NULL; /* XML-NNAMESPACE-PREFIX */ +static unsigned char *b_13 = NULL; /* XML-NTEXT */ +static unsigned char *b_14 = NULL; /* XML-TEXT */ + + +/* Call parameters */ +cob_field *cob_procedure_params[1]; + +/* Perform frame stack */ +struct cob_frame *frame_overflow; +struct cob_frame *frame_ptr; +struct cob_frame frame_stack[255]; + + +/* Data storage */ +static int b_2; /* RETURN-CODE */ +static cob_u8_t b_21[3] __attribute__((aligned)); /* BAZ */ +static cob_u8_t b_24[3] __attribute__((aligned)); /* FXX */ + +/* End of local data storage */ + + +/* Fields (local) */ +static cob_field f_22 = {1, b_21, &a_3}; /* BAZ-1 */ +static cob_field f_23 = {2, b_21 + 1, &a_4}; /* BAZ-2 */ +static cob_field f_24 = {3, b_24, &a_1}; /* FXX */ + +/* End of fields */ + diff --git a/test/resources/globals.cbl b/test/resources/globals.cbl new file mode 100644 index 0000000..4684fe6 --- /dev/null +++ b/test/resources/globals.cbl @@ -0,0 +1,21 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. globals. + DATA DIVISION. + WORKING-STORAGE SECTION. + 77 FOO PIC 999 GLOBAL. + 01 BAR GLOBAL. + 02 BAR-1 PIC 9. + 02 BAR-2 PIC XXX. + 01 BAZ. + 02 BAZ-1 PIC X. + 02 BAZ-2 BINARY-SHORT. + 77 FXX PIC 999. + PROCEDURE DIVISION. + MOVE 3 TO BAR-1 + DISPLAY FOO + DISPLAY BAR-1 + DISPLAY BAR-2 + DISPLAY BAZ-1 + DISPLAY BAZ-2 + DISPLAY FXX + GOBACK. diff --git a/test/resources/globals.i b/test/resources/globals.i new file mode 100644 index 0000000..8d59346 --- /dev/null +++ b/test/resources/globals.i @@ -0,0 +1,22 @@ +#line 1 "globals.cbl" + IDENTIFICATION DIVISION. + PROGRAM-ID. globals. + DATA DIVISION. + WORKING-STORAGE SECTION. + 77 FOO PIC 999 GLOBAL. + 01 BAR GLOBAL. + 02 BAR-1 PIC 9. + 02 BAR-2 PIC XXX. + 01 BAZ. + 02 BAZ-1 PIC X. + 02 BAZ-2 BINARY-SHORT. + 77 FXX PIC 999. + PROCEDURE DIVISION. + MOVE 3 TO BAR-1 + DISPLAY FOO + DISPLAY BAR-1 + DISPLAY BAR-2 + DISPLAY BAZ-1 + DISPLAY BAZ-2 + DISPLAY FXX + GOBACK. diff --git a/test/suite/parser.c.test.ts b/test/suite/parser.c.test.ts index e8f9b61..a70679b 100644 --- a/test/suite/parser.c.test.ts +++ b/test/suite/parser.c.test.ts @@ -132,7 +132,6 @@ suite("C code parse", () => { const cDirs = nativePath.resolve(srcDirs, 'c'); const cblDirs = nativePath.resolve(srcDirs, 'cbl'); const parsed = new SourceMap(cwd, ['subsubsample.cbl'], [cDirs, cblDirs]); - console.log (parsed.toString()); assert.equal(1, parsed.getLinesCount()); assert.equal(3, parsed.getVariablesCount()); @@ -144,4 +143,20 @@ suite("C code parse", () => { assert.equal(alnumGroup_.cobolName, alnumGroup.cobolName); assert.equal(alnumGroup_.rootFileC, alnumGroup.rootFileC); }); + test("Globals", () => { + const parsed = new SourceMap(cwd, ['globals.cbl']); + + assert.equal(6, parsed.getLinesCount()); + assert.equal(8, parsed.getVariablesCount()); + console.log(parsed.toString()); + + const fooVar = parsed.getGlobalByCobol('FOO'); + assert.equal('FOO', fooVar.cobolName); + assert.equal('FOO', parsed.getGlobalByC(fooVar.cName).cobolName); + const barVar = parsed.getGlobalByCobol('BAR'); + assert.equal(4, barVar.size); + const bar1Var = parsed.getGlobalByCobol('BAR.BAR-2'); + assert.equal(3, bar1Var.size); + assert.equal('alphanumeric', bar1Var.displayableType); + }); }); From 6a24b0a2ee0911314dcf9adad882c108253d9b47 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 8 Dec 2025 15:29:02 +0100 Subject: [PATCH 69/70] Test conflicting globals --- .vscode/launch.json | 3 +- src/debugger.ts | 39 ++++-- src/gdb.ts | 157 +++++++++++++---------- src/mi2.ts | 65 ++++++---- src/parser.c.ts | 47 ++++--- test/resources/globals.c | 43 ++++--- test/resources/globals.c.h | 12 +- test/resources/globals.c.l.h | 9 +- test/resources/globals.cbl | 3 +- test/resources/globals.i | 3 +- test/resources/globals2.c | 232 ++++++++++++++++++++++++++++++++++ test/resources/globals2.c.h | 37 ++++++ test/resources/globals2.c.l.h | 42 ++++++ test/resources/globals2.cbl | 9 ++ test/resources/globals2.i | 10 ++ test/suite/parser.c.test.ts | 29 +++-- 16 files changed, 581 insertions(+), 159 deletions(-) create mode 100644 test/resources/globals2.c create mode 100644 test/resources/globals2.c.h create mode 100644 test/resources/globals2.c.l.h create mode 100644 test/resources/globals2.cbl create mode 100644 test/resources/globals2.i diff --git a/.vscode/launch.json b/.vscode/launch.json index 08d0d29..29f7d4f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,7 +19,8 @@ "autoAttachChildProcesses": true, "sourceMaps": true, "outFiles": [ - "${workspaceFolder}/out/**/*.js" + "${workspaceFolder}/**/*.(m|c|)js", + "!**/node_modules/**" ], "preLaunchTask": "npm" }, diff --git a/src/debugger.ts b/src/debugger.ts index 12da206..7223b77 100644 --- a/src/debugger.ts +++ b/src/debugger.ts @@ -36,6 +36,17 @@ export interface Symbol { description: string; } +export interface LocalizedSymbol { + symbol: Symbol; + filename: string; +} + +export function localizeSymbols(fileSymbols: FileSymbols): LocalizedSymbol[] { + return fileSymbols.symbols.map(s => { + return { symbol: s, filename: fileSymbols.filename } + }); +} + const repeatTimeRegex = /(\"\,\s|^)\'(\s|0)\'\s\/i; export class CobolFieldDataParser { @@ -408,19 +419,20 @@ export class Attribute { export class DebuggerVariable { - public displayableType: string; - public details: VariableDetail[]; + public readonly displayableType: string; + public readonly details: VariableDetail[]; public constructor( - public cobolName: string, - public cName: string, - public functionName: string, - public rootFileC: string, - public attribute: Attribute = null, - public size: number = null, + public readonly cobolName: string, + public readonly cName: string, + public readonly functionName: string, + public readonly rootFileC: string, + public readonly isField: boolean, + public readonly attribute: Attribute = null, + public readonly size: number = null, public value: string = null, public parent: DebuggerVariable = null, - public children: Map = new Map()) { + public readonly children: Map = new Map()) { [this.displayableType, this.details] = this.attribute.getDetails(this.size); } @@ -512,17 +524,16 @@ export interface IDebugger { getStackVariables(thread: number, frame: number): Thenable; - globalFileSymbols(nameFilterRegexp?: string): Thenable; + globalStorageSymbols(): Thenable; + + evalSymbol(s: LocalizedSymbol): Promise; - evalSymbol(s: Symbol): Promise; evalExpression(name: string, thread: number, frame: number): Promise; - evalCobField(name: string, thread: number, frame: number): Promise; - evalGlobalCobField(name: string): Promise; isReady(): boolean; changeVariable(name: string, rawValue: string): Promise>; - changeGlobalVariable(name: string, rawValue: string): Promise>; + changeGlobalCVariable(cName: string, rawValue: string): Promise>; examineMemory(from: number, to: number): Thenable; diff --git a/src/gdb.ts b/src/gdb.ts index ff18ba1..c8b778e 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -13,7 +13,7 @@ import { ThreadEvent } from '@vscode/debugadapter'; import {DebugProtocol} from '@vscode/debugprotocol'; -import {Breakpoint, DebuggerVariable, FileSymbols, Symbol, VariableObject} from './debugger'; +import {Breakpoint, DebuggerVariable, localizeSymbols} from './debugger'; import {MINode} from './parser.mi2'; import * as path from "path"; import {MI2} from './mi2'; @@ -29,6 +29,11 @@ class ExtendedVariable { } } +function stripPathExtensions(p1: string) { + const p2 = path.basename(p1, path.extname(p1)); + return (p2 === p1) ? p1 : stripPathExtensions(p2); +} + export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments { cwd: string | null; target: string; @@ -79,6 +84,7 @@ export class GDBDebugSession extends DebugSession { protected miDebugger: MI2; coverageStatus: CoverageStatus; private showCoverage: boolean = true; + private readonly showDetails = settings.displayVariableAttributes; protected initializeRequest(response: DebugProtocol.InitializeResponse, _args: DebugProtocol.InitializeRequestArguments): void { response.body.supportsSetVariable = true; @@ -256,33 +262,6 @@ export class GDBDebugSession extends DebugSession { this.sendResponse(response); } - protected async setVariableRequest(response: DebugProtocol.SetVariableResponse, args: DebugProtocol.SetVariableArguments): Promise { - const showDetails = settings.displayVariableAttributes; - const [id, cat] = this.lookupVariable(args.variablesReference); - try { - let name = args.name; - if (typeof id == "string") { - name = `${id}.${args.name}`; - if (showDetails && args.name === "value") { - name = id; - } - } - if (!showDetails || args.name === "value") { - const invalidatedAreas = (cat == VarCat.Global) ? - await this.miDebugger.changeGlobalVariable(name, args.value) : - await this.miDebugger.changeVariable(name, args.value); - response.body = { value: args.value }; - if (invalidatedAreas.length > 0) { - // Trigger an update of invalidated areas. - this.sendEvent(new DebugAdapter.InvalidatedEvent(invalidatedAreas)); - } - } - this.sendResponse(response); - } catch (err) { - this.sendErrorResponse(response, 11, `Could not continue: ${err}`); - } - } - protected setFunctionBreakPointsRequest(response: DebugProtocol.SetFunctionBreakpointsResponse, args: DebugProtocol.SetFunctionBreakpointsArguments): void { const cb = () => { this.debugReady = true; @@ -421,28 +400,35 @@ export class GDBDebugSession extends DebugSession { } // TODO: invalidate on some operations? - private globalSymbols: Symbol[] = []; + private globalVariables: Map> = new Map(); - protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void { + protected async scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments) { const scopes = [ new Scope("Local", STACK_HANDLES_START + args.frameId, false) ]; - this.miDebugger.globalFileSymbols("^b_[0-9]*$").then(globalsFileSymbols => { - this.globalSymbols = globalsFileSymbols.flatMap(fileSymbols => fileSymbols.symbols); - if (this.globalSymbols.length > 0) { - scopes.push(new Scope("Globals", 1, false)); + const filesSymbols = await this.miDebugger.globalStorageSymbols(); + this.globalVariables.clear(); + await Promise.all(filesSymbols.flatMap(fileSymbols => { + if (fileSymbols.symbols.length > 0) { + const base = stripPathExtensions(fileSymbols.filename); + const scopeId = scopes.length; + const scopeVariables = localizeSymbols(fileSymbols).map(s => this.miDebugger.evalSymbol(s)); + this.globalVariables.set(scopeId, Promise.all(scopeVariables)); + scopes.push(new Scope(`Globals (${base})`, scopeId, false)); + return scopeVariables; + } else { + return []; } - response.body = { scopes: scopes }; - this.sendResponse(response); - }); + })); + response.body = { scopes: scopes }; + this.sendResponse(response); } private debugProtocolVariable(dv: DebuggerVariable, varCat: VarCat) : DebugProtocol.Variable { - const showDetails = settings.displayVariableAttributes; - const reference = (showDetails || !!dv.children.size) - ? this.variableHandles.create([dv.cobolName, varCat]) + const reference = (this.showDetails || !!dv.children.size) + ? this.variableHandles.create([dv.cName, varCat]) : 0; - const value = showDetails + const value = this.showDetails ? `${dv.value || "null"} (${dv.displayableType})` : dv.value || "null"; return { @@ -454,15 +440,12 @@ export class GDBDebugSession extends DebugSession { }; } - private async globalVariableRequest(response: DebugProtocol.VariablesResponse) : Promise { - Promise - .all(this.globalSymbols.map(s => this.miDebugger.evalSymbol(s))) - .then(debuggerVariables => - debuggerVariables.map(v => this.debugProtocolVariable(v, VarCat.Global))) - .then(variables => { - response.body = { variables: variables }; - this.sendResponse(response); - }); + private async globalVariableRequest(response: DebugProtocol.VariablesResponse, scopeId: number): Promise { + const scopeVariables = await this.globalVariables.get(scopeId); + response.body = { + variables: scopeVariables.map(v => this.debugProtocolVariable(v, VarCat.Global)) + }; + this.sendResponse(response); } private async stackVariableRequest(response: DebugProtocol.VariablesResponse, id: number) : Promise { @@ -492,46 +475,41 @@ export class GDBDebugSession extends DebugSession { } protected async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise { - const showDetails = settings.displayVariableAttributes; const [id, cat] = this.lookupVariable(args.variablesReference); + response.body = { variables: [] }; try { - response.body = { variables: [] }; if (typeof id == "number") { if (cat == VarCat.Local) { - log.info('stack:', id.toString()); this.stackVariableRequest(response, id); } else { - log.info('global:', id.toString()); - this.globalVariableRequest(response); + this.globalVariableRequest(response, id); } } else if (typeof id == "string") { // TODO: this evals on an (effectively) unknown thread for multithreaded programs. - const stackVariable = (cat == VarCat.Local) - ? await this.miDebugger.evalCobField(id) - : await this.miDebugger.evalGlobalCobField(id); - if (stackVariable === undefined) { + const v = (cat == VarCat.Local) + ? await this.miDebugger.evalCVariable(id) + : await this.miDebugger.evalCGlobal(id); + if (v === undefined) { this.sendResponse(response); // fail early and silently } let variables: DebugProtocol.Variable[] = []; - if (showDetails) { - variables = stackVariable.toDebugProtocolVariable(showDetails); + if (this.showDetails) { + variables = v.toDebugProtocolVariable(this.showDetails); } - for (const child of stackVariable.children.values()) { - const childId = `${id}.${child.cobolName}`; + for (const child of v.children.values()) { let reference = 0; - if (showDetails || !!child.children.size) { - reference = this.variableHandles.create([childId, cat]); + if (this.showDetails || !!child.children.size) { + reference = this.variableHandles.create([`${child.cName}`, cat]); } let value = child.displayableType; - if (!showDetails) { + if (!this.showDetails) { const evaluatedChild = (cat == VarCat.Local) - ? await this.miDebugger.evalCobField(childId) - : await this.miDebugger.evalGlobalCobField(childId); - // const evaluatedChild = await this.miDebugger.evalCobField(childId); + ? await this.miDebugger.evalCVariable(child.cName) + : await this.miDebugger.evalCGlobal(child.cName); value = evaluatedChild !== undefined ? (evaluatedChild.value || "null") : "?"; } @@ -555,6 +533,47 @@ export class GDBDebugSession extends DebugSession { } } + protected async setVariableRequest(response: DebugProtocol.SetVariableResponse, args: DebugProtocol.SetVariableArguments): Promise { + const [id, cat] = this.lookupVariable(args.variablesReference); + let invalidatedAreas = []; + if (this.showDetails && args.name !== "value") { + this.sendErrorResponse(response, 14, `${args.name} cannot be changed`); + return; + } + const editDetails = this.showDetails && args.name === "value"; + // log.debug("setVartiableRequest", args.name, args.value, args.variablesReference.toString(), id.toString()); + try { + if (cat == VarCat.Local) { + invalidatedAreas = editDetails && typeof id == "string" + ? await this.miDebugger.changeCVariable(id.toString(), args.value) + : await this.miDebugger.changeVariable(args.name, args.value); + response.body = { value: args.value }; + } else if (cat == VarCat.Global) { + let cName: string = null; + if (typeof id == "number") { + // TODO: can we be editing "value" details (ie. can showDetails hold here)? + const vars = await this.globalVariables.get(id); + cName = vars.find(v => v.cobolName == args.name)?.cName; // TODO: check ambiguous item names? + } else if (typeof id == "string" && !editDetails) { + cName = this.miDebugger.lookupGlobalCobolByCName(args.name, id)?.cName; + } else if (typeof id == "string") { + cName = id; + } + if (cName !== null) { + invalidatedAreas = await this.miDebugger.changeGlobalCVariable(cName, args.value); + response.body = { value: args.value }; + } + } + if (invalidatedAreas.length > 0) { + // Trigger an update of invalidated areas. + this.sendEvent(new DebugAdapter.InvalidatedEvent(invalidatedAreas)); + } + this.sendResponse(response); + } catch (err) { + this.sendErrorResponse(response, 11, `Could not set ${args.name}: ${err}`); + } + } + protected pauseRequest(response: DebugProtocol.ContinueResponse, _args: DebugProtocol.ContinueArguments): void { this.miDebugger.interrupt().then(_done => { this.sendResponse(response); diff --git a/src/mi2.ts b/src/mi2.ts index df488e7..b15d043 100644 --- a/src/mi2.ts +++ b/src/mi2.ts @@ -1,4 +1,4 @@ -import { Breakpoint, IDebugger, MIError, Stack, Thread, DebuggerVariable, FileSymbols, Symbol } from "./debugger"; +import { Breakpoint, IDebugger, MIError, Stack, Thread, DebuggerVariable, FileSymbols, LocalizedSymbol } from "./debugger"; import * as ChildProcess from "child_process"; import { EventEmitter } from "events"; import { MINode, parseMI } from './parser.mi2'; @@ -533,7 +533,7 @@ export class MI2 extends EventEmitter implements IDebugger { log.debug("changeVariable"); const functionName = await this.getCurrentFunctionName(); try { - const v = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); + const v = this.map.findVariableByCobol(functionName, name); return this.setDebuggerVariable(v, rawValue); } catch (e) { this.log("stderr", `Failed to set cob field value on ${functionName}.${name}`); @@ -542,14 +542,26 @@ export class MI2 extends EventEmitter implements IDebugger { } } - async changeGlobalVariable(name: string, rawValue: string): Promise> { + async changeCVariable(cName: string, rawValue: string): Promise> { + log.debug("changeCVariable"); + const functionName = await this.getCurrentFunctionName(); + try { + const v = this.map.findVariableByC(functionName, cName); + return this.setDebuggerVariable(v, rawValue); + } catch (e) { + this.log("stderr", `Failed to set cob field value on ${functionName}.${cName}`); + this.log("stderr", (e).message); + throw e; + } + } + + async changeGlobalCVariable(cName: string, rawValue: string): Promise> { log.debug("changeGobalVariable"); - const cobolName = name.toUpperCase(); try { - const v = this.map.getGlobalByCobol(cobolName); + const v = this.map.findGlobalByC(cName); return this.setDebuggerVariable(v, rawValue); } catch (e) { - this.log("stderr", `Failed to set cob field value on ${cobolName} (global)`); + this.log("stderr", `Failed to set cob field value on ${cName} (global)`); this.log("stderr", (e).message); throw e; } @@ -560,12 +572,12 @@ export class MI2 extends EventEmitter implements IDebugger { try { if (v.attribute.type === "integer") { await this.sendCommand(`gdb-set var ${v.cName}=${cleanedRawValue}`); - } else if (this.hasCobPutFieldStringFunction && v.cName.startsWith("f_")) { + } else if (this.hasCobPutFieldStringFunction && v.isField) { await this.sendCommand(`data-evaluate-expression "(int)cob_put_field_str(&${v.cName}, \\"${cleanedRawValue}\\")"`); } else { const finalValue = v.formatValue(cleanedRawValue); let cName = v.cName; - if (v.cName.startsWith("f_")) { + if (v.isField) { cName += ".data"; } await this.sendCommand(`data-evaluate-expression "(void)strncpy(${cName}, \\"${finalValue}\\", ${v.size})"`); @@ -767,23 +779,26 @@ export class MI2 extends EventEmitter implements IDebugger { }); } - async globalFileSymbols(nameFilterRegexp: string = null): Promise { - const nameFilterArg = nameFilterRegexp !== null - ? `--name "${nameFilterRegexp}"` - : ""; - const resp = await this.sendCommand(`symbol-info-variables ${nameFilterArg}`, + async globalStorageSymbols(): Promise { + const resp = await this.sendCommand(`symbol-info-variables --name "^b_[0-9]*$"`, failure_handling.Silence); if (resp?.resultRecords.resultClass !== "done") return []; return (resp.result("symbols.debug")).map(MI2Decoder.decodeFileSymbols); } - async evalSymbol(s: Symbol): Promise { - const v = this.map.getGlobalByC(s.name); + async evalSymbol(s: LocalizedSymbol): Promise { + const v = this.map.getGlobalByC(s.filename, s.symbol.name); await this.updateVariable(v); return v; } + public lookupGlobalCobolByCName(cobolName: string, cName: string): DebuggerVariable { + const cFileMatch = /^'([^']+)'::.*$/.exec(cName); + let cFile = cFileMatch ? cFileMatch[1] : undefined; + return this.map.findGlobalByCobol(cobolName, cFile); + } + async getCurrentFunctionName(): Promise { log.debug("getCurrentFunctionName"); const response = await this.sendCommand("stack-info-frame", failure_handling.Silence); @@ -810,7 +825,7 @@ export class MI2 extends EventEmitter implements IDebugger { const key = MINode.valueOf(element, "name"); const value = MINode.valueOf(element, "value"); - if (key.startsWith("b_")) { + if (key.startsWith("b_")) { // ok for stack variables const cobolVariable = this.map.getVariableByC(`${functionName}.${key}`); if (cobolVariable) { @@ -865,15 +880,15 @@ export class MI2 extends EventEmitter implements IDebugger { } } - async evalCobField(name: string, thread: number = 0, frame: number = 0): Promise { - log.debug("evalCobField", name); + async evalCVariable(cName: string, thread: number = 0, frame: number = 0): Promise { + log.debug("evalCVariable", cName); const functionName = await this.getCurrentFunctionName(); if (functionName === undefined) return; try { - const variable = this.map.getVariableByCobol(`${functionName}.${name.toUpperCase()}`); + const variable = this.map.findVariableByC(functionName, cName); await this.updateVariable(variable, thread, frame); return variable; } catch (e) { @@ -883,15 +898,15 @@ export class MI2 extends EventEmitter implements IDebugger { } } - async evalGlobalCobField(name: string): Promise { - log.debug("evalGlobalCobField", name); + async evalCGlobal(cName: string): Promise { + log.debug("evalCGlobal", cName); try { - const variable = this.map.getGlobalByCobol(name); + const variable = this.map.findGlobalByC(cName); await this.updateVariable(variable); return variable; } catch (e) { - this.log("stderr", `Failed to eval cob field value on ${name}`); + this.log("stderr", `Failed to eval cob field value on ${cName}`); this.log("stderr", e.message); throw e; } @@ -905,9 +920,9 @@ export class MI2 extends EventEmitter implements IDebugger { command += `--thread ${thread} --frame ${frame} `; } - if (this.hasCobGetFieldStringFunction && variable.cName.startsWith("f_")) { + if (this.hasCobGetFieldStringFunction && variable.isField) { command += `"(char *)cob_get_field_str_buffered(&${variable.cName})"`; - } else if (variable.cName.startsWith("f_")) { + } else if (variable.isField) { command += `${variable.cName}.data`; } else { command += variable.cName; diff --git a/src/parser.c.ts b/src/parser.c.ts index f9dfb0a..ffe1bef 100644 --- a/src/parser.c.ts +++ b/src/parser.c.ts @@ -260,29 +260,38 @@ export class SourceMap { if (match[3].startsWith("[")) { size = parseInt(match[3].substring(1, match[3].length - 1)); } + const global = functionName === undefined; const namespace = functionName ?? globalNamespace; - const dataStorage = new DebuggerVariable(match[4], match[2], namespace, rootFileC, - new Attribute(null, VariableType[match[1]], 0, 0), size); + const cName = global ? `'${fileC}'::${match[2]}` : match[2]; + const cobolName = match[4]; + const cobolNAME = cobolName.toUpperCase(); + const dataStorage = new DebuggerVariable(cobolName, cName, namespace, rootFileC, false, new Attribute(null, VariableType[match[1]], 0, 0), size); this.dataStorages.set(`${namespace}.${dataStorage.cName}`, dataStorage); this.variablesByC.set(`${namespace}.${dataStorage.cName}`, dataStorage); - this.variablesByCobol.set(`${namespace}.${dataStorage.cobolName.toUpperCase()}`, dataStorage); + const fullCobolName = global ? `'${fileC}'.${cobolNAME}` : cobolNAME; + this.variablesByCobol.set(`${namespace}.${fullCobolName}`, dataStorage); } match = fieldRegex.exec(line); if (match) { + const global = functionName === undefined; const namespace = functionName ?? globalNamespace; + const cName = global ? `'${fileC}'::${match[1]}` : match[1]; + const cRecord = global ? `'${fileC}'::${match[3]}` : match[3]; const attribute = this.attributes.get(`${cleanedFile}.${match[4]}`); - const dataStorage = this.dataStorages.get(`${namespace}.${match[3]}`); - const field = new DebuggerVariable(match[5], match[1], namespace, rootFileC, - attribute, parseInt(match[2])); + const dataStorage = this.dataStorages.get(`${namespace}.${cRecord}`); + const cobolName = match[5]; + const field = new DebuggerVariable(cobolName, cName, namespace, rootFileC, true, attribute, parseInt(match[2])); this.variablesByC.set(`${namespace}.${field.cName}`, field); + let storageKey = namespace; if (dataStorage) { dataStorage.addChild(field); - this.variablesByCobol.set(`${namespace}.${dataStorage.cobolName.toUpperCase()}.${field.cobolName.toUpperCase()}`, field); - } else { - this.variablesByCobol.set(`${namespace}.${field.cobolName.toUpperCase()}`, field); + const cobolNAME = dataStorage.cobolName.toUpperCase(); + const fullCobolStorage = global ? `'${fileC}'.${cobolNAME}` : cobolNAME; + storageKey = `${namespace}.${fullCobolStorage}`; } + this.variablesByCobol.set(`${storageKey}.${field.cobolName.toUpperCase()}`, field); } match = fileIncludeRegex.exec(line); if (match) { @@ -350,8 +359,8 @@ export class SourceMap { .map(([_,v]) => v); } - public getGlobalByC(varC: string): DebuggerVariable { - return this.getVariableByC(`${globalNamespacePrefix}${varC}`); + public getGlobalByC(fileC: string, varC: string): DebuggerVariable { + return this.getVariableByC(`${globalNamespacePrefix}'${fileC}'::${varC}`); } public getVariableByC(varC: string): DebuggerVariable { @@ -370,12 +379,20 @@ export class SourceMap { return null; } - public getVariableByCobol(path: string): DebuggerVariable { - return this.variablesByCobol.get(path); + public findGlobalByCobol(name: string, cFile: string = undefined): DebuggerVariable { + const prefix = cFile === undefined + ? globalNamespacePrefix + : `${globalNamespacePrefix}'${cFile}'.`; + for (const key of this.variablesByCobol.keys()) { + if (key.startsWith(prefix) && key.endsWith(`.${name.toUpperCase()}`)) { + return this.variablesByCobol.get(key); + } + } + return null; } - public getGlobalByCobol(name: string): DebuggerVariable { - return this.variablesByCobol.get(`${globalNamespacePrefix}${name}`); + public getVariableByCobol(path: string): DebuggerVariable { + return this.variablesByCobol.get(path); } public hasLineCobol(fileC: string, lineC: number): boolean { diff --git a/test/resources/globals.c b/test/resources/globals.c index 55e6318..c3bfcd0 100644 --- a/test/resources/globals.c +++ b/test/resources/globals.c @@ -1,6 +1,6 @@ /* Generated by cobc 3.2.0 */ /* Generated from globals.cbl */ -/* Generated at Dec 05 2025 17:32:48 */ +/* Generated at Dec 09 2025 15:02:41 */ /* GnuCOBOL build date Sep 23 2025 17:57:37 */ /* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ /* Compile command cobc -x -g globals.cbl */ @@ -12,9 +12,9 @@ #define COB_SOURCE_FILE "globals.cbl" #define COB_PACKAGE_VERSION "3.2" #define COB_PATCH_LEVEL 0 -#define COB_MODULE_FORMATTED_DATE "Dec 05 2025 17:32:48" -#define COB_MODULE_DATE 20251205 -#define COB_MODULE_TIME 173248 +#define COB_MODULE_FORMATTED_DATE "Dec 09 2025 15:02:41" +#define COB_MODULE_DATE 20251209 +#define COB_MODULE_TIME 150241 /* Global variables */ #include "globals.c.h" @@ -119,25 +119,25 @@ globals_ (const int entry) #line 16 "globals.cbl" cob_nop (); #line 122 "globals.c" - cob_display (0, 1, 1, &f_19); + cob_display (0, 1, 1, &f_23); /* Line: 17 : DISPLAY : globals.cbl */ #line 17 "globals.cbl" cob_nop (); #line 128 "globals.c" - cob_display (0, 1, 1, &f_20); + cob_display (0, 1, 1, &f_19); /* Line: 18 : DISPLAY : globals.cbl */ #line 18 "globals.cbl" cob_nop (); #line 134 "globals.c" - cob_display (0, 1, 1, &f_22); + cob_display (0, 1, 1, &f_20); /* Line: 19 : DISPLAY : globals.cbl */ #line 19 "globals.cbl" cob_nop (); #line 140 "globals.c" - cob_display (0, 1, 1, &f_23); + cob_display (0, 1, 1, &f_22); /* Line: 20 : DISPLAY : globals.cbl */ #line 20 "globals.cbl" @@ -145,10 +145,23 @@ globals_ (const int entry) #line 146 "globals.c" cob_display (0, 1, 1, &f_24); - /* Line: 21 : GOBACK : globals.cbl */ + /* Line: 21 : CALL : globals.cbl */ #line 21 "globals.cbl" cob_nop (); #line 152 "globals.c" + cob_glob_ptr->cob_call_params = 0; + cob_glob_ptr->cob_stmt_exception = 0; + if (unlikely((cob_glob_ptr->cob_exception_code & 0x0b00) == 0x0b00)) cob_glob_ptr->cob_exception_code = 0; + if (unlikely(call_globals2.funcvoid == NULL || cob_glob_ptr->cob_physical_cancel == 1)) + { + call_globals2.funcvoid = cob_resolve_cobol ("globals2", 0, 1); + } + b_2 = ((int (*)(void))call_globals2.funcint) (); + + /* Line: 22 : GOBACK : globals.cbl */ +#line 22 "globals.cbl" + cob_nop (); +#line 165 "globals.c" goto exit_program; /* Program exit */ @@ -201,35 +214,35 @@ globals_ (const int entry) /* initialize field FOO */ #line 5 "globals.cbl" cob_nop (); -#line 205 "globals.c" +#line 218 "globals.c" memset (b_17, (unsigned char)'0', 3); /* initialize field BAR-1 */ #line 7 "globals.cbl" cob_nop (); -#line 211 "globals.c" +#line 224 "globals.c" *(cob_u8_ptr)(b_18) = (unsigned char)'0'; /* initialize field BAR-2 */ #line 8 "globals.cbl" cob_nop (); -#line 216 "globals.c" +#line 229 "globals.c" memset (b_18 + 1, (unsigned char)' ', 3); /* initialize field BAZ-1 */ #line 10 "globals.cbl" cob_nop (); -#line 222 "globals.c" +#line 235 "globals.c" *(cob_u8_ptr)(b_21) = (unsigned char)' '; /* initialize field BAZ-2 */ #line 11 "globals.cbl" cob_nop (); -#line 227 "globals.c" +#line 240 "globals.c" memset (b_21 + 1, 0x0, 2); /* initialize field FXX */ #line 12 "globals.cbl" cob_nop (); -#line 233 "globals.c" +#line 246 "globals.c" memset (b_24, (unsigned char)'0', 3); diff --git a/test/resources/globals.c.h b/test/resources/globals.c.h index 6f82c2a..b970dee 100644 --- a/test/resources/globals.c.h +++ b/test/resources/globals.c.h @@ -1,6 +1,6 @@ /* Generated by cobc 3.2.0 */ /* Generated from globals.cbl */ -/* Generated at Dec 05 2025 17:32:48 */ +/* Generated at Dec 09 2025 15:02:41 */ /* GnuCOBOL build date Sep 23 2025 17:57:37 */ /* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ /* Compile command cobc -x -g globals.cbl */ @@ -24,17 +24,17 @@ static cob_u8_t b_18[4] __attribute__((aligned)); /* BAR */ /* Attributes */ static const cob_field_attr a_1 = {0x10, 3, 0, 0x0000, NULL}; -static const cob_field_attr a_2 = {0x10, 1, 0, 0x0000, NULL}; -static const cob_field_attr a_3 = {0x21, 0, 0, 0x0000, NULL}; -static const cob_field_attr a_4 = {0x11, 4, 0, 0x0041, NULL}; +static const cob_field_attr a_2 = {0x11, 4, 0, 0x0041, NULL}; +static const cob_field_attr a_3 = {0x10, 1, 0, 0x0000, NULL}; +static const cob_field_attr a_4 = {0x21, 0, 0, 0x0000, NULL}; /* Fields */ /* PROGRAM-ID : globals */ static cob_field f_17 = {3, b_17, &a_1}; /* FOO */ -static cob_field f_19 = {1, b_18, &a_2}; /* BAR-1 */ -static cob_field f_20 = {3, b_18 + 1, &a_3}; /* BAR-2 */ +static cob_field f_19 = {1, b_18, &a_3}; /* BAR-1 */ +static cob_field f_20 = {3, b_18 + 1, &a_4}; /* BAR-2 */ /* End of fields */ diff --git a/test/resources/globals.c.l.h b/test/resources/globals.c.l.h index 9341ef6..aa2b927 100644 --- a/test/resources/globals.c.l.h +++ b/test/resources/globals.c.l.h @@ -1,6 +1,6 @@ /* Generated by cobc 3.2.0 */ /* Generated from globals.cbl */ -/* Generated at Dec 05 2025 17:32:48 */ +/* Generated at Dec 09 2025 15:02:41 */ /* GnuCOBOL build date Sep 23 2025 17:57:37 */ /* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ /* Compile command cobc -x -g globals.cbl */ @@ -26,6 +26,9 @@ static unsigned char *b_13 = NULL; /* XML-NTEXT */ static unsigned char *b_14 = NULL; /* XML-TEXT */ +/* Call pointers */ +static cob_call_union call_globals2; + /* Call parameters */ cob_field *cob_procedure_params[1]; @@ -44,8 +47,8 @@ static cob_u8_t b_24[3] __attribute__((aligned)); /* FXX */ /* Fields (local) */ -static cob_field f_22 = {1, b_21, &a_3}; /* BAZ-1 */ -static cob_field f_23 = {2, b_21 + 1, &a_4}; /* BAZ-2 */ +static cob_field f_22 = {1, b_21, &a_4}; /* BAZ-1 */ +static cob_field f_23 = {2, b_21 + 1, &a_2}; /* BAZ-2 */ static cob_field f_24 = {3, b_24, &a_1}; /* FXX */ /* End of fields */ diff --git a/test/resources/globals.cbl b/test/resources/globals.cbl index 4684fe6..1369f6b 100644 --- a/test/resources/globals.cbl +++ b/test/resources/globals.cbl @@ -13,9 +13,10 @@ PROCEDURE DIVISION. MOVE 3 TO BAR-1 DISPLAY FOO + DISPLAY BAZ-2 DISPLAY BAR-1 DISPLAY BAR-2 DISPLAY BAZ-1 - DISPLAY BAZ-2 DISPLAY FXX + CALL "globals2" GOBACK. diff --git a/test/resources/globals.i b/test/resources/globals.i index 8d59346..4fae0f7 100644 --- a/test/resources/globals.i +++ b/test/resources/globals.i @@ -14,9 +14,10 @@ PROCEDURE DIVISION. MOVE 3 TO BAR-1 DISPLAY FOO + DISPLAY BAZ-2 DISPLAY BAR-1 DISPLAY BAR-2 DISPLAY BAZ-1 - DISPLAY BAZ-2 DISPLAY FXX + CALL "globals2" GOBACK. diff --git a/test/resources/globals2.c b/test/resources/globals2.c new file mode 100644 index 0000000..c48567d --- /dev/null +++ b/test/resources/globals2.c @@ -0,0 +1,232 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from globals2.cbl */ +/* Generated at Dec 09 2025 15:02:39 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -m -g globals2.cbl */ + +#include /* for memcpy, memcmp and friends */ +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "globals2.cbl" +#define COB_PACKAGE_VERSION "3.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "Dec 09 2025 15:02:39" +#define COB_MODULE_DATE 20251209 +#define COB_MODULE_TIME 150239 + +/* Global variables */ +#include "globals2.c.h" + +/* Function prototypes */ + +COB_EXT_EXPORT int globals2 (void); +static int globals2_ (const int); +static void globals2_module_init (cob_module *module); + +/* Functions */ + +static void gc_module_so_init () __attribute__ ((constructor)); +static void gc_module_so_init () +{ + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); +} + +/* PROGRAM-ID 'globals2' */ + +/* ENTRY 'globals2' */ + +int +globals2 () +{ + return globals2_ (0); +} + +static int +globals2_ (const int entry) +{ + /* Program local variables */ + #include "globals2.c.l.h" + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -10) + goto P_dump; + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + frame_ptr->return_address_ptr = &&P_cgerror; + frame_overflow = frame_ptr + 255 - 1; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 7 : Entry globals2 : globals2.cbl */ + l_2:; +#line 7 "globals2.cbl" + ENTRY_GLOBALS2: cob_nop (); +#line 97 "globals2.c" + + /* Line: 7 : MOVE : globals2.cbl */ +#line 7 "globals2.cbl" + cob_nop (); +#line 102 "globals2.c" + memcpy (b_17, "042", 3); + + /* Line: 8 : DISPLAY : globals2.cbl */ +#line 8 "globals2.cbl" + cob_nop (); +#line 108 "globals2.c" + cob_display (0, 1, 1, &f_17); + + /* Line: 9 : GOBACK : globals2.cbl */ +#line 9 "globals2.cbl" + cob_nop (); +#line 114 "globals2.c" + goto exit_program; + + /* Program exit */ + + exit_program: + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + P_cgerror: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + globals2_module_init (module); + + module->collating_sequence = NULL; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->xml_code = NULL; + module->xml_event = NULL; + module->xml_information = NULL; + module->xml_namespace = NULL; + module->xml_namespace_prefix = NULL; + module->xml_nnamespace = NULL; + module->xml_nnamespace_prefix = NULL; + module->xml_ntext = NULL; + module->xml_text = NULL; + module->json_code = NULL; + module->json_status = NULL; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + /* initialize field RETURN-CODE */ + b_2 = 0; + + /* initialize field FOO */ +#line 5 "globals2.cbl" + cob_nop (); +#line 165 "globals2.c" + memset (b_17, (unsigned char)'0', 3); + + + if (0 == 1) goto P_cgerror; + initialized = 1; + goto P_ret_initialize; + + P_dump: + return 0; + + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) + return 0; + if (module && module->module_active) + cob_fatal_error (COB_FERROR_CANCEL); + + b_2 = 0; + cob_module_free (&module); + + initialized = 0; + + P_clear_decimal: + return 0; + +} + +/* End PROGRAM-ID 'globals2' */ + +/* Initialize module structure for globals2 */ +static void globals2_module_init (cob_module *module) +{ + module->module_name = "globals2"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->gc_version = COB_PACKAGE_VERSION; + module->module_entry.funcptr = (void *(*)())globals2; + module->module_cancel.funcptr = (void *(*)())globals2_; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 0; + module->flag_main = 0; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + module->flag_debug_trace = 0; + module->flag_dump_ready = 0; + module->xml_mode = 1; + module->module_stmt = 0; + module->module_sources = NULL; +} + +/* End functions */ + diff --git a/test/resources/globals2.c.h b/test/resources/globals2.c.h new file mode 100644 index 0000000..af71219 --- /dev/null +++ b/test/resources/globals2.c.h @@ -0,0 +1,37 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from globals2.cbl */ +/* Generated at Dec 09 2025 15:02:39 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -m -g globals2.cbl */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Data storage */ + +/* PROGRAM-ID : globals2 */ +static cob_u8_t b_17[3] __attribute__((aligned)); /* FOO */ + +/* End of data storage */ + + +/* Attributes */ + +static const cob_field_attr a_1 = {0x10, 3, 0, 0x0000, NULL}; + + +/* Fields */ + +/* PROGRAM-ID : globals2 */ +static cob_field f_17 = {3, b_17, &a_1}; /* FOO */ + +/* End of fields */ + + +#define cob_nop if (!module) cob_nop + diff --git a/test/resources/globals2.c.l.h b/test/resources/globals2.c.l.h new file mode 100644 index 0000000..4c4c6b5 --- /dev/null +++ b/test/resources/globals2.c.l.h @@ -0,0 +1,42 @@ +/* Generated by cobc 3.2.0 */ +/* Generated from globals2.cbl */ +/* Generated at Dec 09 2025 15:02:39 */ +/* GnuCOBOL build date Sep 23 2025 17:57:37 */ +/* GnuCOBOL package date Jul 28 2023 17:02:56 UTC */ +/* Compile command cobc -m -g globals2.cbl */ + +/* Program local variables for 'globals2' */ + +/* Module initialization indicator */ +static unsigned int initialized = 0; + +/* Module structure pointer */ +static cob_module *module = NULL; + +/* Global variable pointer */ +cob_global *cob_glob_ptr; + + +/* LINKAGE SECTION (Items not referenced by USING clause) */ +static unsigned char *b_9 = NULL; /* XML-NAMESPACE */ +static unsigned char *b_10 = NULL; /* XML-NAMESPACE-PREFIX */ +static unsigned char *b_11 = NULL; /* XML-NNAMESPACE */ +static unsigned char *b_12 = NULL; /* XML-NNAMESPACE-PREFIX */ +static unsigned char *b_13 = NULL; /* XML-NTEXT */ +static unsigned char *b_14 = NULL; /* XML-TEXT */ + + +/* Call parameters */ +cob_field *cob_procedure_params[1]; + +/* Perform frame stack */ +struct cob_frame *frame_overflow; +struct cob_frame *frame_ptr; +struct cob_frame frame_stack[255]; + + +/* Data storage */ +static int b_2; /* RETURN-CODE */ + +/* End of local data storage */ + diff --git a/test/resources/globals2.cbl b/test/resources/globals2.cbl new file mode 100644 index 0000000..725ea41 --- /dev/null +++ b/test/resources/globals2.cbl @@ -0,0 +1,9 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. globals2. + DATA DIVISION. + WORKING-STORAGE SECTION. + 77 FOO PIC 999 GLOBAL. + PROCEDURE DIVISION. + MOVE 42 TO FOO + DISPLAY FOO + GOBACK. diff --git a/test/resources/globals2.i b/test/resources/globals2.i new file mode 100644 index 0000000..22b7613 --- /dev/null +++ b/test/resources/globals2.i @@ -0,0 +1,10 @@ +#line 1 "globals2.cbl" + IDENTIFICATION DIVISION. + PROGRAM-ID. globals2. + DATA DIVISION. + WORKING-STORAGE SECTION. + 77 FOO PIC 999 GLOBAL. + PROCEDURE DIVISION. + MOVE 42 TO FOO + DISPLAY FOO + GOBACK. diff --git a/test/suite/parser.c.test.ts b/test/suite/parser.c.test.ts index a70679b..7124caf 100644 --- a/test/suite/parser.c.test.ts +++ b/test/suite/parser.c.test.ts @@ -145,18 +145,29 @@ suite("C code parse", () => { }); test("Globals", () => { const parsed = new SourceMap(cwd, ['globals.cbl']); - - assert.equal(6, parsed.getLinesCount()); - assert.equal(8, parsed.getVariablesCount()); + assert.equal(9, parsed.getLinesCount()); + assert.equal(11, parsed.getVariablesCount()); console.log(parsed.toString()); - - const fooVar = parsed.getGlobalByCobol('FOO'); - assert.equal('FOO', fooVar.cobolName); - assert.equal('FOO', parsed.getGlobalByC(fooVar.cName).cobolName); - const barVar = parsed.getGlobalByCobol('BAR'); + + const fooVar = parsed.findGlobalByCobol('FOO'); + assert.ok(fooVar.cobolName.endsWith('FOO')); + assert.ok(parsed.findGlobalByC(fooVar.cName).cobolName.endsWith('FOO')); + const barVar = parsed.findGlobalByCobol('BAR'); assert.equal(4, barVar.size); - const bar1Var = parsed.getGlobalByCobol('BAR.BAR-2'); + const bar1Var = parsed.findGlobalByCobol('BAR.BAR-2'); assert.equal(3, bar1Var.size); assert.equal('alphanumeric', bar1Var.displayableType); + + parsed.addLib('globals2.so'); + assert.equal(12, parsed.getLinesCount()); + assert.equal(14, parsed.getVariablesCount()); + + const fooVar_ = parsed.findGlobalByCobol('FOO'); + assert.ok(parsed.findGlobalByC(fooVar_.cName).cobolName.endsWith('FOO')); + assert.notEqual(parsed.findGlobalByCobol('FOO', nativePath.join(cwd, 'globals.c.h')), + parsed.findGlobalByCobol('FOO', nativePath.join(cwd, 'globals2.c.h'))); + assert.equal(parsed.findGlobalByCobol('FOO', nativePath.join(cwd, 'globals2.c.h')), + parsed.findGlobalByCobol('foo', nativePath.join(cwd, 'globals2.c.h'))); + assert.ok(parsed.findGlobalByCobol('BAR-2', nativePath.join(cwd, 'globals.c.h'))); }); }); From 7a3baf0e258c65a6a8b42bb69b523bc1b971836c Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 12 Dec 2025 15:56:58 +0100 Subject: [PATCH 70/70] Fix CHANGELOG entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 864650d..2492377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Next -* Show global data items in Variables panel [PR #39](https://github.com/ocamlpro/superbol-vscode-debug/pull/39) +* Show global data items in Variables panel [PR #40](https://github.com/ocamlpro/superbol-vscode-debug/pull/40) * Fixed a bug that made the extension hang when debugged programs displayed signed numbers [PR #39](https://github.com/ocamlpro/superbol-vscode-debug/pull/39) * Show COBOL statements in entries of stackframe summary [PR #38](https://github.com/ocamlpro/superbol-vscode-debug/pull/38) * Remove `gdbpath` and `libcobpath` from launch configurations (these are provided in extension settings) [PR #36](https://github.com/ocamlpro/superbol-vscode-debug/pull/36)