one-file (1f) functions
from: one-file (1f) Informer v1.0.1
<< snip >>
Any one-file (1f) program fully compiled will have a source file appended to it. The source contains code to output that source file to the console, which can be save to a file. Only TEXT files (usually .cpp) and ZIP (.zip) sources are attached, with the '--src-type' switch giving the required file extention.
<< snip >>
prog-1f --source (this will tell you if there is no source)
prog-1f --src-size (this will output '12345' if there is no source)
prog-1f --version (this should have '(one-file)' or '(1f)' in the output)
prog-1f --1f (confirmation beyond doubt, exits with 31 or 32)
Any one-file (1f) option will return 31 (0x1f) if successful, and 32 (0x20) if an error occured, making it easier than ever to detect a one-file (1f) program.
<< snip >>
end: one-file (1f) Informer v1.0.1
Example
=======
$ ./sdlSlide-1f --1f
sdlSlide (one-file) v1.2.3
Copyright 2016 MiNTed Games
one-file (1f) source information.
usage: sdlSlide-1f _option_
_option_:
--src|--source output attached one-file (1f) source file
--src-size size of appended source (in bytes) (44921)
--src-type type of source appended (TXT/ZIP) (.cpp)
To save one-file (1f) source to file use one of the following:
sdlSlide-1f --src > sdlSlide-1f.cpp
sdlSlide-1f --src > sdlSlide-1f`sdlSlide-1f --src-type`
To verify one-file (1f) source file size:
sdlSlide-1f --src-size (match this to the size in a directory listing)
or use:
NAME=sdlSlide; if [ `ls -l $NAME-1f.cpp|cut -d \ -f 5` = `./$NAME-1f --src-size` ]; then echo Verified; else echo Failed; fi
one-file (1f) options exit with status:
31 successful (0x1f)
32 an error occured (0x20)
Switches
=========
In order to be useful as one-file (1f) compatible or complient, every source file (or main source file in multiple file sources) needs to contain functions to process and output the above text and associated command line options.
The bare minimum for command line processing needs to be the following, even if no text is actually output to console:
--1f|-1f
--src|--source
--src-size
--src-type
one-file (1f) Informer mentions "Only TEXT files (usually .cpp) and ZIP (.zip) sources are attached". This is not strictly true, after all any binary blob can be piped out and appended to the compiled program using '>>'. It says "Only" to avoid people attatching any escoteric format they desire, and releasing that into the wilds of the net, its just a pain in the "behind" and essentually underminds the main point of using one-file (1f), source accessability.
Stick with ASCII TEXT format, or ZIP format files, and you will be fine, in one hundred years your great grandchildren will be able to access and modify your loving creation.
Functions
=========
Just as an excersize (and for easy reference), we will list the functions as if included in external source files using header definitions (.h, hpp), which at a bare minimum are:
void version_1f()
void output_1f(char *file_1f)
int main(int argc, char *argv[])
Those should be the last three functions in you code. Handleing of command line switches can also be passed off to functions if you want a tighter main() function block, if so they should preceed (come before) version_1f() in reverse order, to satisfy the compiler preprocessing of source files (especially where only one source file is used).
Keeping command line processing as the main body of your main() functions also makes sense, see the source example below (as well as the full sources available through the links at the top an bottom of this page), as there is nothing else in main() of the actual main program loop, except as a case/switch statement (implimenting a mini virtual state machine).
The --version switch uses the version_1f() function to output ASCII text, allowing exit(0) with regular no error output (which is hex 0x00 or just plain 0). ALL other one-file (1f) related command line switches, including --1f, --src, --src-size, --src-type, need to end with exit(31) for true (which is hex 0x1f), and exit(32) for false (which is hex 0x20).
The define NO_SIZE is used to check (and double check) against the program and source sizes (offset_1f & sizeOf_1f) at various places. To help maintain some sort of sanity for the compiler, every now and again you should visually verify the size of the source attachement, and binary before attachment, to make sure that the compiler is using the same bit size for NO_SIZE, PRG_SIZE and SRC_SIZE. This is not crucial, but it helps with a couple of things: 1) a quick mental comparison of file byte sizes. 2) recording of the actualy sizes the last time you finished development work. 3) the bit length (byte size) the compiler uses when storing those numbers in binary compiled format is the same length as NO_SIZE.
from: sdlSlide-1f.cpp
<< snip >>
/*
one-file source appendage
*/
#define NO_SIZE 45678
//#define SRC_TYPE ".zip" // if its a ZIP appendage
#define SRC_TYPE ".cpp" // if its a TEXT appendage, name the extention
#ifndef PRG_SIZE
//#define PRG_SIZE 27142 // last checked binary size was ...
#define PRG_SIZE NO_SIZE // .. this should be close to actual
#endif
#ifndef SRC_SIZE // size of 1 text file or 1 zip file
//#define SRC_SIZE 44921 // last checked source size was ...
#define SRC_SIZE NO_SIZE // .. affects binary size if too small
#endif
const long offset_1f = PRG_SIZE; // this has never been accurate (EXT4)
const long sizeOf_1f = SRC_SIZE; // we use this (-sizeOf_1f) as offset
/* one-file (1f) start */
<< snip >>
end: sdlSlide-1f.cpp
Notice here the sequence "NO_SIZE 45678", which in bit size (number of bytes), is equivalent to the actual size of the largest file "SRC_SIZE 44921". Again, its not crucial or critical, and comes as much from the initial problems found when trying to extract the source, as it does from a reminder point of view. It turned out to be more accurate to step back SRC_SIZE bytes from the end of the PRG file on the file system, than it was to step forward PRG_SIZE bytes from the begining of the PRG file (which was very inacurate).
The identifier "/* one-file (1f) start" defines the start of your acutual code, parts which are different, not including headers. Its underlying function though, is simply to mark the end of the one-file (1f) '#define's and 'const'ants, in such a way as its visually instructive, and can be easiy processed by any one-file (1f) tools or utilities. See blocks for more detailed information.
The Code
========
from: sdlSlide-1f.cpp
<< snip: one-file header blocks >>
/* one-file (1f) functions */
<< snip: your functions >>
/* one-file (1f) specific */
void version_1f()
{
printf("sdlSlide (one-file) v%s\n", VERSION);
}
void output_1f(char *file_1f)
{
FILE *source_1f;
char out_1f[1];
if (offset_1f == NO_SIZE || sizeOf_1f == NO_SIZE)
{
version_1f();
printf("error: no source file or zip\n");
exit(32);
}else{
source_1f = fopen(file_1f, "rb");
if (source_1f == NULL)
{
version_1f();
printf("error: cant open '%s'\n", file_1f);
exit(32);
}
// fseek(source_1f, offset_1f + 223, SEEK_SET); // off by ?
fseek(source_1f, -sizeOf_1f, SEEK_END);
while(true)
{
if (!fread(out_1f, 1, 1, source_1f))
{
fclose(source_1f);
break;
}else
putchar((int) out_1f[0]);
}
}
}
/* one-file (1f) main */
int main(int argc, char *argv[])
{
/* place used variables here */
int j, argDone, section;
/* this is the begining of commandline argument processing */
if ( (argc > 1) && ( (strcmp("--version", argv[1]) == 0) || (strcmp("-v", argv[1]) == 0) ) )
{
version_1f();
exit(0);
}
/* every program should have one of these */
if ( (argc == 1) || ( (argc > 1) && (strcmp("--help", argv[1]) == 0) ) )
{
version_1f();
printf("Copyright 2016 MiNTed Games\n\n");
printf("View graphics files, using SDL v1.2.\n\n");
printf("usage: sdlSlide-1f [_option_] []\n");
if (argc > 1)
{
printf("_option_:\n");
printf("\t--1f one-file (1f) source information\n");
printf("\t--background instead of black screen\n");
printf("\t--slideshow Slideshow images list (with options) then exit\n");
printf("\t--delay Delay between slides seconds (number keys, default 4)\n");
printf("\t--repeat Show images list times\n");
printf("\t--center Show image centered (C key)\n");
printf("\t--zoom Set zoom to %% (same as below) (default 100, +/- keys)\n");
printf("\t--pixels Pixels size or skip (-) pixels, (default 1, +/- keys)\n");
printf("\t--fullscreen Set window to fullscreen (F11 key)\n");
printf("\t--fit Scale and Center image to fit page\n");
printf("\t--format Display file information (no shows all formats)\n");
printf("\t--novideo Dont display images (use with verbose)\n");
printf("\t--size Only output size (no image)\n");
printf("\t--help This help information\n");
printf("\t-v|--version Version information\n");
printf("\t-V|--verbose Verbose output\n");
printf("\t--debug Extra verbose output\n");
printf("\nspecial thanks to: www.parallelrealities.co.uk\n");
}
printf("\n");
exit(0);
}
/* every one-file (1f) program should have this */
if ( (argc > 1 ) && ( (strcmp("-1f", argv[1]) == 0) || (strcmp("--1f", argv[1]) == 0) ) )
{
version_1f();
printf("Copyright 2016 MiNTed Games\n");
printf("one-file (1f) source information.\n\n");
if (offset_1f == NO_SIZE || sizeOf_1f == NO_SIZE)
{
printf("no source file or zip\n");
exit(32);
}else{
printf("usage: sdlSlide-1f _option_\n");
printf("_option_:\n");
printf("\t--src|--source output attached one-file (1f) source file\n");
printf("\t--src-size size of appended source (in bytes) (%d)\n", SRC_SIZE);
printf("\t--src-type type of source appended (TXT/ZIP) (%s)\n", SRC_TYPE);
printf("\n");
printf("To save one-file (1f) source to file use one of the following:\n");
printf("\tsdlSlide-1f --src > sdlSlide-1f.cpp\n");
// printf("\tsdlSlide-1f --src > sdlSlide-1f.zip\n");
printf("\tsdlSlide-1f --src > sdlSlide-1f`sdlSlide-1f --src-type`\n");
printf("To verify one-file (1f) source file size:\n");
printf("\tsdlSlide-1f --src-size (match this to the size in a directory listing)\n");
printf("or use:\n");
printf("NAME=sdlSlide; if [ `ls -l $NAME-1f.cpp|cut -d \\ -f 5` = `./$NAME-1f --src-size` ]; then echo Verified; else echo Failed; fi\n");
printf("one-file (1f) options exit with status:\n");
printf("\t31 successful (0x1f)\n");
printf("\t32 an error occured (0x20)\n");
exit(31);
}
}
/* here we handle the one-file (1f) source switches */
if ( (argc > 1) && ( (strcmp("--source", argv[1]) == 0) || (strcmp("--src", argv[1]) == 0) ) )
{
output_1f(argv[0]);
exit(31);
}
if ( (argc > 1) && (strcmp("--src-type", argv[1]) == 0) )
{
printf(SRC_TYPE);
exit(31);
}
if ( (argc > 1) && (strcmp("--src-size", argv[1]) == 0) )
{
printf("%d", SRC_SIZE);
exit(31);
}
/* only now do we initial the SDL interface library */
sdlSlide_Init(); // Must do this first
/* here we handle the programs command line switches */
j = 0;
for (int i = 1; i < argc; i++)
{
argDone = 0;
if ( (strcmp(argv[i], "--format") == 0) || (strcmp(argv[i], "--formats") == 0) )
{
sdlSlide.showFormat = 1;
argDone = 1;
}
if ( (strcmp(argv[i], "--verbose") == 0) || (strcmp(argv[i], "-V") == 0) )
{
sdlSlide.info = 1;
argDone = 1;
}
if ( (strcmp(argv[i], "--novideo") == 0) || (strcmp(argv[i], "---no-video") == 0) )
{
sdlSlide.useVideo = 0;
argDone = 1;
}
if (strcmp(argv[i], "--debug") == 0)
{
sdlSlide.debug = 1;
argDone = 1;
}
if (strcmp(argv[i], "--size") == 0)
{
sdlSlide.showSize = 1;
argDone = 1;
}
if (strcmp(argv[i], "--center") == 0)
{
sdlSlide.center = 1;
argDone = 1;
}
if (strcmp(argv[i], "--fullscreen") == 0)
{
sdlSlide.fullscreen = 1;
argDone = 1;
}
if (strcmp(argv[i], "--fit") == 0)
{
sdlSlide.fitPage = 1;
argDone = 1;
}
if (strcmp(argv[i], "--slideshow") == 0)
{
sdlSlide.slideshow = 1;
argDone = 1;
}
if (strcmp(argv[i], "--zoom") == 0)
{
i++;
if (i == argc)
{ printf("error: --zoom needs a number\n"); exit(1); }
sdlSlide.zoom = atoi(argv[i]);
if (sdlSlide.zoom == 0)
sdlSlide.zoom = 100;
if (sdlSlide.zoom != 100)
sdlSlide.useZoom = 1;
argDone = 1;
}
if (strcmp(argv[i], "--pixels") == 0)
{
i++;
if (i == argc)
{ printf("error: --pixels needs a number\n"); exit(1); }
sdlSlide.scale = atoi(argv[i]);
if (sdlSlide.scale == 0)
sdlSlide.scale = 1;
if (sdlSlide.scale != 1)
sdlSlide.useScale = 1;
if (sdlSlide.scale < 0)
sdlSlide.oneIn = 1;
argDone = 1;
}
if (strcmp(argv[i], "--fps") == 0)
{
i++;
if (i == argc)
{ printf("error: --fps needs a number\n"); exit(1); }
sdlSlide.fps = atoi(argv[i]);
argDone = 1;
}
if (strcmp(argv[i], "--delay") == 0)
{
i++;
if (i == argc)
{ printf("error: --delay needs a number\n"); exit(1); }
sdlSlide.delay = atoi(argv[i]);
argDone = 1;
}
if (strcmp(argv[i], "--repeat") == 0)
{
i++;
if (i == argc)
{ printf("error: --repeat needs a number\n"); exit(1); }
sdlSlide.repeat = atoi(argv[i]);
argDone = 1;
}
if (strcmp(argv[i], "--background") == 0)
{
i++;
if (i == argc)
{ printf("error: --repeat needs a filename\n"); exit(1); }
strcpy(sdlSlide.background, argv[i]);
sdlSlide.useBackground = 1;
argDone = 1;
}
if (argDone == 0)
{
strcpy(sdlSlide.playList[j], argv[i]);
j++;
}
}
sdlSlide.playlist = j;
/* here we branch (and exit) showing supported formats */
if (sdlSlide.showFormat && sdlSlide.playlist == 0)
{
version_1f();
printf("[15] image formats:");
if(sdlSlide.info)
{
printf("\n");
printf("\t.ICO Microsoft Icon format\n");
printf("\t.CUR Microsoft Cursor format\n");
printf("\t.BMP Microsoft Bit Map image\n");
printf("\t.GIF Graphics Interchange Format\n");
printf("\t.JPG JPEG encoded graphic image (lossy)\n");
printf("\t.JPEG JPEG encoded graphic image (lossy)\n");
printf("\t.ILBM InterLeaved BitMap image (IFF containers)\n");
printf("\t.LBM InterLeaved BitMap image (IFF containers)\n");
printf("\t.PCX PC Paintbrush eXtended graphic\n");
printf("\t.PNG Portable Network Graphic\n");
printf("\t.PNM Portable Network M\n");
printf("\t.TIF 32bit Image File Format\n");
printf("\t.TIFF 32bit Image File Format\n");
printf("\t.XCF GIMP image\n");
printf("\t.XBM X Windows mono Bit Map image (ASCII)\n");
printf("\t.XPM X Windows color Pixel Map image (ASCII)\n");
printf("\t.XV X Windows\n");
printf("\t.WEBP Cell/Mobile phone Web graphic\n");
}else{
printf(" ICO CUR BMP GIF JPG JPEG ILBM LBM PCX PNG PNM TIF TIFF XCF XBM XPM XV WEBP\n");
}
exit(0);
/* there should be a way to itterate supported formats */
}
/* this allows the SDL sub-systems to free memory properly */
atexit(cleanUp);
/* only now do we start the SDL sub-systems (SND/GFX/NET) */
initSystem(); // Opens video mode and sound
initVars();
/* .. and process the command line settings affecting SDL */
if (sdlSlide.showSize)
{
if (!sdlSlide.playlist)
{ printf("error: --size needs at least one file\n"); exit(1); }
getImageFile();
imageSize();
exit(0);
}
if (sdlSlide.useBackground)
{
loadBackground(sdlSlide.background);
}
/* .. before hitting the "main loop" (mini virtual state machine) */
section = 0;
while (true)
{
// non-blocking (shows high CPU usage)
// should be event driven, but this is faster
//printf("%d ",section);
switch(section)
{
case 0:
section = getImageFile();
break;
case 1:
section = checkKeys();
break;
case 2:
section = slideShow();
break;
case 3:
section = slideDelay();
break;
case 8:
section = showRepeat();
break;
case 9:
sdlSlide.next++;
section = 0;
break;
}
if (section == 10)
exit(0);
}
/* this is the end, .. my friend, the end */
return(0);
}
end: sdlSlide-1f.cpp
The future is so bright, I gotta wear 'shades-1f' ...
|
©2016 - Paul Wratt - one-file (1f)
|