libk  Check-in [926d05a4ce]

Overview
Comment:add docs/manifesto for kfile; add initial kfile headers and function prototypes; update headers to include c++ extern guards so libk functions can be used from c++
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 926d05a4cebe7f378e11889dd24cb49866891b5fed75accc487502fbf53c5e94
User & Date: lexi on 2019-07-27 03:55:06
Other Links: manifest | tags
Context
2019-07-27
03:59
fix typo check-in: 85bec55157 user: lexi tags: trunk
03:55
add docs/manifesto for kfile; add initial kfile headers and function prototypes; update headers to include c++ extern guards so libk functions can be used from c++ check-in: 926d05a4ce user: lexi tags: trunk
2019-07-26
21:56
add kmath module stub check-in: 85a8c60bd2 user: lexi tags: trunk
Changes

Modified kcore/core.h from [46cfa15699] to [7135ae8006].

     1      1   #ifndef KIcore
     2      2   #define KIcore
     3      3   #include <k/type.h>
     4      4   #include <k/io.h>
     5      5   #include <k/str.h>
            6  +
            7  +#ifdef __cplusplus
            8  +extern "C" {
            9  +#endif
     6     10   
     7     11   typedef struct kvar {
     8     12   	ksraw name;
     9     13   	ksraw val;
    10     14   	char* platform;
    11     15   } kvar;
    12     16   
................................................................................
    77     81   #		endif
    78     82   #	endif
    79     83   #	if (__STDC_VERSION__ >= 201103L)
    80     84   #		define KFstd_c11
    81     85   #		define KVstd c11
    82     86   #	endif
    83     87   #	ifdef __cplusplus
           88  +#		define KFstd_c89
    84     89   #		define KFstd_cpp
    85     90   #		define KVstd c++
    86     91   #		if (__cplusplus >= 201103L)
    87     92   #			define KFstd_cpp11
    88     93   #			define KVstd c++11
    89     94   #		endif /* TODO: add more */
    90     95   #	endif
................................................................................
   106    111    * being defined in C++ or K&R C. */
   107    112   #if defined (__cplusplus) && ! defined(KFclean)
   108    113   #	if __cplusplus >= 201103L
   109    114   #		define null nullptr
   110    115   #	else
   111    116   #		define null ((void*)0)
   112    117   #	endif
   113         -#elif defined __STDC__
          118  +#elif defined __STDC__ && (!defined __clang__ || defined KFclean)
   114    119   	enum { null = 0 };
   115    120   	/* believe it or not, this is actually
   116    121   	 * completely legal. doesn't even raise
   117         -	 * a single warning. i was surprised too. */
          122  +	 * a single warning in GCC. i was surprised
          123  +	 * too. alas, it later turned out that
          124  +	 * clang will throw a fit about this, so
          125  +	 * we only use the enum method if __clang__
          126  +	 * is undefined, or if the alternative is
          127  +	 * no null keyword at all. */
   118    128   #elif ! defined(KFclean)
   119    129   #	define null ((void*)0)
   120    130   #endif
          131  +
          132  +#ifndef KFclean
          133  +#	ifdef __cplusplus
          134  +#		define noreturn [[ noreturn ]]
          135  +#	elif __STDC_VERSION__ >= 201103L
          136  +#		define noreturn _Noreturn
          137  +#	else
          138  +#		define noreturn
          139  +#	endif
          140  +#endif
   121    141   
   122    142   #ifdef __cplusplus
   123         -#	define noreturn [[ noreturn ]]
          143  +	[[noreturn]] void kstop(stat_long code);
   124    144   #elif __STDC_VERSION__ >= 201103L
   125         -#	define noreturn _Noreturn
          145  +	_Noreturn void kstop(stat_long code);
   126    146   #else
   127         -#	define noreturn
          147  +	void kstop(stat_long code);
   128    148   #endif
   129    149   
   130         -noreturn void kstop(stat_long code);
   131         -
   132         -#ifdef KFclean
   133         -#	undef noreturn
          150  +#ifdef __cplusplus
          151  +}
   134    152   #endif
   135    153   
   136    154   #endif

Modified kfile/file.h from [7ec69a3e9e] to [a786627a56].

     1      1   #ifndef KIfile
     2      2   #define KIfile
            3  +#include <k/type.h>
            4  +#include <k/io.h>
            5  +
            6  +#ifdef __cplusplus
            7  +extern "C" {
            8  +#endif
            9  +
           10  +typedef enum kfcond {
           11  +	kfcond_ok = 0,
           12  +	kfcond_fail = 1,
           13  +		// an unspecified error occurred
           14  +	kfcond_bad_domain,
           15  +		// the values passed to the function are not within
           16  +		// that function's domain and are invalid
           17  +	kfcond_overstep,
           18  +		// kfstep() was only able to move part of the
           19  +		// distance requested
           20  +	kfcond_bad_index,
           21  +		// the requested index is past the end of the file
           22  +	kfcond_notfound,
           23  +		// the specified object could not be found
           24  +	kfcond_unauth,
           25  +		// you do not have permission to open this object
           26  +	kfcond_mem,
           27  +		// there is not enough memory to complete the
           28  +		// requested operation
           29  +} kfcond;
           30  +
           31  +typedef enum kfile_kind {
           32  +	kfile_closed,
           33  +		// the file object does not refer to an open file
           34  +	kfile_open,
           35  +		// the file object refers to an open file
           36  +} kfile_kind;
           37  +
           38  +enum kfopen {
           39  +	/* file open modes */
           40  +	kf_read   = 1 << 9,  kf_write = 1 << 10,
           41  +	kf_ascii  = 1 << 11, kf_new   = 1 << 12,
           42  +	kf_create = 1 << 13, kf_load  = 1 << 14,
           43  +	kf_top    = 1 << 15, kf_end   = 1 << 16,
           44  +	kf_wipe   = 1 << 17, kf_map   = 1 << 18,
           45  +
           46  +	/* file permission flags */
           47  +	kf_ur = 4 << 6, kf_uw = 2 << 6, kf_ux = 1 << 6,
           48  +	kf_gr = 4 << 3, kf_gw = 2 << 3, kf_gx = 1 << 3, 
           49  +	kf_or = 4 << 0, kf_ow = 2 << 0, kf_ox = 1 << 0,
           50  +}
           51  +
           52  +typedef struct kfile {
           53  +	enum kfile_kind kind;
           54  +	enum kfopen mode;
           55  +	kiochan chan;
           56  +	u8* content;
           57  +} kfile;
           58  +
           59  +enum kfset_mode {
           60  +	kfset_none, // do not move
           61  +	kfset_top, // move to x bytes from the start of the file
           62  +	kfset_end, // move to x bytes from the end of the file
           63  +}
           64  +
           65  +enum kfplace { 
           66  +	kfplace_none,
           67  +	kfplace_conf,
           68  +	kfplace_home,
           69  +	kfplace_desk,
           70  +	kfplace_dl,
           71  +	kfplace_img,
           72  +	kfplace_vid,
           73  +	kfplace_msc,
           74  +	kfplace_doc,
           75  +	kfplace_dat,
           76  +	kfplace_share,
           77  +	kfplace_share_global,
           78  +	kfplace_cache,
           79  +}
           80  +
           81  +kfile kfplace(enum kfplace location, const char* file, enum kfopen mode);
           82  +kfile kfopen (const char* file, enum kfopen mode);
           83  +kfile kfopens(const ksraw file, enum kfopen mode);
           84  +
           85  +kfcond kfset (struct kfile file, enum kfset_mode mode, sz position);
           86  +kfcond kfstep(struct kfile file, offset position);
           87  +
           88  +kfcond kfshred(struct kfile file, sz count);
           89  +
           90  +#ifdef __cplusplus
           91  +}
           92  +#endif
     3     93   
     4     94   #endif

Modified kfile/kfile.md from [194f78820a] to [e76252504c].

     1      1   # kfile
            2  +kfile is libk's file handling library. kfile uses the short naming convention and its sigil is `f`. it is designed to abstract over OS idioms so that developers can write code that simply expresses their intent, and kfile will figure out the correct thing to do on a given platform. to that end, one of kfile's most important functions is `kfplace()` - see below.
            3  +
            4  +## functions
            5  +
            6  +  * `struct kfile kfplace(enum kfplace location, const char* file, enum kfopen mode)` - when you need to open a file in a location that will vary between environments, such as configuration directories, download dirs, image dirs, etc, use `kfplace()` instead of `kfopen()`. the arguments work like `kfopen()`, except that `file` is not a normal path. instead, it specifies a file in the program's configuration directory to open, and the lead constant will tell it what kind of file you are trying to open. in most cases, a null or empty filename is an error, but see `enum kfplace` for exceptions. `file` must not begin with a slash; if they do, `kfcond_bad_domain` will be returned.
            7  +  * `kfcond kfget(enum kfplace, ksmut buffer)` - this function will write the prefix for a particular environment directory into `buffer`, or return `kfcond_fail` if `buffer` is not big enough. the best way to use this function is with a for loop; see examples. do not use this to generate paths for file access; use `kfplace()` instead.
            8  +  * `struct kfile kfopen(const char* file, enum kfopen mode)` - opens a file at the specified pathname. mode is a bit mask . if null is passed as a filename, a temporary file will be created in the appropriate place, using memfds or similar if available and the system temporary directory otherwise. `mode` is a bit flag; the lowest nine bits represent filesystem permissions to be used when creating a file and the rest control how the file will be opened - at least one of `kf_read` or `kf_write` must be passed. see `enum kfopen`. **do not** use kfopen to attempt direct access to configuration files in root of the user's home directory; libk **will** detect this and instruct your users to file bug reports. use kfplace(kfplace_conf) instead to open files in the configuration directory appropriate to the local environment.
            9  +  * `struct kfile kfopens(const ksraw file, enum kfopen mode)` - like kfopen but allows specifying the filename via a `ksraw` string rather than a `const char*`.
           10  +  * `kfcond kfset(struct kfile file, enum kfset_mode mode, sz position)` - repositions the read/write head at `position` bytes into the file (if mode is `kfset_top`) or at `position` bytes from the end of the file (if mode is `kfset_end`). attempting to index past the end of the file will return `kfcond_bad_index`. returns `kfcond_ok` on success.
           11  +  * `kfcond kfstep(struct kfile file, offset position)` - moves the read/write head `position` bytes ahead if `position` is a positive number, or backwards otherwise. attempting to move past the start or end of the file will move the cursor to the start or end and return `kfcond_overstep`. returns `kfcond_ok` on success.
           12  +  * `kfcond kfshred(struct kfile file, sz count)` - write over `file` with random data `count` times, then truncate it.
           13  +  * **posix functions** - POSIX has a wide array of nonportable file IO calls that are important particularly with regards to `exec()` and piping data across processes. for this reason, on POSIX platforms, libk exposes these calls to the user.
           14  +   * kfposix_pipe() - creates a pipe in memory
           15  +   * kfposix_fifo() - creates a named pipe at the specified path
           16  +
           17  +## structs
           18  + * `struct kfile` - represents an open file. a `kfile` struct should always be initialized with `kfopen()` or `kfconf()` before use, or the values it contains will be meaningless and useless!
           19  +   * `enum kfile_kind kind` - either `kfile_closed` if the object does not represent an open file, or `kfile_open` if it does
           20  +   * `enum kfopen mode` - details about the open file. `kf_new` is only set if the file was created by a `kf_new`-flagged open call
           21  +   * `struct kiochan chan` - a channel that can be used to read or write to a file
           22  +   * `u8* content` - a pointer to the start of the file in memory, if it is loaded with `kf_map`
           23  +   * `sz len` - size of the file as of open. this is not updated by `kiosend()` calls!
           24  +
           25  +## enums
           26  +
           27  +### enum kfplace
           28  +`enum kfplace` contains constants that refer to standardized locations that may vary across environments. on POSIX, the XDG specification will be respected to allow the user to select her own directories. unlike `kfopen()`, `kfplace()` will also create any necessary directories if `kf_new` or `kf_create` are passed.
           29  +
           30  +  * `kfplace_conf` - this mode is designed specifically for opening configuration files.  the configuration directory is determined based on OS, environment variables, and the name of the binary; on POSIX OSes, it will use `$XDG_CONFIG_HOME/argv[0]` as the configuration base, cleanly falling back to platform defaults (`$HOME/.config`, and determining home directories based on $USER or failing that UID if `$HOME` is unset). on OSX, it will use `~/Library/argv[0]`. note that if `null` or the empty string are passed as `file`, `kfconf()` will open a file with the name of the configuration base, instead of treating it as a folder to look for configuration files in.
           31  +  * `kfplace_home` - open a file in the user's home folder. on POSIX, it will use the value of `$HOME` or get the user's home directory with the appropriate calls if `$HOME` is unset. **THINK CAREFULLY BEFORE USING THIS FUNCTIONALITY - NEVER USE IT FOR STORING CONFIGURATION.** if you use this flag to create dotfiles in the homedir, libk **will** inform the user and instruct her to file a bug report.
           32  +  * `kfplace_desk` - open a file on the user's desktop, or failing that, home folder. on POSIX, it will use the value of `XDG_DESKTOP_DIR` in `$XDG_CONFIG_HOME/user-dirs.dirs`; on OSX, it will use `$HOME/Downloads`. the same restriction against dotfiles applies here as well.
           33  +  * `kfplace_dl` - open a file in the user's download directory. on POSIX, it will use the value of `XDG_DOWNLOAD_DIR` in `$XDG_CONFIG_HOME/user-dirs.dirs`; on OSX, it will use `$HOME/Downloads`.
           34  +  * `kfplace_img` - open a file in the user's image directory. on POSIX, it will use the value of `XDG_PICTURES_DIR` in `$XDG_CONFIG_HOME/user-dirs.dirs`; on OSX, it will use `$HOME/Pictures`.
           35  +  * `kfplace_vid` - open a file in the user's video directory. on POSIX, it will use the value of `XDG_VIDEOS_DIR` in `$XDG_CONFIG_HOME/user-dirs.dirs`; on OSX, it will use `$HOME/Movies`.
           36  +  * `kfplace_msc` - open a file in the user's video directory. on POSIX, it will use the value of `XDG_MUSIC_DIR` in `$XDG_CONFIG_HOME/user-dirs.dirs`; on OSX, it will use `$HOME/Music`.
           37  +  * `kfplace_dat` - open a file in the user data directory, the homedir equivalent of `/usr/share`. on POSIX, it will use the value of `$XDG_DATA_HOME/argv[0]`; on OSX, it will use `$HOME/Library/Application Support/argv[0]`.
           38  +  * `kfplace_share` - open a file in the system data directory. this is typified by `/usr/share/argv[0]` on POSIX. on OSX, it will use `/Library/Application Support/argv[0]`.
           39  +  * `kfplace_share_global` - like `kfplace_share`, except without the program-specific suffix.
           40  +  * `kfplace_cache` - open a file in the user's cache directory. on POSIX, this will generally be `$HOME/.cache/argv[0]`.
           41  +
           42  +### enum kfopen
           43  +`enum kfopen` contains flags that may be OR'd together and passed to `kfopen()` to alter its behavior.
           44  +  * `kf_read` - opens a file for reading
           45  +  * `kf_write` - opens a file for writing
           46  +  * `kf_ascii` - opens a file in ascii mode, where available. if not set, the file will be opened in binary mode.
           47  +  * `kf_new` - creates a new file with the chosen name if one does not already exist, opening the existing file otherwise
           48  +  * `kf_create` - creates a new file with the chosen name if it does not already exist, failing otherwise
           49  +  * `kf_load` - loads the file directly into memory, allowing it to be read via indexing into a pointer rather than kiosend() and kiorecv() calls. this is most useful for quickly opening files for reading. if kf_write is also passed, a kiochan will be created to permit writing to the file via standard mechanisms. note: `kf_load` will use mmap() to load the file where possible, but on systems without `mmap()` or `MMAP_SHARED`, `kf_load` will be implemented using standard file IO primitives. for this reason, writing to the region of memory containing the file is implementation-defined behavior. if you really want to be able to modify the file in memory, use `kf_map` instead - it is guaranteed to memory-map the file, but will fail outright on platforms without memory mapping available, so its use is discouraged unless absolutely necessary, or as a platform-specific optimization.
           50  +  * `kf_top` - if passed, the kiochan will be positioned at the top of the file. this is the default if kf_read is passed; otherwise, it will be positioned at the end so the file can be appended to.
           51  +   * if you wish to read the file with kiorecv() calls: `kf_read | kf_top`
           52  +   * if you wish your writes to overwrite what is already present in the file: `kf_write | kf_top`
           53  +   * if you wish to append to an existing file: `kf_write | kf_end`
           54  +  * `kf_end` - positions the `kiochan` at the end of the file. see above.
           55  +  * `kf_wipe` - if a file already exists, erase its contents before writing. to prevent accidental deletions, it is an error to pass `kf_read | kf_wipe`.
           56  +  * kfopen also has constants that can be used to spell out file permissions; these are guaranteed to be the standard POSIX octal triple on all platforms. on POSIX platforms, the triple will be passed through to the OS unmodified; on others, libk itself will interpret it.
           57  +  * `kf_ur` - represents the owner's permission to read the file
           58  +  * `kf_uw` - represents the owner's permission to write to the file
           59  +  * `kf_ux` - represents the owner's permission to execute the file
           60  +  * `kf_gr` - represents the group's permission to read the file
           61  +  * `kf_gw` - represents the group's permission to write to the file
           62  +  * `kf_gx` - represents the group's permission to execute the file
           63  +  * `kf_or` - represents all other users' permission to read the file
           64  +  * `kf_ow` - represents all other users' permission to write to the file
           65  +  * `kf_ox` - represents all other users' permission to execute the file
           66  +
           67  +## macros
           68  +if `KFclean` is not defined, the following macros will be:
           69  +
           70  + * `KFsep` is the string used to separate directories in file paths. it will be set to `"\\"` on Windows, `"/"` on POSIX, and so on.
           71  +
           72  +## examples
           73  +`kfget()` is somewhat tricky to use. this is a feature, not a bug - there are very few legitimate uses for it and it should not be convenient to use. use `kfplace()` instead.
           74  +
           75  +    for (sz len = 80; len < kf_path_max; len << 2) {
           76  +    	char path [len];
           77  +    	if (kfget(kfplace_desk, (ksmut){len, path}) != kfcond_ok)
           78  +    		continue;
           79  +    	kiosend(env.std, (ksraw){len, path}, null);
           80  +    	break;
           81  +    }

Modified kgraft/graft.h from [510bcb01f3] to [fb28754f18].

     1      1   #ifndef KIgraft
     2      2   #define KIgraft
            3  +
            4  +#ifdef __cplusplus
            5  +extern "C" {
            6  +#endif
            7  +
            8  +#ifdef __cplusplus
            9  +}
           10  +#endif
     3     11   
     4     12   #endif

Modified kio/io.h from [e3d3c3c357] to [8ac183a3d1].

     7      7    * platform-specific code is found in the *.platform.h
     8      8    * files.
     9      9    */
    10     10   
    11     11   #include <k/str.h>
    12     12   #include <k/type.h>
    13     13   #include <k/mem.h>
           14  +
           15  +#ifdef __cplusplus
           16  +extern "C" {
           17  +#endif
    14     18   
    15     19   typedef enum kiostream_kind {
    16     20   	kiostream_closed,
    17     21   	  // this kiostream cannot be written to
    18     22   	kiostream_file,
    19     23   	  // this kiostream represents a file
    20     24   	kiostream_sock,
................................................................................
    22     26   	  // UNIX, IP, or otherwise
    23     27   	kiostream_term,
    24     28   	  // this socket is being used to communicate
    25     29   	  // directly with a human being
    26     30   	kiostream_ansi,
    27     31   	  // like kiostream_term, but can also understand
    28     32   	  // ANSI control codes
           33  +	kiostream_pipe,
           34  +	  // this kiostream sends or receives data to
           35  +	  // another running process
    29     36   	kiostream_other
    30     37   	  // no fuckin idea
    31     38   } kiostream_kind;
    32     39   
    33     40   typedef struct kiostream {
    34     41   	kiostream_kind kind;
    35     42   	#include "kiostream.platform.h"
................................................................................
    54     61       kiocond_fail, // action failed - unspecified reason
    55     62   	kiocond_fail_closed_stream, // action failed because stream is closed
    56     63   } kiocond;
    57     64   
    58     65   kiocond kiosend(kiochan, ksraw, sz*); // send data to a channel
    59     66   kiocond kiorecv(kiochan, ksraw*); // receive data from a channel
    60     67   kmptr kiorecvall(kiochan, kmcell*, kmkind); // automatically allocate a bufer for a channel
    61         -  // kmkind is only used if kmcell* is NULL
           68  +  // kmkind is only used if kmcell* is null
    62     69   kiocond kiocon(kiochan, kiochan); // connect one channel to another
           70  +
           71  +#ifdef __cplusplus
           72  +}
           73  +#endif
    63     74   
    64     75   #endif

Modified kmem/mem.h from [ace4d63e01] to [e8670496c8].

     1      1   #ifndef KImem
     2      2   #define KImem
     3      3   #include <k/type.h>
     4      4   
     5      5   #ifndef KFclean
     6      6   #	define Kmsz(e) ( sizeof (e) / sizeof (e) [0] )
     7      7   #endif
            8  +
            9  +#ifdef __cplusplus
           10  +extern "C" {
           11  +#endif
     8     12   
     9     13   typedef enum kmkind {
    10     14   	kmkind_none,
    11     15   	kmkind_heap,
    12     16   	kmkind_pool,
    13     17   	kmkind_ref,
    14     18   	kmkind_tree
................................................................................
    35     39   	kmcell* cell;
    36     40   } kmptr;
    37     41   
    38     42   /* heap functions */
    39     43   
    40     44   void* kmheapa(sz);
    41     45   void  kmheapf(void*);
           46  +
           47  +#ifdef __cplusplus
           48  +}
           49  +#endif
    42     50   
    43     51   #endif

Modified kmsg/msg.h from [b69837b00c] to [11e7005879].

     1      1   #ifndef KImsg
     2      2   #define KImsg
            3  +
            4  +#ifdef __cplusplus
            5  +extern "C" {
            6  +#endif
            7  +
            8  +#ifdef __cplusplus
            9  +}
           10  +#endif
     3     11   
     4     12   #endif

