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: |
926d05a4cebe7f378e11889dd24cb498 |
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