Differences From
Artifact [4cea7e271a]:
31 31
32 32 libk is designed to fix this (in hindsight) glaring error.
33 33
34 34 however, a common problem with libraries is the proliferation of inordinately long and hard-to-type function names such as `SuperWidget_Widget_Label_Font_Size_Set()`. this may be tolerable in IDEs with robust auto-complete or when referencing a highly-specific, sparsely-used library; it is however completely intolerable in the case of a core library with heavily used functionality.
35 35
36 36 therefore, libk uses two slightly different naming conventions: the **short** convention, for core functions the user will call frequently, and the **full** convention, for less-commonly used functions. the inconvenience of remembering which is which will hopefully be outweighed by the keystrokes (and bytes) saved.
37 37
38 -in the **full** convention, a function's name is prefixed with its module name followed by an underscore. thus, `kfile/open.c` will be invoked as `kfile_open()`.
38 +in the **full** convention, an identifier's name is prefixed with its module name followed by an underscore. thus, `kgraft/list.c` is invoked as `kgraft_list()`.
39 39
40 -in the **short** convention, the function name is prefixed by the letter `k` followed by the module's "glyph" -- a one- or two-letter sequence that represents the module, usually the first one or two characters. therefore, `kio/write.c` is invoked as `kiowrite`.
40 +in the **short** convention, identifiers are prefixed by the letter `k` followed by the module's "glyph" -- a one- or two-letter sequence that represents the module, usually the first one or two characters. therefore, `kfile/open.c` is invoked as `kfopen`.
41 41
42 42 which naming convention a module uses should be specified at the top of its documentation. if it uses the short convention, its glyph should be specified as well
43 43
44 +in both naming conventions, the following rules apply:
45 +
46 + 1. the possible values of enumeration types are always preceded by the name of the enumeration type and an underscore. for instance, the enum `kschain_kind` has a value named `kschain_kind_block`. **exception:** an enum named `<S>_kind`, where `<S>` is a struct type, may simply use the prefix `<S>_`.
47 + 2. macros begin with the uppercase letter `K` -- e.g. `Kmacro`. macros that can be defined by the user to alter the behavior of the api should begin with `KF` if they are on/off flags, or `KV` otherwise.
48 + 3. capital letters are only used in macro prefixes.
49 + 4. low-level function names are prefixed with the API they call into. for example, the function that performs the POSIX syscall `write` is named `kio_posix_fd_write`.a wrapper around the Windows function `CreateProcess()` might be called `kproc_win_createprocess`.
50 +
44 51 ### atoms
45 52
46 53 libk uses the concept of "atoms" (small, regular strings of text) to standardize common references, such as operating systems or processor architectures.
47 54
48 55 #### operating systems
49 56
50 57 these atoms will be used to reference operating systems.
................................................................................
71 78
72 79 these atoms will be used to reference particular system architectures. these will mostly be used in the filenames of assembly code.
73 80
74 81 ## macros
75 82
76 83 libk will not in any circumstance use macros to encode magic numbers, instead using typedef'd enums. all libk macros begin with the uppercase letter `K` -- e.g. `Kmacro`. macros that can be defined by the user to alter the behavior of the api should begin with `KF` if they are on/off flags, or `KV` otherwise. **macros should only be defined by the libk headers if the flag `KFclean` is *not* defined at the time of inclusion.**
77 84
85 +include guards take the form of the bare module name prefixed by `KI`. so to test if `k/term.h` has been included, you could write `#ifdef KIterm`.
86 +
78 87 ## languages
79 88
80 89 libk uses only three languages: C (\*.c, \*.h), yasm (\*.s), and make (makefile).
81 90
82 91 other assemblers will probably be necessary for the more exotic targets, however.
83 92
84 93 ## repository structure
................................................................................
90 99 each function should be kept in a separate file within its module's directory. when OS or architecture-specific code is needed, the file's name should be a list of one or more of the fields [arch, OS, bits, format] separated by a `.` -- for instance, the 32-bit x86 haiku version of a function called `write` defined in assembly would be named `write.x86.haiku.32.s`. however, if a function has an extraordinarily large number of versions, they may instead be stored in a folder with the same name as the function.
91 100
92 101 each module should have a header named the same thing as the module except without the `k` prefix. (e.g. the header for `kio` is `kio/io.h`) located in its folder. this is the header that the end-user will be importing, and should handle any user-defined flags to present the API the user has selected.
93 102
94 103 each module directory should contain a makefile that can build that module. see **makefiles** below. all makefiles should be named `makefile` (**not** `Makefile`).
95 104
96 105 each module should contain a markdown file. this file's name should be the name of the parent directory suffixed with `.md`; for instance, `kterm` should contain the file `kterm/kterm.md`. this file should document the module as thoroughly as possible
106 +
107 +each module may contain any number of files of the name `exe.*.c`. this files will be treated as *tools* by the build system and compiled as executables, rather than libraries. they should be compiled to `out/$module.$tool`
97 108
98 109 the repository root and each module may also contain the directory `misc`. this directory may be used to store miscellaneous data such as ABI references, developer discussions, and roadmaps. if the `misc` directory is deleted, this must not affect the library or build system's function in any way - that is, nothing outside a `misc` folder may reference a `misc` folder or anything inside it, including documentation. the `misc` directory should be removed when its contents are no longer needed. in most cases, the repository wiki and forum should be used instead of the `misc` folder.
99 110
100 111 the folder `arch` in the root of the repository contains syscall tables and ABI implementations for various architectures.
101 112
102 113 ## makefiles
103 114
104 115 libk uses `make` as its build system. makefiles should be handwritten. there will be one global makefile in the root of the repository, and one makefile for each module.
105 116
106 117 each rule should be prefixed with ${OUT}, to allow retargeting of the build-dir with the OUT environment variable. this is particularly important since the makefiles chain.
107 118
108 119 the rest is TBD.
109 120
121 +## design principles
122 +
123 +there are four overriding principles that guide the design of libk.
124 +
125 + 1. it should be easy to write code that uses it.
126 + 2. it should be easy to read code that uses it.
127 + 3. the simple, obvious way of using libk should produce the most optimal code.
128 + 4. code that uses libk should be idiomatic C.
129 +
130 +for these reasons, the codebase follows a number of strict rules.
131 +
132 +### booleans are banned
133 +there are a number of reasons for this.
134 +
135 +the first is simply that the boolean type in C is a bit messy and libk headers are intended to import as few extra files as possible.
136 +
137 +the second is that boolean-using code can be hard to read. consider a struct declaration of the form `rule r = { 10, buf, true, false, true }`: the meaning of this declaration is opaque unless you've memorized the structure's definition.
138 +
139 +instead, libk uses enums liberally. so the above might be rewritten as e.g.:
140 +
141 + rule r = { 10, buf,
142 + rule_kind_undialectical,
143 + rule_action_expropriate,
144 + rule_target_bourgeoisie
145 + };
146 +
147 +this makes code much more legible and has the added benefit of making the definitions easier to expand at a later date if new functionality values is needed without breaking the API or ABI.
148 +
110 149 ## build process
111 150
112 151 libk has a number of targets. all files generated by a `make` invocation will be stored in the folder "out" at the root of the repository. this directory may be deleted entirely to clean the repository.
113 152
114 -**defs** will create the directory `out/k/` and populate it with module header files. the `k/` directory shall be suitable to copy to `/usr/include` or similar. these header files will copied by building the `defs` target of each module's makefile.
153 +**defs** will create the directory `out/k/` and populate it with module header files. the `k/` directory shall be suitable to copy to `/usr/include` or similar. these header files will copied by building the `${OUT}/$(module).h` target of each module's makefile.
115 154
116 155 **libk.so** will build the dynamically linked form of libk, according to the build variables set
117 156
118 157 **libk.a** will build the statically linked form of libk, according to the build variables set
119 158
120 159 **tool** will build the executables used for modules such as `kgraft`.
121 160