Skip to content

Commit 25ff944

Browse files
committed
Fixed prompter for new nested ELEM arguments on the CALL/PARM on IBM i V7R4+ also updated the settings for case-conversion of the command/parm names
1 parent ad0aeac commit 25ff944

22 files changed

+742
-77
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [0.0.50] - 2026-02-21
6+
### Fixed
7+
- **CALL PARM parameter rendering**: Fixed CALL command PARM parameter only showing first value instead of all values
8+
- V7R4+ PARM has nested ELEM structure with Type/Length/Decimal specifications
9+
- Added `fieldset.appendChild(elemDiv)` to render nested ELEM sub-elements properly
10+
- Fixed CSS layout for nested elements to display on separate lines
11+
- Fixed value preservation for unchanged nested ELEM values
12+
- **Tokenizer bounds checking**: Fixed "invalid string length" runtime error when prompting commands with positional parameters
13+
- Added bounds checks (`i < input.length`) to the tokenizeCL.ts file which Prevents infinite loops when reaching end of input string
14+
### Changed
15+
- **Settings renamed for clarity**: Renamed case conversion settings to better describe their purpose
16+
- `convertToUpperCase``convertParmValueToUpperCase`: Only affects &variables, *operators, and %functions in parameters
17+
- `formatCase``convertCmdAndParmNameCase`: Affects command names and parameter keyword names (CHGVAR/chgvar, VAR/var)
18+
- **Architecture simplification**: Unified case conversion logic in formatter pipeline
19+
- Removed duplicate case conversion from `buildCLCommand()` function
20+
- Added case conversion to `formatCLCmd()` unified formatter
21+
- Exported `translateCase()` helper function from formatCL.ts
22+
- Proper separation: `buildCLCommand` builds raw command, `formatCLCmd` applies formatting
23+
524
## [0.0.49] - 2026-02-21
625
### Fixed
726
- **Public API: Export correction**: Fixed `activate()` function to properly return API exports for external extensions

media/prompter.js

Lines changed: 25 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

