Skip to content

astrorigin/nanabozo

Repository files navigation

nanabozo

nanabozo is a command-line application that translates CHTML scripts into pure C code. In other terms, it lets you mix HTML (or equivalent) with C/C++, like you would with PHP.

First CGI example

Here is a simple CHTML example:

<?
#define PAGE_TITLE "Hello World Example"

int main(void) {
    char *world = "World";
    /* Headers */
    print("Content-Type: text/html; charset=utf-8\n\n");
?>
<html>
<head>
<title><?= PAGE_TITLE ?></title>
</head>
<body>
<h1><?% "Hello %s!", world ?></h1>
</body>
</html>
<?
    return 0;
} // end main()
?>

Let's put that snippet in a file called helloworld.php (why not), then we execute nanabozo like this:

nanabozo helloworld.php helloworld.c

And now let's examine what helloworld.c looks like:

/*
 *      Generated by nanabozo (do not edit)
 *      Sun Jan 14 11:08:12 CET 2018
 */

That is an informational, self-explanatory comment. You can disable that comment header with the option -c, passing it an empty string (-c ""), or have your own comment instead if you want (-c "$(cat license.txt)"):

#include <stdio.h>
#define print(x) fputs(x, stdout)

By default, stdio.h is included, and the function print defined. As you can see, stdout is the file we are sending our text to, just like another CGI application:

/* BEGIN C (line 1) */
#define PAGE_TITLE "Hello World Example"

int main(void) {
    char *world = "World";
    /* Headers */
    print("Content-Type: text/html; charset=utf-8\n\n");
/* END C (line 8) */

Enclosed by begin/end comments, the first part of our C code is given here, as it was in the first file. You can omit those comments with the option -n if you want, but they are useful for debugging purposes.

Nothing special here, our CGI needs a main() function. Note that the function print is used to send the usual mandatory headers:

print("<html>\n"
"<head>\n"
"<title>");

Our HTML script begins. The function print is used to pass it to stdout:

/* BEGIN C= (line 11) */
print( PAGE_TITLE );
/* END C= (line 11) */

The C code that was in between the tags <?= and ?> is given as argument to the function print.

Another HTML part follows:

print("</title>\n"
"</head>\n"
"<body>\n"
"<h1>");

Then, what was in between the tags <?% and ?> is passed as arguments to the function printf:

/* BEGIN C% (line 14) */
printf( "Hello %s!", world );
/* END C% (line 14) */

Finally, the rest of the HTML and the end of the main() function:

print("</h1>\n"
"</body>\n"
"</html>\n");
/* BEGIN C (line 17) */
    return 0;
} // end main()
/* END C (line 20) */

You can compile helloworld.c and your CGI application is ready. In a hurry, you can try something like:

nanabozo helloworld.php | gcc -x c -o helloworld.cgi -

More options

nanabozo has options to accomodate for different workflows.

The option -m can be used to include a basic, main function definition wrapping around your script.

The option -t can be used to send a basic Content-Type HTTP header (text/html, charset UTF-8) before any other output.

The option -a can be used to pass a string to prepend to the content of the CHTML script.

The option -z can be used to pass a string to append to the content of the CHTML script.

Our simple example could be rewritten without the definition of the main() function. In bash, it could be like this:

nanabozo -a $'int main(void) {\n' -z $'\n\treturn 0;\n}' helloworld.php helloworld.c
# note that is equivalent to:
nanabozo -m helloworld.php helloworld.c

You could however make things even worse:

< helloworld.php nanabozo -a "$(cat myfile.h myfile.c)" > helloworld.c

The option -p can be used to pass an alternative function name to replace the print function.

The option -f can be used to pass an alternative function name to replace the printf function.

And if you replace both print and printf, stdio.h will not be included. A command such as:

nanabozo -p print -f printf helloworld.php helloworld.c

will not have stdio.h included, nor print defined. You have to take care of them on your side.

The option -v prints version information and exits.

The option -h prints usage information and exits.

Limitations and bugs

If your CHTML file has lines longer than 512 characters (the humanly acceptable), you can recompile with INPUTSIZE defined with a higher value.

And if you find a bug or anything problematic, please contact stan(at)astrorigin.com.

Installation

Simply:

make install-all

A package for Debian systems should be found on Github and homepage.

License

nanabozo is licensed under the GPL v2 license:

nanabozo - tool for CHTML script-coding
Copyright (C) 2018-2020 Stanislas Marquis <stan@astrorigin.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

About

nanabozo is a command-line application that translates CHTML scripts into C/C++ code

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published