Skip to content
/ c99sh Public

A shebang-friendly script for "interpreting" single C99, C11, and C++ files, including rcfile support.

License

Notifications You must be signed in to change notification settings

RhysU/c99sh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

c99sh

A shebang-friendly script for "interpreting" single C99, C11, and C++ files, including rcfile support.

For example, installing this ~/.c99shrc control file

-Wall -g -O2
#include <stdio.h>

permits executing hello containing

#!/usr/bin/env c99sh
int main()
{
    puts("Hello, world!");
}

to produce the output one expects provided c99sh is in the path. You may also run c99sh foo.c to execute some foo.c lacking the shebang line. Try c99sh -v foo.c if you encounter trouble and want to see the compilation command. Check out c99sh -h for all the command line options you might use. In particular, for simple tasks you might find that the command line options in conjunction with HERE documents can accomplish many things. For example,

$ ./c99sh -sm <<HERE
puts("Hello, world!");
HERE

Control files can supply compilation and linking flags, preprocessor directives like #include, and pkg-config directives to simplify library usage. A c99shrc located in the same directory as the interpreted source will be used. Otherwise a ~/.c99shrc is processed if available. See c99shrc.example for an extended control file enabling GSL, GLib, and SQLite capabilities. This permits quickly getting access to higher-level data structures.

A more entertaining example is an OpenMP-enabled Monte Carlo computation of π screaming like a banshee on all your cores (c99shrc, source):

#!/usr/bin/env c99sh

int main(int argc, char *argv[])
{
    long long niter = argc > 1 ? atof(argv[1]) : 100000;
    long long count = 0;

    #pragma omp parallel
    {
        unsigned int seed = omp_get_thread_num();

        #pragma omp for reduction(+: count) schedule(static)
        for (long long i = 0; i < niter; ++i) {
            const double x = rand_r(&seed) / (double) RAND_MAX;
            const double y = rand_r(&seed) / (double) RAND_MAX;
            count += sqrt(x*x + y*y) < 1;
        }

    }

    printf("%lld: %g\n", niter, M_PI - 4*(count / (double) niter));
}

Take that, GIL.

Kidding aside, the speedup in the edit-compile-run loop can be handy during prototyping or analysis. It is nice when useful one-off scripts can be moved directly into C ABI code instead of requiring an additional {Python,Octave,R}-to-C translation and debugging phase. For example, compare the Octave version of some simple logic with the equivalent c99sh-based version requiring only a few one-time additions to your ~/.c99shrc.

As nearly the entire C99-oriented implementation works for C++, by invoking c99sh through either a copy or symlink named cxxsh, you can write C++-based logic. The relevant control files are named like cxxshrc in this case and they support directives like using namespace std and namespace fb == foo::bar. See cxx/hello and cxx/cxxshrc for a hello world C++ example. One nice use case is hacking atop Eigen since it provides pkg-config support. That is, cxxsh -p eigen3 myprogram builds and runs a one-off, Eigen-based program. With the right cxxshrc, such a program can be turned into a script. Though, you will likely notice the compilation overhead much moreso with C++ than C99. That said, for repeated invocation an output binary can be saved with the -x option should repeated recompilation be prohibitively expensive. C11 can be used via a symlink named c11sh with control files like c11shrc.

The idea for c99sh came from 21st Century C's section "Compiling C Programs via Here Document" (available online) by Ben Klemens. Additionally, I wrote it somewhat in reaction to browsing the C++-ish work by elsamuko/cppsh.

About

A shebang-friendly script for "interpreting" single C99, C11, and C++ files, including rcfile support.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •