+ 1 Library structure

Specifies some of the automatic inclusion files. Others are located in other packages.

Also throw in some "don't know where to put them" files.

+ 2 Std.flx

The top level library module.


  header '#include "flx_rtl_config.hpp"';
  include "std/__init__";

+ 3 Default includes for Standard library.


  // ISO C++99 standard header tags
  include "std/c/__init__";
  // core type classes
  include "std/algebra/__init__";
  // base scalar types 
  include "std/scalar/__init__";
  // utility
  include "std/debug";
  // control
  include "std/control/__init__";
  include "std/pthread/__init__";
  include "std/program/__init__";
  //memory management
  include "std/gc";
  // I/O
  include "std/io/__init__";
  include "std/time";
  // codecs
  include "std/codec/__init__";
  // base data types
  include "std/datatype/__init__";
  include "std/strings/__init__";
  // database REMOVED
  //include "std/db/__init__";
  // Version
  include "std/version";
  // Platform support (implementation exposure)
  include "std/osx/__init__";
  include "std/posix/__init__";
  include "std/win32/__init__";
  // Felix (implementation exposure)
  include "std/felix/__init__";

+ 4 C stuff

Structure of C sublibrary.


  include "std/c/c_headers";
  include "std/c/cxx_headers";
  include "std/c/cptr";
  include "std/c/cstdlib";
  include "std/c/carray";
  include "std/c/c_hack";
  include "std/c/shared_ptr";

+ 5 Data types

Structure of datatype library.


  // special
  include "std/datatype/typing";
  include "std/datatype/functional";
  include "std/datatype/special";
  include "std/datatype/unitsum";
  // base data types
  include "std/datatype/tuple";
  include "std/datatype/option";
  include "std/datatype/slice";
  include "std/datatype/list";
  include "std/datatype/assoc_list";
  //include "std/datatype/sexpr";
  //include "std/datatype/lsexpr";
  //include "std/datatype/ralist";
  // arrays
  include "std/datatype/array_class";
  include "std/datatype/array";
  include "std/datatype/varray";
  include "std/datatype/darray";
  //include "std/datatype/sarray";
  //include "std/datatype/bsarray";
  include "std/datatype/judy";
  include "std/datatype/sort";
  // dictionaries
  include "std/datatype/strdict";
  // tree
  //include "std/datatype/avl";

+ 6 Posix

Structure of Posix support library.


  struct Posix {};
  include "std/posix/posix_headers";
  include "std/posix/errno";
  include "std/posix/signal";
  include "std/posix/time";
  include "std/posix/filestat";
  include "std/posix/directory";
  include "std/posix/filesystem";
  include "std/posix/process";
  include "std/posix/shell";
  include "std/posix/faio_posix";
  include "std/posix/mmap";

+ 7 Win32

Structure of Win32 library.


  struct Win32 {};
  // windows services
  include "std/win32/shell";
  include "std/win32/filestat";
  include "std/win32/directory";
  include "std/win32/process";
  include "std/win32/filesystem";
  include "std/win32/time";
  include "std/win32/signal";
  include "std/win32/faio_win32";
  include "std/win32/win32_headers";

+ 8 Platform independent Computation enforcement

Using --import=std/plat/platindep.flxh on flxg command fails to set any of the usual platform macros like FLX_LINUX, FLX_POSIX, FLX_WIN32. Instead it sets the macro PLAT_INDEP. This should bug out any compilations requiring platform specific macros.


  // Platform independent compilation enforced by
  // failing to set any platform macros.
  macro val PLAT_INDEP = 1;

+ 9 C hackery

