Files
sibo-playground/docs/reference/04-plib-core.md
T

459 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PLIB Core API Reference (Psion SIBO / Workabout MX)
Categorised function reference for the core **PLIB** library, drawn from the
*PLIB Reference*, Version 2.10 (3 February 1995), (C) Psion PLC.
## Conventions
- Signatures are transcribed from the manual. The OCR source occasionally
mangles glyphs; signatures below are corrected to the manual's own C types
where the intent is unambiguous. Uncertain items are marked **[?]**.
- Types: `TEXT` = char/byte string, `UBYTE`/`BYTE`, `UWORD`/`WORD` (16-bit),
`UINT`/`INT` (16-bit), `ULONG`/`LONG` (32-bit), `DOUBLE` (64-bit float),
`VOID`, `HANDLE`, `BOOL`.
- Many functions return `0` on success and a negative `E_*` error number
(defined in `p_gen.h` etc.) on failure.
- `f_*` twins of `p_*` allocators/senders behave identically except they call
`p_leave(E_GEN_NOMEMORY)` / `p_leave(err)` instead of returning `NULL`/`err`.
---
## 1. String & Buffer Handling
Declared chiefly in `p_std.h` / `plib.h`. Buffers (`b*`) take an explicit
length; strings (`s*`) are zero-terminated.
### 1.1 Copy, length, concatenate, fill
| Signature | Purpose |
|---|---|
| `UBYTE *p_bcpy(VOID *target, VOID *source, UINT len);` | Copy `len` bytes source→target (overlap-safe); returns `target+len`. |
| `UINT p_slen(TEXT *str);` | Return length of zero-terminated string, excluding the terminator. |
| `TEXT *p_scpy(TEXT *target, TEXT *source);` | Copy string source→target; returns address of target's terminating zero. |
| `TEXT *p_scpym(TEXT *target, ...);` | Copy+concatenate a NULL-terminated list of strings into target. |
| `TEXT *p_scat(TEXT *lstr, TEXT *rstr);` | Append rstr to lstr; returns address of new terminating zero. |
| `TEXT *p_scatm(TEXT *lstr, ...);` | Append a NULL-terminated list of strings to lstr. |
| `UBYTE *p_brep(VOID *buf, INT buf_len, VOID *pattern, INT pat_len);` | Fill buf by replicating a byte pattern; returns `buf+buf_len`. |
| `TEXT *p_srep(TEXT *buf, INT buf_len, TEXT *pattern);` | Fill buf by replicating a string pattern (terminator excluded). |
| `VOID p_bswap(VOID *buf1, VOID *buf2, INT len);` | Swap `len` bytes between two buffers. |
| `UBYTE *p_bfil(VOID *buf, UINT buf_len, INT fill_byte);` | Fill buf with a repeated byte; returns `buf+buf_len`. |
| `TEXT *p_jtob(TEXT *tbuf, INT tlen, TEXT *sbuf, INT slen, INT type, INT fill);` | Left/right/centre-align sbuf in tbuf (`P_JLEFT`/`P_JRIGHT`/`P_JCENTRE`), padding with `fill`. |
### 1.2 Comparison
| Signature | Purpose |
|---|---|
| `INT p_bcmp(VOID *lbuf, INT lbuf_len, VOID *rbuf, INT rbuf_len);` | Compare two buffers byte-wise; returns lbufrbuf (<0 / 0 / >0). |
| `INT p_scmp(TEXT *lstr, TEXT *rstr);` | Compare two strings; returns lstrrstr. |
| `INT p_bcmpi(TEXT *lbuf, INT lbuf_len, TEXT *rbuf, INT rbuf_len);` | Case-independent buffer compare. |
| `INT p_scmpi(TEXT *lstr, TEXT *rstr);` | Case-independent string compare. |
*(OCR renders these as `p_bemp`/`p_bempi`; the intended names are `p_bcmp`/`p_bcmpi`.)*
### 1.3 Searching (character, substring, wildcard)
| Signature | Purpose |
|---|---|
| `INT p_bloc(VOID *buf, INT buf_len, INT ch);` | Index of first `ch` in buffer, or 1. |
| `INT p_sloc(TEXT *str, INT ch);` | Index of first `ch` in string, or 1. |
| `INT p_bloci(TEXT *buf, INT buf_len, INT ch);` | Case-independent forward char search in buffer. |
| `INT p_sloci(TEXT *str, INT ch);` | Case-independent forward char search in string. |
| `INT p_slocr(TEXT *str, INT ch);` | Reverse (last-occurrence) char search in string. |
| `INT p_slocri(TEXT *str, INT ch);` | Case-independent reverse char search in string. |
| `INT p_bsub(VOID *buf, INT buf_len, VOID *sbuf, INT sbuf_len);` | Index of first occurrence of a byte sequence in buffer, or 1. |
| `INT p_ssub(TEXT *str, TEXT *substr);` | Index of first occurrence of substring in string, or 1. |
| `INT p_bsubi(TEXT *buf, INT buf_len, TEXT *sbuf, INT sbuf_len);` | Case-independent buffer subsequence search. |
| `INT p_ssubi(TEXT *str, TEXT *substr);` | Case-independent substring search. |
| `INT p_bmatch(TEXT *buf, INT blen, TEXT *mbuf, INT mlen);` | Match buffer against a wildcard spec (`*`, `?`); returns TRUE/FALSE. |
| `INT p_bmatchi(TEXT *buf, INT blen, TEXT *mbuf, INT mlen);` | Case-independent wildcard buffer match. |
| `INT p_smatch(TEXT *str, TEXT *mstr);` | Match string against wildcard spec (`*`, `?`). |
| `INT p_smatchi(TEXT *str, TEXT *mstr);` | Case-independent wildcard string match. |
### 1.4 Character classification (return TRUE/FALSE for `c` modulo 256)
| Signature | Purpose |
|---|---|
| `INT p_isupper(INT c);` | Uppercase alphabetic (accented or not). |
| `INT p_islower(INT c);` | Lowercase alphabetic. |
| `INT p_isalpha(INT c);` | Alphabetic either case. |
| `INT p_isdigit(INT c);` | Decimal digit 09. |
| `INT p_isalnum(INT c);` | Alphanumeric. |
| `INT p_isxdigit(INT c);` | Hex digit 09, AF, af. |
| `INT p_isspace(INT c);` | Whitespace (space, HT, NL, VT, FF, CR). |
| `INT p_iscntrl(INT c);` | Control character (031, 127). |
| `INT p_ispunct(INT c);` | Printable graphic, not alphanumeric/space. |
| `INT p_isgraph(INT c);` | Printable graphic (alnum or punct). |
| `INT p_isprint(INT c);` | Printable, i.e. `p_isgraph` plus space. |
### 1.5 Folding & case conversion, skipping
| Signature | Purpose |
|---|---|
| `TEXT *p_skipwh(TEXT *str);` | Skip leading whitespace; return first non-white char. |
| `TEXT *p_skipch(TEXT *str);` | Skip non-white chars; return first whitespace/terminator. |
| `INT p_tofold(INT c);` | Fold char via built-in fold table (for case-insensitive matching). |
| `TEXT *p_scpyf(TEXT *target, TEXT *source);` | Copy string folding each char (like `p_scpy`). |
| `VOID p_sconf(TEXT *str);` | Fold the characters of a string in place. |
| `INT p_toupper(INT c);` | Convert char to upper case (display use, not matching). |
| `INT p_tolower(INT c);` | Convert char to lower case (display use, not matching). |
| `VOID p_scap(TEXT *str);` | Capitalise string: first char upper, rest lower. *(EPOC 2.14+)* |
> **Folding vs. case:** `p_tofold`/`p_sconf` are for case-insensitive
> ordering/matching (symbol tables); `p_toupper`/`p_tolower`/`p_scap` are for
> human-visible text and must **not** be used for comparison.
---
## 2. Arrays, Queues & Sorting (misc utilities)
Doubly-linked circular queues use `P_QUE` headers; delta queues use `P_DELTA`.
| Signature | Purpose |
|---|---|
| `INT p_bsrch(INT nrec, INT (*compf)(), INT *pmid, UBYTE *pmatch);` | Binary search over `nrec` records via callback; writes found index to `*pmid`. |
| `INT p_qsort(INT nrec, INT (*ordf)(), VOID (*excf)(), UBYTE *base);` | Quicksort `nrec` records using ordering and exchange callbacks. |
| `VOID p_enque(P_QUE *pNew, P_QUE *pEntry);` | Insert `pNew` before `pEntry` in its doubly-linked queue. |
| `VOID p_deque(P_QUE *pEntry);` | Unlink `pEntry` from its queue. |
*(The manual also documents `p_dequed` for delta queues; its clean signature is
not printed in the source text — **[?]**.)*
---
## 3. CRC & Checksums
| Signature | Purpose |
|---|---|
| `VOID p_crc(UWORD *pcrc, UBYTE *buf, UINT len);` | Incrementally accumulate CCITT CRC-16 (x¹⁶+x¹²+x⁵+1) over `len` bytes; init `*pcrc` to 0 first. |
---
## 4. Console I/O
Primitive console services layered on the `CON:` device / window server. The
console is opened automatically on first use. PLIB offers only line output of
mono-spaced text and simple backspace-edited line input; richer row/column
control lives in the `CON:` device driver, and full UI in the Window Server.
Internal buffer is `P_MAXSYSIO` (258) bytes, limiting output to 256 bytes/call.
| Signature | Purpose |
|---|---|
| `VOID p_putch(UINT c);` | Write one character to the console. |
| `VOID p_puts(TEXT *str);` | Write a string and start a new line. |
| `VOID p_printf(TEXT *fstr, ...);` | Format args (as `p_atob`), write line, advance to next line. |
| `VOID p_print(TEXT *fstr, ...);` | As `p_printf` but no automatic newline (use `\r`,`\n`). |
| `INT p_getch(VOID);` | Wait for a keypress; return its character code. |
| `INT p_gets(TEXT *str);` | Read a line (backspace editing) up to `P_MAXSYSIO-1`; returns length. |
| `INT p_getl(TEXT *pmt, TEXT *str, INT len);` | Write prompt `pmt`, read up to `len` chars into `str`; returns length. |
---
## 5. Number ↔ String Conversion
Declared in the *Integer Conversion and Rectangle Functions* chapter.
### 5.1 Integer/long → text
| Signature | Purpose |
|---|---|
| `UINT p_itob(TEXT *buf, INT value);` | Signed decimal of INT → buf; returns chars written. |
| `INT p_ltob(TEXT *buf, LONG value);` | Signed decimal of LONG → buf; returns chars written. |
| `INT p_gtob(TEXT *buf, UINT value, INT radix);` | Unsigned UINT in any radix → buf. |
| `INT p_gltob(TEXT *buf, ULONG value, INT radix);` | Unsigned ULONG in any radix → buf. |
### 5.2 Formatted multi-argument output
| Signature | Purpose |
|---|---|
| `INT p_atob(TEXT *buf, TEXT *fstr, VOID *parg);` | `printf`-style format of arg list `parg` into buf; returns chars written. |
| `VOID p_atos(TEXT *str, TEXT *fstr, ...);` | Convenience variadic wrapper over `p_atob` producing a zero-terminated string. |
Format `%[<align>][<fill>]<width><type>`; types: `b` binary, `c` char, `d`
signed dec, `f` fill only, `m`/`w` 2-byte MSB/LSB binary *(EPOC 2.17+)*, `o`
octal, `s` string, `u` unsigned dec, `x` hex. Widen to long with `l`/`L` or
upper-case type; `<width>`/`<fill>` may be `*` (taken from args).
### 5.3 Text → integer/long (radix conversions)
All take `TEXT **pstr` (advanced past the parsed field on success), return 0 or
`E_GEN_OVER`/`E_GEN_FAIL`.
| Signature | Purpose |
|---|---|
| `INT p_stoi(TEXT **pstr, WORD *pval);` | Signed decimal string → 16-bit WORD. |
| `INT p_stol(TEXT **pstr, LONG *pval);` | Signed decimal string → 32-bit LONG. |
| `INT p_stog(TEXT **pstr, UWORD *pval, INT radix);` | Unsigned string in any radix → 16-bit UWORD. |
| `INT p_stogl(TEXT **pstr, ULONG *pval, INT radix);` | Unsigned string in any radix → 32-bit ULONG. |
| `INT p_stoa(TEXT **pstr, TEXT *fstr, ...);` | Scan multiple fields from a string into args per format `fstr`. |
### 5.4 Double ↔ text (floating point conversion)
| Signature | Purpose |
|---|---|
| `INT p_dtob(TEXT *pbuf, DOUBLE *pval, P_DTOB *pformat);` | Format a double to text per `P_DTOB` (type/width/decimals/point/triad); returns chars or `E_GEN_*`. |
| `INT p_stod(TEXT **pstr, DOUBLE *pval, INT point);` | Parse a floating-point number from text (`point` = decimal-point char) → double. |
> Note: the manual provides no `p_dtos` — double→string is `p_dtob`.
---
## 6. Floating Point, Scientific & Math
Declared in `p_math.h`. Trig args are in **radians**. `E_CONFIG`/config via
`p_getctd`. Two families exist:
- **Scientific functions** (`p_sin``p_pow`) and `p_rand`/`p_frand` require the
8087 emulator (`sys$8087.ldd`).
- **Arithmetic primitives** (`p_fld``p_longtof`) are emulator-independent —
usable to do FP without loading the emulator.
Macros (also emulator-triggering with FP operands): `ABS(x)`, `MAX(a,b)`, `MIN(a,b)`.
### 6.1 Scientific (require emulator)
All return 0 or `E_GEN_ARG`/`E_GEN_UNDER`/`E_GEN_OVER`.
| Signature | Purpose |
|---|---|
| `INT p_sin(DOUBLE *pret, DOUBLE *parg);` | Sine. |
| `INT p_cos(DOUBLE *pret, DOUBLE *parg);` | Cosine. |
| `INT p_tan(DOUBLE *pret, DOUBLE *parg);` | Tangent (arg magnitude limited). |
| `INT p_asin(DOUBLE *pret, DOUBLE *parg);` | Arc sine (`ABS(*parg)<=1`). |
| `INT p_acos(DOUBLE *pret, DOUBLE *parg);` | Arc cosine (`ABS(*parg)<=1`). |
| `INT p_atan(DOUBLE *pret, DOUBLE *parg);` | Arc tangent. |
| `INT p_ln(DOUBLE *pret, DOUBLE *parg);` | Natural (base-e) log. |
| `INT p_exp(DOUBLE *pret, DOUBLE *parg);` | e raised to `*parg`. |
| `INT p_log(DOUBLE *pret, DOUBLE *parg);` | Base-10 log. |
| `INT p_sqrt(DOUBLE *pret, DOUBLE *parg);` | Square root. |
| `INT p_pow(DOUBLE *pret, DOUBLE *parg1, DOUBLE *parg2);` | `*parg1` raised to `*parg2`. |
### 6.2 Emulator-independent FP arithmetic
For one-arg functions, `pret` and `parg` may alias. Return 0 or `E_GEN_*`.
| Signature | Purpose |
|---|---|
| `INT p_fld(DOUBLE *pret, DOUBLE *parg);` | Load: `*pret = *parg`. |
| `INT p_fadd(DOUBLE *pret, DOUBLE *parg);` | `*pret += *parg`. |
| `INT p_fsub(DOUBLE *pret, DOUBLE *parg);` | `*pret -= *parg`. |
| `INT p_fmul(DOUBLE *pret, DOUBLE *parg);` | `*pret *= *parg`. |
| `INT p_fdiv(DOUBLE *pret, DOUBLE *parg);` | `*pret /= *parg`. |
| `INT p_fcmp(DOUBLE *parg1, DOUBLE *parg2);` | Compare: returns 1 / 0 / 1. *(OCR: `p_femp`.)* |
| `INT p_fneg(DOUBLE *parg);` | Negate `*parg` in place. |
| `INT p_mod(DOUBLE *pret, DOUBLE *parg1, DOUBLE *parg2);` | Remainder of `*parg1 / *parg2`. |
| `INT p_int(DOUBLE *pret, DOUBLE *parg);` | Integer part (toward zero) → double. |
| `INT p_inti(WORD *pret, DOUBLE *parg);` | Integer part → 16-bit WORD (range-checked). |
| `INT p_intl(LONG *pret, DOUBLE *parg);` | Integer part → 32-bit LONG (range-checked). |
| `VOID p_itof(DOUBLE *pret, WORD *parg);` | Convert WORD → double. |
| `VOID p_longtof(DOUBLE *pret, LONG *parg);` | Convert LONG → double. |
### 6.3 Random numbers
| Signature | Purpose |
|---|---|
| `ULONG p_randl(ULONG *pseed);` | Next pseudo-random 32-bit long; updates `*pseed`. (No emulator.) |
| `DOUBLE p_rand(ULONG *pseed);` | Random double in [0,1); updates `*pseed`. (Emulator required.) |
| `VOID p_frand(DOUBLE *pret, ULONG *pseed);` | Random double in [0,1) → `*pret`; updates `*pseed`. |
> **Long integer arithmetic:** PLIB exposes no dedicated `p_lmul`/`p_ldiv`
> helpers; 32-bit `LONG`/`ULONG` work is done with native C, the `l*`
> conversion routines above, and `p_ltob`/`p_stol`/`p_stogl`/`p_randl`.
---
## 7. Rectangle & Geometry Utilities
Operate on `P_RECT` / `P_POINT` (declared with the integer-conversion chapter).
| Signature | Purpose |
|---|---|
| `VOID p_offrec(P_RECT *rect, INT xoffset, INT yoffset);` | Move a rectangle by an offset. |
| `VOID p_insrec(P_RECT *rect, INT xinset, INT yinset);` | Shrink/expand a rectangle about its centre. |
| `VOID p_unirec(P_RECT *rect1, P_RECT *rect2, P_RECT *result);` | Union (smallest enclosing rectangle). |
| `INT p_intrec(P_RECT *rect1, P_RECT *rect2, P_RECT *result);` | Intersection; returns TRUE if they intersect. |
| `INT p_pinrec(P_POINT *point, P_RECT *rect);` | TRUE if point lies inside rectangle. |
| `INT p_emprec(P_RECT *rect);` | TRUE if rectangle is empty. |
| `VOID p_absrec(P_RECT *rect, P_RECT *result);` | Normalise negative sides to positive. |
---
## 8. Memory Allocation & the Heap
Heap cells are allocated from the process data segment (max ~64K). `f_*`
variants leave with `E_GEN_NOMEMORY` instead of returning `NULL`.
### 8.1 Cell allocation
| Signature | Purpose |
|---|---|
| `VOID *p_alloc(UINT size);` | Allocate a heap cell ≥ `size` bytes; returns address or `NULL`. |
| `VOID *f_alloc(UINT size);` | As `p_alloc` but leaves on failure. |
| `VOID p_free(VOID *pcell);` | Free a cell (no-op if `pcell` is 0). |
| `VOID *p_realloc(VOID *pcell, UINT size);` | Resize a cell (preserving contents); `pcell==0``p_alloc`. |
| `VOID *f_realloc(VOID *pcell, UINT size);` | As `p_realloc` but leaves on failure. |
| `VOID *p_adjust(VOID *pcell, UINT offset, INT amount);` | Open (+) or close () a gap mid-cell for insert/delete. |
| `UINT p_alen(VOID *pcell);` | Return actual cell length in bytes (≥ requested). |
### 8.2 Heap tuning & diagnostics
| Signature | Purpose |
|---|---|
| `VOID p_hgran(UINT nparas);` | Set heap growth granularity (paragraphs of 16 bytes; ≤ `E_MAX_GROWBY`). |
| `VOID p_allwalk(VOID (*fptr)(VOID *fpar, INT isalloc, UINT len), VOID *fpar);` | Walk every heap cell, calling `fptr`; panics on inconsistency. |
| `VOID p_allchk(INT num);` | Check allocated cells vs. free list; `p_panic(0xff)` with diagnostics if corrupt. |
| `UINT p_allspc(VOID **pheap);` | Return potential free heap space; write heap start to `*pheap`. |
| `p_altchk(...)` **[?]** | Thorough heap-integrity check (referenced by name; full signature not printed in source). |
### 8.3 System memory info
| Signature | Purpose |
|---|---|
| `UINT p_getram(VOID);` | Addressable system RAM in 16-byte paragraphs (≤ 32768). |
| `UINT p_totalK(VOID);` | Total machine RAM in KB, ignoring bank-switching. *(EPOC 3.50+)* |
| `UINT p_sgfree(VOID);` | Available addressable segmented memory in paragraphs. |
| `UINT p_sgramdisk(VOID);` | Paragraphs of addressable RAM used by the internal RAM disk. |
### 8.4 External data segments (shared memory / IPC)
| Signature | Purpose |
|---|---|
| `INT p_sgdelete(TEXT *pName);` | Delete a named external data segment. |
| `INT p_sgcopyto(HANDLE nHandle, LONG pos, VOID *source, UINT len);` | Write `len` bytes into an open segment at `pos`. |
| `INT p_sgcopyfr(HANDLE nHandle, LONG pos, VOID *target, UINT len);` | Read `len` bytes from an open segment at `pos`. |
| `UINT p_sgsize(HANDLE nHandle);` | Size of an open segment in 16-byte paragraphs. |
| `INT p_sgadjust(HANDLE nHandle, INT nParas);` | Grow/shrink an open segment by `nParas` paragraphs. |
| `INT p_sgclose(HANDLE nHandle);` | Close an open segment. |
| `VOID p_sglock(HANDLE nHandle);` | Lock a segment against relocation. |
| `VOID p_sgunlock(HANDLE nHandle);` | Unlock a previously locked segment. |
*(The chapter also references `p_sgcreate`/`p_sgopen`/`p_sgfind`; their clean
signatures are not isolated in the source text — **[?]**.)*
### 8.5 Environment variables
| Signature | Purpose |
|---|---|
| `INT p_getenv(TEXT *pMatch, TEXT *pValue);` | Get value of matching env var (string). |
| `INT p_getenviron(TEXT *pMatch, INT mLength, VOID *pValue);` | Get env var value (binary, length-specified match). |
| `INT p_setenv(TEXT *pName, TEXT *pValue);` | Set/create a string env var. |
| `INT p_setenviron(TEXT *pName, INT nLength, VOID *pValue, INT vLength);` | Set a binary env var. |
| `INT p_delenv(TEXT *pMatch);` | Delete matching env var. |
| `INT p_delenviron(TEXT *pMatch, INT mLength);` | Delete env var (length-specified match). |
| `INT p_fndenv(TEXT *pMatch, TEXT *pName, TEXT *pValue, HANDLE *pHandle);` | Iterate/find env vars by name pattern. |
| `INT p_findenviron(TEXT *pMatch, INT mLength, UBYTE *pBuf, HANDLE *pHandle);` | Iterate/find env vars (binary). |
---
## 9. Date, Time & Timers
System time = seconds since 00:00:00 1 Jan 1970 (`ULONG`). Day-based math uses
`P_DAYSEC` (days since 1900 + seconds in day); human form uses `P_DATE`
(year-1900, month 011, day 030, h/m/s, yrday). Declared in `p_date.h`.
### 9.1 System clock
| Signature | Purpose |
|---|---|
| `ULONG p_date(VOID);` | Return current system time (seconds since 1970). |
| `VOID p_sdate(ULONG newTime);` | Set system time (may fire due absolute timers). |
### 9.2 Sleeping / synchronous timers
| Signature | Purpose |
|---|---|
| `INT p_sleep(ULONG n);` | Sleep `n` tenths of a second (relative timer). |
| `INT p_sleept(LONG nTicks);` | Sleep `nTicks` system ticks (32/s SIBO). |
| `INT p_sleepa(ULONG time);` | Sleep until absolute system `time` (wakes machine). |
*(Asynchronous timers are driven through an open `TIM:` channel via
`p_ioc(P_FRELATIVE)` / `p_ioc(P_FABSOLUTE)` and cancelled with `p_iow(...,P_FCANCEL)`.)*
### 9.3 Date/time conversions
| Signature | Purpose |
|---|---|
| `VOID p_sttods(ULONG *pstim, P_DAYSEC *pds);` | System time → days-since-1900 + seconds-in-day. |
| `INT p_dstost(P_DAYSEC *pds, ULONG *pstim);` | `P_DAYSEC` → system time. |
| `INT p_dstodt(P_DAYSEC *pds, P_DATE *pdt);` | `P_DAYSEC``P_DATE` (fills yrday). |
| `INT p_dttods(P_DATE *pdt, P_DAYSEC *pds);` | Validate `P_DATE``P_DAYSEC`. |
| `INT p_dayinm(INT year, INT month);` | Days in given month (leap-aware); year since 1900. |
| `INT p_wkday(ULONG nDay);` | Weekday (0=Mon … 6=Sun) for day-since-1900. |
| `INT p_weekno(ULONG nDay);` | Week number 153 for day-since-1900. |
### 9.4 Localised name/text lookups
| Signature | Purpose |
|---|---|
| `INT p_nmday(TEXT *buf, INT daynum);` | Language day name (0=Mon … 6). |
| `INT p_nmdaya(TEXT *buf, INT daynum);` | Abbreviated day name. *(EPOC 3.18+)* |
| `INT p_nmmon(TEXT *buf, INT monthnum);` | Language month name (0=Jan … 11). |
| `INT p_nmmona(TEXT *buf, INT monthnum);` | Abbreviated month name. *(EPOC 3.18+; OCR prints this as a second `p_nmmon`.)* |
| `VOID p_getsuffixes(TEXT *buf);` | Fill array of 31 day-of-month suffixes (3-byte elements). |
| `VOID p_getampmtext(TEXT *buf, INT n);` | am (`n=0`) / pm (`n=1`) suffix text. |
| `VOID p_getctd(E_CONFIG *pcfg);` | Copy system locale/config (`E_CONFIG`) struct. |
---
## 10. Object-Oriented Programming Primitives (brief)
PLIB provides run-time OOP: categories (load modules of classes) identified by
category number or `HANDLE`; objects are heap instances with a class header.
`f_*` twins leave with `p_leave` on failure. Declared with the OOP chapter.
### 10.1 Category / object creation & class management
| Signature | Purpose |
|---|---|
| `HANDLE p_getlibh(INT catNum);` | Convert a category number to a category handle (0 = local). |
| `VOID *p_new(INT catNum, INT classNum);` | Create an instance of `classNum` in category `catNum`; property zeroed. |
| `VOID *f_new(INT catNum, INT classNum);` | As `p_new`, leaves on OOM. |
| `VOID *p_newlibh(HANDLE catHandle, INT classNum);` | Create instance by category handle. |
| `VOID *f_newlibh(HANDLE catHandle, INT classNum);` | As `p_newlibh`, leaves on OOM. |
| `VOID *f_newsend(INT catNum, INT classNum, INT methodNum, ...);` | Create then send init `methodNum`; cleans up (destroy) on leave. |
| `VOID *f_newlibhsend(HANDLE catHandle, INT classNum, INT methodNum, ...);` | As `f_newsend` but by category handle. |
| `VOID p_reclass(INT catNum, INT classNum, VOID *pObject);` | Change an object's class (same property length). |
| `VOID p_reclassbyhandle(HANDLE catHandle, INT classNum, VOID *pObject);` | Reclass by category handle. |
| `INT p_loadfilelib(VOID *fcb, UINT n, HANDLE *pCatHandle, INT link);` | Load an external category (load module) and get its handle. |
| `VOID p_linklib(HANDLE catHandle);` | Link a loaded category to the local process. |
| `VOID p_ccpy(VOID *pTarget, VOID *pSource, UINT count);` | Copy `count` bytes (category/object helper copy). |
### 10.2 Message sending
`p_send*` use the stack (`CDECL`) convention; the `p_send2..5` / `f_send2..5`
numbered variants use the faster register convention. `f_*` leaves with
`p_leave(err)` if the method returns negative.
| Signature | Purpose |
|---|---|
| `INT p_send(VOID *pObject, INT methodNum, ...);` | Dispatch `methodNum` to object, searching class then superclasses. |
| `INT f_send(VOID *pObject, INT methodNum, ...);` | As `p_send`, leaves on negative return. |
| `INT p_send2(VOID *pObject, INT methodNum);``p_send5(VOID *pObject, INT methodNum, VOID *p1, VOID *p2, VOID *p3);` | Register-convention sends with 03 extra args (`f_send2..5` twins). |
| `INT p_supersend(VOID *pObject, INT methodNum, ...);` | Dispatch starting at the superclass of the calling method (`p_supersend2..5`). |
| `INT p_entersend(VOID *pObject, INT methodNum, ...);` | Dispatch as if via `p_enter` (unwinds on `p_leave`) (`p_entersend2..5`). |
| `INT p_exactsend(HANDLE catHandle, INT classNum, VOID *pObject, INT methodNum, ...);` | Dispatch starting at an explicitly named class. |
---
## 11. Related Error/Process Primitives (referenced above)
These appear alongside the categories above and are commonly used with them:
| Signature | Purpose |
|---|---|
| `INT p_enter(VOID *pfunc, ...);` | Enter a function under structured error trapping. |
| `VOID p_panic(INT nPanic);` | Abort the process with a panic number (unrecoverable). |
| `VOID p_exit(INT nReason);` | Graceful process termination. |
*(Full error-handling and process/IPC APIs are outside this core-PLIB scope but
`p_enter`/`p_leave`/`p_panic` underpin the `f_*` allocator and sender twins.)*
---
### Uncertainty notes
- OCR corrected: `p_bcmp`/`p_bcmpi` (src `p_bemp`), `p_fcmp` (src `p_femp`),
`p_pow` (src fragment `p (…)1_POw`), `p_nmmona` (src duplicate `p_nmmon`).
- `p_altchk`, `p_dequed`, `p_sgcreate`, `p_sgopen`, `p_sgfind` are named in the
manual but their clean C signatures are not isolated in the source text; marked **[?]**.
- Version-gated functions annotated where the manual states a minimum EPOC version.