Modified knet/net.h from [a2f498298b] to [2dd21f521d].

     1      1   #ifndef KInet
     2      2   #define KInet
            3  +
            4  +#ifdef __cplusplus
            5  +extern "C" {
            6  +#endif
            7  +
            8  +#ifdef __cplusplus
            9  +}
           10  +#endif
     3     11   
     4     12   #endif

Modified kproc/proc.h from [8fdd57f87b] to [23532f29b4].

     1      1   #ifndef KIproc
     2      2   #define KIproc
            3  +
            4  +#ifdef __cplusplus
            5  +extern "C" {
            6  +#endif
            7  +
            8  +#ifdef __cplusplus
            9  +}
           10  +#endif
     3     11   
     4     12   #endif

Modified kstr/str.h from [69d05c5e37] to [a45d7fa32d].

     1      1   #ifndef KIstr
     2      2   #define KIstr
     3      3   
     4      4   #include <k/mem.h>
            5  +
            6  +#ifdef __cplusplus
            7  +extern "C" {
            8  +#endif
     5      9   
     6     10   typedef struct kstr {
     7     11   	sz size;
     8     12   	kmptr ptr;
     9     13   } kstr;
    10     14   
    11     15   typedef struct ksraw {
................................................................................
    13     17   	const char* ptr;
    14     18   } ksraw;
    15     19   
    16     20   typedef struct ksmut {
    17     21   	sz size;
    18     22   	char* ptr;
    19     23   } ksmut;
           24  +
           25  +#ifdef __cplusplus
           26  +}
           27  +#endif
           28  +
    20     29   #endif

Modified kterm/term.h from [891027d45b] to [7961166852].

     1      1   #ifndef KIterm
     2      2   #define KIterm
            3  +
            4  +#ifdef __cplusplus
            5  +extern "C" {
            6  +#endif
            7  +
            8  +#ifdef __cplusplus
            9  +}
           10  +#endif
     3     11   
     4     12   #endif