media/prompter.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "clprompter",
33
"displayName": "Bob Cozzi's CL Prompter for IBM i",
44
"description": "Bob Cozzi's CL Prompter for IBM i CL commands",
5-
"version": "0.0.49",
5+
"version": "0.0.50",
66
"author": {
77
"name": "Bob Cozzi",
88
"url": "https://github.com/bobcozzi"
@@ -104,20 +104,20 @@
104104
"default": "${tmpdir}",
105105
"description": "Directory where clPrompt-<cmdName>.html file is written. Use ${tmpdir} for system temp, ${userHome} for home directory, or an absolute path."
106106
},
107-
"clPrompter.convertToUpperCase": {
107+
"clPrompter.convertParmValueToUpperCase": {
108108
"type": "boolean",
109109
"default": true,
110-
"description": "Convert CL variables, operators (*BCAT, *TCAT, etc.), and built-in functions (%SUBST, %TRIM, etc.) to uppercase. When true, text like '&pickles *bcat %trim(x)' becomes '&PICKLES *BCAT %TRIM(x)'. When false, preserves original case. Applies to both the prompter display and final command output."
110+
"description": "Convert CL variables, operators (*BCAT, *TCAT, etc.), and built-in functions (%SUBST, %TRIM, etc.) within parameter values to uppercase. When true, text like '&pickles *bcat %trim(x)' becomes '&PICKLES *BCAT %TRIM(x)'. When false, preserves original case. Applies when returning from the prompter."
111111
},
112-
"clPrompter.formatCase": {
112+
"clPrompter.convertCmdAndParmNameCase": {
113113
"type": "string",
114114
"default": "*UPPER",
115115
"enum": [
116116
"*UPPER",
117117
"*LOWER",
118118
"*NONE"
119119
],
120-
"description": "Case conversion for CL source. *UPPER = uppercase, *LOWER = lowercase, *NONE = no change."
120+
"description": "Case conversion for CL command names and parameter keywords. *UPPER = uppercase (CHGVAR VAR(...)), *LOWER = lowercase (chgvar var(...)), *NONE = no change. Applies when returning from the prompter and when formatting CL source."
121121
},
122122
"clPrompter.formatIndentComments": {
123123
"type": "string",

src/debugCALL.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// This file can be used to diagnose issues with CALL command parsing
2+
// To use this, add diagnostic logging to extension.ts to see what XML is actually being received
3+
4+
import { extractParmMetas } from './parseCL';
5+
6+
export function debugCALLCommandXML(xml: string): void {
7+
console.log('=== CALL Command XML Diagnostics ===');
8+
9+
// Extract PARM parameter metas
10+
const metas = extractParmMetas(xml);
11+
const parmMeta = metas.find(m => m.Kwd === 'PARM');
12+
13+
if (!parmMeta) {
14+
console.log('ERROR: PARM parameter not found in XML');
15+
return;
16+
}
17+
18+
console.log('PARM parameter details:');
19+
console.log(' Kwd:', parmMeta.Kwd);
20+
console.log(' Type:', parmMeta.Type);
21+
console.log(' Max:', parmMeta.Max);
22+
console.log(' Has Elems:', parmMeta.Elems?.length || 0);
23+
console.log(' Has Quals:', parmMeta.Quals?.length || 0);
24+
25+
if (parmMeta.Elems && parmMeta.Elems.length > 0) {
26+
console.log(' Child Elem[0]:');
27+
console.log(' Type:', parmMeta.Elems[0].Type);
28+
console.log(' MaxLen:', (parmMeta.Elems[0] as any).MaxLen);
29+
}
30+
31+
// Check if Max > 1 (multi-instance)
32+
if (parmMeta.Max && parmMeta.Max > 1) {
33+
console.log(' ✓ PARM is multi-instance (Max > 1)');
34+
console.log(' ✓ Parser will split space-separated values into multiple instances');
35+
} else {
36+
console.log(' ✗ PARM is NOT multi-instance (Max =', parmMeta.Max, ')');
37+
console.log(' ✗ Parser will treat entire value as single instance');
38+
console.log(' ✗ This indicates V7R3 or earlier XML structure');
39+
}
40+
41+
// Extract the raw PARM tag from XML
42+
const parmTagMatch = xml.match(/<Parm[^>]*\bKwd="PARM"[^>]*>/i);
43+
if (parmTagMatch) {
44+
console.log('\nRaw PARM tag from XML:');
45+
console.log(parmTagMatch[0]);
46+
}
47+
48+
console.log('=== End Diagnostics ===\n');
49+
}

src/extension.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export async function activate(context: vscode.ExtensionContext) {
9090
// Get format options from configuration
9191
const config = vscode.workspace.getConfiguration('clPrompter');
9292
const formatOptions: FormatOptions = {
93-
cvtcase: config.get('formatCase', '*UPPER') as '*UPPER' | '*LOWER' | '*NONE',
93+
cvtcase: config.get('convertCmdAndParmNameCase', '*UPPER') as '*UPPER' | '*LOWER' | '*NONE',
9494
indrmks: config.get('formatIndentComments', '*YES') as '*NO' | '*YES',
9595
labelpos: config.get('formatLabelPosition', 2),
9696
bgncol: config.get('formatCmdPosition', 14),
@@ -141,7 +141,7 @@ export async function activate(context: vscode.ExtensionContext) {
141141
// Get format options from configuration
142142
const config = vscode.workspace.getConfiguration('clPrompter');
143143
const formatOptions: FormatOptions = {
144-
cvtcase: config.get('formatCase', '*UPPER') as '*UPPER' | '*LOWER' | '*NONE',
144+
cvtcase: config.get('convertCmdAndParmNameCase', '*UPPER') as '*UPPER' | '*LOWER' | '*NONE',
145145
indrmks: config.get('formatIndentComments', '*YES') as '*NO' | '*YES',
146146
labelpos: config.get('formatLabelPosition', 2),
147147
bgncol: config.get('formatCmdPosition', 14),
@@ -503,6 +503,11 @@ export class ClPromptPanel {
503503
try {
504504
this._parmMap = parseCLParms(cmdWithKeywords, this._parmMetas);
505505
console.log('[clPrompter] parseCLParms keys:', Object.keys(this._parmMap));
506+
// Debug PARM specifically for CALL command
507+
if (this._parmMap['PARM']) {
508+
console.log('[clPrompter] PARM immediately after parseCLParms:', JSON.stringify(this._parmMap['PARM']));
509+
console.log('[clPrompter] PARM length:', this._parmMap['PARM'].length);
510+
}
506511
// Debug RMTFILE specifically
507512
if (this._parmMap['RMTFILE']) {
508513
console.log('[clPrompter] RMTFILE immediately after parseCLParms:', JSON.stringify(this._parmMap['RMTFILE']));
@@ -579,7 +584,7 @@ export class ClPromptPanel {
579584
const keywordColor = config.get('kwdColor');
580585
const valueColor = config.get('kwdValueColor');
581586
const autoAdjust = config.get('kwdColorAutoAdjust');
582-
const convertToUpperCase = config.get('convertToUpperCase', true);
587+
const convertParmValueToUpperCase = config.get('convertParmValueToUpperCase', true);
583588

584589
panel.webview.postMessage({
585590
type: 'formData',
@@ -590,7 +595,7 @@ export class ClPromptPanel {
590595
paramMap: this._parmMap,
591596
parmMap: this._parmMap,
592597
parmMetas: this._parmMetas,
593-
config: { keywordColor, valueColor, autoAdjust, convertToUpperCase }
598+
config: { keywordColor, valueColor, autoAdjust, convertParmValueToUpperCase }
594599
});
595600
panel.webview.postMessage({ type: "setLabel", label: cmdLabel, comment: cmdComment });
596601
this._sentFormData = true;
@@ -747,9 +752,9 @@ export class ClPromptPanel {
747752
const submittedComment = message.values['comment'] as string | undefined;
748753
const normalizedComment = submittedComment ? submittedComment.replace(/\r\n|\n|\r/g, ' ') : submittedComment;
749754

750-
// Get the convertToUpperCase setting
755+
// Get the case conversion setting for parameter values
751756
const config = vscode.workspace.getConfiguration('clPrompter');
752-
const convertToUpperCase = config.get('convertToUpperCase', true);
757+
const convertParmValueToUpperCase = config.get('convertParmValueToUpperCase', true);
753758

754759
let cmd = buildCLCommand(
755760
this._cmdName,
@@ -760,7 +765,7 @@ export class ClPromptPanel {
760765
this._parmMetas,
761766
this._presentParms,
762767
undefined,
763-
convertToUpperCase
768+
convertParmValueToUpperCase
764769
);
765770

766771
// Append comment if present (use normalized comment)

0 commit comments

Comments
 (0)