https://github.com/akkartik/mu/blob/main/linux/411string.mu
  1 # read up to 'len' graphemes after skipping the first 'start' ones
  2 fn substring in: (addr array byte), start: int, len: int, out-ah: (addr handle array byte) {
  3   var in-stream: (stream byte 0x100)
  4   var in-stream-addr/esi: (addr stream byte) <- address in-stream
  5   write in-stream-addr, in
  6   var out-stream: (stream byte 0x100)
  7   var out-stream-addr/edi: (addr stream byte) <- address out-stream
  8   $substring:core: {
  9     # skip 'start' graphemes
 10     var i/eax: int <- copy 0
 11     {
 12       compare i, start
 13       break-if->=
 14       {
 15         var dummy/eax: grapheme <- read-grapheme in-stream-addr
 16         compare dummy, 0xffffffff/end-of-file
 17         break-if-= $substring:core
 18       }
 19       i <- increment
 20       loop
 21     }
 22     # copy 'len' graphemes
 23     i <- copy 0
 24     {
 25       compare i, len
 26       break-if->=
 27       {
 28         var g/eax: grapheme <- read-grapheme in-stream-addr
 29         compare g, 0xffffffff/end-of-file
 30         break-if-= $substring:core
 31         write-grapheme out-stream-addr, g
 32       }
 33       i <- increment
 34       loop
 35     }
 36   }
 37   stream-to-array out-stream-addr, out-ah
 38 }
 39 
 40 fn test-substring {
 41   var out-h: (handle array byte)
 42   var out-ah/edi: (addr handle array byte) <- address out-h
 43   # prefix substrings
 44   substring 0, 0, 3, out-ah
 45   var out/eax: (addr array byte) <- lookup *out-ah
 46   check-strings-equal out, "", "F - test-substring/null"
 47   substring "", 0, 3, out-ah
 48   var out/eax: (addr array byte) <- lookup *out-ah
 49 #?   print-string-to-real-screen out
 50 #?   print-string-to-real-screen "\n"
 51   check-strings-equal out, "", "F - test-substring/empty"
 52   #
 53   substring "abcde", 0, 3, out-ah
 54   var out/eax: (addr array byte) <- lookup *out-ah
 55 #?   print-string-to-real-screen out
 56 #?   print-string-to-real-screen "\n"
 57   check-strings-equal out, "abc", "F - test-substring/truncate"
 58   #
 59   substring "abcde", 0, 5, out-ah
 60   var out/eax: (addr array byte) <- lookup *out-ah
 61   check-strings-equal out, "abcde", "F - test-substring/all"
 62   #
 63   substring "abcde", 0, 7, out-ah
 64   var out/eax: (addr array byte) <- lookup *out-ah
 65   check-strings-equal<
#include "fs.h"
#include "common.h"
#include "list.h"
#include "alloc.h"
#include "spinlock.h"
#include "vmm.h"
#include "sharedmemory.h"

static List* gShmList = NULL;
static Spinlock gShmListLock;

static FileSystemNode* gShmRoot = NULL;

static FileSystemDirent gDirent;

static BOOL sharedmemorydir_open(File *file, uint32 flags);
static FileSystemDirent *sharedmemorydir_readdir(FileSystemNode *node, uint32 index);
static FileSystemNode *sharedmemorydir_finddir(FileSystemNode *node, char *name);

typedef struct SharedMemory {
    FileSystemNode* node;
    List* physicalAddressList;
    Spinlock physicalAddressListLock;
    //TODO: