Writing c
Coding style and guidance when writing C code. Use whenever C code is being written, read or updated.From its SKILL.md
npx -y skills add gerph/riscos-agent-skills --skill writing-cAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
9.9 KB, ~2.3k tokens by cl100k_base, as published. Nobody here has run it
Guidance for writing C code.
Project Structure
- Source file conventions:
- C source files live in a directory called
c, and do not have an extension. - C header files live in a directory called
h, and do not have an extension. - For example, a C file for writing files might be called
c/file_writer, and its header would be calledh/file_writer. - Within the source files, the convention is still to use the extension, for example,
#include "file_writer.h". - The filenames must NEVER be in the form
c/filename.corh/filename.h.
- C source files live in a directory called
- Makefile files have names that start with
Makefileand end with,fe1.- Makefile include files can be found in the directory
$AMUFILES.
- Makefile include files can be found in the directory
- Built absolutes:
aif32/<name>,ffa(32-bit absolute) oraif64/<name>,ffa(64-bit absolute) - Built modules:
rm32/<name>,ffa(32-bit module) orrm64/<name>,ffa(64-bit module) - BBC BASIC files are named with a suffix of
,fd1. They do not need line numbers. - The version number of the project is in
VersionNum, a C include file which describes values. - If the project is a module, a
cmhgdirectory will exist with a file describing the module definition and entry points. - If the project name is not otherwise given, the environment variable
$ROBUILD_PROJECTcontains its name. - RISC OS application names should normally be capitalised and should generally avoid hyphens.
- For example, prefer
WimpClicksoverwimp-clicksfor the built application and package name.
- For example, prefer
- Place separate functionality in separate files. For example, module interfaces should be in
c/module, and hardware interface would be inc/hardware.
In the filesystem:
Wrong:
c/name.ch/name.h
Correct:
c/nameh/name
C Coding style
- Code conforms largely to C89.
- All variable declarations must appear at the top of their block, before any statements. Create new blocks to ensure that variables are scoped in their use. Do not declare variables inline with code.
- Use
int32_t,uint32_tand friends as appropriate.int64_tis not available for 32-bit, but is available in the 64-bit compiler. - When representing on-disk or in-memory RISC OS layout fields with a fixed binary size, prefer explicit fixed-width types such as
int32_trather thanint, so the layout remains correct in 64-bit builds. - If you get errors from the compiler like
Serious error: <command> expected but found '<type>', this probably means that there is a variable declaration in the middle of the function. C89 requires that variable declarations be at the start of the block.
- Braces go at the start of lines (not the ends).
- Indentation is 4 characters.
- Do not leave trailing spaces, even on blank lines.
- Magic numbers and strings (bare numbers and strings in the code) should be avoided.
- Use
enumif you need to enumerate a set of values like state values. - Use
#definefor values like bit-fields and constant strings.
- Use
No Threading
RISC OS is single-threaded. Do not use threading or assume re-entrancy.
Includes
- You may use includes
stdint.handstdbool.hif needed. - Interfacing with the OS and calling SWIs will usually need
kernel.handswis.h. - Include
stdlib.hfor NULL when needed.
Commenting
- Retain comments where they remain correct.
- Add comments to describe intent.
- Functions should include a prologue comment to describe the function's purpose and arguments, in a similar style to the rest of the project.
- Both C and H files should contain a prologue comment to describe the file's purpose, and its relationship to others in the project, if necessary.
File prologues:
/*******************************************************************
* File: filename
* Purpose: Description
* Author: AUTHOR
******************************************************************/
Function prologues:
/*******************************************************************
Function: function_name
Description: Description of function
Parameters: var = value
Returns: none
******************************************************************/
64-bit build notes
- Treat the 64-bit build as a stricter compiler pass, even when the 32-bit Norcroft build is happy.
- Do not define a private
statichelper with the same name as a shared helper already declared in a header. The 64-bit toolchain will reject this immediately. - Code that calls low-level kernel helpers should be checked for 64-bit visibility and availability. If a helper is not available for
__riscos64, either provide a real 64-bit implementation or return an explicit unsupported/error result rather than relying on implicit declarations. - Keep 32-bit-only SWI or ABI dependencies behind narrow helper functions so they can be
#ifdef __riscos64guarded cleanly.
Porting graphics-dependent code
When porting code that talks to the graphics or pointer system, separate it into:
- pure algorithmic control flow
- state queries
- side-effect backends
This makes it possible to implement and test the orchestration logic before the real plotting or output backend exists. For example, tiled sprite plotting can be implemented as:
- local tile placement logic
- a support hook to read graphics bounds and eig factors
- repeated calls into the lower-level sprite plotting reason
That keeps partial implementations honest and avoids hard-coding fake graphics behaviour into otherwise reusable logic.
When part of the implementation drops below the normal graphics interfaces and touches screen memory directly, isolate that path behind dedicated helpers. That makes it easier to keep cursor removal, mode checks, and 32-bit/64-bit differences local to the framebuffer code instead of leaking through the general rendering logic.
Porting record-based BASIC code
When porting BBC BASIC code that uses fixed-offset records and ad hoc blocks:
- Convert the record layouts into explicit C structures with descriptive member names before rewriting the higher-level logic.
- Pull narrow behavioural rules into pure helpers where practical, especially for geometry adjustment, selection arithmetic, and message-block construction.
- For Wimp or clipboard protocols, separate block construction from message sending so the protocol details can be regression-tested without a live desktop session.
Self-test reporting
When tests are skipped because of OS version or environment restrictions, count and report the skipped cases explicitly. Do not silently reduce the apparent coverage of the test run.
Compilation and linking errors
- "Serious error: <command> expected": This is almost always a C89 violation where a variable was declared after a statement. Move all declarations to the top of the
{ }block, or wrap the logic in a new{ ... }block:
void my_function(void)
{
int i = 0;
do_something();
{
int j = 5; // Valid in C89 because it's at the top of this sub-block
do_more(j);
}
}
- Static/non-static declaration mismatch: Check whether a source file has redefined a helper which is already declared in a shared header or implemented elsewhere.
- Undefined symbols at link time: Check if
o.modhead(the CMHG object) or your assembly objects (e.g.,o.veneer) are missing from theOBJSvariable in your makefile. - Implicit declaration warnings in 64-bit builds: Treat these as real porting work, especially for SWI wrappers and kernel helper entry points.
Standard C files
- The C includes for RISC OS can be found in the directories:
/riscos-built/Export/C/and/riscos-built/Export/Lib- searched first./riscos-resources/Export/C/and/riscos-resources/Export/Lib- searched second.
- Use
riscos-libsearchto find exported headers, libraries, functions and defines:riscos-libsearch ScreenSave- find a function or define by name.riscos-libsearch Sprite.h- find matching headers and their host filenames.riscos-libsearch --symbols riscos/Sprite.h- list symbols from a header.riscos-libsearch --lib RISC_OSLib- show a library's headers, objects and symbols.riscos-libsearch --lib-list- list known libraries.
riscos-libsearchreads the baked system index from/riscos-resources/Export/Lib/libraries.dband, when present, the user-built index from/riscos-built/Export/libraries.db. Built results take priority over system results for the same include path.- If
/riscos-built/Exporthas changed and lookup results look stale, runriscos-libsearch --indexto rebuild the user-built index. - RISC OS interface values and constants can be found in the following includes (include name
riscos/NAME.his held in fileriscos/h/NAME):riscos/CMOS.h- NVRAM valuesriscos/DynArea.h- Dynamic area constantsriscos/EnvNumbers.h- Program environment registration valuesriscos/Events.h- Event numbersriscos/FileTypes.h- RISC OS file type numbersriscos/Heap.h-OS_Heapconstantsriscos/Messages.h- Wimp message numbersriscos/ModeVariables.h-OS_ReadModeVariableandOS_ReadVduVariablesvaluesriscos/ModHand.h- RISC OS module area constantsriscos/NewErrors.h- Error numbers and standard stringsriscos/OSPlatformFeatures.h- Platform informationriscos/OSReadSysInfo.h- OS informationriscos/OSScreenMode.h- Screen mode selection and informationriscos/Oswords.h-OS_Wordconstantsriscos/Pointer.h-OS_Pointerconstantsriscos/Services.h- Service numbers.riscos/Sprite.h-OS_SpriteOpconstantsriscos/UpCall.h-OS_UpCallconstantsriscos/Vectors.h- Vector numbers
What ships with it: 1 file
192 B alongside SKILL.md
agents/
- openai.yaml192 B