ahay/src/authoring-sf-programs-c
Claude Code and agent skill by ahay/src
- community
Checking that the SKILL.md file is still in the repository.
Use when authoring a new Madagascar sf* main program in C (the reference implementation — all other language APIs wrap this).
Install
npx vskill@latest install ahay/src/authoring-sf-programs-cSKILL.md
When to use
Load this skill whenever you are writing a new sf<name> main program in C. C is the reference implementation for Madagascar: the Fortran 77, Fortran 90, C++, Python, Julia, Java, Matlab, Octave, and Chapel APIs all wrap or mirror the C API. Every claim in this skill is grounded in api/c/rsf.h (the amalgamated public header at build/api/c/rsf.h) and the test programs under api/c/. (CUDA programs exist in user directories but Madagascar has no dedicated api/cuda/ binding; they use the C API for RSF I/O and CUDA for compute.)
This skill is C-specific. For language-agnostic conventions (file naming, self-doc format, parameter style, build integration) see the companion:
../authoring-sf-programs/SKILL.md— shared conventions (load this too)
Typical placement: user/<youruser>/M<name>.c. The build system finds every M*.c in a user directory and compiles it into sf<name>.
Skeleton
This is the minimal correct skeleton for a C main program. Copy it verbatim and extend from here.
Key invariants:
sf_initmust be the first RSF call.- Open all
sf_inputfiles beforesf_output— the first output inherits dimensions from the first input by default. - Always call
exit(0)(notreturn 0) at the end; this is the Madagascar convention.
Self-doc header
Every M<name>.c must begin with a comment block that the build system extracts to produce sfdoc sf<name> output. The format (sourced from user/fomels/Mpick.c in this tree):
Rules extracted from real programs in this tree:
- First comment — brief one-line description on the opening line, optional extended prose below. This entire block becomes the program's documentation.
- Parameter inline comments — each
sf_getint/sf_getfloat/sf_getboolcall is followed immediately by a/* description */comment on the next line. The doc extractor captures these and lists them as named parameters insfdoc. - Second comment — the GPL copyright block. Keep it verbatim.
#include <rsf.h>comes after both comment blocks, before any other code.
Example parameter documentation from user/fomels/Mpick.c:
Each /* ... */ directly following a sf_get* call is parsed as the parameter description; it appears under "parameters:" in sfdoc sf<name>.
I/O API
Signatures from build/api/c/rsf.h.
Initialization
Must be the first RSF call. Parses the command line into an internal parameter table; opens stdin/stdout for piped RSF data.
Opening files
tag is a logical name used on the command line: sfmyprog in=data.rsf out=result.rsf. Use "in" and "out" for the primary pipes (stdin / stdout). Additional named files ("den", "mask", etc.) are opened the same way. Output files inherit dimension headers from the first input by default — override with explicit sf_put* calls before the first write.
Returns the data type (SF_FLOAT, SF_COMPLEX, SF_INT, etc.). Use to validate input type before reading.
Closes an sf_file handle and flushes metadata. For secondary outputs (not stdin/stdout) it is good practice to call this explicitly; for primary stdin/stdout it is called implicitly on exit.
Reading and writing float data
Read/write size consecutive floats. arr must be pre-allocated. These are the most common I/O calls.
Reading and writing complex data
sf_complex is float _Complex (or the platform equivalent). Use when the input type is SF_COMPLEX.
Header metadata API
RSF files carry key=value pairs in a text header. There are two directions:
- Read from input header —
sf_hist*family. Returnstrueif the key exists. - Write to output header —
sf_put*family. Must be called before the first data write.
Signatures from build/api/c/rsf.h:
Reading header values
sf_histstring returns a heap-allocated string (or NULL); test with if (NULL != (...)). Example:
Writing header values
Axis objects
Madagascar uses sf_axis structs to bundle n, d, o, label, and unit for each dimension. These simplify copying or transforming axes between files.
Example — copy axis 1 from input to output unchanged, then set a new axis 2:
sf_filedims is a convenience wrapper that reads all n values at once:
Parameter API
Command-line parameters are set by the caller as key=value pairs. Signatures from build/api/c/rsf.h:
Scalar getters
All scalar getters return true if the key was found (false otherwise). sf_getstring returns a pointer or NULL.
Array getters
Array getters read up to n comma-separated values (e.g. rect=3,5,1).
Default-value pattern
The canonical Madagascar idiom — always provide a fallback default when the parameter is optional:
The /* ... */ on the line after each sf_get* call is parsed by the doc extractor and shown in sfdoc sf<name>.
For required parameters that have no sane default, call sf_error when absent:
Memory API
Signatures from build/api/c/rsf.h. All allocators abort with a meaningful error message on allocation failure — never return NULL.
1-D allocators
2-D and 3-D allocators
The multi-dimensional allocators return a pointer-to-pointer (standard C array-of-arrays), but the underlying data is one contiguous block — out[0] (for 2-D) or out[0][0] (for 3-D) points to it. This makes it safe to pass arr[0] to sf_floatread/sf_floatwrite as a flat buffer:
Deallocation
Madagascar does not provide a custom deallocator. Use standard free() directly:
Most production Madagascar programs skip explicit free calls before exit(0) because the OS reclaims all memory on process exit. This is acceptable; add free calls when running under Valgrind or in regression test programs that check for leaks.
Error API
Signatures from build/api/c/rsf.h:
sf_error prints the formatted message to stderr, then calls exit(1). Use it for unrecoverable conditions (bad input, missing required header key, wrong data type):
sf_warning prints to stderr but does not exit — execution continues. Use it for progress messages and non-fatal conditions:
Both functions accept printf-style format strings and variadic arguments.
Extra libraries
Most programs need only #include <rsf.h> and link against librsf. When a program needs helpers from api/c/ (FFT, solvers, splines, etc.) or a user-directory helper module, the SConstruct in the user directory must declare the dependency.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/authoring-sf-programs-c/SKILL.md
Popularity
- Repository stars
- 349
- Repository forks
- 191
- 7-day trend score
- 29
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/ahay/src/authoring-sf-programs-c)