tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] RFC: TCC Shell Programming


From: ZHAO Wei
Subject: [Tinycc-devel] RFC: TCC Shell Programming
Date: 20 Jun 2003 11:08:31 +0800

Hello, this is a Request For Comments about a procedure to further
enable TCC to do Shell Programming. I came upon this idea when preparing
my second article in a series for IBM developerWorks/China to introduce
TCC. The article is in Chinese, so I rewrite the main idea here in
English.

The key to shell programming is the pipe. Concering pipe usage, there
are two things. One is to let TCC the compiler itself to cooperate with
other tools using pipes. Two is to let programs written for TCC to
cooperate using pipes.

TCC the compiler itself can use pipes with help from /dev/stdin. Though
it's not perfect, but enough for us now. Thanks to previous Tinycc-devel
postings to let me know this. :)

Point two above is almost moot. Because any C program can use stdin and
stdout to cooperate with others utilizing pipes.

The disadvantage of the above method is that one has to launch a lot of
processes which is not cool. :) With TCC we can have another method.

Let's see the following example for a simple tac implementation:

--------8<--[tac.c]------
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

struct record {
        struct record *prev;
        char *line;
};

void tac(FILE *in, FILE *out)
{
        struct record *this;
        struct record *last;
        size_t len = 0;

        last = NULL;
        this = (struct record *) malloc(sizeof(struct record));
        this->line = NULL;
        while ((getline(&(this->line), &len, in)) != -1) {
                this->prev = last;
                last = this;
                this = (struct record *) malloc(sizeof(struct record));
                this->line = NULL;
        }
        if (this->line)
                free(this->line);
        free(this);
        while (last) {
                this = last;
                last = this->prev;
                fprintf(out, "%s", this->line);
                if (this->line)
                        free(this->line);
                free(this);
        }
}

#ifdef STANDALONE
int main(int argc, char **argv)
{
/*      FILE *pipe; */

/*      pipe = tmpfile(); */
/*      tac(stdin, pipe); */
/*      fseek(pipe, 0, SEEK_SET); */
/*      tac(pipe, stdout); */
/*      fclose(pipe); */
        tac(stdin, stdout);
        return 0;
}
#endif /* STANDALONE */
-------->8--[tac.c]------

We can run tcc -DSTANDALONE -run tac.c to get a a standalone version for
tac. And if we want to utilizing tac() in a pipe series, we can just
call this function like we did above in the commented code, which is a
tac | tac. And the pipe combo utilizes only one process.

Do you like the idea? If there're enough interests, I can start building
a set of functions in the above manner. :) I only wrote few very simple
ones like the above for my article.

Please comment. Thanks a lot!

-- 
ZHAO Wei
address@hidden address@hidden
http://www.advogato.org/person/zhaoway/
Linux & Free Software Consultant, Nanjing, China





reply via email to

[Prev in Thread] Current Thread [Next in Thread]