export interface CdlEventHandler { eventName: string parameterNames: string[] } function structuralCode(line: string): string { let result = "" let inString = false let escaped = false for (const character of line) { if (escaped) { escaped = false result += inString ? " " : character continue } if (character === "\\") { escaped = true result += inString ? " " : character continue } if (character === '"') { inString = !inString result += " " continue } if (character === "#" && !inString) { break } result += inString ? " " : character } return result } function braceDelta(line: string): number { let delta = 0 for (const character of structuralCode(line)) { if (character === "{") { delta += 1 } else if (character === "}") { delta -= 1 } } return delta } export function cdlEventHandlerAtLine( source: string, declarationLine: number ): CdlEventHandler | undefined { const lines = source.split(/\r?\n/) const declaration = lines[declarationLine] if (declaration === undefined) { return undefined } const eventMatch = /^\s*EVENT\s+([^\s{]+)/.exec(structuralCode(declaration)) if (!eventMatch) { return undefined } const parameterNames: string[] = [] let eventOpened = false let depth = 0 for (let lineNumber = declarationLine; lineNumber < lines.length; lineNumber++) { const line = lines[lineNumber] const code = structuralCode(line) if (eventOpened && depth === 1) { const parameterMatch = /^\s*PARAM\s+([^\s{]+)/.exec(code) if (parameterMatch) { parameterNames.push(parameterMatch[1]) } } const delta = braceDelta(line) if (!eventOpened && delta > 0) { eventOpened = true } if (eventOpened) { depth += delta if (depth <= 0) { break } } } return { eventName: eventMatch[1], parameterNames } } function momEventName(eventName: string): string { return `MOM_${eventName.replace(/^MOM_/i, "")}` } function momVariableName(parameterName: string): string { return `mom_${parameterName.replace(/^mom_/i, "")}` } export function createCdlEventHandlerSnippet(handler: CdlEventHandler): string { const globals = [ ...new Set(handler.parameterNames.map((parameter) => momVariableName(parameter))) ] const lines = [`proc ${momEventName(handler.eventName)} { } {`] if (globals.length > 0) { lines.push(...globals.map((variable) => ` global ${variable}`), "") } lines.push(" #Put your UDE Handler Tcl here", "", "}") return lines.join("\n") }