Using cling for scripting

I am experimenting with using cling as script interpreter, eg:

#!/usr/bin/cling

#include <iostream>
std::cout << "Hello world" << std::endl;

This works well, but I was wondering if there is a way to access args from within the script.

Is that possible?

One way to do it would be through macros, eg:

runme.cpp:

#!/usr/bin/cling

#include <iostream>
std::cout << "The answer is " << x << std::endl;

And then:

user@laptop:~$ ./runme.cpp -Dx=42
The answer is 42

I suppose there is no way of passing args directly, as in:

user@laptop:~$ ./runme.cpp 42

I ended up writing a small wrapper called cliche to allow bash-like passing of args to a C++ script:

cliche

#!/bin/bash

escaped() {
    local p="$1"
    p=${p//$'\\'/\\\\} p=${p//$'\"'/\\\"}
    p=${p//$'\a'/\\a} p=${p//$'\b'/\\b} p=${p//$'\f'/\\f}
    p=${p//$'\n'/\\n} p=${p//$'\r'/\\r} p=${p//$'\t'/\\t} p=${p//$'\v'/\\v}
    echo "\"$p\""
}

size=$#
if ((size > 0)); then
    script="$1"
    shift
    
    args=$(escaped "$script")
    for arg in "$@"; do args+=", $(escaped "$arg")"; done
else
    script= args=
fi  

exec cling -std=c++17 -D"getargs()=std::array<const char*, $size>{ $args }" "$script"

Place cliche into /usr/bin and then you can do this in your C++ script:

runme.cpp

#!/usr/bin/cliche

#include <array>
#include <iostream>

auto args = getargs();
for(auto n = 0; n < args.size(); ++n) {
    std::cout << "args[" << n << "] = " << args[n] << std::endl;
}

And pass any args to your script just like a bash script:

user@laptop:~$ ./runme.cpp foo bar baz
args[0] = ./runme.cpp
args[1] = foo
args[2] = bar
args[3] = baz

Share and enjoy.

D-mo

1 Like

As I’ve mentioned in my other post, I am now hosting Debian packages for Cling for Ubuntu 22.04 in my PPA: ppa-verse/xeus-cling.

The package also includes the cliche wrapper with a small man page for it.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.