@crownpeak/dqm-react-component-dev-mcp 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (444) hide show
  1. package/README.md +138 -0
  2. package/data/.env.example +22 -0
  3. package/data/.gitattributes +47 -0
  4. package/data/.glfrc.json +7 -0
  5. package/data/.husky/pre-commit +5 -0
  6. package/data/.nvmrc +1 -0
  7. package/data/CHANGELOG.md +75 -0
  8. package/data/CODE_OF_CONDUCT.md +129 -0
  9. package/data/CONTRIBUTING.md +203 -0
  10. package/data/DOCS-STRUCTURE.md +307 -0
  11. package/data/I18N.md +292 -0
  12. package/data/LICENSE +22 -0
  13. package/data/README.md +315 -0
  14. package/data/SECURITY.md +125 -0
  15. package/data/WIKI-DEPLOYMENT.md +348 -0
  16. package/data/docs/AI-FEATURES.md +610 -0
  17. package/data/docs/API-REFERENCE.md +1022 -0
  18. package/data/docs/AUTHENTICATION.md +301 -0
  19. package/data/docs/BACKEND-API.md +468 -0
  20. package/data/docs/DEVELOPMENT.md +375 -0
  21. package/data/docs/EXAMPLES.md +622 -0
  22. package/data/docs/MCP-SERVER.md +307 -0
  23. package/data/docs/MIGRATION-GUIDE.md +367 -0
  24. package/data/docs/NPM-PUBLISH.md +193 -0
  25. package/data/docs/QUICKSTART.md +206 -0
  26. package/data/docs/REDIS-SETUP.md +162 -0
  27. package/data/docs/SERVER.md +228 -0
  28. package/data/docs/TROUBLESHOOTING.md +657 -0
  29. package/data/docs/WIDGET-GUIDE.md +638 -0
  30. package/data/docs/WIKI-HOME.md +58 -0
  31. package/data/docs/WIKI-SIDEBAR.md +39 -0
  32. package/data/package.json +171 -0
  33. package/data/playwright.config.ts +64 -0
  34. package/data/probe/.cargo/config.toml +10 -0
  35. package/data/probe/.claude/commands/performance-review.md +15 -0
  36. package/data/probe/.clinerules +288 -0
  37. package/data/probe/.dockerignore +57 -0
  38. package/data/probe/.githooks/post-commit +11 -0
  39. package/data/probe/.githooks/pre-commit +99 -0
  40. package/data/probe/.githooks/pre-commit-vow +9 -0
  41. package/data/probe/.prompts/engineer.md +41 -0
  42. package/data/probe/.roomodes +28 -0
  43. package/data/probe/.windsurfrules +0 -0
  44. package/data/probe/BASH_TOOL_SUMMARY.md +148 -0
  45. package/data/probe/BENCHMARKING.md +256 -0
  46. package/data/probe/CLAUDE.md +226 -0
  47. package/data/probe/CODE_OF_CONDUCT.md +128 -0
  48. package/data/probe/CONTRIBUTING.md +193 -0
  49. package/data/probe/Cargo.toml +120 -0
  50. package/data/probe/Cross.toml +10 -0
  51. package/data/probe/DOCKER-README.md +224 -0
  52. package/data/probe/Dockerfile +32 -0
  53. package/data/probe/ENHANCED_DEBUG_TELEMETRY.md +188 -0
  54. package/data/probe/LICENSE +201 -0
  55. package/data/probe/Makefile +210 -0
  56. package/data/probe/README.md +824 -0
  57. package/data/probe/SECURITY.md +67 -0
  58. package/data/probe/WINDOWS-GUIDE.md +294 -0
  59. package/data/probe/benches/parsing_benchmarks.rs +370 -0
  60. package/data/probe/benches/search_benchmarks.rs +599 -0
  61. package/data/probe/benches/simd_benchmarks.rs +372 -0
  62. package/data/probe/benches/timing_benchmarks.rs +287 -0
  63. package/data/probe/build-windows.bat +229 -0
  64. package/data/probe/codex-config/config.toml +6 -0
  65. package/data/probe/docs/PERFORMANCE_OPTIMIZATION.md +161 -0
  66. package/data/probe/examples/cache_demo.rs +46 -0
  67. package/data/probe/examples/chat/.dockerignore +37 -0
  68. package/data/probe/examples/chat/ChatSessionManager.js +295 -0
  69. package/data/probe/examples/chat/Dockerfile +98 -0
  70. package/data/probe/examples/chat/LICENSE +201 -0
  71. package/data/probe/examples/chat/LOCAL_IMAGE_SUPPORT.md +195 -0
  72. package/data/probe/examples/chat/MCP_INTEGRATION.md +400 -0
  73. package/data/probe/examples/chat/README.md +338 -0
  74. package/data/probe/examples/chat/TRACING.md +226 -0
  75. package/data/probe/examples/chat/appTracer.js +968 -0
  76. package/data/probe/examples/chat/auth.js +76 -0
  77. package/data/probe/examples/chat/bin/probe-chat.js +13 -0
  78. package/data/probe/examples/chat/build.js +104 -0
  79. package/data/probe/examples/chat/cancelRequest.js +84 -0
  80. package/data/probe/examples/chat/demo-agentic-image-flow.js +88 -0
  81. package/data/probe/examples/chat/demo-local-images.js +128 -0
  82. package/data/probe/examples/chat/fileSpanExporter.js +181 -0
  83. package/data/probe/examples/chat/implement/README.md +228 -0
  84. package/data/probe/examples/chat/implement/backends/AiderBackend.js +750 -0
  85. package/data/probe/examples/chat/implement/backends/BaseBackend.js +276 -0
  86. package/data/probe/examples/chat/implement/backends/ClaudeCodeBackend.js +767 -0
  87. package/data/probe/examples/chat/implement/backends/MockBackend.js +237 -0
  88. package/data/probe/examples/chat/implement/backends/registry.js +85 -0
  89. package/data/probe/examples/chat/implement/core/BackendManager.js +567 -0
  90. package/data/probe/examples/chat/implement/core/ImplementTool.js +354 -0
  91. package/data/probe/examples/chat/implement/core/config.js +428 -0
  92. package/data/probe/examples/chat/implement/core/timeouts.js +58 -0
  93. package/data/probe/examples/chat/implement/core/utils.js +496 -0
  94. package/data/probe/examples/chat/implement/types/BackendTypes.js +126 -0
  95. package/data/probe/examples/chat/index.js +669 -0
  96. package/data/probe/examples/chat/mcpServer.js +341 -0
  97. package/data/probe/examples/chat/npm/LICENSE +15 -0
  98. package/data/probe/examples/chat/npm/README.md +168 -0
  99. package/data/probe/examples/chat/npm/bin/probe-chat.js +156 -0
  100. package/data/probe/examples/chat/npm/index.js +259 -0
  101. package/data/probe/examples/chat/npm/package.json +54 -0
  102. package/data/probe/examples/chat/package.json +102 -0
  103. package/data/probe/examples/chat/probeChat.js +456 -0
  104. package/data/probe/examples/chat/probeTool.js +491 -0
  105. package/data/probe/examples/chat/storage/JsonChatStorage.js +476 -0
  106. package/data/probe/examples/chat/telemetry.js +281 -0
  107. package/data/probe/examples/chat/test/integration/chatFlows.test.js +320 -0
  108. package/data/probe/examples/chat/test/integration/toolCalling.test.js +471 -0
  109. package/data/probe/examples/chat/test/mocks/mockLLMProvider.js +269 -0
  110. package/data/probe/examples/chat/test/test-backends.js +90 -0
  111. package/data/probe/examples/chat/test/testUtils.js +530 -0
  112. package/data/probe/examples/chat/test/unit/backendTimeout.test.js +161 -0
  113. package/data/probe/examples/chat/test/unit/packageFiles.test.js +120 -0
  114. package/data/probe/examples/chat/test/verify-tests.js +118 -0
  115. package/data/probe/examples/chat/test-agentic-image-loading.js +294 -0
  116. package/data/probe/examples/chat/test-ai-sdk-telemetry.js +204 -0
  117. package/data/probe/examples/chat/test-chat-tracing.js +38 -0
  118. package/data/probe/examples/chat/test-direct-function.js +49 -0
  119. package/data/probe/examples/chat/test-file-size-validation.js +103 -0
  120. package/data/probe/examples/chat/test-full-mcp-integration.js +258 -0
  121. package/data/probe/examples/chat/test-github-context.txt +12 -0
  122. package/data/probe/examples/chat/test-hierarchy.js +203 -0
  123. package/data/probe/examples/chat/test-image-spans.js +37 -0
  124. package/data/probe/examples/chat/test-local-image-reading.js +176 -0
  125. package/data/probe/examples/chat/test-mcp-integration.js +136 -0
  126. package/data/probe/examples/chat/test-mcp-probe-server.js +161 -0
  127. package/data/probe/examples/chat/test-mcp-with-ai.js +279 -0
  128. package/data/probe/examples/chat/test-multiple-allowed-dirs.js +111 -0
  129. package/data/probe/examples/chat/test-probe-mcp-server.js +110 -0
  130. package/data/probe/examples/chat/test-security-validation.js +145 -0
  131. package/data/probe/examples/chat/test-simple-tracing.js +32 -0
  132. package/data/probe/examples/chat/test-trace-verification.js +235 -0
  133. package/data/probe/examples/chat/test-tracing.js +114 -0
  134. package/data/probe/examples/chat/tokenCounter.js +419 -0
  135. package/data/probe/examples/chat/tokenUsageDisplay.js +134 -0
  136. package/data/probe/examples/chat/webServer.js +1103 -0
  137. package/data/probe/examples/reranker/Cargo.toml +33 -0
  138. package/data/probe/examples/reranker/DEBUG_OUTPUT_ANALYSIS.md +71 -0
  139. package/data/probe/examples/reranker/MODELS.md +66 -0
  140. package/data/probe/examples/reranker/MODEL_COMPARISON.md +60 -0
  141. package/data/probe/examples/reranker/MULTI_MODEL_ANALYSIS.md +176 -0
  142. package/data/probe/examples/reranker/PERFORMANCE_SUMMARY.md +156 -0
  143. package/data/probe/examples/reranker/README.md +347 -0
  144. package/data/probe/examples/reranker/RUST_BERT_COMPARISON.md +82 -0
  145. package/data/probe/examples/reranker/TOKENIZATION_GUIDE.md +120 -0
  146. package/data/probe/examples/reranker/check_rust_tokenizer.py +108 -0
  147. package/data/probe/examples/reranker/convert_to_torchscript.py +109 -0
  148. package/data/probe/examples/reranker/debug_scoring.py +189 -0
  149. package/data/probe/examples/reranker/debug_tokenization.py +154 -0
  150. package/data/probe/examples/reranker/download_models.sh +73 -0
  151. package/data/probe/examples/reranker/requirements.txt +13 -0
  152. package/data/probe/examples/reranker/run_comprehensive_benchmark.sh +83 -0
  153. package/data/probe/examples/reranker/rust_bert_test/Cargo.toml +12 -0
  154. package/data/probe/examples/reranker/rust_bert_test/README.md +54 -0
  155. package/data/probe/examples/reranker/simple_test.py +50 -0
  156. package/data/probe/examples/reranker/test_all_models.sh +63 -0
  157. package/data/probe/examples/reranker/test_bert_results.sh +44 -0
  158. package/data/probe/examples/reranker/test_cross_encoder.py +334 -0
  159. package/data/probe/examples/reranker/test_cross_encoder.sh +80 -0
  160. package/data/probe/examples/reranker/test_exact_comparison.py +151 -0
  161. package/data/probe/examples/reranker/test_parallel_performance.sh +56 -0
  162. package/data/probe/examples/reranker/test_scores.py +132 -0
  163. package/data/probe/install.ps1 +508 -0
  164. package/data/probe/install.sh +460 -0
  165. package/data/probe/npm/CLONE_METHOD_EXAMPLES.md +596 -0
  166. package/data/probe/npm/CONTEXT_COMPACTION.md +303 -0
  167. package/data/probe/npm/DELEGATE_TOOL_README.md +166 -0
  168. package/data/probe/npm/MAID_INTEGRATION.md +313 -0
  169. package/data/probe/npm/MCP_INTEGRATION_SUMMARY.md +241 -0
  170. package/data/probe/npm/README.md +824 -0
  171. package/data/probe/npm/bin/.gitignore +7 -0
  172. package/data/probe/npm/bin/.gitkeep +0 -0
  173. package/data/probe/npm/bin/README.md +12 -0
  174. package/data/probe/npm/bin/probe +167 -0
  175. package/data/probe/npm/docs/CLAUDE_CODE_INTEGRATION.md +414 -0
  176. package/data/probe/npm/docs/CODEX_INTEGRATION.md +502 -0
  177. package/data/probe/npm/docs/EDIT_CREATE_TOOLS.md +233 -0
  178. package/data/probe/npm/docs/RETRY_AND_FALLBACK.md +674 -0
  179. package/data/probe/npm/example-usage.js +335 -0
  180. package/data/probe/npm/examples/multi-engine-demo.js +117 -0
  181. package/data/probe/npm/examples/probe-agent-cli.js +113 -0
  182. package/data/probe/npm/examples/test-agent-edit.js +114 -0
  183. package/data/probe/npm/examples/test-edit-create.js +120 -0
  184. package/data/probe/npm/examples/test-edit-direct.js +114 -0
  185. package/data/probe/npm/index.d.ts +744 -0
  186. package/data/probe/npm/jest.config.js +52 -0
  187. package/data/probe/npm/package.json +117 -0
  188. package/data/probe/npm/scripts/build-agent.cjs +75 -0
  189. package/data/probe/npm/scripts/build-cjs.js +124 -0
  190. package/data/probe/npm/scripts/build-mcp.cjs +36 -0
  191. package/data/probe/npm/scripts/postinstall.js +216 -0
  192. package/data/probe/npm/test-codex-e2e.js +78 -0
  193. package/data/probe/npm/test-download-lock.js +109 -0
  194. package/data/probe/npm/test-grep-security.js +94 -0
  195. package/data/probe/npm/test-grep-simplified.js +63 -0
  196. package/data/probe/npm/test-grep.js +51 -0
  197. package/data/probe/npm/tests/README.md +96 -0
  198. package/data/probe/npm/tests/agent-compact-history.test.js +174 -0
  199. package/data/probe/npm/tests/allow-tests-default.test.js +151 -0
  200. package/data/probe/npm/tests/contextCompactor.test.js +498 -0
  201. package/data/probe/npm/tests/delegate-config.test.js +353 -0
  202. package/data/probe/npm/tests/delegate-integration.test.js +348 -0
  203. package/data/probe/npm/tests/extractor-integration.test.js +162 -0
  204. package/data/probe/npm/tests/extractor.test.js +317 -0
  205. package/data/probe/npm/tests/fixtures/sampleDiagrams.js +267 -0
  206. package/data/probe/npm/tests/integration/claude-code-auto-fallback.spec.js +148 -0
  207. package/data/probe/npm/tests/integration/claude-code-multi-step.spec.js +127 -0
  208. package/data/probe/npm/tests/integration/claude-code-tool-events.spec.js +163 -0
  209. package/data/probe/npm/tests/integration/codex-auto-fallback.spec.js +191 -0
  210. package/data/probe/npm/tests/integration/codex-tool-events.spec.js +147 -0
  211. package/data/probe/npm/tests/integration/examplesChatMcp.test.js +402 -0
  212. package/data/probe/npm/tests/integration/mcpDotenvSupport.test.js +174 -0
  213. package/data/probe/npm/tests/integration/mcpErrorHandling.test.js +566 -0
  214. package/data/probe/npm/tests/integration/mcpRobustness.test.js +564 -0
  215. package/data/probe/npm/tests/integration/mcpStdoutPurity.test.js +355 -0
  216. package/data/probe/npm/tests/integration/probeAgentMcp.test.js +398 -0
  217. package/data/probe/npm/tests/integration/retryFallback.test.js +368 -0
  218. package/data/probe/npm/tests/integration/schema-in-initial-message.test.js +318 -0
  219. package/data/probe/npm/tests/integration/schema-validation-loop-prevention.test.js +244 -0
  220. package/data/probe/npm/tests/integration/schemaRetryLogic.test.js +94 -0
  221. package/data/probe/npm/tests/integration/validationFlow.test.js +329 -0
  222. package/data/probe/npm/tests/manual/test-codex-basic.js +110 -0
  223. package/data/probe/npm/tests/mcp/mcpClientManager.test.js +614 -0
  224. package/data/probe/npm/tests/mcp/mcpConfig.test.js +359 -0
  225. package/data/probe/npm/tests/mcp/mcpXmlBridge.test.js +436 -0
  226. package/data/probe/npm/tests/mcp/mockMcpServer.js +510 -0
  227. package/data/probe/npm/tests/mcp-strict-syntax.test.js +319 -0
  228. package/data/probe/npm/tests/mermaidQuoteEscaping.test.js +214 -0
  229. package/data/probe/npm/tests/nestedQuoteFix.test.js +40 -0
  230. package/data/probe/npm/tests/setup.js +46 -0
  231. package/data/probe/npm/tests/unit/allowed-tools.test.js +513 -0
  232. package/data/probe/npm/tests/unit/attempt-completion-closing-tag-in-content.test.js +188 -0
  233. package/data/probe/npm/tests/unit/attemptCompletionJsonFix.test.js +238 -0
  234. package/data/probe/npm/tests/unit/attemptCompletionJsonIssue.test.js +128 -0
  235. package/data/probe/npm/tests/unit/backtickAutoFix.test.js +35 -0
  236. package/data/probe/npm/tests/unit/bash-probe-agent-integration.test.js +389 -0
  237. package/data/probe/npm/tests/unit/bash-simple-commands.test.js +324 -0
  238. package/data/probe/npm/tests/unit/bash-tool-comprehensive.test.js +371 -0
  239. package/data/probe/npm/tests/unit/bash-tool-integration.test.js +310 -0
  240. package/data/probe/npm/tests/unit/bash-tool.test.js +341 -0
  241. package/data/probe/npm/tests/unit/completion-prompt.test.js +379 -0
  242. package/data/probe/npm/tests/unit/cwd-path-options.test.js +287 -0
  243. package/data/probe/npm/tests/unit/delegate-limits.test.js +422 -0
  244. package/data/probe/npm/tests/unit/direct-content-attempt-completion.test.js +235 -0
  245. package/data/probe/npm/tests/unit/edit-create-tools.test.js +609 -0
  246. package/data/probe/npm/tests/unit/enhancedMermaidValidation.test.js +577 -0
  247. package/data/probe/npm/tests/unit/extract-content.test.js +83 -0
  248. package/data/probe/npm/tests/unit/extract-multiple-targets.test.js +89 -0
  249. package/data/probe/npm/tests/unit/fallbackManager.test.js +442 -0
  250. package/data/probe/npm/tests/unit/githubCompatibilityValidation.test.js +258 -0
  251. package/data/probe/npm/tests/unit/imageConfig.test.js +149 -0
  252. package/data/probe/npm/tests/unit/imagePathResolution.test.js +345 -0
  253. package/data/probe/npm/tests/unit/json-fixing-agent.test.js +238 -0
  254. package/data/probe/npm/tests/unit/json-validation-enhanced-errors.test.js +199 -0
  255. package/data/probe/npm/tests/unit/jsonValidationInfiniteLoopFix.test.js +228 -0
  256. package/data/probe/npm/tests/unit/maidIntegration.test.js +139 -0
  257. package/data/probe/npm/tests/unit/maxIterationsWarning.test.js +195 -0
  258. package/data/probe/npm/tests/unit/mermaidEdgeLabelFix.test.js +161 -0
  259. package/data/probe/npm/tests/unit/mermaidHtmlEntities.test.js +76 -0
  260. package/data/probe/npm/tests/unit/mermaidInfiniteLoopFix.test.js +64 -0
  261. package/data/probe/npm/tests/unit/mermaidValidation.test.js +723 -0
  262. package/data/probe/npm/tests/unit/mermaidValidationVisorExample.test.js +309 -0
  263. package/data/probe/npm/tests/unit/probe-agent-clone-realistic.test.js +643 -0
  264. package/data/probe/npm/tests/unit/probe-agent-clone.test.js +476 -0
  265. package/data/probe/npm/tests/unit/probe-agent-delegate.test.js +400 -0
  266. package/data/probe/npm/tests/unit/probe-agent-model-option.test.js +118 -0
  267. package/data/probe/npm/tests/unit/probeTool-security.test.js +283 -0
  268. package/data/probe/npm/tests/unit/readImageTool.test.js +418 -0
  269. package/data/probe/npm/tests/unit/retryManager.test.js +317 -0
  270. package/data/probe/npm/tests/unit/schema-aware-reminders.test.js +288 -0
  271. package/data/probe/npm/tests/unit/schemaDefinitionDetection.test.js +115 -0
  272. package/data/probe/npm/tests/unit/schemaUtils.test.js +1268 -0
  273. package/data/probe/npm/tests/unit/simpleTelemetry.test.js +282 -0
  274. package/data/probe/npm/tests/unit/simplified-attempt-completion.test.js +274 -0
  275. package/data/probe/npm/tests/unit/single-quote-json-bug.test.js +231 -0
  276. package/data/probe/npm/tests/unit/subgraphAutoFix.test.js +110 -0
  277. package/data/probe/npm/tests/unit/system-prompt.test.js +32 -0
  278. package/data/probe/npm/tests/unit/types-probe-agent-options.test.js +42 -0
  279. package/data/probe/npm/tests/unit/xmlParsing.test.js +720 -0
  280. package/data/probe/npm/tsconfig.json +21 -0
  281. package/data/probe/result1.txt +19 -0
  282. package/data/probe/result2.txt +26 -0
  283. package/data/probe/scripts/benchmark.sh +270 -0
  284. package/data/probe/scripts/cache_memory_analysis.rs +844 -0
  285. package/data/probe/scripts/claude-hook-wrapper.sh +56 -0
  286. package/data/probe/site/.env.example +10 -0
  287. package/data/probe/site/DEPLOYMENT.md +86 -0
  288. package/data/probe/site/README.md +183 -0
  289. package/data/probe/site/adding-languages.md +135 -0
  290. package/data/probe/site/ai-chat.md +427 -0
  291. package/data/probe/site/ai-integration.md +1488 -0
  292. package/data/probe/site/blog/agentic-flow-custom-xml-protocol.md +407 -0
  293. package/data/probe/site/blog/index.md +118 -0
  294. package/data/probe/site/blog/v0.6.0-release.md +426 -0
  295. package/data/probe/site/blog.md +8 -0
  296. package/data/probe/site/changelog.md +200 -0
  297. package/data/probe/site/cli-mode.md +437 -0
  298. package/data/probe/site/code-extraction.md +436 -0
  299. package/data/probe/site/contributing/README.md +9 -0
  300. package/data/probe/site/contributing/documentation-cross-references.md +215 -0
  301. package/data/probe/site/contributing/documentation-maintenance.md +275 -0
  302. package/data/probe/site/contributing/documentation-structure.md +75 -0
  303. package/data/probe/site/documentation-cross-references.md +215 -0
  304. package/data/probe/site/documentation-guide.md +132 -0
  305. package/data/probe/site/documentation-maintenance.md +275 -0
  306. package/data/probe/site/features.md +147 -0
  307. package/data/probe/site/how-it-works.md +118 -0
  308. package/data/probe/site/index.md +175 -0
  309. package/data/probe/site/index.md.bak +133 -0
  310. package/data/probe/site/installation.md +235 -0
  311. package/data/probe/site/integrations/docker.md +248 -0
  312. package/data/probe/site/integrations/github-actions.md +413 -0
  313. package/data/probe/site/language-support-overview.md +168 -0
  314. package/data/probe/site/mcp-integration.md +587 -0
  315. package/data/probe/site/mcp-server.md +304 -0
  316. package/data/probe/site/navigation-structure.md +76 -0
  317. package/data/probe/site/nodejs-sdk.md +798 -0
  318. package/data/probe/site/output-formats.md +625 -0
  319. package/data/probe/site/package.json +21 -0
  320. package/data/probe/site/public/_headers +28 -0
  321. package/data/probe/site/public/_redirects +11 -0
  322. package/data/probe/site/quick-start.md +289 -0
  323. package/data/probe/site/search-functionality.md +291 -0
  324. package/data/probe/site/search-reference.md +291 -0
  325. package/data/probe/site/supported-languages.md +215 -0
  326. package/data/probe/site/use-cases/README.md +8 -0
  327. package/data/probe/site/use-cases/advanced-cli.md +253 -0
  328. package/data/probe/site/use-cases/ai-code-editors.md +239 -0
  329. package/data/probe/site/use-cases/building-ai-tools.md +529 -0
  330. package/data/probe/site/use-cases/cli-ai-workflows.md +285 -0
  331. package/data/probe/site/use-cases/deploying-probe-web-interface.md +255 -0
  332. package/data/probe/site/use-cases/integrating-probe-into-ai-code-editors.md +161 -0
  333. package/data/probe/site/use-cases/nodejs-sdk.md +596 -0
  334. package/data/probe/site/use-cases/team-chat.md +350 -0
  335. package/data/probe/site/web-interface.md +434 -0
  336. package/data/probe/site/wrangler.toml +9 -0
  337. package/data/probe/test-api-key.sh +1 -0
  338. package/data/probe/test-probe-implementation/hello.js +7 -0
  339. package/data/probe/test_cases/demonstrate_early_termination_issues.sh +176 -0
  340. package/data/probe/test_cases/early_termination_issues.rs +533 -0
  341. package/data/probe/test_data/test_nested_struct.go +26 -0
  342. package/data/probe/tests/README.md +286 -0
  343. package/data/probe/tests/README_search_determinism_tests.md +116 -0
  344. package/data/probe/tests/adjacent_comment_test.rs +152 -0
  345. package/data/probe/tests/apostrophe_handling_tests.rs +132 -0
  346. package/data/probe/tests/block_filtering_with_ast_tests.rs +669 -0
  347. package/data/probe/tests/block_merging_tests.rs +396 -0
  348. package/data/probe/tests/c_outline_format_tests.rs +2179 -0
  349. package/data/probe/tests/cache_invalidation_issues.rs.disabled +682 -0
  350. package/data/probe/tests/cache_order_tests.rs +147 -0
  351. package/data/probe/tests/cache_query_scoping_tests.rs +221 -0
  352. package/data/probe/tests/cli_tests.rs +680 -0
  353. package/data/probe/tests/comment_context_integration_test.rs +240 -0
  354. package/data/probe/tests/common.rs +33 -0
  355. package/data/probe/tests/complex_block_merging_tests.rs +599 -0
  356. package/data/probe/tests/complex_query_block_filtering_tests.rs +422 -0
  357. package/data/probe/tests/control_flow_closing_braces_test.rs +91 -0
  358. package/data/probe/tests/cpp_outline_format_tests.rs +1507 -0
  359. package/data/probe/tests/csharp_outline_format_tests.rs +941 -0
  360. package/data/probe/tests/elastic_query_integration_tests.rs +922 -0
  361. package/data/probe/tests/extract_command_tests.rs +1848 -0
  362. package/data/probe/tests/extract_deduplication_tests.rs +146 -0
  363. package/data/probe/tests/extract_input_file_tests.rs +84 -0
  364. package/data/probe/tests/extract_prompt_tests.rs +102 -0
  365. package/data/probe/tests/filename_search_tests.rs +96 -0
  366. package/data/probe/tests/fixtures/user/AssemblyInfo.cs +3 -0
  367. package/data/probe/tests/github_extract_tests.rs +234 -0
  368. package/data/probe/tests/go_comment_test.rs +253 -0
  369. package/data/probe/tests/go_outline_format_tests.rs +2587 -0
  370. package/data/probe/tests/go_path_resolver_tests.rs +96 -0
  371. package/data/probe/tests/html_outline_format_tests.rs +637 -0
  372. package/data/probe/tests/integration_tests.rs +837 -0
  373. package/data/probe/tests/ip_whitelist_test.rs +148 -0
  374. package/data/probe/tests/java_outline_format_tests.rs +1611 -0
  375. package/data/probe/tests/javascript_extract_tests.rs +315 -0
  376. package/data/probe/tests/javascript_outline_format_tests.rs +1464 -0
  377. package/data/probe/tests/json_format_tests.rs +436 -0
  378. package/data/probe/tests/json_schema_validation_tests.rs +450 -0
  379. package/data/probe/tests/lib_usage.rs +60 -0
  380. package/data/probe/tests/line_comment_context_extension_test.rs +459 -0
  381. package/data/probe/tests/line_map_cache_tests.rs +114 -0
  382. package/data/probe/tests/markdown_integration_tests.rs +190 -0
  383. package/data/probe/tests/mocks/test_ip_whitelist.go +11 -0
  384. package/data/probe/tests/mocks/test_object.js +27 -0
  385. package/data/probe/tests/mocks/test_struct.go +50 -0
  386. package/data/probe/tests/multi_keyword_pattern_tests.rs +464 -0
  387. package/data/probe/tests/multi_language_syntax_integration_tests.rs +218 -0
  388. package/data/probe/tests/multiple_capture_groups_tests.rs +169 -0
  389. package/data/probe/tests/negative_compound_word_tests.rs +246 -0
  390. package/data/probe/tests/nested_symbol_extraction_tests.rs +99 -0
  391. package/data/probe/tests/outline_cross_file_interference_test.rs +335 -0
  392. package/data/probe/tests/outline_keyword_preservation_test.rs +67 -0
  393. package/data/probe/tests/output_format_edge_cases_tests.rs +693 -0
  394. package/data/probe/tests/parallel_extraction_tests.rs +178 -0
  395. package/data/probe/tests/parallel_search_tests.rs +355 -0
  396. package/data/probe/tests/path_resolver_tests.rs +698 -0
  397. package/data/probe/tests/php_outline_format_extended_tests.rs +928 -0
  398. package/data/probe/tests/php_outline_format_tests.rs +768 -0
  399. package/data/probe/tests/property_tests.proptest-regressions +9 -0
  400. package/data/probe/tests/property_tests.rs +118 -0
  401. package/data/probe/tests/python_outline_format_tests.rs +1538 -0
  402. package/data/probe/tests/query_command_json_tests.rs +438 -0
  403. package/data/probe/tests/query_command_tests.rs +232 -0
  404. package/data/probe/tests/query_command_xml_tests.rs +569 -0
  405. package/data/probe/tests/quoted_term_with_negative_keyword_tests.rs +216 -0
  406. package/data/probe/tests/required_terms_filename_tests.rs +116 -0
  407. package/data/probe/tests/ruby_outline_format_tests.rs +1011 -0
  408. package/data/probe/tests/rust_line_comment_context_test.rs +151 -0
  409. package/data/probe/tests/rust_outline_format_enhanced_tests.rs +725 -0
  410. package/data/probe/tests/rust_outline_format_tests.rs +843 -0
  411. package/data/probe/tests/schemas/xml_output_schema.xsd +38 -0
  412. package/data/probe/tests/search_determinism_tests.rs +451 -0
  413. package/data/probe/tests/search_hints_tests.rs +253 -0
  414. package/data/probe/tests/special_character_escaping_tests.rs +417 -0
  415. package/data/probe/tests/stemming_compound_word_filtering_tests.rs +535 -0
  416. package/data/probe/tests/strict_elastic_syntax_tests.rs +404 -0
  417. package/data/probe/tests/swift_outline_format_tests.rs +3319 -0
  418. package/data/probe/tests/symbols_tests.rs +166 -0
  419. package/data/probe/tests/test_file.rs +45 -0
  420. package/data/probe/tests/test_tokenize.rs +28 -0
  421. package/data/probe/tests/timeout_tests.rs +82 -0
  422. package/data/probe/tests/tokenization_tests.rs +195 -0
  423. package/data/probe/tests/tokenized_block_filtering_tests.rs +174 -0
  424. package/data/probe/tests/typescript_extract_tests.rs +214 -0
  425. package/data/probe/tests/typescript_outline_format_tests.rs +2188 -0
  426. package/data/probe/tests/xml_format_tests.rs +568 -0
  427. package/data/probe/tests/xml_schema_validation_tests.rs +497 -0
  428. package/data/scripts/postinstall.mjs +9 -0
  429. package/data/scripts/set-version.js +0 -0
  430. package/data/scripts/wiki-build.sh +111 -0
  431. package/data/scripts/wiki-deploy.sh +73 -0
  432. package/data/serve.json +12 -0
  433. package/data/test/demo-dynamic.html +134 -0
  434. package/data/test/demo-esm.html +105 -0
  435. package/data/test/demo-iife.html +78 -0
  436. package/data/tsconfig.json +7 -0
  437. package/data/vite.server.ts +483 -0
  438. package/data/vitest.config.ts +40 -0
  439. package/data/wiki/Home.md +58 -0
  440. package/data/wiki/_Sidebar.md +39 -0
  441. package/docs-mcp.config.json +20 -0
  442. package/package.json +56 -0
  443. package/src/config.js +111 -0
  444. package/src/index.js +395 -0
