VX/C - OpenVMS C to ANSI C
Overview
VX/C is Sector7's automated source-to-source translator for C. It reads OpenVMS/VAX-C and DEC C source and emits portable, POSIX-compliant ANSI C, optimized for Linux and other POSIX/UNIX platforms (e.g. macOS). It identifies, flags, and corrects VMS-specific syntax and dependencies so migrated code compiles cleanly off OpenVMS.
Every machine-applied edit is annotated inline with a /*S7-nnn*/ comment, so each change stays traceable and reviewable. VX/C behaves like a C front-end: it runs its own lexer, a full C grammar, a macro and #include preprocessor, and an edit buffer that rewrites the original source in place. It works with existing Makefiles and build systems and fits continuous-integration workflows. The command-line binary is vxcpp.
<!-- Webflow embed (min). Source: c-page-technical/c-tech-body-embed-dark.html → python3 website/embeds/minify_webflow_embed.py … -->
<div class="s7-tech-embed" data-vxcd-body-embed="1" data-technical-mega-embed="1" lang="en"><h2 id="architecture">How VX/C works</h2><p>
VX/C is a source-to-source translator, not a compiler back-end: it produces C text, not
object files. The binary, <code>vxcpp</code>, behaves like a C front-end. It runs its own
lexer, a full C grammar with rewrite actions, a macro and <code>#include</code> preprocessor,
a symbol-table and scope engine, and an edit buffer that rewrites the original token stream
in place. Recognised input includes OpenVMS/VAX-C and DEC C, along with VMS-C language
extensions such as <code>variant_union</code>, <code>variant_struct</code>,
<code>globalref</code>, and <code>MAIN_PROGRAM</code>.
</p><h6>Processing model</h6><style>.s7-tech-embed .process-flow {margin: 1.5rem 0;padding: 16px;border: 1px solid var(--s7t-border);border-radius: 10px;background: rgba(255, 255, 255, 0.01);}.s7-tech-embed .process-endpoint {display: grid;grid-template-columns: 72px minmax(0, 1fr);gap: 14px;align-items: center;padding: 14px 16px;border-radius: 8px;background: var(--s7t-surface);color: var(--s7t-text);}.s7-tech-embed .process-output {border: 1px solid var(--s7t-note-bd);background: var(--s7t-note-bg);}.s7-tech-embed .process-label,.s7-tech-embed .process-number {font-family: var(--s7t-mono);color: var(--s7t-accent);font-size: 0.76em;font-weight: 700;letter-spacing: 0.08em;text-transform: uppercase;}.s7-tech-embed .process-endpoint div,.s7-tech-embed .process-stage {min-width: 0;}.s7-tech-embed .process-endpoint strong,.s7-tech-embed .process-endpoint span:last-child,.s7-tech-embed .process-stage strong,.s7-tech-embed .process-stage span:last-child {display: block;}.s7-tech-embed .process-endpoint strong,.s7-tech-embed .process-stage strong {margin-bottom: 4px;color: var(--s7t-text);}.s7-tech-embed .process-endpoint span:last-child,.s7-tech-embed .process-stage span:last-child {color: var(--s7t-muted);font-size: 0.9em;line-height: 1.45;}.s7-tech-embed .process-stages {display: grid;grid-template-columns: repeat(3, minmax(0, 1fr));gap: 10px;margin: 10px 0;}.s7-tech-embed .process-stage {padding: 15px;border-top: 3px solid var(--s7t-accent);border-radius: 6px;background: var(--s7t-surface2);color: var(--s7t-text);}.s7-tech-embed .process-stage .process-number {margin-bottom: 10px;}@media (max-width: 800px) {.s7-tech-embed .process-stages {grid-template-columns: 1fr;}.s7-tech-embed .process-endpoint {grid-template-columns: 1fr;gap: 5px;}}</style><div class="process-flow" aria-label="VX/C source transformation stages"><div class="process-endpoint"><span class="process-label">Input</span><div><strong>OpenVMS C source</strong><span>VAX-C, DEC C, and VMS-C language extensions</span></div></div><div class="process-stages"><div class="process-stage"><span class="process-number">01</span><strong>Lexer</strong><span>Tokenises the source and recognises VMS-C extensions.</span></div><div class="process-stage"><span class="process-number">02</span><strong>Grammar</strong><span>Parses C syntax and selects the required rewrite actions.</span></div><div class="process-stage"><span class="process-number">03</span><strong>Edit buffer</strong><span>Rewrites the token stream and records each applied fix.</span></div></div><div class="process-endpoint process-output"><span class="process-label">Output</span><div><strong>Portable POSIX ANSI C</strong><span>Transformed source plus diagnostics on standard error</span></div></div></div><h6>Run lifecycle</h6><ol><li>Install a watchdog timer and exit handlers to bound each run.</li><li>Read trace controls from the environment (<code>VXCPP_DEBUG</code> / <code>VXCPP_TRACE</code>).</li><li>Parse the command-line switches.</li><li>Load the target platform personality (Linux or macOS) predefined macros; if none is selected, abort.</li><li>Parse the source, applying edits into the edit buffer.</li><li>If any parse errors occurred, suppress output and abort; otherwise write the transformed source to <code>--output=</code> or standard output.</li></ol><div class="callout"><strong>Fail-fast output.</strong> If the parse accumulates any errors, VX/C does not write
partial output. It aborts and reports how many errors were seen, so a broken translation is
never emitted silently.
</div><h6>Components</h6><div class="table-wrapper"><table><thead><tr><th>Component</th><th>Role</th></tr></thead><tbody><tr><td><code>vxcpp</code></td><td>The translator: lexer, C grammar with rewrite actions, preprocessor, and output writer.</td></tr><tr><td><code>vxaddargs</code></td><td>Companion scanner that discovers variadic call sites and maintains the <code>--vararg_file</code> fixed-argument-count database.</td></tr><tr><td>Platform personalities</td><td>Predefined-macro tables, one per target host: Linux (GCC macros) and macOS (Apple LLVM/clang macros).</td></tr><tr><td>Fix-tag catalogue</td><td>The <code>/*S7-nnn*/</code> code set that annotates every applied edit in the output.</td></tr></tbody></table></div><h2 id="dialects">Source coverage and target platforms</h2><p>
VX/C accepts OpenVMS C written for VAX-C and DEC C, including the VMS-C language extensions,
and rewrites it into portable ANSI C. Output targets Linux and other POSIX/UNIX platforms
(e.g. macOS). There is no Windows target.
</p><h6>VMS-C constructs handled</h6><p>The extensions and non-ANSI constructs VX/C rewrites into portable form include:</p><div class="table-wrapper"><table><thead><tr><th>VMS / OpenVMS C construct</th><th>ANSI C result</th></tr></thead><tbody><tr><td><code>variant_union</code></td><td><code>union</code></td></tr><tr><td><code>variant_struct</code></td><td><code>struct</code></td></tr><tr><td><code>globalref</code></td><td><code>extern</code></td></tr><tr><td><code>MAIN_PROGRAM()</code></td><td>Synthesised <code>int main(int argc, char **argv)</code>.</td></tr><tr><td>K&R variadics (<code><varargs.h></code>, <code>va_dcl</code>, <code>va_alist</code>)</td><td><code><stdarg.h></code> form with a generated argument counter.</td></tr><tr><td>Old-style function definitions</td><td>ANSI prototypes with inserted return types and parameter types.</td></tr><tr><td>Address-of a constant or string (<code>&123</code>, <code>&"HELLO"</code>)</td><td><code>i_constant()</code> / <code>f_constant()</code> or the literal itself.</td></tr></tbody></table></div><h6>Target personalities</h6><p>
VX/C selects a target personality at run time and loads that host's predefined macros so
preprocessor conditionals resolve the same way the native compiler would. Two personalities
ship today: Linux, using GCC predefined macros, and macOS, using Apple LLVM/clang predefined
macros. If no personality is selected, VX/C aborts rather than guessing.
</p><h2 id="transformations">Transformations and fix tags</h2><p>
Every edit VX/C makes is annotated in the output with a <code>/*S7-nnn*/</code> comment, so a
reviewer can see exactly what changed and why. Annotations can be suppressed with
<code>--no-s7-tags</code>. VX/C identifies and resolves the following categories of VMS /
OpenVMS C issue.
</p><div class="table-wrapper"><table><thead><tr><th>Feature code</th><th>Issue identified</th></tr></thead><tbody><tr><td><strong>01.01</strong></td><td>Addressing constants (numbers)</td></tr><tr><td><strong>01.02</strong></td><td>Addressing strings</td></tr><tr><td><strong>03.01</strong></td><td>Variant struct/union usage</td></tr><tr><td><strong>04.01</strong></td><td>Assigning unions to unions</td></tr><tr><td><strong>05.01</strong></td><td><code>#include</code> from a text library without quotes or angle brackets</td></tr><tr><td><strong>05.02</strong></td><td>Logical-name <code>#include</code> references</td></tr><tr><td><strong>05.04</strong></td><td>Case sensitivity in <code>#include</code> paths</td></tr><tr><td><strong>06.01</strong></td><td>Missing function arguments</td></tr><tr><td><strong>08.02</strong></td><td>Type mismatches</td></tr><tr><td><strong>09.01</strong></td><td>Inconsistent function naming cases</td></tr><tr><td><strong>10.02</strong></td><td>Use of VMS-specific compiler calls (e.g. <code>vax$errno</code>)</td></tr><tr><td><strong>10.04</strong></td><td>Incompatible POSIX type usage (<code>stderr</code>, etc.)</td></tr><tr><td><strong>16.01</strong></td><td>Undefined return types</td></tr><tr><td><strong>19.01</strong></td><td>Typecasting on the left-hand side of assignments</td></tr></tbody></table></div><p>The tool's inline replacement tags (<code>/*S7-nnn*/</code>) map back to these 14 categories.</p><h6>Example: missing return type and terminal return</h6><p>
An old-style function with no return type and no <code>return</code> statement is legal in
VMS C but not in ANSI C. VX/C inserts <code>int</code> and a terminating return.
</p>
<pre><span class="cmt">/* VMS / OpenVMS C */</span>
static ACCT_INIT (void)
{
}
<span class="cmt">/* Migrated ANSI C */</span>
static int <span class="cmt">/*S7-100*/</span> ACCT_INIT (void)
{
return ( int)0; <span class="cmt">/*S7-102*/</span>
}</pre>
<h6>Example: missing arguments to a VMS system service</h6><p>
VX/C pads system-service calls (<code>SYS$</code>, <code>LIB$</code>, <code>STR$</code>, and
similar) that were written with fewer than the required arguments.
</p>
<pre><span class="cmt">/* VMS / OpenVMS C */</span>
int t = SYS$QIO(0);
<span class="cmt">/* Migrated ANSI C */</span>
int t = SYS$QIO(0<span class="cmt">/*S7-041*/</span>,0,0,0,0,0,0,0,0,0,0,0);</pre>
<h6>Example: buffered I/O retargeting and argument padding</h6><p>
Buffered-I/O calls are retargeted to the <code>vms_*</code> runtime wrappers
(<code>S7-040</code>), short argument lists are padded (<code>S7-041</code>), and
<code>fopen</code> gets a trailing <code>NULL</code> (<code>S7-042</code>).
</p>
<pre><span class="cmt">/* VMS / OpenVMS C */</span>
cp = strerror(12);
fp = fopen("account.dat", "r+", "shr=nil");
i = fclose(fp);
<span class="cmt">/* Migrated ANSI C */</span>
cp = <span class="cmt">/*S7-040*/</span>vms_strerror(12<span class="cmt">/*S7-041*/</span>,0);
fp = <span class="cmt">/*S7-040*/</span>vms_fopen("account.dat", "r+", "shr=nil", NULL <span class="cmt">/*S7-042*/</span>);
i = <span class="cmt">/*S7-040*/</span>vms_fclose(fp);</pre>
<h6>Example: address-of-constant rewrites</h6><p>
Taking the address of a numeric constant, a float, or a string literal is rewritten to a
portable equivalent.
</p>
<pre><span class="cmt">/* VMS / OpenVMS C */</span>
i = & 1234;
i = & 133.23;
cp = &"HELLO";
<span class="cmt">/* Migrated ANSI C */</span>
i = i_constant(1234)<span class="cmt">/*S7-008*/</span>;
i = f_constant(133.23)<span class="cmt">/*S7-010*/</span>;
cp = "HELLO"<span class="cmt">/*S7-012*/</span>;</pre>
<h6>Example: K&R varargs to stdarg</h6><p>
Old K&R variadic prototypes are converted to <code><stdarg.h></code> form:
<code>#include <varargs.h></code> becomes <code>#include <stdarg.h></code>, the
<code>va_alist</code> / <code>va_dcl</code> parameter list is rewritten with a generated
argument counter, and <code>va_start</code> / <code>va_count</code> are adjusted to match.
The <code>vxaddargs</code> companion tool supplies the correct fixed argument count for each
function through the <code>--vararg_file</code> database.
</p><div class="callout"><strong>Traceability.</strong> Because each transformation carries its own
<code>/*S7-nnn*/</code> tag, a reviewer can diff the migrated source against the original and
account for every change the tool made.
</div><h2 id="cli">Command-line interface</h2><p>
VX/C follows a standard compilation-like invocation. You run <code>vxcpp</code> with a list of
switches and one or more C source files; transformed source is written to
<code>--output=</code> or standard output, and diagnostics go to standard error.
</p>
<pre>vxcpp --vararg_file=/opt/vxrt/varargs_file \
--include=./include \
--vmsinclude=./vms_include \
--output=account_posix.c \
account.c</pre>
<h6>Core switches</h6><div class="table-wrapper"><table><thead><tr><th>Switch</th><th>Effect</th></tr></thead><tbody><tr><td><code>--vms-api=lower|upper</code></td><td>Force VMS API identifiers to lower or upper case.</td></tr><tr><td><code>--vmsinclude=<dir></code></td><td>Directory of VMS system include files that should not be translated.</td></tr><tr><td><code>--include=<dir></code></td><td>Search <code><dir></code> for header files.</td></tr><tr><td><code>--include-recursive=<dir></code></td><td>Recursively search <code><dir></code> for headers.</td></tr><tr><td><code>--hmap=<in.h>,<out.h></code></td><td>Single header remap. Repeatable.</td></tr><tr><td><code>--hmapdir=<dir></code></td><td>Use any <code>.h</code> in <code><dir></code> as a suffix-match replacement. Repeatable.</td></tr><tr><td><code>--hmapfile=<file></code></td><td>Read input-header to output-header mappings from a file.</td></tr><tr><td><code>--vararg_file=<file></code></td><td>Path to the variadic-function fixed-argument-count database.</td></tr><tr><td><code>--copy=<in_dir>,<out_dir></code></td><td>Directory-tree mode: mirror all output under <code><out_dir></code>.</td></tr><tr><td><code>--output=<file></code></td><td>Write transformed source to a file instead of standard output.</td></tr><tr><td><code>--no-s7-tags</code></td><td>Suppress the <code>/*S7-nnn*/</code> annotations in the output.</td></tr><tr><td><code>--vms-guard-macros</code></td><td>Wrap certain changes in <code>#if defined</code> guards.</td></tr><tr><td><code>-t[fimpstc]</code></td><td>Trace: Files, Input, Macro, Pre-processor, Symbols, Tokens, Comments. Combinable.</td></tr><tr><td><code>--version</code> / <code>-h</code></td><td>Print the version banner or help, then exit.</td></tr></tbody></table></div><h6>Configuration and mapping files</h6><p>
Common option sets and header remaps do not have to be retyped on every run.
<code>--hmapfile=</code> reads input-header to output-header mappings, <code>--vararg_file=</code>
supplies fixed argument counts for variadic functions, and <code>--copy=</code> processes a
whole directory tree, mirroring its subdirectories into an output tree. This makes VX/C easy
to drive from a batch script over a source estate and then compile the transformed output.
</p><h6>Trace controls</h6><p>
Tracing is available through the <code>-t</code> switch or the <code>VXCPP_DEBUG</code> /
<code>VXCPP_TRACE</code> environment variables, which accept a comma-separated option string
(pre-processor, tokens, symbols, files, macros, and more) plus an optional
<code>output=<file></code> redirect. <code>YYDEBUG=n</code> enables parser debug output.
</p><h2 id="headers">Header and include handling</h2><p>
VX/C normalises <code>#include</code> directives and remaps VMS header names to their POSIX
equivalents. System includes are forced to angle-bracket delimiters and user includes to
quoted form, filename case is corrected to match the file on a case-sensitive POSIX
filesystem, and VMS text-library or logical-name includes are rewritten to portable paths.
</p><h6>#include fixes</h6><div class="table-wrapper"><table><thead><tr><th>Situation</th><th>Result</th></tr></thead><tbody><tr><td><code>#include</code> from a text library without delimiters</td><td>Quoted <code>#include</code>.</td></tr><tr><td><code>#include</code> via a VMS logical name</td><td>Resolved to a portable path.</td></tr><tr><td>Case mismatch in an <code>#include</code> path</td><td>Corrected to the actual filename case.</td></tr><tr><td>System header in quotes</td><td>Switched to angle brackets.</td></tr><tr><td>User header in angle brackets</td><td>Switched to quotes.</td></tr><tr><td><code>#pragma dictionary "file"</code> (CDD)</td><td><code>#include "file.h"</code>.</td></tr><tr><td><code>#include <varargs.h></code></td><td><code>#include <stdarg.h></code>.</td></tr></tbody></table></div><h6>Built-in VMS to POSIX header map</h6><p>
Beyond user-supplied <code>--hmap*</code> maps, VX/C ships a fixed VMS to POSIX header-name
table. The built-in pairs are:
</p><div class="table-wrapper"><table><thead><tr><th>VMS header</th><th>POSIX header</th></tr></thead><tbody><tr><td><code>inet.h</code></td><td><code>arpa/inet.h</code></td></tr><tr><td><code>nameser.h</code></td><td><code>arpa/nameser.h</code></td></tr><tr><td><code>nameser_compat.h</code></td><td><code>arpa/nameser_compat.h</code></td></tr><tr><td><code>if.h</code></td><td><code>net/if.h</code></td></tr><tr><td><code>if_arp.h</code></td><td><code>net/if_arp.h</code></td></tr><tr><td><code>if_types.h</code></td><td><code>net/if_types.h</code></td></tr><tr><td><code>netdb.h</code></td><td><code>netdb.h</code></td></tr><tr><td><code>in.h</code></td><td><code>netinet/in.h</code></td></tr><tr><td><code>tcp.h</code></td><td><code>netinet/tcp.h</code></td></tr><tr><td><code>in6.h</code></td><td><code>netinet6/in6.h</code></td></tr><tr><td><code>file.h</code></td><td><code>sys/file.h</code></td></tr><tr><td><code>ioctl.h</code></td><td><code>sys/ioctl.h</code></td></tr><tr><td><code>ipc.h</code></td><td><code>sys/ipc.h</code></td></tr><tr><td><code>mman.h</code></td><td><code>sys/mman.h</code></td></tr><tr><td><code>resource.h</code></td><td><code>sys/resource.h</code></td></tr><tr><td><code>sem.h</code></td><td><code>sys/sem.h</code></td></tr><tr><td><code>signal.h</code></td><td><code>sys/signal.h</code></td></tr><tr><td><code>socket.h</code></td><td><code>sys/socket.h</code></td></tr><tr><td><code>stat.h</code></td><td><code>sys/stat.h</code></td></tr><tr><td><code>statvfs.h</code></td><td><code>sys/statvfs.h</code></td></tr><tr><td><code>timeb.h</code></td><td><code>sys/timeb.h</code></td></tr><tr><td><code>times.h</code></td><td><code>sys/times.h</code></td></tr><tr><td><code>types.h</code></td><td><code>sys/types.h</code></td></tr><tr><td><code>uio.h</code></td><td><code>sys/uio.h</code></td></tr><tr><td><code>unistd.h</code></td><td><code>sys/unistd.h</code></td></tr><tr><td><code>utsname.h</code></td><td><code>sys/utsname.h</code></td></tr><tr><td><code>wait.h</code></td><td><code>sys/wait.h</code></td></tr><tr><td><code>ints.h</code></td><td><code>stdint.h</code></td></tr><tr><td><code>perror.h</code></td><td><code>stdio.h</code></td></tr></tbody></table></div><h6>Example: #pragma dictionary to #include</h6><p>
Migrated code that pulled records from the OpenVMS Common Data Dictionary through
<code>#pragma dictionary</code> is rewritten to a portable <code>#include</code> of the
dictionary-derived header.
</p>
<pre><span class="cmt">/* VMS / OpenVMS C */</span>
typedef
#pragma dictionary "account_cmn.def"
<span class="cmt">/* Migrated ANSI C */</span>
typedef
#include "account_cmn.def.h" <span class="cmt">/*S7-084 DICTIONARY */</span></pre>
<h2 id="compatibility">Compatibility status</h2><p>The table below summarises what VX/C transforms today and which targets it supports.</p><div class="table-wrapper"><table><thead><tr><th>Capability</th><th>Status</th></tr></thead><tbody><tr><td>K&R to ANSI prototype conversion, inserted return types and parameter types</td><td><span class="ac-live">live</span></td></tr><tr><td>Missing-argument padding for <code>SYS$</code>, <code>LIB$</code>, <code>STR$</code> calls</td><td><span class="ac-live">live</span></td></tr><tr><td>Trailing-<code>NULL</code> insertion (<code>fopen</code>, <code>LIB$SIGNAL</code>, and similar)</td><td><span class="ac-live">live</span></td></tr><tr><td>Buffered-I/O retargeting to <code>vms_*</code> runtime wrappers</td><td><span class="ac-live">live</span></td></tr><tr><td>Address-of-constant rewrites (<code>i_constant</code> / <code>f_constant</code>)</td><td><span class="ac-live">live</span></td></tr><tr><td><code>#pragma dictionary</code> to <code>#include</code> (CDD)</td><td><span class="ac-live">live</span></td></tr><tr><td><code><varargs.h></code> to <code><stdarg.h></code> conversion</td><td><span class="ac-live">live</span></td></tr><tr><td><code>#include</code> delimiter, case, and logical-name fixes</td><td><span class="ac-live">live</span></td></tr><tr><td>Built-in and user-supplied header name remapping</td><td><span class="ac-live">live</span></td></tr><tr><td>Missing <code>switch</code> default insertion</td><td><span class="ac-live">live</span></td></tr><tr><td>Header guard-macro insertion</td><td><span class="ac-live">live</span></td></tr><tr><td>Linux target personality</td><td><span class="ac-live">live</span></td></tr><tr><td>macOS target personality</td><td><span class="ac-live">live</span></td></tr><tr><td>Windows target</td><td><span class="ac-no">out of scope</span></td></tr></tbody></table></div><h6>Diagnostics and exit codes</h6><p>
All operator messages are written to standard error; transformed source goes to
<code>--output=</code> or standard output. VX/C returns a distinct exit code per failure class
so a build script can react appropriately.
</p><div class="table-wrapper"><table><thead><tr><th>Code</th><th>Meaning</th></tr></thead><tbody><tr><td><code>1</code></td><td>File error</td></tr><tr><td><code>2</code></td><td>Internal error</td></tr><tr><td><code>3</code></td><td>Syntax error</td></tr><tr><td><code>4</code></td><td>Missing include</td></tr><tr><td><code>5</code></td><td>Option error</td></tr><tr><td><code>6</code></td><td>No output (errors suppressed output)</td></tr><tr><td><code>7</code></td><td>Identifier error</td></tr></tbody></table></div><h2 id="quickref">Quick reference</h2><h6>Invocation</h6>
<pre>vxcpp [switches] file.c <span class="cmt"># transformed source to stdout or --output=</span>
vxcpp --copy=<in>,<out> ... <span class="cmt"># directory-tree mode</span></pre>
<h6>Core switches</h6><div class="kw-grid"><div>--vms-api=lower|upper</div><div>--vmsinclude=<dir></div><div>--include=<dir></div><div>--include-recursive=<dir></div><div>--hmap=<in>,<out></div><div>--hmapdir=<dir></div><div>--hmapfile=<file></div><div>--vararg_file=<file></div><div>--copy=<in>,<out></div><div>--output=<file></div><div>--no-s7-tags</div><div>--vms-guard-macros</div><div>-t[fimpstc]</div><div>--version</div><div>-h</div></div><h6>Environment variables</h6><div class="kw-grid"><div>VXCPP_DEBUG</div><div>VXCPP_TRACE</div><div>YYDEBUG</div></div><h6>Exit codes</h6><div class="kw-grid"><div>1 FILE</div><div>2 INTERNAL</div><div>3 SYNTAX</div><div>4 MISSING_INCLUDE</div><div>5 OPTION</div><div>6 NO_OUTPUT</div><div>7 IDENTIFIER</div></div><h6>At a glance</h6><ul><li><strong>Binary:</strong> <code>vxcpp</code> (product VX/C).</li><li><strong>Input:</strong> OpenVMS/VAX-C and DEC C, including VMS-C extensions.</li><li><strong>Output:</strong> portable, POSIX-compliant ANSI C.</li><li><strong>Change markers:</strong> inline <code>/*S7-nnn*/</code> tags across 14 feature-coded categories.</li><li><strong>Header remaps:</strong> 29 built-in VMS to POSIX pairs, plus user <code>--hmap*</code> maps.</li><li><strong>Targets:</strong> Linux and other POSIX/UNIX platforms (e.g. macOS). No Windows.</li></ul></div>