c-next 0.2.13 → 0.2.14
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.
- package/dist/index.js +65 -47
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/src/cli/ArgParser.ts +2 -6
- package/src/cli/PlatformIOCommand.ts +27 -29
- package/src/cli/__tests__/PlatformIOCommand.test.ts +23 -0
- package/src/transpiler/Transpiler.ts +10 -2
- package/src/transpiler/data/IncludeResolver.ts +11 -1
- package/src/transpiler/data/__tests__/IncludeResolver.test.ts +50 -0
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +20 -13
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +20 -6
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { hideBin } from "yargs/helpers";
|
|
|
11
11
|
// package.json
|
|
12
12
|
var package_default = {
|
|
13
13
|
name: "c-next",
|
|
14
|
-
version: "0.2.
|
|
14
|
+
version: "0.2.14",
|
|
15
15
|
description: "A safer C for embedded systems development. Transpiles to clean, readable C.",
|
|
16
16
|
packageManager: "npm@11.9.0",
|
|
17
17
|
type: "module",
|
|
@@ -195,10 +195,8 @@ var ConfigPrinter_default = ConfigPrinter;
|
|
|
195
195
|
function configureYargs(args, argv) {
|
|
196
196
|
return yargs(args).scriptName("cnext").usage(
|
|
197
197
|
`Usage:
|
|
198
|
-
cnext <file.cnx>
|
|
198
|
+
cnext <file.cnx> Entry point file (follows includes)
|
|
199
199
|
cnext <file.cnx> -o <output.c> Single file with explicit output
|
|
200
|
-
cnext <files...> -o <dir> Multi-file mode
|
|
201
|
-
cnext <dir> Directory mode (recursive)
|
|
202
200
|
|
|
203
201
|
A safer C for embedded systems development.`
|
|
204
202
|
).option("o", {
|
|
@@ -275,10 +273,8 @@ A safer C for embedded systems development.`
|
|
|
275
273
|
default: false
|
|
276
274
|
}).epilogue(
|
|
277
275
|
`Examples:
|
|
278
|
-
cnext main.cnx
|
|
276
|
+
cnext src/main.cnx # Entry point (follows includes)
|
|
279
277
|
cnext main.cnx -o build/main.c # Explicit output path
|
|
280
|
-
cnext src/*.cnx -o build/ # Multiple files to directory
|
|
281
|
-
cnext src/ # Compile all .cnx files in src/ (recursive)
|
|
282
278
|
|
|
283
279
|
Target platforms: teensy41, cortex-m7, cortex-m4, cortex-m3, cortex-m0+, cortex-m0, avr
|
|
284
280
|
|
|
@@ -415,37 +411,36 @@ var PlatformIOCommand = class {
|
|
|
415
411
|
*/
|
|
416
412
|
static install() {
|
|
417
413
|
const { pioIniPath, scriptPath } = getPioProjectPaths();
|
|
418
|
-
const buildScript = `Import("env")
|
|
414
|
+
const buildScript = String.raw`Import("env")
|
|
419
415
|
import subprocess
|
|
420
416
|
import sys
|
|
421
417
|
from pathlib import Path
|
|
422
418
|
|
|
423
419
|
def transpile_cnext():
|
|
424
|
-
"""Transpile
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
if not src_dir.exists():
|
|
420
|
+
"""Transpile from main.cnx entry point — cnext follows includes"""
|
|
421
|
+
entry = Path("src/main.cnx")
|
|
422
|
+
if not entry.exists():
|
|
428
423
|
return
|
|
429
424
|
|
|
430
|
-
|
|
431
|
-
if not cnx_files:
|
|
432
|
-
return
|
|
433
|
-
|
|
434
|
-
print(f"Transpiling {len(cnx_files)} c-next files...")
|
|
425
|
+
print("Transpiling from main.cnx...")
|
|
435
426
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
427
|
+
try:
|
|
428
|
+
result = subprocess.run(
|
|
429
|
+
["cnext", str(entry)],
|
|
430
|
+
check=True,
|
|
431
|
+
capture_output=True,
|
|
432
|
+
text=True
|
|
433
|
+
)
|
|
434
|
+
if result.stdout:
|
|
435
|
+
lines = result.stdout.strip().split("\n")
|
|
436
|
+
for line in lines:
|
|
437
|
+
if line.startswith(("Compiled", "Collected", "Generated")):
|
|
438
|
+
print(f" {line}")
|
|
439
|
+
print(" ✓ Transpilation complete")
|
|
440
|
+
except subprocess.CalledProcessError as e:
|
|
441
|
+
print(f" ✗ Transpilation failed")
|
|
442
|
+
print(e.stderr)
|
|
443
|
+
sys.exit(1)
|
|
449
444
|
|
|
450
445
|
# Run transpilation at import time (before compilation starts)
|
|
451
446
|
transpile_cnext()
|
|
@@ -475,13 +470,12 @@ transpile_cnext()
|
|
|
475
470
|
console.log("\u2713 PlatformIO integration configured!");
|
|
476
471
|
console.log("");
|
|
477
472
|
console.log("Next steps:");
|
|
478
|
-
console.log(
|
|
479
|
-
|
|
480
|
-
);
|
|
481
|
-
console.log(" 2. Run: pio run");
|
|
473
|
+
console.log(" 1. Create src/main.cnx as your entry point");
|
|
474
|
+
console.log(" 2. Use #include to pull in other .cnx files");
|
|
475
|
+
console.log(" 3. Run: pio run");
|
|
482
476
|
console.log("");
|
|
483
477
|
console.log(
|
|
484
|
-
"The transpiler will
|
|
478
|
+
"The transpiler will follow includes from main.cnx automatically."
|
|
485
479
|
);
|
|
486
480
|
console.log("Commit both .cnx and generated .c files to version control.");
|
|
487
481
|
}
|
|
@@ -133386,16 +133380,23 @@ var HeaderGeneratorUtils = class _HeaderGeneratorUtils {
|
|
|
133386
133380
|
}
|
|
133387
133381
|
}
|
|
133388
133382
|
const userIncludeSet = new Set(options.userIncludes ?? []);
|
|
133389
|
-
|
|
133390
|
-
|
|
133391
|
-
|
|
133392
|
-
|
|
133393
|
-
|
|
133394
|
-
|
|
133383
|
+
const extractStem = (inc) => {
|
|
133384
|
+
const match = /["<]([^">]+)[">]/.exec(inc);
|
|
133385
|
+
if (!match) return inc;
|
|
133386
|
+
return match[1].replace(/^.*\//, "").replace(/\.(?:h|hpp)$/, "");
|
|
133387
|
+
};
|
|
133388
|
+
const userIncludeStems = new Set(
|
|
133389
|
+
(options.userIncludes ?? []).map(extractStem)
|
|
133390
|
+
);
|
|
133395
133391
|
for (const directive of headersToInclude) {
|
|
133396
|
-
if (
|
|
133397
|
-
|
|
133392
|
+
if (userIncludeSet.has(directive)) {
|
|
133393
|
+
continue;
|
|
133394
|
+
}
|
|
133395
|
+
const stem = extractStem(directive);
|
|
133396
|
+
if (stem && userIncludeStems.has(stem)) {
|
|
133397
|
+
continue;
|
|
133398
133398
|
}
|
|
133399
|
+
lines.push(directive);
|
|
133399
133400
|
}
|
|
133400
133401
|
const hasIncludes = options.includeSystemHeaders !== false || options.userIncludes && options.userIncludes.length > 0 || headersToInclude.size > 0;
|
|
133401
133402
|
if (hasIncludes) {
|
|
@@ -137760,9 +137761,16 @@ var DependencyGraph_default = DependencyGraph;
|
|
|
137760
137761
|
// src/transpiler/data/IncludeResolver.ts
|
|
137761
137762
|
var defaultFs5 = NodeFileSystem_default.instance;
|
|
137762
137763
|
var IncludeResolver = class _IncludeResolver {
|
|
137763
|
-
|
|
137764
|
+
/**
|
|
137765
|
+
* @param cppMode Controls .h vs .hpp extension for .cnx include directives.
|
|
137766
|
+
* Note: In the Transpiler, cppDetected may change after IncludeResolver runs
|
|
137767
|
+
* (e.g., when a .hpp header is discovered during Stage 2). HeaderGeneratorUtils
|
|
137768
|
+
* uses stem-based dedup to handle any resulting .h/.hpp mismatch.
|
|
137769
|
+
*/
|
|
137770
|
+
constructor(searchPaths, fs = defaultFs5, cppMode = false) {
|
|
137764
137771
|
this.searchPaths = searchPaths;
|
|
137765
137772
|
this.fs = fs;
|
|
137773
|
+
this.cppMode = cppMode;
|
|
137766
137774
|
}
|
|
137767
137775
|
/**
|
|
137768
137776
|
* Type helper for accessing IResolvedIncludes externally.
|
|
@@ -137771,6 +137779,7 @@ var IncludeResolver = class _IncludeResolver {
|
|
|
137771
137779
|
static _resolvedIncludesType = void 0;
|
|
137772
137780
|
resolvedPaths = /* @__PURE__ */ new Set();
|
|
137773
137781
|
fs;
|
|
137782
|
+
cppMode;
|
|
137774
137783
|
/**
|
|
137775
137784
|
* Extract includes from source content and resolve them to files
|
|
137776
137785
|
*
|
|
@@ -137835,7 +137844,8 @@ var IncludeResolver = class _IncludeResolver {
|
|
|
137835
137844
|
}
|
|
137836
137845
|
if (file.type === EFileType_default.CNext) {
|
|
137837
137846
|
result.cnextIncludes.push(file);
|
|
137838
|
-
const
|
|
137847
|
+
const ext = this.cppMode ? ".hpp" : ".h";
|
|
137848
|
+
const headerPath = includeInfo.path.replace(/\.cnx$|\.cnext$/, ext);
|
|
137839
137849
|
const directive = includeInfo.isLocal ? `#include "${headerPath}"` : `#include <${headerPath}>`;
|
|
137840
137850
|
result.headerIncludeDirectives.set(absolutePath, directive);
|
|
137841
137851
|
}
|
|
@@ -141708,7 +141718,11 @@ var Transpiler = class {
|
|
|
141708
141718
|
void 0,
|
|
141709
141719
|
this.fs
|
|
141710
141720
|
);
|
|
141711
|
-
const resolver = new IncludeResolver_default(
|
|
141721
|
+
const resolver = new IncludeResolver_default(
|
|
141722
|
+
searchPaths,
|
|
141723
|
+
this.fs,
|
|
141724
|
+
this.cppDetected
|
|
141725
|
+
);
|
|
141712
141726
|
const resolved = resolver.resolve(source, sourcePath);
|
|
141713
141727
|
this.warnings.push(...resolved.warnings);
|
|
141714
141728
|
const { headers: allHeaders, warnings: headerWarnings } = IncludeResolver_default.resolveHeadersTransitively(
|
|
@@ -141980,7 +141994,11 @@ var Transpiler = class {
|
|
|
141980
141994
|
void 0,
|
|
141981
141995
|
this.fs
|
|
141982
141996
|
);
|
|
141983
|
-
const resolver = new IncludeResolver_default(
|
|
141997
|
+
const resolver = new IncludeResolver_default(
|
|
141998
|
+
searchPaths,
|
|
141999
|
+
this.fs,
|
|
142000
|
+
this.cppDetected
|
|
142001
|
+
);
|
|
141984
142002
|
const resolved = resolver.resolve(content, cnxFile.path);
|
|
141985
142003
|
this._collectHeaders(resolved, cnextBaseNames, headerSet);
|
|
141986
142004
|
this._processCnextIncludes(
|