Hackery for mapping between Felix and C/C++.


  This class provides access to raw C/C++ encodings.
  Incorrect typing is likely to pass by Felix and
  be trapped by the C/C++ compiler. Incorrect management
  of storage can lead to corruption. The use of the
  C_hack class is necessary for interfacing.
  class C_hack
    C void type. Incomplete, can't be instantiated.
    incomplete type void_t = "void";
    Standard variable argument list pointer type.
    type va_list = "va_list";
    GCC specific valist thingo: it will
    be optimised away if not used (eg on MSVC).
    type __builtin_va_list = '__builtin_va_list';
    Throw away result of a function call:
    only useful for C functions that are mainly
    called for side effects.
    proc ignore[t]:t = "(void)$t;";
    C style cast.
    fun cast[dst,src]: src->dst = '(?1)($1:assign)' is cast;
    C++ static cast.
    fun static_cast[dst,src]: src->dst = 'static_cast<?1>($1)' is postfix;
    C++ dynamic cast.
    fun dynamic_cast[dst,src]: src->dst = 'dynamic_cast<?1>($1)' is postfix;
    C++ const cast.
    fun const_cast[dst,src]: src->dst = 'const_cast<?1>($1)' is postfix;
    C++ reinterpret cast.
    fun reinterpret_cast[dst,src]: src->dst = 'reinterpret_cast<?1>($1)' is postfix;
    Felix reinterpret cast.
    More powerful than C++ reinterpret cast.
    Allows casting an rvalue to an lvalue.
    fun reinterpret[dst,src]: src->dst = 'reinterpret<?1>($1)' is postfix;
    const sizeof[t]:size = 'sizeof(?1)';
    Special NULL check for Felix pointers.
    Should never succeed.
    fun isNULL[t]: &t -> bool = "(0==$1)";
    Special NULL check for carray.
    Should never succeed.
    fun isNULL[t]: +t -> bool = "(0==$1)";
    Polymorphic null pointer constant
    Values of this type should not exist.
    This value is provided for checking.
    const null[t]:&t = "(?1*)NULL";
    C++ default value for a type T.
    Workaround for g++ 3.2.2 parsing bug,
    it can parse T() as a default ctor call,
    but screws up on (T())
    fun dflt[t]:1->t = "dflt<?1>()" requires header
      "template<class T> T dflt() { return T(); }";
    body checked_malloc = """
      void *checked_malloc(size_t n) {
        void *p = ::std::malloc(n);
        if(p) return p;
        else throw "out of memory";
    Raw unchecked malloc.
    Used typed malloc in carray if possible.
    gen raw_malloc: !ints -> address = '::std::malloc($1)' requires Cxx_headers::cstdlib;
    Malloc with out of memory check.
    Throws c"out of memory" if out of memory.
    gen malloc: !ints -> address = 'checked_malloc($1)' requires Cxx_headers::cstdlib, checked_malloc;
    Raw unchecked free.
    proc free: address = '::std::free($1);' requires Cxx_headers::cstdlib;
    Invoke C++ destructor
    proc destroy[T] : &T = "::destroy($1);/*C_hack*/"; // from flx_compiler_support_bodies

+ 10 C stdlib Rand

Just to get random functions.


  open class Cstdlib
    requires Cxx_headers::cstdlib;
    const RAND_MAX:long;
    C89 Standard C library seed random number generator.
    proc srand: uint = '::std::srand($1);';
    C89 Standard C library random number generator.
    Known to be not very good. Try not to use it!
    fun rand: unit -> int = '::std::rand()';

+ 11 Raw C interfaces

Raw functions.


  // This file contains raw, low level bindings to C functions.
  // It is not intended to be used by application code.
  // It is provided for library code to use so there's a central place
  // that does C interfacing.
  // Note that since Felix doesn't have const, arguments will normally
  // not needs any casts, but const pointer returns will.
  // TODO: We should break this up according to what in which
  // header file. Also we should put a URL in to Open Group
  // definition page. This will allow browsing clients
  // of the interface to lookup the Posix definitions.
  // YET! See above, it's likely to change.
  class Raw_C
    open Cxx_headers;
    typedef ntbs = &char; // hackery: Null Terminated Byte String 
    // memory allocation
    gen malloc:size -> address = "::std::malloc($1)" requires cstdlib;
    proc free:address = "::std::free($1);" requires cstdlib;
    gen realloc:address * size -> address = "::std::realloc($a)" requires cstdlib;
    proc calloc:size = "::std::calloc($a)" requires cstdlib;
    // memory init and copy
    gen memset:address * int * size -> address = "::std::memset($a)" requires cstring;
    gen memcpy:address * address * size -> address = "::std::memcpy($a)" requires cstring;
    gen memmove:address * address * size -> address = "::std::memmove($a)" requires cstring;
    // NTBS
    gen strlen: ntbs -> size = "::std::strlen($1)" requires cstring;
    gen strcpy:ntbs * ntbs -> ntbs = "::std::strcpy($a)" requires cstring;
    gen strncpy:ntbs * ntbs * size -> ntbs = "::std::strncpy($a)" requires cstring;
    gen strdup:ntbs -> ntbs = "::std::strdup($a)" requires cstring;
    gen strcat:ntbs * ntbs -> ntbs = "::std::strcat($a)" requires cstring;
    gen strchr:ntbs * int -> ntbs = "::std::strchr($a)" requires cstring;
    gen strcmp:ntbs * ntbs-> int = "::std::strcmp($a)" requires cstring;

+ 12 OSX platform tag


  struct Osx{};
  include "std/posix/__init__";

+ 13 Linux specifics


  module Linux {
    header '#include "plat_linux.hpp"';
    requires package "plat_linux";
    fun get_cpu_nr: 1 -> int;

+ 14 Linux smap

Parses and totals proc/PID/smaps memory stats.


  publish """
  Parses and totals proc/PID/smaps memory stats. 
  See smaps_total
  ** don't do [stack] as is last map in smaps and feof appear to be broken or 
  ** doesnt work with /proc files
  Example: (gets total smaps values for heap
   open Smaps;
    val my_smaps = smaps_total(getpid(),"[heap]");
    println("Heap Size=>"+str(my_smaps.size)+" kB");
    //Smaps for other processes
    val m = smaps_total(uint_topid(23264ui),"/usr/lib/libsqlite3.so.0.8.6");
    println("SQLite Size:RSS=>"+str((m.size))+" kB:"+ str((m.rss))+" kB");
  class Smaps {
    open Smaps;
    struct smaps_metric {
    fun getpid: ()->Process::pid_t = "getpid()";
    fun pid_touint: Process::pid_t->uint = "((unsigned int)$1)";
    fun uint_topid: uint->Process::pid_t = "((pid_t)$1)";
    fun min_whitespace(s:string) = {
      var fw = false;
      var m = "";
      for var i in 0ui upto (len s) - 1ui do
        val c = s.[int(i)];
        if  (c == char ' ' and not fw) do
          fw = true; m = m + c;
        elif not c == char ' ' do
          fw = false; m = m + c;
      return m;
  publish """
    Returns summation of blocks for each path specified for a given pid. 
    Path is one of [heap] | [vdso] | [stack] | path dynamic lib (e.g /lib/libbz2.so.1.0.6)
  fun smaps_total(p:Process::pid_t,path:string):smaps_metric ={
    var y = pid_touint p;
    val file = fopen_input ("/proc/"+str(pid_touint p)+"/smaps");
    var at_map = false;
    var end_of_map = false;
    var nums = smaps_metric(0ui,0ui,0ui,0ui,0ui,0ui,0ui,0ui,0ui,0ui,0ui,0ui,0ui,0ui);
    var size = 0ui;
    while not (feof file) and not end_of_map do
      val ln = min_whitespace(strip(readln file));
      val cols = split(ln,' ');
      var spath = let Cons (h,_) = rev cols in h;
      if not at_map  do
        at_map = match find (ln,path) with |Some _ => true |_ => false endmatch;
      elif (at_map  and (len cols) > 5ui) and not spath == path do
        var kv = let Cons (k,Cons (s,_)) = cols in (k,uint(s));
        match kv with 
          |("Size:",e) => nums.size = nums.size + uint(e);
  	|("Rss:",e) => nums.rss = nums.rss + uint(e);
  	|("Pss:",e) => nums.pss = nums.pss + uint(e);
  	|("Shared_Clean:",e) => nums.shared_clean = nums.shared_clean + uint(e);
  	|("Shared_Dirty:",e) => nums.shared_dirty = nums.shared_dirty + uint(e);
  	|("Private_Clean:",e) => nums.private_clean = nums.private_clean + uint(e);
  	|("Private_Dirty:",e) => nums.private_dirty = nums.private_dirty + uint(e);
  	|("Referenced:",e) => nums.referenced = nums.referenced + uint(e);
  	|("Anonymous:",e) => nums.anonymous = nums.anonymous + uint(e);
  	|("AnonHugePages:",e) => nums.anonhugepages = nums.anonhugepages +  uint(e);
  	|("Swap:",e) => nums.swap = nums.swap +  uint(e);
  	|("KernelPageSize:",e) => nums.kernelpagesize = nums.kernelpagesize + uint(e);
  	|("MMUPageSize:",e) => nums.mmupagesize = nums.mmupagesize + uint(e);
  	|("Locked:",e) => nums.locked = nums.locked + uint(e);
          |(k,v) => {}();
    fclose file;
    return nums;