@@ -0,0 +1,2179 @@
1
+ use anyhow::Result;
2
+ use std::fs;
3
+ use tempfile::TempDir;
4
+
5
+ mod common;
6
+ use common::TestContext;
7
+
8
+ #[test]
9
+ fn test_c_outline_basic_symbols() -> Result<()> {
10
+ let temp_dir = TempDir::new()?;
11
+ let test_file = temp_dir.path().join("basic.c");
12
+
13
+ let content = r#"// Basic C functions and structures for testing
14
+ #include <stdio.h>
15
+ #include <stdlib.h>
16
+ #include <string.h>
17
+ #include <math.h>
18
+
19
+ // Constants and macros
20
+ #define MAX_SIZE 100
21
+ #define PI 3.14159
22
+ #define SQUARE(x) ((x) * (x))
23
+
24
+ // Type definitions
25
+ typedef struct {
26
+ char name[50];
27
+ double* history;
28
+ int count;
29
+ int capacity;
30
+ } Calculator;
31
+
32
+ typedef enum {
33
+ OPERATION_ADD,
34
+ OPERATION_SUBTRACT,
35
+ OPERATION_MULTIPLY,
36
+ OPERATION_DIVIDE
37
+ } OperationType;
38
+
39
+ // Global variables
40
+ static Calculator* global_calculator = NULL;
41
+ const double DEFAULT_PRECISION = 0.01;
42
+
43
+ // Function prototypes
44
+ Calculator* create_calculator(const char* name);
45
+ void destroy_calculator(Calculator* calc);
46
+ double add_numbers(Calculator* calc, double x, double y);
47
+ double subtract_numbers(Calculator* calc, double x, double y);
48
+ double multiply_numbers(Calculator* calc, double x, double y);
49
+ double divide_numbers(Calculator* calc, double x, double y);
50
+ int get_history_count(const Calculator* calc);
51
+ double* get_history(const Calculator* calc);
52
+
53
+ // Function implementations
54
+
55
+ /**
56
+ * Creates a new calculator instance
57
+ * @param name The name of the calculator
58
+ * @return Pointer to the new calculator or NULL on failure
59
+ */
60
+ Calculator* create_calculator(const char* name) {
61
+ Calculator* calc = malloc(sizeof(Calculator));
62
+ if (calc == NULL) {
63
+ return NULL;
64
+ }
65
+
66
+ // Initialize name
67
+ strncpy(calc->name, name, sizeof(calc->name) - 1);
68
+ calc->name[sizeof(calc->name) - 1] = '\0';
69
+
70
+ // Initialize history
71
+ calc->capacity = 10;
72
+ calc->history = malloc(calc->capacity * sizeof(double));
73
+ if (calc->history == NULL) {
74
+ free(calc);
75
+ return NULL;
76
+ }
77
+
78
+ calc->count = 0;
79
+ return calc;
80
+ }
81
+
82
+ /**
83
+ * Destroys a calculator instance and frees memory
84
+ * @param calc Pointer to the calculator to destroy
85
+ */
86
+ void destroy_calculator(Calculator* calc) {
87
+ if (calc != NULL) {
88
+ if (calc->history != NULL) {
89
+ free(calc->history);
90
+ }
91
+ free(calc);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Records an operation result in the calculator's history
97
+ * @param calc Pointer to the calculator
98
+ * @param result The result to record
99
+ * @return 0 on success, -1 on failure
100
+ */
101
+ static int record_operation(Calculator* calc, double result) {
102
+ if (calc == NULL) {
103
+ return -1;
104
+ }
105
+
106
+ // Expand history if needed
107
+ if (calc->count >= calc->capacity) {
108
+ calc->capacity *= 2;
109
+ double* new_history = realloc(calc->history, calc->capacity * sizeof(double));
110
+ if (new_history == NULL) {
111
+ return -1;
112
+ }
113
+ calc->history = new_history;
114
+ }
115
+
116
+ calc->history[calc->count++] = result;
117
+ return 0;
118
+ }
119
+
120
+ /**
121
+ * Adds two numbers and records the result
122
+ * @param calc Pointer to the calculator
123
+ * @param x First number
124
+ * @param y Second number
125
+ * @return The sum of x and y
126
+ */
127
+ double add_numbers(Calculator* calc, double x, double y) {
128
+ double result = x + y;
129
+ if (calc != NULL) {
130
+ record_operation(calc, result);
131
+ }
132
+ return result;
133
+ }
134
+
135
+ /**
136
+ * Subtracts y from x and records the result
137
+ * @param calc Pointer to the calculator
138
+ * @param x First number
139
+ * @param y Second number
140
+ * @return The difference x - y
141
+ */
142
+ double subtract_numbers(Calculator* calc, double x, double y) {
143
+ double result = x - y;
144
+ if (calc != NULL) {
145
+ record_operation(calc, result);
146
+ }
147
+ return result;
148
+ }
149
+
150
+ /**
151
+ * Multiplies two numbers and records the result
152
+ * @param calc Pointer to the calculator
153
+ * @param x First number
154
+ * @param y Second number
155
+ * @return The product of x and y
156
+ */
157
+ double multiply_numbers(Calculator* calc, double x, double y) {
158
+ double result = x * y;
159
+ if (calc != NULL) {
160
+ record_operation(calc, result);
161
+ }
162
+ return result;
163
+ }
164
+
165
+ /**
166
+ * Divides x by y and records the result
167
+ * @param calc Pointer to the calculator
168
+ * @param x Dividend
169
+ * @param y Divisor
170
+ * @return The quotient x / y, or NAN if y is zero
171
+ */
172
+ double divide_numbers(Calculator* calc, double x, double y) {
173
+ double result;
174
+ if (fabs(y) < DEFAULT_PRECISION) {
175
+ result = NAN;
176
+ } else {
177
+ result = x / y;
178
+ }
179
+
180
+ if (calc != NULL && !isnan(result)) {
181
+ record_operation(calc, result);
182
+ }
183
+ return result;
184
+ }
185
+
186
+ /**
187
+ * Gets the number of operations in history
188
+ * @param calc Pointer to the calculator
189
+ * @return Number of operations or -1 if calc is NULL
190
+ */
191
+ int get_history_count(const Calculator* calc) {
192
+ if (calc == NULL) {
193
+ return -1;
194
+ }
195
+ return calc->count;
196
+ }
197
+
198
+ /**
199
+ * Gets a pointer to the calculator's history array
200
+ * @param calc Pointer to the calculator
201
+ * @return Pointer to history array or NULL if calc is NULL
202
+ */
203
+ double* get_history(const Calculator* calc) {
204
+ if (calc == NULL) {
205
+ return NULL;
206
+ }
207
+ return calc->history;
208
+ }
209
+
210
+ /**
211
+ * Prints the calculator's history to stdout
212
+ * @param calc Pointer to the calculator
213
+ */
214
+ void print_history(const Calculator* calc) {
215
+ if (calc == NULL) {
216
+ printf("Calculator is NULL\n");
217
+ return;
218
+ }
219
+
220
+ printf("History for calculator '%s':\n", calc->name);
221
+ for (int i = 0; i < calc->count; i++) {
222
+ printf(" %d: %.2f\n", i + 1, calc->history[i]);
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Clears the calculator's history
228
+ * @param calc Pointer to the calculator
229
+ */
230
+ void clear_history(Calculator* calc) {
231
+ if (calc != NULL) {
232
+ calc->count = 0;
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Main function demonstrating calculator usage
238
+ */
239
+ int main(int argc, char* argv[]) {
240
+ Calculator* calc = create_calculator("Main Calculator");
241
+ if (calc == NULL) {
242
+ fprintf(stderr, "Failed to create calculator\n");
243
+ return 1;
244
+ }
245
+
246
+ // Perform some calculations
247
+ double result1 = add_numbers(calc, 10.5, 20.3);
248
+ double result2 = multiply_numbers(calc, 5.0, 7.0);
249
+ double result3 = divide_numbers(calc, 100.0, 4.0);
250
+
251
+ printf("Results: %.2f, %.2f, %.2f\n", result1, result2, result3);
252
+
253
+ // Print history
254
+ print_history(calc);
255
+
256
+ // Cleanup
257
+ destroy_calculator(calc);
258
+
259
+ return 0;
260
+ }
261
+ "#;
262
+
263
+ fs::write(&test_file, content)?;
264
+
265
+ let ctx = TestContext::new();
266
+ let output = ctx.run_probe(&[
267
+ "search",
268
+ "Calculator",
269
+ test_file.to_str().unwrap(),
270
+ "--format",
271
+ "outline",
272
+ "--allow-tests",
273
+ ])?;
274
+
275
+ // Verify C outline format features
276
+ assert!(
277
+ output.contains("Calculator"),
278
+ "Missing Calculator in search results - output: {}",
279
+ output
280
+ );
281
+ assert!(
282
+ output.contains("..."),
283
+ "Missing truncation ellipsis in outline format - output: {}",
284
+ output
285
+ );
286
+ // Look for C-specific comment syntax in closing braces or structure
287
+ let has_c_syntax = output.contains("typedef struct")
288
+ || output.contains("Calculator*")
289
+ || output.contains("void destroy_calculator")
290
+ || output.contains("//");
291
+ assert!(
292
+ has_c_syntax,
293
+ "Missing C-specific syntax in outline format - output: {}",
294
+ output
295
+ );
296
+
297
+ Ok(())
298
+ }
299
+
300
+ #[test]
301
+ fn test_c_outline_control_flow_statements() -> Result<()> {
302
+ let temp_dir = TempDir::new()?;
303
+ let test_file = temp_dir.path().join("control_flow.c");
304
+
305
+ let content = r#"#include <stdio.h>
306
+ #include <stdlib.h>
307
+ #include <string.h>
308
+
309
+ /**
310
+ * Complex algorithm demonstrating various control flow statements with gaps
311
+ */
312
+ int* complex_algorithm(int* data, int size, int threshold, int* result_size) {
313
+ if (data == NULL || size <= 0) {
314
+ *result_size = 0;
315
+ return NULL;
316
+ }
317
+
318
+ int* result = malloc(size * sizeof(int));
319
+ if (result == NULL) {
320
+ *result_size = 0;
321
+ return NULL;
322
+ }
323
+
324
+ int count = 0;
325
+ int counter = 0;
326
+
327
+ // First processing phase with for loop
328
+ for (int i = 0; i < size; i++) {
329
+ int item = data[i];
330
+
331
+ if (item > threshold) {
332
+ counter++;
333
+
334
+ // Complex nested conditions
335
+ if (counter % 2 == 0) {
336
+ result[count++] = item * 2;
337
+ } else {
338
+ result[count++] = item + 10;
339
+ }
340
+
341
+ // Additional processing with switch
342
+ switch (item % 4) {
343
+ case 0:
344
+ result[count - 1] += 100;
345
+ break;
346
+ case 1:
347
+ result[count - 1] += 10;
348
+ break;
349
+ case 2:
350
+ result[count - 1] += 1;
351
+ break;
352
+ default:
353
+ result[count - 1] -= 5;
354
+ break;
355
+ }
356
+ }
357
+ }
358
+
359
+ // Second processing phase with while loop
360
+ int index = 0;
361
+ while (index < count) {
362
+ int value = result[index];
363
+
364
+ if (value < 0) {
365
+ // Remove negative values by shifting
366
+ for (int j = index; j < count - 1; j++) {
367
+ result[j] = result[j + 1];
368
+ }
369
+ count--;
370
+ } else if (value > 1000) {
371
+ // Cap large values
372
+ result[index] = 1000;
373
+ index++;
374
+ } else {
375
+ index++;
376
+ }
377
+ }
378
+
379
+ *result_size = count;
380
+ return result;
381
+ }
382
+
383
+ /**
384
+ * Process matrix with nested loops demonstrating closing brace comments
385
+ */
386
+ int** process_matrix(int** matrix, int rows, int cols) {
387
+ if (matrix == NULL || rows <= 0 || cols <= 0) {
388
+ return NULL;
389
+ }
390
+
391
+ // Allocate result matrix
392
+ int** processed = malloc(rows * sizeof(int*));
393
+ if (processed == NULL) {
394
+ return NULL;
395
+ }
396
+
397
+ for (int i = 0; i < rows; i++) {
398
+ processed[i] = malloc(cols * sizeof(int));
399
+ if (processed[i] == NULL) {
400
+ // Cleanup on failure
401
+ for (int j = 0; j < i; j++) {
402
+ free(processed[j]);
403
+ }
404
+ free(processed);
405
+ return NULL;
406
+ }
407
+
408
+ // Process each row
409
+ for (int j = 0; j < cols; j++) {
410
+ int cell = matrix[i][j];
411
+ int processed_cell;
412
+
413
+ if (cell > 0) {
414
+ processed_cell = cell * 2;
415
+ } else if (cell < 0) {
416
+ processed_cell = abs(cell);
417
+ } else {
418
+ processed_cell = 1;
419
+ }
420
+
421
+ processed[i][j] = processed_cell;
422
+ }
423
+ }
424
+
425
+ return processed;
426
+ }
427
+
428
+ /**
429
+ * Analyze data with complex switch statement and error handling
430
+ */
431
+ const char* analyze_data(int value, char* buffer, size_t buffer_size) {
432
+ if (buffer == NULL || buffer_size == 0) {
433
+ return "ERROR: Invalid buffer";
434
+ }
435
+
436
+ const char* result;
437
+
438
+ switch (value) {
439
+ case 0:
440
+ result = "ZERO";
441
+ break;
442
+
443
+ case 1:
444
+ case 2:
445
+ case 3:
446
+ case 4:
447
+ case 5:
448
+ result = "SMALL_POSITIVE";
449
+ break;
450
+
451
+ case -1:
452
+ case -2:
453
+ case -3:
454
+ case -4:
455
+ case -5:
456
+ result = "SMALL_NEGATIVE";
457
+ break;
458
+
459
+ default:
460
+ if (value > 5 && value <= 100) {
461
+ result = "MEDIUM_POSITIVE";
462
+ } else if (value > 100 && value <= 1000) {
463
+ result = "LARGE_POSITIVE";
464
+ } else if (value < -5 && value >= -100) {
465
+ result = "MEDIUM_NEGATIVE";
466
+ } else if (value < -100) {
467
+ result = "LARGE_NEGATIVE";
468
+ } else {
469
+ result = "VERY_LARGE_POSITIVE";
470
+ }
471
+ break;
472
+ }
473
+
474
+ // Copy result to buffer with bounds checking
475
+ size_t result_len = strlen(result);
476
+ if (result_len >= buffer_size) {
477
+ strncpy(buffer, result, buffer_size - 1);
478
+ buffer[buffer_size - 1] = '\0';
479
+ } else {
480
+ strcpy(buffer, result);
481
+ }
482
+
483
+ return buffer;
484
+ }
485
+
486
+ /**
487
+ * Recursive function with complex termination conditions
488
+ */
489
+ long factorial_with_memoization(int n, long* memo, int memo_size) {
490
+ // Base cases
491
+ if (n < 0) {
492
+ return -1; // Error case
493
+ }
494
+
495
+ if (n == 0 || n == 1) {
496
+ return 1;
497
+ }
498
+
499
+ // Check memoization
500
+ if (n < memo_size && memo[n] != 0) {
501
+ return memo[n];
502
+ }
503
+
504
+ // Recursive calculation with loop for large values
505
+ long result = 1;
506
+ if (n > 20) {
507
+ // Use iterative approach for large values to avoid stack overflow
508
+ for (int i = 2; i <= n; i++) {
509
+ result *= i;
510
+
511
+ // Check for overflow
512
+ if (result < 0) {
513
+ return -1;
514
+ }
515
+ }
516
+ } else {
517
+ // Use recursion for smaller values
518
+ result = n * factorial_with_memoization(n - 1, memo, memo_size);
519
+ }
520
+
521
+ // Store in memo if space available
522
+ if (n < memo_size) {
523
+ memo[n] = result;
524
+ }
525
+
526
+ return result;
527
+ }
528
+ "#;
529
+
530
+ fs::write(&test_file, content)?;
531
+
532
+ let ctx = TestContext::new();
533
+ let output = ctx.run_probe(&[
534
+ "search",
535
+ "complex_algorithm",
536
+ test_file.to_str().unwrap(),
537
+ "--format",
538
+ "outline",
539
+ "--allow-tests",
540
+ ])?;
541
+
542
+ // Verify outline format for complex algorithm with control flow
543
+ assert!(
544
+ output.contains("complex_algorithm"),
545
+ "Missing complex_algorithm function - output: {}",
546
+ output
547
+ );
548
+ assert!(
549
+ output.contains("..."),
550
+ "Missing truncation ellipsis in outline format - output: {}",
551
+ output
552
+ );
553
+ // Should contain closing brace comment for function
554
+ assert!(
555
+ output.contains("} //") || output.contains("}//") || output.contains("} /*"),
556
+ "Missing closing brace comment for function - output: {}",
557
+ output
558
+ );
559
+ // Should show C function signature patterns
560
+ let has_c_function_pattern = output.contains("int*")
561
+ || output.contains("char**")
562
+ || output.contains("(")
563
+ || output.contains(")");
564
+ assert!(
565
+ has_c_function_pattern,
566
+ "Missing C function signature patterns - output: {}",
567
+ output
568
+ );
569
+
570
+ Ok(())
571
+ }
572
+
573
+ #[test]
574
+ fn test_c_outline_structs_and_unions() -> Result<()> {
575
+ let temp_dir = TempDir::new()?;
576
+ let test_file = temp_dir.path().join("structs_unions.c");
577
+
578
+ let content = r#"#include <stdio.h>
579
+ #include <stdlib.h>
580
+ #include <string.h>
581
+ #include <stdint.h>
582
+
583
+ // Complex struct definitions with various member types
584
+ typedef struct Point {
585
+ double x;
586
+ double y;
587
+ } Point;
588
+
589
+ typedef struct Rectangle {
590
+ Point top_left;
591
+ Point bottom_right;
592
+ char label[32];
593
+ uint32_t color;
594
+ } Rectangle;
595
+
596
+ typedef struct Circle {
597
+ Point center;
598
+ double radius;
599
+ char label[32];
600
+ uint32_t color;
601
+ } Circle;
602
+
603
+ // Union for different shape types
604
+ typedef union ShapeData {
605
+ Rectangle rect;
606
+ Circle circle;
607
+ } ShapeData;
608
+
609
+ typedef enum {
610
+ SHAPE_RECTANGLE,
611
+ SHAPE_CIRCLE,
612
+ SHAPE_TRIANGLE
613
+ } ShapeType;
614
+
615
+ // Complex struct with nested structures and function pointers
616
+ typedef struct Shape {
617
+ ShapeType type;
618
+ ShapeData data;
619
+ double (*area_func)(const struct Shape* shape);
620
+ double (*perimeter_func)(const struct Shape* shape);
621
+ void (*print_func)(const struct Shape* shape);
622
+ struct Shape* next; // For linked list
623
+ } Shape;
624
+
625
+ // Function pointer typedef
626
+ typedef void (*ProcessFunc)(void* data, size_t size);
627
+
628
+ // Complex data structure
629
+ typedef struct DataProcessor {
630
+ char name[64];
631
+ ProcessFunc process_func;
632
+ void* context;
633
+ size_t buffer_size;
634
+ uint8_t* buffer;
635
+ struct {
636
+ uint64_t total_processed;
637
+ uint32_t operations_count;
638
+ double average_time;
639
+ } stats;
640
+ } DataProcessor;
641
+
642
+ // Bit field structure
643
+ typedef struct StatusFlags {
644
+ unsigned int initialized : 1;
645
+ unsigned int error : 1;
646
+ unsigned int processing : 1;
647
+ unsigned int completed : 1;
648
+ unsigned int reserved : 28;
649
+ } StatusFlags;
650
+
651
+ // Forward declarations
652
+ double rectangle_area(const Shape* shape);
653
+ double rectangle_perimeter(const Shape* shape);
654
+ void print_rectangle(const Shape* shape);
655
+ double circle_area(const Shape* shape);
656
+ double circle_perimeter(const Shape* shape);
657
+ void print_circle(const Shape* shape);
658
+
659
+ // Function implementations
660
+
661
+ /**
662
+ * Creates a new rectangle shape
663
+ */
664
+ Shape* create_rectangle(double x1, double y1, double x2, double y2, const char* label, uint32_t color) {
665
+ Shape* shape = malloc(sizeof(Shape));
666
+ if (shape == NULL) {
667
+ return NULL;
668
+ }
669
+
670
+ shape->type = SHAPE_RECTANGLE;
671
+ shape->data.rect.top_left.x = x1 < x2 ? x1 : x2;
672
+ shape->data.rect.top_left.y = y1 > y2 ? y1 : y2;
673
+ shape->data.rect.bottom_right.x = x1 > x2 ? x1 : x2;
674
+ shape->data.rect.bottom_right.y = y1 < y2 ? y1 : y2;
675
+
676
+ strncpy(shape->data.rect.label, label, sizeof(shape->data.rect.label) - 1);
677
+ shape->data.rect.label[sizeof(shape->data.rect.label) - 1] = '\0';
678
+ shape->data.rect.color = color;
679
+
680
+ shape->area_func = rectangle_area;
681
+ shape->perimeter_func = rectangle_perimeter;
682
+ shape->print_func = print_rectangle;
683
+ shape->next = NULL;
684
+
685
+ return shape;
686
+ }
687
+
688
+ /**
689
+ * Creates a new circle shape
690
+ */
691
+ Shape* create_circle(double cx, double cy, double radius, const char* label, uint32_t color) {
692
+ Shape* shape = malloc(sizeof(Shape));
693
+ if (shape == NULL) {
694
+ return NULL;
695
+ }
696
+
697
+ shape->type = SHAPE_CIRCLE;
698
+ shape->data.circle.center.x = cx;
699
+ shape->data.circle.center.y = cy;
700
+ shape->data.circle.radius = radius > 0 ? radius : 1.0;
701
+
702
+ strncpy(shape->data.circle.label, label, sizeof(shape->data.circle.label) - 1);
703
+ shape->data.circle.label[sizeof(shape->data.circle.label) - 1] = '\0';
704
+ shape->data.circle.color = color;
705
+
706
+ shape->area_func = circle_area;
707
+ shape->perimeter_func = circle_perimeter;
708
+ shape->print_func = print_circle;
709
+ shape->next = NULL;
710
+
711
+ return shape;
712
+ }
713
+
714
+ /**
715
+ * Calculates rectangle area
716
+ */
717
+ double rectangle_area(const Shape* shape) {
718
+ if (shape == NULL || shape->type != SHAPE_RECTANGLE) {
719
+ return 0.0;
720
+ }
721
+
722
+ const Rectangle* rect = &shape->data.rect;
723
+ double width = rect->bottom_right.x - rect->top_left.x;
724
+ double height = rect->top_left.y - rect->bottom_right.y;
725
+
726
+ return width * height;
727
+ }
728
+
729
+ /**
730
+ * Calculates rectangle perimeter
731
+ */
732
+ double rectangle_perimeter(const Shape* shape) {
733
+ if (shape == NULL || shape->type != SHAPE_RECTANGLE) {
734
+ return 0.0;
735
+ }
736
+
737
+ const Rectangle* rect = &shape->data.rect;
738
+ double width = rect->bottom_right.x - rect->top_left.x;
739
+ double height = rect->top_left.y - rect->bottom_right.y;
740
+
741
+ return 2.0 * (width + height);
742
+ }
743
+
744
+ /**
745
+ * Prints rectangle information
746
+ */
747
+ void print_rectangle(const Shape* shape) {
748
+ if (shape == NULL || shape->type != SHAPE_RECTANGLE) {
749
+ printf("Invalid rectangle\n");
750
+ return;
751
+ }
752
+
753
+ const Rectangle* rect = &shape->data.rect;
754
+ printf("Rectangle '%s': (%.2f,%.2f) to (%.2f,%.2f), Color: 0x%08X\n",
755
+ rect->label,
756
+ rect->top_left.x, rect->top_left.y,
757
+ rect->bottom_right.x, rect->bottom_right.y,
758
+ rect->color);
759
+ }
760
+
761
+ /**
762
+ * Calculates circle area
763
+ */
764
+ double circle_area(const Shape* shape) {
765
+ if (shape == NULL || shape->type != SHAPE_CIRCLE) {
766
+ return 0.0;
767
+ }
768
+
769
+ const Circle* circle = &shape->data.circle;
770
+ return 3.14159 * circle->radius * circle->radius;
771
+ }
772
+
773
+ /**
774
+ * Calculates circle perimeter
775
+ */
776
+ double circle_perimeter(const Shape* shape) {
777
+ if (shape == NULL || shape->type != SHAPE_CIRCLE) {
778
+ return 0.0;
779
+ }
780
+
781
+ const Circle* circle = &shape->data.circle;
782
+ return 2.0 * 3.14159 * circle->radius;
783
+ }
784
+
785
+ /**
786
+ * Prints circle information
787
+ */
788
+ void print_circle(const Shape* shape) {
789
+ if (shape == NULL || shape->type != SHAPE_CIRCLE) {
790
+ printf("Invalid circle\n");
791
+ return;
792
+ }
793
+
794
+ const Circle* circle = &shape->data.circle;
795
+ printf("Circle '%s': Center (%.2f,%.2f), Radius %.2f, Color: 0x%08X\n",
796
+ circle->label,
797
+ circle->center.x, circle->center.y,
798
+ circle->radius,
799
+ circle->color);
800
+ }
801
+
802
+ /**
803
+ * Creates a data processor with specified parameters
804
+ */
805
+ DataProcessor* create_data_processor(const char* name, ProcessFunc func, size_t buffer_size) {
806
+ DataProcessor* processor = malloc(sizeof(DataProcessor));
807
+ if (processor == NULL) {
808
+ return NULL;
809
+ }
810
+
811
+ strncpy(processor->name, name, sizeof(processor->name) - 1);
812
+ processor->name[sizeof(processor->name) - 1] = '\0';
813
+
814
+ processor->process_func = func;
815
+ processor->context = NULL;
816
+ processor->buffer_size = buffer_size;
817
+
818
+ if (buffer_size > 0) {
819
+ processor->buffer = malloc(buffer_size);
820
+ if (processor->buffer == NULL) {
821
+ free(processor);
822
+ return NULL;
823
+ }
824
+ } else {
825
+ processor->buffer = NULL;
826
+ }
827
+
828
+ // Initialize stats
829
+ processor->stats.total_processed = 0;
830
+ processor->stats.operations_count = 0;
831
+ processor->stats.average_time = 0.0;
832
+
833
+ return processor;
834
+ }
835
+
836
+ /**
837
+ * Destroys a data processor and frees memory
838
+ */
839
+ void destroy_data_processor(DataProcessor* processor) {
840
+ if (processor != NULL) {
841
+ if (processor->buffer != NULL) {
842
+ free(processor->buffer);
843
+ }
844
+ free(processor);
845
+ }
846
+ }
847
+
848
+ /**
849
+ * Destroys a shape and frees memory
850
+ */
851
+ void destroy_shape(Shape* shape) {
852
+ if (shape != NULL) {
853
+ free(shape);
854
+ }
855
+ }
856
+ "#;
857
+
858
+ fs::write(&test_file, content)?;
859
+
860
+ let ctx = TestContext::new();
861
+ let output = ctx.run_probe(&[
862
+ "search",
863
+ "Shape",
864
+ test_file.to_str().unwrap(),
865
+ "--format",
866
+ "outline",
867
+ "--allow-tests",
868
+ ])?;
869
+
870
+ // Verify outline format for struct and union patterns
871
+ assert!(
872
+ output.contains("Shape"),
873
+ "Missing Shape-related symbols - output: {}",
874
+ output
875
+ );
876
+ assert!(
877
+ output.contains("..."),
878
+ "Missing truncation ellipsis in outline format - output: {}",
879
+ output
880
+ );
881
+ // Should show C struct/union/typedef patterns
882
+ let has_c_type_patterns = output.contains("typedef")
883
+ || output.contains("struct")
884
+ || output.contains("union")
885
+ || output.contains("*")
886
+ || output.contains("Rectangle")
887
+ || output.contains("Circle");
888
+ assert!(
889
+ has_c_type_patterns,
890
+ "Missing C type definition patterns - output: {}",
891
+ output
892
+ );
893
+
894
+ Ok(())
895
+ }
896
+
897
+ #[test]
898
+ fn test_c_outline_preprocessor_and_macros() -> Result<()> {
899
+ let temp_dir = TempDir::new()?;
900
+ let test_file = temp_dir.path().join("preprocessor.c");
901
+
902
+ let content = r#"// Complex C preprocessor directives and macros
903
+ #include <stdio.h>
904
+ #include <stdlib.h>
905
+ #include <stdint.h>
906
+
907
+ // Configuration macros
908
+ #define VERSION_MAJOR 2
909
+ #define VERSION_MINOR 1
910
+ #define VERSION_PATCH 0
911
+ #define VERSION_STRING "2.1.0"
912
+
913
+ #ifdef DEBUG
914
+ #define DBG_PRINT(fmt, ...) printf("[DEBUG] " fmt "\n", ##__VA_ARGS__)
915
+ #else
916
+ #define DBG_PRINT(fmt, ...) do {} while(0)
917
+ #endif
918
+
919
+ // Utility macros
920
+ #define MAX(a, b) ((a) > (b) ? (a) : (b))
921
+ #define MIN(a, b) ((a) < (b) ? (a) : (b))
922
+ #define CLAMP(value, min_val, max_val) MIN(MAX(value, min_val), max_val)
923
+
924
+ // Array size calculation
925
+ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
926
+
927
+ // Bit manipulation macros
928
+ #define SET_BIT(value, bit) ((value) |= (1 << (bit)))
929
+ #define CLEAR_BIT(value, bit) ((value) &= ~(1 << (bit)))
930
+ #define TEST_BIT(value, bit) ((value) & (1 << (bit)))
931
+
932
+ // Complex macro with multiple statements
933
+ #define SAFE_FREE(ptr) do { \
934
+ if ((ptr) != NULL) { \
935
+ free(ptr); \
936
+ (ptr) = NULL; \
937
+ } \
938
+ } while(0)
939
+
940
+ // Conditional compilation for different platforms
941
+ #ifdef _WIN32
942
+ #define PLATFORM "Windows"
943
+ #define PATH_SEPARATOR '\\'
944
+ #elif defined(__linux__)
945
+ #define PLATFORM "Linux"
946
+ #define PATH_SEPARATOR '/'
947
+ #elif defined(__APPLE__)
948
+ #define PLATFORM "macOS"
949
+ #define PATH_SEPARATOR '/'
950
+ #else
951
+ #define PLATFORM "Unknown"
952
+ #define PATH_SEPARATOR '/'
953
+ #endif
954
+
955
+ // Feature flags
956
+ #if VERSION_MAJOR >= 2
957
+ #define FEATURE_ADVANCED_MATH 1
958
+ #define FEATURE_LOGGING 1
959
+ #else
960
+ #define FEATURE_ADVANCED_MATH 0
961
+ #define FEATURE_LOGGING 0
962
+ #endif
963
+
964
+ // Compiler-specific attributes
965
+ #if defined(__GNUC__) || defined(__clang__)
966
+ #define FORCE_INLINE __attribute__((always_inline)) inline
967
+ #define NO_RETURN __attribute__((noreturn))
968
+ #define UNUSED __attribute__((unused))
969
+ #elif defined(_MSC_VER)
970
+ #define FORCE_INLINE __forceinline
971
+ #define NO_RETURN __declspec(noreturn)
972
+ #define UNUSED
973
+ #else
974
+ #define FORCE_INLINE inline
975
+ #define NO_RETURN
976
+ #define UNUSED
977
+ #endif
978
+
979
+ // Type definitions with macros
980
+ typedef struct {
981
+ uint32_t flags;
982
+ char platform[16];
983
+ int version_major;
984
+ int version_minor;
985
+ int version_patch;
986
+ } SystemInfo;
987
+
988
+ /**
989
+ * Function using preprocessor features
990
+ */
991
+ SystemInfo* get_system_info(void) {
992
+ static SystemInfo info = {0};
993
+ static int initialized = 0;
994
+
995
+ if (!initialized) {
996
+ strcpy(info.platform, PLATFORM);
997
+ info.version_major = VERSION_MAJOR;
998
+ info.version_minor = VERSION_MINOR;
999
+ info.version_patch = VERSION_PATCH;
1000
+
1001
+ #if FEATURE_ADVANCED_MATH
1002
+ SET_BIT(info.flags, 0); // Math feature flag
1003
+ #endif
1004
+
1005
+ #if FEATURE_LOGGING
1006
+ SET_BIT(info.flags, 1); // Logging feature flag
1007
+ #endif
1008
+
1009
+ initialized = 1;
1010
+ DBG_PRINT("System info initialized for %s", PLATFORM);
1011
+ }
1012
+
1013
+ return &info;
1014
+ }
1015
+
1016
+ /**
1017
+ * Function demonstrating macro usage
1018
+ */
1019
+ int* process_array(int* array, size_t size) {
1020
+ if (array == NULL || size == 0) {
1021
+ DBG_PRINT("Invalid array parameters");
1022
+ return NULL;
1023
+ }
1024
+
1025
+ int* result = malloc(size * sizeof(int));
1026
+ if (result == NULL) {
1027
+ DBG_PRINT("Failed to allocate memory for %zu elements", size);
1028
+ return NULL;
1029
+ }
1030
+
1031
+ // Process using macros
1032
+ for (size_t i = 0; i < size; i++) {
1033
+ int value = array[i];
1034
+
1035
+ // Clamp value between 0 and 100
1036
+ result[i] = CLAMP(value, 0, 100);
1037
+
1038
+ DBG_PRINT("Processed array[%zu]: %d -> %d", i, value, result[i]);
1039
+ }
1040
+
1041
+ return result;
1042
+ }
1043
+
1044
+ /**
1045
+ * Utility function with inline optimization
1046
+ */
1047
+ FORCE_INLINE int fast_multiply(int a, int b) {
1048
+ return a * b;
1049
+ }
1050
+
1051
+ /**
1052
+ * Function that never returns
1053
+ */
1054
+ NO_RETURN void fatal_error(const char* message) {
1055
+ fprintf(stderr, "FATAL ERROR: %s\n", message);
1056
+ exit(1);
1057
+ }
1058
+
1059
+ /**
1060
+ * Function with conditional compilation
1061
+ */
1062
+ void print_features(void) {
1063
+ printf("Application Version: %s\n", VERSION_STRING);
1064
+ printf("Platform: %s\n", PLATFORM);
1065
+ printf("Path Separator: %c\n", PATH_SEPARATOR);
1066
+
1067
+ #if FEATURE_ADVANCED_MATH
1068
+ printf("Advanced Math: Enabled\n");
1069
+ #else
1070
+ printf("Advanced Math: Disabled\n");
1071
+ #endif
1072
+
1073
+ #if FEATURE_LOGGING
1074
+ printf("Logging: Enabled\n");
1075
+ #else
1076
+ printf("Logging: Disabled\n");
1077
+ #endif
1078
+
1079
+ SystemInfo* info = get_system_info();
1080
+ printf("System Flags: 0x%08X\n", info->flags);
1081
+ }
1082
+
1083
+ /**
1084
+ * Main function demonstrating all features
1085
+ */
1086
+ int main(void) {
1087
+ print_features();
1088
+
1089
+ int test_array[] = {-10, 25, 150, 75, -5, 200};
1090
+ size_t array_size = ARRAY_SIZE(test_array);
1091
+
1092
+ printf("\nOriginal array size: %zu\n", array_size);
1093
+
1094
+ int* processed = process_array(test_array, array_size);
1095
+ if (processed != NULL) {
1096
+ printf("Processed array: ");
1097
+ for (size_t i = 0; i < array_size; i++) {
1098
+ printf("%d ", processed[i]);
1099
+ }
1100
+ printf("\n");
1101
+
1102
+ SAFE_FREE(processed);
1103
+ }
1104
+
1105
+ // Test inline function
1106
+ int product = fast_multiply(7, 8);
1107
+ printf("Fast multiply result: %d\n", product);
1108
+
1109
+ return 0;
1110
+ }
1111
+
1112
+ // Clean up macros if needed
1113
+ #undef DBG_PRINT
1114
+ #undef SAFE_FREE
1115
+ "#;
1116
+
1117
+ fs::write(&test_file, content)?;
1118
+
1119
+ let ctx = TestContext::new();
1120
+ let output = ctx.run_probe(&[
1121
+ "search",
1122
+ "get_system_info",
1123
+ test_file.to_str().unwrap(),
1124
+ "--format",
1125
+ "outline",
1126
+ "--allow-tests",
1127
+ ])?;
1128
+
1129
+ // Verify outline format for preprocessor and macros
1130
+ assert!(
1131
+ output.contains("get_system_info"),
1132
+ "Missing get_system_info function - output: {}",
1133
+ output
1134
+ );
1135
+ assert!(
1136
+ output.contains("..."),
1137
+ "Missing truncation ellipsis in outline format - output: {}",
1138
+ output
1139
+ );
1140
+ // Should show C preprocessor patterns and function signatures
1141
+ let has_c_preprocessor_patterns = output.contains("SystemInfo")
1142
+ || output.contains("#if")
1143
+ || output.contains("void")
1144
+ || output.contains("*")
1145
+ || output.contains("printf");
1146
+ assert!(
1147
+ has_c_preprocessor_patterns,
1148
+ "Missing C preprocessor and function patterns - output: {}",
1149
+ output
1150
+ );
1151
+
1152
+ Ok(())
1153
+ }
1154
+
1155
+ #[test]
1156
+ fn test_c_outline_large_function_closing_braces() -> Result<()> {
1157
+ let temp_dir = TempDir::new()?;
1158
+ let test_file = temp_dir.path().join("large_function.c");
1159
+
1160
+ let content = r#"#include <stdio.h>
1161
+ #include <stdlib.h>
1162
+ #include <string.h>
1163
+ #include <ctype.h>
1164
+
1165
+ /**
1166
+ * Large function with multiple nested blocks to test closing brace comments
1167
+ */
1168
+ char** complex_text_processor(char** input, int input_count, int* output_count) {
1169
+ if (input == NULL || input_count <= 0 || output_count == NULL) {
1170
+ *output_count = 0;
1171
+ return NULL;
1172
+ }
1173
+
1174
+ // Initialize output array
1175
+ char** output = malloc(input_count * 2 * sizeof(char*));
1176
+ if (output == NULL) {
1177
+ *output_count = 0;
1178
+ return NULL;
1179
+ }
1180
+
1181
+ int current_output = 0;
1182
+ char* categories[10] = {"short", "medium", "long", "email", "url", "number",
1183
+ "uppercase", "lowercase", "mixed", "special"};
1184
+
1185
+ // Phase 1: Categorize and validate input
1186
+ for (int i = 0; i < input_count; i++) {
1187
+ char* text = input[i];
1188
+ if (text == NULL || strlen(text) == 0) {
1189
+ printf("Warning: empty text at index %d\n", i);
1190
+ continue;
1191
+ }
1192
+
1193
+ size_t len = strlen(text);
1194
+ char* processed = malloc(len + 100); // Extra space for modifications
1195
+ if (processed == NULL) {
1196
+ printf("Memory allocation failed for index %d\n", i);
1197
+ continue;
1198
+ }
1199
+
1200
+ // Determine category and process accordingly
1201
+ if (len <= 10) {
1202
+ // Short text processing
1203
+ strcpy(processed, "SHORT: ");
1204
+
1205
+ // Check if numeric
1206
+ int is_numeric = 1;
1207
+ for (size_t j = 0; j < len; j++) {
1208
+ if (!isdigit(text[j])) {
1209
+ is_numeric = 0;
1210
+ break;
1211
+ }
1212
+ }
1213
+
1214
+ if (is_numeric) {
1215
+ strcat(processed, "NUM_");
1216
+ strcat(processed, text);
1217
+ } else {
1218
+ // Convert to uppercase
1219
+ for (size_t j = 0; j < len; j++) {
1220
+ if (islower(text[j])) {
1221
+ processed[7 + j] = toupper(text[j]);
1222
+ } else {
1223
+ processed[7 + j] = text[j];
1224
+ }
1225
+ }
1226
+ processed[7 + len] = '\0';
1227
+ }
1228
+
1229
+ } else if (len <= 50) {
1230
+ // Medium text processing
1231
+ strcpy(processed, "MEDIUM: ");
1232
+
1233
+ // Check for email pattern
1234
+ if (strchr(text, '@') != NULL && strchr(text, '.') != NULL) {
1235
+ strcat(processed, "EMAIL_");
1236
+ strncat(processed, text, 30); // Truncate long emails
1237
+ } else if (strncmp(text, "http", 4) == 0) {
1238
+ strcat(processed, "URL_");
1239
+ strncat(processed, text, 30); // Truncate long URLs
1240
+ } else {
1241
+ // Title case conversion
1242
+ int capitalize_next = 1;
1243
+ size_t processed_len = strlen(processed);
1244
+
1245
+ for (size_t j = 0; j < len && processed_len + j < len + 99; j++) {
1246
+ if (isspace(text[j])) {
1247
+ processed[processed_len + j] = text[j];
1248
+ capitalize_next = 1;
1249
+ } else if (capitalize_next && isalpha(text[j])) {
1250
+ processed[processed_len + j] = toupper(text[j]);
1251
+ capitalize_next = 0;
1252
+ } else {
1253
+ processed[processed_len + j] = tolower(text[j]);
1254
+ }
1255
+ }
1256
+ processed[processed_len + len] = '\0';
1257
+ }
1258
+
1259
+ } else {
1260
+ // Long text processing
1261
+ strcpy(processed, "LONG: ");
1262
+
1263
+ // Count character types
1264
+ int uppercase_count = 0, lowercase_count = 0, digit_count = 0, special_count = 0;
1265
+
1266
+ for (size_t j = 0; j < len; j++) {
1267
+ if (isupper(text[j])) {
1268
+ uppercase_count++;
1269
+ } else if (islower(text[j])) {
1270
+ lowercase_count++;
1271
+ } else if (isdigit(text[j])) {
1272
+ digit_count++;
1273
+ } else {
1274
+ special_count++;
1275
+ }
1276
+ }
1277
+
1278
+ // Determine dominant character type
1279
+ if (uppercase_count > lowercase_count && uppercase_count > digit_count) {
1280
+ strcat(processed, "UPPER_DOM: ");
1281
+ } else if (lowercase_count > uppercase_count && lowercase_count > digit_count) {
1282
+ strcat(processed, "LOWER_DOM: ");
1283
+ } else if (digit_count > uppercase_count && digit_count > lowercase_count) {
1284
+ strcat(processed, "DIGIT_DOM: ");
1285
+ } else {
1286
+ strcat(processed, "MIXED_DOM: ");
1287
+ }
1288
+
1289
+ // Truncate and add summary
1290
+ size_t current_len = strlen(processed);
1291
+ if (len > 30) {
1292
+ strncat(processed, text, 30);
1293
+ strcat(processed, "...");
1294
+ sprintf(processed + strlen(processed), " (len=%zu)", len);
1295
+ } else {
1296
+ strcat(processed, text);
1297
+ }
1298
+ }
1299
+
1300
+ output[current_output++] = processed;
1301
+ }
1302
+
1303
+ // Phase 2: Sort results by category
1304
+ for (int i = 0; i < current_output - 1; i++) {
1305
+ for (int j = i + 1; j < current_output; j++) {
1306
+ if (strcmp(output[i], output[j]) > 0) {
1307
+ char* temp = output[i];
1308
+ output[i] = output[j];
1309
+ output[j] = temp;
1310
+ }
1311
+ }
1312
+ }
1313
+
1314
+ // Phase 3: Final validation and cleanup
1315
+ int final_count = 0;
1316
+ for (int i = 0; i < current_output; i++) {
1317
+ if (output[i] != NULL && strlen(output[i]) > 0) {
1318
+ if (final_count != i) {
1319
+ output[final_count] = output[i];
1320
+ }
1321
+ final_count++;
1322
+ } else {
1323
+ free(output[i]);
1324
+ }
1325
+ }
1326
+
1327
+ *output_count = final_count;
1328
+ return output;
1329
+ }
1330
+ "#;
1331
+
1332
+ fs::write(&test_file, content)?;
1333
+
1334
+ let ctx = TestContext::new();
1335
+ let output = ctx.run_probe(&[
1336
+ "search",
1337
+ "complex_text_processor",
1338
+ test_file.to_str().unwrap(),
1339
+ "--format",
1340
+ "outline",
1341
+ "--allow-tests",
1342
+ ])?;
1343
+
1344
+ // Verify outline format for large function with closing brace comments
1345
+ assert!(
1346
+ output.contains("complex_text_processor"),
1347
+ "Missing complex_text_processor function - output: {}",
1348
+ output
1349
+ );
1350
+ assert!(
1351
+ output.contains("..."),
1352
+ "Missing truncation ellipsis in outline format - output: {}",
1353
+ output
1354
+ );
1355
+ // Should have closing brace comment for the large function
1356
+ assert!(
1357
+ output.contains("} //") || output.contains("}//") || output.contains("} /*"),
1358
+ "Missing closing brace comment for large function - output: {}",
1359
+ output
1360
+ );
1361
+ // Should show C-specific patterns for large functions
1362
+ let has_c_patterns =
1363
+ output.contains("char**") || output.contains("int*") || output.contains("function");
1364
+ assert!(
1365
+ has_c_patterns,
1366
+ "Missing C-specific patterns for large function - output: {}",
1367
+ output
1368
+ );
1369
+
1370
+ Ok(())
1371
+ }
1372
+
1373
+ #[test]
1374
+ fn test_c_outline_search_command() -> Result<()> {
1375
+ let temp_dir = TempDir::new()?;
1376
+ let test_file = temp_dir.path().join("search_test.c");
1377
+
1378
+ let content = r#"#include <stdio.h>
1379
+ #include <stdlib.h>
1380
+
1381
+ typedef struct DataProcessor {
1382
+ int processed_count;
1383
+ double* data;
1384
+ size_t capacity;
1385
+ } DataProcessor;
1386
+
1387
+ DataProcessor* create_processor(size_t initial_capacity) {
1388
+ DataProcessor* processor = malloc(sizeof(DataProcessor));
1389
+ if (processor == NULL) return NULL;
1390
+
1391
+ processor->processed_count = 0;
1392
+ processor->capacity = initial_capacity;
1393
+ processor->data = malloc(initial_capacity * sizeof(double));
1394
+
1395
+ if (processor->data == NULL) {
1396
+ free(processor);
1397
+ return NULL;
1398
+ }
1399
+
1400
+ return processor;
1401
+ }
1402
+
1403
+ int process_data(DataProcessor* processor, double* input, size_t count) {
1404
+ if (processor == NULL || input == NULL) return -1;
1405
+
1406
+ for (size_t i = 0; i < count; i++) {
1407
+ if (input[i] != 0.0) {
1408
+ processor->data[processor->processed_count++] = input[i];
1409
+ }
1410
+ }
1411
+
1412
+ return processor->processed_count;
1413
+ }
1414
+
1415
+ char* process_file(const char* filename) {
1416
+ if (filename == NULL) return NULL;
1417
+
1418
+ size_t len = strlen(filename) + 20;
1419
+ char* result = malloc(len);
1420
+ if (result == NULL) return NULL;
1421
+
1422
+ snprintf(result, len, "Processed %s", filename);
1423
+ return result;
1424
+ }
1425
+
1426
+ void process_async(DataProcessor* processor, void (*callback)(int)) {
1427
+ if (processor == NULL || callback == NULL) return;
1428
+
1429
+ // Simulate async processing
1430
+ int result = processor->processed_count * 2;
1431
+ callback(result);
1432
+ }
1433
+
1434
+ void test_data_processing() {
1435
+ DataProcessor* processor = create_processor(100);
1436
+ if (processor == NULL) return;
1437
+
1438
+ double test_data[] = {1.0, 2.0, 0.0, 3.0};
1439
+ int count = process_data(processor, test_data, 4);
1440
+
1441
+ printf("Processed %d items\n", count);
1442
+
1443
+ free(processor->data);
1444
+ free(processor);
1445
+ }
1446
+ "#;
1447
+
1448
+ fs::write(&test_file, content)?;
1449
+
1450
+ let ctx = TestContext::new();
1451
+ let output = ctx.run_probe(&[
1452
+ "search",
1453
+ "process",
1454
+ temp_dir.path().to_str().unwrap(),
1455
+ "--format",
1456
+ "outline",
1457
+ "--allow-tests",
1458
+ ])?;
1459
+
1460
+ // Should find symbols containing "process"
1461
+ assert!(
1462
+ output.contains("DataProcessor")
1463
+ || output.contains("process_data")
1464
+ || output.contains("process_file")
1465
+ || output.contains("process_async"),
1466
+ "Should find process-related symbols - output: {}",
1467
+ output
1468
+ );
1469
+
1470
+ Ok(())
1471
+ }
1472
+ #[test]
1473
+ fn test_c_outline_closing_brace_comments_syntax() -> Result<()> {
1474
+ let temp_dir = TempDir::new()?;
1475
+ let test_file = temp_dir.path().join("closing_braces.c");
1476
+
1477
+ let content = r#"#include <stdio.h>
1478
+ #include <stdlib.h>
1479
+
1480
+ /**
1481
+ * Large function that should get C-style closing brace comment with // syntax
1482
+ */
1483
+ int large_function_with_nested_blocks(int param1, int param2, int param3) {
1484
+ if (param1 > 0) {
1485
+ for (int i = 0; i < param1; i++) {
1486
+ if (param2 % 2 == 0) {
1487
+ switch (param3) {
1488
+ case 1:
1489
+ printf("Case 1\n");
1490
+ break;
1491
+ case 2:
1492
+ printf("Case 2\n");
1493
+ break;
1494
+ default:
1495
+ printf("Default case\n");
1496
+ break;
1497
+ }
1498
+ } else {
1499
+ while (param2 > 0) {
1500
+ param2--;
1501
+ if (param2 == 10) {
1502
+ break;
1503
+ }
1504
+ }
1505
+ }
1506
+ }
1507
+ }
1508
+
1509
+ // More code to make this function large
1510
+ int result = 0;
1511
+ for (int j = 0; j < 10; j++) {
1512
+ result += j * param1;
1513
+ }
1514
+
1515
+ return result;
1516
+ }
1517
+
1518
+ /**
1519
+ * Small function that should NOT get closing brace comments
1520
+ */
1521
+ int small_function(int x) {
1522
+ return x * 2;
1523
+ }
1524
+
1525
+ /**
1526
+ * Medium function to test threshold behavior
1527
+ */
1528
+ void medium_function(int count) {
1529
+ for (int i = 0; i < count; i++) {
1530
+ printf("Iteration: %d\n", i);
1531
+ if (i % 2 == 0) {
1532
+ printf("Even number\n");
1533
+ }
1534
+ }
1535
+ }
1536
+ "#;
1537
+
1538
+ fs::write(&test_file, content)?;
1539
+
1540
+ let ctx = TestContext::new();
1541
+ let output = ctx.run_probe(&[
1542
+ "search",
1543
+ "large_function",
1544
+ test_file.to_str().unwrap(),
1545
+ "--format",
1546
+ "outline",
1547
+ "--allow-tests",
1548
+ ])?;
1549
+
1550
+ // Should contain C-style closing brace comments with // syntax (not /* */)
1551
+ assert!(
1552
+ output.contains("} //"),
1553
+ "Missing C-style closing brace comments with // syntax - output: {}",
1554
+ output
1555
+ );
1556
+
1557
+ // Should not contain /* */ style comments for closing braces
1558
+ assert!(
1559
+ !output.contains("} /*") || !output.contains("*/"),
1560
+ "Should not use /* */ style for C closing brace comments - output: {}",
1561
+ output
1562
+ );
1563
+
1564
+ // Should show function keyword in closing brace comment
1565
+ assert!(
1566
+ output.contains("function") || output.contains("Function"),
1567
+ "Missing function keyword in closing brace comment - output: {}",
1568
+ output
1569
+ );
1570
+
1571
+ Ok(())
1572
+ }
1573
+
1574
+ #[test]
1575
+ fn test_c_outline_header_file_support() -> Result<()> {
1576
+ let temp_dir = TempDir::new()?;
1577
+ let test_file = temp_dir.path().join("header_test.h");
1578
+
1579
+ let content = r#"#ifndef HEADER_TEST_H
1580
+ #define HEADER_TEST_H
1581
+
1582
+ #include <stdint.h>
1583
+ #include <stdbool.h>
1584
+
1585
+ // Forward declarations
1586
+ typedef struct Point Point;
1587
+ typedef struct Vector Vector;
1588
+
1589
+ /**
1590
+ * Point structure with coordinates
1591
+ */
1592
+ typedef struct Point {
1593
+ double x;
1594
+ double y;
1595
+ double z;
1596
+ } Point;
1597
+
1598
+ /**
1599
+ * Vector structure with direction and magnitude
1600
+ */
1601
+ typedef struct Vector {
1602
+ Point start;
1603
+ Point end;
1604
+ double magnitude;
1605
+ bool normalized;
1606
+ } Vector;
1607
+
1608
+ /**
1609
+ * Function prototypes - typical header file pattern
1610
+ */
1611
+ Point* create_point(double x, double y, double z);
1612
+ void destroy_point(Point* point);
1613
+ Vector* create_vector(Point* start, Point* end);
1614
+ void destroy_vector(Vector* vector);
1615
+ double calculate_distance(const Point* p1, const Point* p2);
1616
+ Vector* normalize_vector(Vector* vector);
1617
+ bool points_equal(const Point* p1, const Point* p2, double tolerance);
1618
+
1619
+ /**
1620
+ * Inline function definition in header
1621
+ */
1622
+ static inline double point_magnitude(const Point* point) {
1623
+ if (point == NULL) {
1624
+ return 0.0;
1625
+ }
1626
+ return sqrt(point->x * point->x + point->y * point->y + point->z * point->z);
1627
+ }
1628
+
1629
+ /**
1630
+ * Macro definitions
1631
+ */
1632
+ #define POINT_ZERO {0.0, 0.0, 0.0}
1633
+ #define VECTOR_ZERO {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, 0.0, false}
1634
+ #define MAX_POINTS 1000
1635
+ #define EPSILON 1e-10
1636
+
1637
+ /**
1638
+ * Conditional compilation for different platforms
1639
+ */
1640
+ #ifdef __cplusplus
1641
+ extern "C" {
1642
+ #endif
1643
+
1644
+ // Additional C++ compatible declarations would go here
1645
+
1646
+ #ifdef __cplusplus
1647
+ }
1648
+ #endif
1649
+
1650
+ #endif // HEADER_TEST_H
1651
+ "#;
1652
+
1653
+ fs::write(&test_file, content)?;
1654
+
1655
+ let ctx = TestContext::new();
1656
+ let output = ctx.run_probe(&[
1657
+ "search",
1658
+ "typedef",
1659
+ test_file.to_str().unwrap(),
1660
+ "--format",
1661
+ "outline",
1662
+ "--allow-tests",
1663
+ ])?;
1664
+
1665
+ // Should parse and format .h files correctly
1666
+ assert!(
1667
+ output.contains("Point") || output.contains("typedef"),
1668
+ "Missing Point struct in header file - output: {}",
1669
+ output
1670
+ );
1671
+
1672
+ // Should show header-specific patterns
1673
+ let has_header_patterns = output.contains("#ifndef")
1674
+ || output.contains("#define")
1675
+ || output.contains("typedef struct")
1676
+ || output.contains("extern")
1677
+ || output.contains("inline")
1678
+ || output.contains("struct");
1679
+ assert!(
1680
+ has_header_patterns,
1681
+ "Missing header file specific patterns - output: {}",
1682
+ output
1683
+ );
1684
+
1685
+ // Should have outline formatting - search might not be long enough for truncation
1686
+ let has_outline_features =
1687
+ output.contains("...") || output.contains("typedef") || output.contains("Point");
1688
+ assert!(
1689
+ has_outline_features,
1690
+ "Missing outline format features in header file - output: {}",
1691
+ output
1692
+ );
1693
+
1694
+ Ok(())
1695
+ }
1696
+
1697
+ #[test]
1698
+ fn test_c_outline_test_detection() -> Result<()> {
1699
+ let temp_dir = TempDir::new()?;
1700
+ let test_file = temp_dir.path().join("test_functions.c");
1701
+
1702
+ let content = r#"#include <stdio.h>
1703
+ #include <assert.h>
1704
+ #include <string.h>
1705
+
1706
+ /**
1707
+ * Regular function - not a test
1708
+ */
1709
+ int calculate_sum(int a, int b) {
1710
+ return a + b;
1711
+ }
1712
+
1713
+ /**
1714
+ * Test function with test_ prefix - should be detected as test
1715
+ */
1716
+ void test_calculate_sum() {
1717
+ int result = calculate_sum(2, 3);
1718
+ assert(result == 5);
1719
+ printf("test_calculate_sum passed\n");
1720
+ }
1721
+
1722
+ /**
1723
+ * Another test function with test_ prefix
1724
+ */
1725
+ void test_string_operations() {
1726
+ char buffer[100];
1727
+ strcpy(buffer, "Hello");
1728
+ strcat(buffer, " World");
1729
+
1730
+ assert(strcmp(buffer, "Hello World") == 0);
1731
+ assert(strlen(buffer) == 11);
1732
+
1733
+ printf("test_string_operations passed\n");
1734
+ }
1735
+
1736
+ /**
1737
+ * Test function with assert statements - should be detected
1738
+ */
1739
+ int test_array_operations() {
1740
+ int arr[] = {1, 2, 3, 4, 5};
1741
+ int sum = 0;
1742
+
1743
+ for (int i = 0; i < 5; i++) {
1744
+ sum += arr[i];
1745
+ }
1746
+
1747
+ assert(sum == 15);
1748
+ assert(arr[0] == 1);
1749
+ assert(arr[4] == 5);
1750
+
1751
+ return 0;
1752
+ }
1753
+
1754
+ /**
1755
+ * Function with assert but not a test name - might be detected
1756
+ */
1757
+ void validate_input(int input) {
1758
+ assert(input > 0);
1759
+ assert(input < 1000);
1760
+ printf("Input %d is valid\n", input);
1761
+ }
1762
+
1763
+ /**
1764
+ * Unit test style function
1765
+ */
1766
+ void test_memory_allocation() {
1767
+ int* ptr = malloc(sizeof(int) * 10);
1768
+ assert(ptr != NULL);
1769
+
1770
+ for (int i = 0; i < 10; i++) {
1771
+ ptr[i] = i * 2;
1772
+ }
1773
+
1774
+ assert(ptr[5] == 10);
1775
+ free(ptr);
1776
+
1777
+ printf("test_memory_allocation passed\n");
1778
+ }
1779
+
1780
+ /**
1781
+ * Main function to run tests
1782
+ */
1783
+ int main() {
1784
+ test_calculate_sum();
1785
+ test_string_operations();
1786
+ test_array_operations();
1787
+ test_memory_allocation();
1788
+ validate_input(42);
1789
+
1790
+ printf("All tests passed!\n");
1791
+ return 0;
1792
+ }
1793
+ "#;
1794
+
1795
+ fs::write(&test_file, content)?;
1796
+
1797
+ let ctx = TestContext::new();
1798
+ let output = ctx.run_probe(&[
1799
+ "search",
1800
+ "assert",
1801
+ test_file.to_str().unwrap(),
1802
+ "--format",
1803
+ "outline",
1804
+ "--allow-tests",
1805
+ ])?;
1806
+
1807
+ // Should find test-related functions or patterns
1808
+ let has_test_content = output.contains("test_calculate_sum")
1809
+ || output.contains("test_string_operations")
1810
+ || output.contains("assert")
1811
+ || output.contains("calculate_sum");
1812
+ assert!(
1813
+ has_test_content,
1814
+ "Missing test-related content - output: {}",
1815
+ output
1816
+ );
1817
+
1818
+ // Should show C test patterns
1819
+ let has_c_test_patterns = output.contains("assert")
1820
+ || output.contains("int")
1821
+ || output.contains("void")
1822
+ || output.contains("printf")
1823
+ || output.contains("malloc");
1824
+ assert!(
1825
+ has_c_test_patterns,
1826
+ "Missing C test-related patterns - output: {}",
1827
+ output
1828
+ );
1829
+
1830
+ // Should have outline formatting features
1831
+ let has_outline_features = output.contains("...")
1832
+ || output.contains("assert")
1833
+ || output.contains("test_")
1834
+ || output.contains("void");
1835
+ assert!(
1836
+ has_outline_features,
1837
+ "Missing outline format features in test detection - output: {}",
1838
+ output
1839
+ );
1840
+
1841
+ Ok(())
1842
+ }
1843
+
1844
+ #[test]
1845
+ fn test_c_outline_pointer_and_advanced_constructs() -> Result<()> {
1846
+ let temp_dir = TempDir::new()?;
1847
+ let test_file = temp_dir.path().join("advanced_c.c");
1848
+
1849
+ let content = r#"#include <stdio.h>
1850
+ #include <stdlib.h>
1851
+ #include <string.h>
1852
+
1853
+ /**
1854
+ * Function pointer typedef
1855
+ */
1856
+ typedef int (*CompareFunc)(const void* a, const void* b);
1857
+ typedef void (*CallbackFunc)(int result, void* user_data);
1858
+
1859
+ /**
1860
+ * Complex struct with function pointers
1861
+ */
1862
+ typedef struct Processor {
1863
+ char name[64];
1864
+ CompareFunc compare_func;
1865
+ CallbackFunc callback_func;
1866
+ void* user_data;
1867
+ int (*process_func)(struct Processor* self, void* data, size_t size);
1868
+ void (*cleanup_func)(struct Processor* self);
1869
+ } Processor;
1870
+
1871
+ /**
1872
+ * Function that takes function pointer as parameter
1873
+ */
1874
+ void process_array_with_callback(int* array, size_t length,
1875
+ int (*transform_func)(int value),
1876
+ void (*result_callback)(int index, int result)) {
1877
+ if (array == NULL || transform_func == NULL) {
1878
+ return;
1879
+ }
1880
+
1881
+ for (size_t i = 0; i < length; i++) {
1882
+ int result = transform_func(array[i]);
1883
+ if (result_callback != NULL) {
1884
+ result_callback((int)i, result);
1885
+ }
1886
+ }
1887
+ }
1888
+
1889
+ /**
1890
+ * Function returning pointer to pointer
1891
+ */
1892
+ char** create_string_array(int count, const char* prefix) {
1893
+ char** strings = malloc(count * sizeof(char*));
1894
+ if (strings == NULL) {
1895
+ return NULL;
1896
+ }
1897
+
1898
+ for (int i = 0; i < count; i++) {
1899
+ size_t len = strlen(prefix) + 20;
1900
+ strings[i] = malloc(len);
1901
+ if (strings[i] != NULL) {
1902
+ snprintf(strings[i], len, "%s_%d", prefix, i);
1903
+ }
1904
+ }
1905
+
1906
+ return strings;
1907
+ }
1908
+
1909
+ /**
1910
+ * Function with complex pointer arithmetic
1911
+ */
1912
+ void reverse_array_pointers(int* start, int* end) {
1913
+ while (start < end) {
1914
+ int temp = *start;
1915
+ *start = *end;
1916
+ *end = temp;
1917
+ start++;
1918
+ end--;
1919
+ }
1920
+ }
1921
+
1922
+ /**
1923
+ * Function with void pointer and casting
1924
+ */
1925
+ void generic_swap(void* a, void* b, size_t size) {
1926
+ unsigned char* byte_a = (unsigned char*)a;
1927
+ unsigned char* byte_b = (unsigned char*)b;
1928
+
1929
+ for (size_t i = 0; i < size; i++) {
1930
+ unsigned char temp = byte_a[i];
1931
+ byte_a[i] = byte_b[i];
1932
+ byte_b[i] = temp;
1933
+ }
1934
+ }
1935
+
1936
+ /**
1937
+ * Preprocessor macro with function-like behavior
1938
+ */
1939
+ #define SAFE_DELETE(ptr) do { \
1940
+ if ((ptr) != NULL) { \
1941
+ free(ptr); \
1942
+ (ptr) = NULL; \
1943
+ } \
1944
+ } while(0)
1945
+
1946
+ #define MAX(a, b) ((a) > (b) ? (a) : (b))
1947
+ #define MIN(a, b) ((a) < (b) ? (a) : (b))
1948
+
1949
+ /**
1950
+ * Function using the macros
1951
+ */
1952
+ void cleanup_processor(Processor** processor_ptr) {
1953
+ if (processor_ptr == NULL || *processor_ptr == NULL) {
1954
+ return;
1955
+ }
1956
+
1957
+ Processor* proc = *processor_ptr;
1958
+
1959
+ if (proc->cleanup_func != NULL) {
1960
+ proc->cleanup_func(proc);
1961
+ }
1962
+
1963
+ SAFE_DELETE(proc->user_data);
1964
+ SAFE_DELETE(*processor_ptr);
1965
+ }
1966
+ "#;
1967
+
1968
+ fs::write(&test_file, content)?;
1969
+
1970
+ let ctx = TestContext::new();
1971
+ let output = ctx.run_probe(&[
1972
+ "search",
1973
+ "typedef",
1974
+ test_file.to_str().unwrap(),
1975
+ "--format",
1976
+ "outline",
1977
+ "--allow-tests",
1978
+ ])?;
1979
+
1980
+ // Should show function pointer and pointer-related patterns
1981
+ let has_pointer_patterns = output.contains("*")
1982
+ || output.contains("CompareFunc")
1983
+ || output.contains("CallbackFunc")
1984
+ || output.contains("void*")
1985
+ || output.contains("char**")
1986
+ || output.contains("int*")
1987
+ || output.contains("typedef");
1988
+ assert!(
1989
+ has_pointer_patterns,
1990
+ "Missing pointer-related patterns - output: {}",
1991
+ output
1992
+ );
1993
+
1994
+ // Should have outline formatting features
1995
+ let has_outline_features = output.contains("...")
1996
+ || output.contains("typedef")
1997
+ || output.contains("CompareFunc")
1998
+ || output.contains("struct");
1999
+ assert!(
2000
+ has_outline_features,
2001
+ "Missing outline format features in advanced C constructs - output: {}",
2002
+ output
2003
+ );
2004
+
2005
+ // Should show C-specific advanced constructs
2006
+ let has_advanced_c = output.contains("typedef")
2007
+ || output.contains("struct")
2008
+ || output.contains("malloc")
2009
+ || output.contains("sizeof")
2010
+ || output.contains("#define")
2011
+ || output.contains("Processor");
2012
+ assert!(
2013
+ has_advanced_c,
2014
+ "Missing advanced C constructs - output: {}",
2015
+ output
2016
+ );
2017
+
2018
+ Ok(())
2019
+ }
2020
+
2021
+ #[test]
2022
+ fn test_c_outline_keyword_highlighting() -> Result<()> {
2023
+ let temp_dir = TempDir::new()?;
2024
+ let test_file = temp_dir.path().join("keyword_test.c");
2025
+
2026
+ let content = r#"#include <stdio.h>
2027
+ #include <stdlib.h>
2028
+ #include <stdbool.h>
2029
+
2030
+ /**
2031
+ * Function demonstrating various C keywords for highlighting
2032
+ */
2033
+ int demonstrate_keywords(int count, const char* message, bool verbose) {
2034
+ // Static local variable
2035
+ static int call_count = 0;
2036
+ call_count++;
2037
+
2038
+ // Register variable (though rarely used in modern C)
2039
+ register int fast_counter;
2040
+
2041
+ // Volatile variable
2042
+ volatile int shared_flag = 0;
2043
+
2044
+ // Const pointer to const data
2045
+ const char* const constant_message = "Hello, World!";
2046
+
2047
+ // Auto keyword (implicit in C99+)
2048
+ auto int automatic_var = 42;
2049
+
2050
+ // Extern declaration
2051
+ extern int global_variable;
2052
+
2053
+ // Different loop types with keywords
2054
+ for (fast_counter = 0; fast_counter < count; fast_counter++) {
2055
+ if (verbose && fast_counter % 2 == 0) {
2056
+ printf("Processing item %d: %s\n", fast_counter, message);
2057
+ }
2058
+
2059
+ switch (fast_counter % 4) {
2060
+ case 0:
2061
+ if (shared_flag == 0) {
2062
+ shared_flag = 1;
2063
+ }
2064
+ break;
2065
+ case 1:
2066
+ while (shared_flag > 0) {
2067
+ shared_flag--;
2068
+ if (shared_flag <= 0) break;
2069
+ }
2070
+ break;
2071
+ case 2:
2072
+ do {
2073
+ shared_flag++;
2074
+ } while (shared_flag < 3);
2075
+ break;
2076
+ default:
2077
+ goto cleanup;
2078
+ }
2079
+ }
2080
+
2081
+ cleanup:
2082
+ // Return with appropriate value
2083
+ return call_count;
2084
+ }
2085
+
2086
+ /**
2087
+ * Function with different storage classes and type qualifiers
2088
+ */
2089
+ static inline void storage_class_demo(void) {
2090
+ // Different storage classes
2091
+ static const int static_const_var = 100;
2092
+ extern volatile int extern_volatile_var;
2093
+ register unsigned int register_var = 0;
2094
+
2095
+ // Type qualifiers
2096
+ const int* const_ptr;
2097
+ volatile int* volatile_ptr;
2098
+ restrict int* restrict_ptr; // C99 feature
2099
+
2100
+ // Compound types
2101
+ struct {
2102
+ union {
2103
+ int int_val;
2104
+ float float_val;
2105
+ } data;
2106
+ enum {
2107
+ STATE_INIT,
2108
+ STATE_RUNNING,
2109
+ STATE_STOPPED
2110
+ } state;
2111
+ } compound_var;
2112
+ }
2113
+
2114
+ /**
2115
+ * Function using sizeof, typeof (GCC extension), and other operators
2116
+ */
2117
+ void operator_keyword_demo(void) {
2118
+ int array[10];
2119
+ size_t array_size = sizeof(array);
2120
+ size_t element_size = sizeof(array[0]);
2121
+ size_t num_elements = array_size / element_size;
2122
+
2123
+ // Typeof is a GCC extension
2124
+ #ifdef __GNUC__
2125
+ typeof(array[0]) another_int = 42;
2126
+ #endif
2127
+
2128
+ // Alignment specifier (C11)
2129
+ #if __STDC_VERSION__ >= 201112L
2130
+ _Alignas(16) int aligned_var;
2131
+ size_t alignment = _Alignof(int);
2132
+ #endif
2133
+ }
2134
+ "#;
2135
+
2136
+ fs::write(&test_file, content)?;
2137
+
2138
+ let ctx = TestContext::new();
2139
+ let output = ctx.run_probe(&[
2140
+ "search",
2141
+ "demonstrate_keywords",
2142
+ test_file.to_str().unwrap(),
2143
+ "--format",
2144
+ "outline",
2145
+ "--allow-tests",
2146
+ ])?;
2147
+
2148
+ // Should find functions with keyword in their name or content
2149
+ assert!(
2150
+ output.contains("keyword") || output.contains("demonstrate_keywords"),
2151
+ "Missing keyword-related functions - output: {}",
2152
+ output
2153
+ );
2154
+
2155
+ // Should show C keywords in the outline format
2156
+ let has_c_keywords = output.contains("static")
2157
+ || output.contains("const")
2158
+ || output.contains("volatile")
2159
+ || output.contains("int")
2160
+ || output.contains("void")
2161
+ || output.contains("for")
2162
+ || output.contains("while")
2163
+ || output.contains("if")
2164
+ || output.contains("switch");
2165
+ assert!(
2166
+ has_c_keywords,
2167
+ "Missing C keywords in outline format - output: {}",
2168
+ output
2169
+ );
2170
+
2171
+ // Should have outline formatting with truncation
2172
+ assert!(
2173
+ output.contains("..."),
2174
+ "Missing truncation in keyword demonstration outline - output: {}",
2175
+ output
2176
+ );
2177
+
2178
+ Ok(())
2179
+ }