LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Blogs > rainbowsally
User Name
Password

Notices


Rate this Entry

Run C/C++ Code As Script

Posted 09-04-2013 at 11:36 AM by rainbowsally
Updated 08-06-2014 at 07:13 AM by rainbowsally (new version)

runc update Sept 27, 2013

http://rainbowsally.org/rainbowsally...-rs-1.2.tar.gz

Changes slist_count() to standard objlist syntax and removes slist_getCount()
Removes destructor functions from objlist so that each class explicitly free anything memory they allocate.
Added atexit() function to tmpmem/tmpstr functions.
Most of these changes address memory leaks and/or memory that remains accessible after the apps close.

--------------
We now return to our regularly scheduled program...ing. ;-)
-----------------------

Run C/C++ Code As Script

Today's Features
  • Run C/C++ code as shell scripts.

I hadn't seen another version of "RunC (runc1 and runc2)" on the net when I wrote this. It's a great idea, and here's why.

Some of us remember the days of Basic interpreters, and then Basic compilers -- hot stuff. And Basic was something of a standard programming language and could handle just about any house cleaning or other task you had in mind plus had some (at the time it seemed) nifty graphics capability.

In *Nix environments there are so many different languages that you don't know what to choose for a standard. As a result, 'bash' is most often used and let's face it, trying to follow or debug bash shell code is a sure recipe for brain damage.

So let's back up an inch.

This isn't to say there's no place for bash or any of the other interpreters, BUT...

Why use bash? Why use ANY interpreter? Well, the reason is simple. We need to talk to the operating system.

But is the operating system written in an interpreted language? Well, no, it's written in C/C++ and assembler (or even hex code).

So really the common denominator is hex bytes that the cpu can understand, but writing hex is extremely prone to errors, even in short snips of code and let's face it, C/C++ is a fantastically efficient super-macro-assembler with tons of cool features that can be utilized at compile time (rather than at run time) so that code is small, fast as hell, and pretty close to fool-proof.

So why not use C/C++ as the interpreted language?

Several attempts to do this have had mixed results. I didn't do it. Others did. But there are so many variables involved that creating a realiable C/C++ interpreter gets very messy and seems darned near impossible.

And once you have a C/C++ interpreter, of course, you're going to want to make a byte-code compiler.

A compiler? Uh... Wait a sec. A compiler for C/C++ code? Isn't that sorta deja vu?

Since we are talking about compiling C/C++ why not let's just cut out the middle man and compile C/C++ as though it were a shell script and run it (if it compiles) and maybe learn a bit of C/C++ in the process?

So C/C++ newbees, we are once again at the bottom of the development ladder and welcome aboard for some fun with Computer Mad Science[tm]!

Note: The main difference between this runc and others is that we WANT a bash-like ability to use built-in functions to easily
  1. read pipes and
  2. read and write files

And we want to create new strings automatically with formatting ala printf().

For these functions we borrow the old slist and tmpstr code from an ancient mc2 version.

Lo! Once we create an slist using
Code:
char** a = slist_new()
we have some bash equivalents that come in very handy. Here's some examples.

Code:
bash: a="$(<filename)"
runc: slist_fileRead(&a, filename);

bash: echo "$a" > filename
runc: slist_fileWrite(&a, filename);

bash: a=$(ls *.txt)
runc: slist_pipeRead(&a, "ls *.txt");
The obvious advantages of the runc code is that spaces between words will NOT be interpreted as individual args. Lines of text are preserved as lines of text, probably as you intended.

And then what if we want to quickly create a temporary string without having to allocate the string and sprintf() into it.

Code:
runc: char * a = tmpstr(enoughBytes, "test # %d", n++);
or using system() with C vars?

Code:
runc: system(tmpstr(enoughBytes, "%s %s", funcname, params));
Think about that. And if you need to make sure a string survives a thousand new temps Copy it with strdup(). The temps get recycled every thousand new strings.

Let's take a peek at some test code that when made executable (chmod +x fileName) will run as though they are shell scripts.


file: test1
purpose: example (executable)
Code:
#!/usr/local/bin/runc

#include <stdio.h>

int main(int argc, char** argv)
{
  printf("%d arg(s)\n", argc);
  for(int i = 1; i < argc; i++)
    printf("%s\n", argv[i]);  
  return 0;
}
Run this with the command line
Code:
./test1 "this is a test" 1 2 3

file: test2
purpose: example (executable)
Code:
#!/usr/local/bin/runc

#include <stdio.h>
#include <runc.h>

int main(int argc, char** argv)
{
  char** list = slist_new();
  slist_pipeRead(&list, "ls");
  printf("testing slist_pipeRead() function with command = 'ls'\n");
  for(int i = 0; i < slist_count(&list); i++)
    printf("% 3d: %s\n", i+1, slist_get(&list, i));
  return 0;
}
Run this with the command line
Code:
./test2
Let's assume the reader is a C/C++ beginner and skip the code for the application and just download the thing since the code above should be enough of a teaser in itself. ;-)

http://rainbowsally.org/rainbowsally...c-rs-01.tar.gz

There are two ways to install/uninstall this. One is from the makefile.

Code:
make
sudo make install
The other is to use a deb package, which is preferred because then you don't need to hang onto the Makefile. (Check out alien, if you need an RPM.)

If you use Mint you should be able to simply cd into the build-deb folder and CLICK on the numbered exec(utable) files to make, create the deb package, and cleanup duplicate files.

[The makefile was created with 'mc2 --fetch cpp-32'. You can get mc2 at this blog, but the templates may need to be modified for the debian library paths. The deb templates will be forthcoming shortly.]

This version is experimental/unofficial. I'm not sure I'll even use it myself, but who knows. If it ends up being useful enough it might take off like mc2 did. :-)

For more examples of using slist, tmpstr, and system calls, check out the main source file in the src subdir.

[If you d/loaded the kdevelop3 package at this blog, click on IDE.exec and see what happens. :-) ]

Compare the functionality to that bogus HOG in kde 4 (and the HOG writes 50 megs of bs for a "hello world" app in a hidden folder in your user's home folder.) Try the graphical regex editor. Nice? :-)

Newer is obviously not always better.

The Computer Mad Science Team.

:-)
Posted in Uncategorized
Views 1357 Comments 0
« Prev     Main     Next »
Total Comments 0

Comments

 

  



All times are GMT -5. The time now is 02:01 AM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration