one-file (1f) blocks
As of one-file (1f) Informer v1.0.2 the following one-file (1f) blocks should be present in any source file that is based on the the output of '_skel-1f.cpp'. This allows any one-file (1f) source tools or utilities to interact with the source files in a known way, can produce information about it (like 'source-1f'), and allows for automation to be processed on said source (like 'make-1f').
The very top starts with the _program_name_ on the second (2nd) line. The beginning of the third (3rd) line denotes that the binary and source are one-file (1f) compliant, along with a short description, usually the same as that included in the output of the program. The fourth (4th) line contains a copyright year, and who its for. The short form of any _copyright_liscence_ should be pasted next, the default one in the '_skel-1f.cpp' is for GPLv2, but it could be anything you prefer, and the default is open to change if it is felt there is a need for improvement. That top block should look similar to:
one-file (1f) _short_description_
Copyright (C) 20xx _copy_who_
All Rights Reserved
The next block is (currently) the one-file (1f) compile instruction (see link for more details). At its simpliest, it is a three (3) line, two (2) pass, set of commands, that can be copied & pasted directly into a commandline shell (for easy of use):
/* one-file (1f) compile
Next up we have a list of space seperated development packages that are required to be installed to successfully allow the above one-file (1f) compile to succeed without errors. If you code doesn't have any, then leave the line blank, or remove the block completely (essentially its optional):
/* one-file (1f) requires
The next block will always be present, unless for some reason your program does not use any includes, even then leave the block indicator there anyway, as it basically defines the start of "real code":
/* one-file (1f) headers */
After any initial header includes, these are the base defines that are required by the one-file (1f) commandline switch handling code, and one-file (1f) source verification. They are filled in at compile time by the one-file (1f) compile commandline instructions:
one-file source appendage
As opposed to the actual name of this block indicator, which visually indicates the beginning of you code, it actually marks the end of the "pre-defined" block sections, sections that are more "informational" than "programatic".
You may find that (especially in the early stages of development) you dont have a need for any of the next four (4) one-file (1) identifier blocks, with the next block being the functions block. Its OK to leave them in, or take them out, but this one must be there:
/* one-file (1f) start */
/* one-file (1f) defines */
/* one-file (1f) enums */
/* one-file (1f) structs */
/* one-file (1f) classes */
This block is the start of your "real" program, broken out of the main loop as individual functions, some of which may be refered to as sub-routines. Without the use of header file includes, the functions need to be listed in reverse order of there use. That is to say, first you define the function, before (the compiler lets) you use the function.
Remember its OK to place one line block remarks to outline a group of functions, making it easier to see visually where you are in the code, and (if you like to use DocBook or Doxygen) to add multi-line function "informer" block remarks before each function:
/* one-file (1f) functions */
This marks the beginning of the one-file (1f) specific functions that return the version, and dump the source to console, ending before the "main" block is defined in the source:
/* one-file (1f) specific */
The main function (in C/C++), and for most one-file (1f) programs, (as of one-file (1f) Informer v1.0.2) it only contains the commandline switch handling routines, any call to initialization and appending of cleanup routines like atexit(), before the main while loop, which acts as a "mini virtual state machine":
/* one-file (1f) main */
int main(int argc, char *argv)
<< snip >>
This last block indicator is indented to visually match the progromatic end of execution and the return to the OS with "error=0":
<< snip >>
/* this is the end, .. my friend, the end */
Multiple commands, files, compile, requires, and notes blocks may be optionally included, so any source one-file (1f) source tools or utilities should expect there to be more than one, even if there are usually none found. That is to say they should be manipulated as an array of said blocks.
All other one-file (1f) blocks can be considered as individual to the current OS, with the exception on commented out "named header blocks" used for other OS's, however there is only one active header block in any one-file (1f) source at compile time.
As a one-file (1f) source in the main one-file (1f) project is maintained and compiled on varying OS's over time, it may become useful to add multiple option blocks for those OS's, usually 'compile' & 'requires' blocks, but may not be limited to them alone.
For what ever reason, for example, say to setup a bridge IP address, and add the user to its group via the super user, in order to use the compiled binary, it may be nessecary for a one-file (1f) source to contain shell commands.
With commands, especially multi-line (but more so with extra file blocks) be careful when including C/C++ style /* comment blocks */. They can reak havoc on your compiler if you are not careful, espcially if you forget to close the one-file (1f) block with "*/" at the beginning of a new line.
A1. USER COMMANDS
Any included commands that are specific to the super user (root user or administrator) can be placed in specific blocks. If they are required before compile instructions are used (to build files, or set privilages) then place them before any related compile blocks. If they are required after compile, before runtime use (to build resources, or configurations) then place them after the related compile blocks. The commandline itself should start after the '# ' (hash,space. "*/" at the beginning of a line marks the end of the block. If its a multi-line shell command, (for linux) place \ at the end:
/* one-file (1f) # echo << file.conf\
# one line\
A2. SUPER USER COMMANDS
Any included commands that are specific to the super user (root user or administrator) can be placed in specific blocks. If they are required before compile instructions are used (to build files, or set privilages) then place them before any related compile blocks. If they are required after compile, before runtime use (to build resources, or configurations) then place them after the related compile blocks. The commandline itself should start after the '$ ' (dollar,space). "*/" at the beginning of a line marks the end of the block. If its a multi-line shell command, (for linux) place \ at the end:
/* one-file (1f) $ find / -name libpepperflash.so | xargs ls -l
Any included files that are reuired can be placed in specific blocks. If they are required before compile instructions are used (to build files, or inline Makefile) then place them before any related compile blocks. If they are required after compile, before runtime use (to build resources, or configurations) then place them after the related compile blocks. The filename itself should be between 'single quotes', the contents on the next line. "*/" at the beginning of a line marks the end of file (EOF):
/* one-file (1f) 'Makefile'
# some Makefile commands
You may want to, or feel the need to, add notes, either important to the 'compile' or 'requires' blocks, information that needs to be known in order to successfully compile the project. Place any relevant notes blocks before there related blocks. If it generic place it after the top block. You can place as many notes blocks as you feel need to have. If they are not one-file (1f) related, then they should probably just be regular block remarks. "*/" at the beginning of a new line marks the end of the one-file (1f) notes block:
/* one-file (1f) notes
/* one-file (1f) notes (requires)
/* one-file (1f) notes (linux)
/* one-file (1f) notes (2017-01-21)
If you are like many of us and you like to compile on multiple platforms, especially, say for example, Linux and Windows, and you use a Windows native build system (instead of CygWin or MinGW) then you one-file (1f) compile instructions will (usually) be completely incompatible, so you may want to have two (2) compile blocks (or more for different OS versions). In which case just place (_os_) or (_os_version_) in the block name, like so:
/* one-file (1f) compile (linux)
/* one-file (1f) compile (win)
/* one-file (1f) compile (win_64_2003_server_visual_studio_6)
/* one-file (1f) compile (amigaos)
The same thing can be done for requires blocks too, if you think it important to provide library names for different OS's, for example, Debian, BSD and RHEL. These often use different names for development packages (eg. '-dev' or '_devel'), as well as some other semi-core package names (eg. 'cloog' is named different on Ubuntu than Debian):
/* one-file (1f) requires (Debian Wheezy)
/* one-file (1f) requires (Ubuntu 15.04)
/* one-file (1f) requires (VoidLinux)
/* one-file (1f) requires (MSX)
In both the above cases ('compile' & 'requires') simply make (_the_contents_) descriptive, and short as practically possible. If you find things "getting out of hand", or you feel like 50% of your source is made up of one-file (1f) blocks that dont contain code as such, then maybe move to a multi-file source appendage with ZIP format and a proper 'Makefile' with everything automated through that.
At the end of the day, athough one-file (1f) sources should be informational, and instructive to a certain degree from a learning perspective as well as visual reminders, the source should be practical to manage for the programmer too, so dont feel like you "have" to do things a certain way. It's supposed to be about convieniance more than anything (like a guide), not adherance (as in a law).
The future is so bright, I gotta wear 'shades-1f' ...
©2016 - Paul Wratt - one-file (1f)