Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

executable postscript programs?

101 views
Skip to first unread message

luser- -droog

unread,
Dec 6, 2010, 10:47:06 PM12/6/10
to
Is there a way to trick bash into accepting % instead of #
on the bang line?
I'd like to put
%!/usr/bin/gs
at the front of my postscript program to run the script as a command.

If you could only put a full command there, I think
#!/bin/sed 1d|/usr/bin/gs
could work.

Do I have to make a helper script to prune the first line
and then pipe to gs?

luserXtrog

unread,
Dec 13, 2010, 3:54:55 AM12/13/10
to
On Dec 6, 9:47 pm, luser- -droog <mijo...@yahoo.com> wrote:
> Is there a way to trick bash into accepting % instead of #
> on the bang line?
> I'd like to put
> %!/usr/bin/gs
> at the front of my postscript program to run the script as a command.

This is so cool, i've got to share it with anyone who didn't follow
into the other group.

With this program compiled in my home directory as gscmd:

#include <unistd.h>
int main(int i, char **v) {
execl("/usr/bin/gs", "gs",
"-dQUIET",
"-c", "(#!)cvn{currentfile =string readline pop pop}bind def",
"--", v[1], NULL);
}

I can edit this document in vi:

#!/home/olpc/gscmd
/Palatino-Roman 20 selectfont
/lead 24 def
/scratch 5 string def
/space ( ) def
/dash ( ) dup 1 8#320 put def
/stringtype { show //dash show } def
/integertype { //scratch cvs show //space show } dup 3 1 roll def
/nametype exch def
36 720 moveto
{
{()(Shelf Lives)}

{(Iced Coffee (refridgerated))8/hours (, (room temp)) 4/hours}
{(Iced Tea)12/hours}

{(Chai)24/hours}
{(Mocha)24/hours}

{(Open Coffee Beans)7/days}

{(Caramel)14/days}
{(White Mocha)14/days}

{(Bottled Syrups)30/days}

} cvlit {
gsave
{ dup type exec } forall
grestore
0 lead neg rmoveto
} forall
showpage

And I can preview it with the ex: command !%
!% !!

So I think this trick should be called
"Throwing it for a loop."

--
Is it really 3 in the morning?

luserXtrog

unread,
Dec 13, 2010, 4:09:16 AM12/13/10
to
On Dec 13, 2:54 am, luserXtrog <mijo...@yahoo.com> wrote:
>
> #include <unistd.h>
> int main(int i, char **v) {
>     execl("/usr/bin/gs", "gs",
>         "-dQUIET",
>         "-c", "(#!)cvn{currentfile =string readline pop pop}bind def",
>         "--", v[1], NULL);
>
> }
>
> #!/home/olpc/gscmd
> /Palatino-Roman 20 selectfont
> /lead 24 def
> /scratch 5 string def
> /space ( ) def

Anybody know how best to pass arguments with this method?
I mean besides fixing the C program to actually pass
all its arguments. How do you pass arguments from the
gs command line into the postscript program?

At first guess, you could put them in an array as part
of the -c string. But I feel there's got to be a nicer
way. Perhaps something someone's already done that I
could shamelessly exploit. Bwaahahaha!

--
You're supposed to be a lap cat. Act like one!

Helge Blischke

unread,
Dec 13, 2010, 5:07:09 AM12/13/10
to
luserXtrog wrote:

Every argument passed to gs by a -s or -d switch gets defined in systemdict
during initialization. Example:

gs -NODISPLAY -sME="I'm a nerd"
GS>/ME where{/ME get == flush}if
(I'm a nerd)
GS>

Helge


luserXtrog

unread,
Dec 15, 2010, 12:22:06 AM12/15/10
to

That's a start, I think.
With the following, I can pass an option on the shebang:

#include <unistd.h>
int main(int i, char **v) {
execl("/usr/bin/gs", "gs",
"-dQUIET",
"-c", "(#!)cvn{currentfile =string readline pop pop}bind def",

//"--",
v[1], v[2], v[3], v[4], v[5], NULL);
}
...
#!/home/olpc/gscmd -dsmall
/fsld
[ 20 24 ]
/small where { pop pop [ 10 11 ] } if
def
/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def

But this won't work as a command, because they end up in the wrong
order on the line: gs processes the file before it even sees
the -d option. And I don't like having to lose the "--". That
seemed to keep gs from opening %stdin with executive. And my
one-page document would disappear with just [enter].

Thinking through my goal a little further, I'd like to
put all the options in an array, perhaps called $ or $$.
And I'd like to provide a shift procedure like a real shell.

I guess it all boils down to string-mangling in C. All of this
should fit into the -c argument, I think.

--
lxt

luserXtrog

unread,
Dec 15, 2010, 12:56:14 AM12/15/10
to
On Dec 14, 11:22 pm, luserXtrog <mijo...@yahoo.com> wrote:

> Thinking through my goal a little further, I'd like to
> put all the options in an array, perhaps called $ or $$.
> And I'd like to provide a shift procedure like a real shell.
>
> I guess it all boils down to string-mangling in C. All of this
> should fit into the -c argument, I think.

Now that I look at it. I'm not sure I like it.
Maybe a dictionary really /is/ best.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int arc, char **arv) {
char c[500] = "";
char d[550];
char s[2] = "/";
int i;
for (i = 2; i < arc; i++) {
strcat(c, s);
strcat(c, arv[i]);
}
sprintf(d, "(#!)cvn{currentfile =string readline pop pop}bind def /
$$ { %s } cvlit def", c);


execl("/usr/bin/gs", "gs",
"-dQUIET",
"-c",

d,
"--",
arv[1], NULL);
}

...

#!/home/olpc/gscmd
/fsld
[ 20 24 ]
%/small where { pop pop [ 10 11 ] } if
false $$ {
/small eq { pop true exit } if
} forall {


pop
[ 10 11 ]
} if
def

/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def


That 'false ... forall' baloney is a lot uglier
than 'where'.

--
back to the sandbox...

luserXtrog

unread,
Dec 15, 2010, 3:35:34 AM12/15/10
to
On Dec 14, 11:56 pm, luserXtrog <mijo...@yahoo.com> wrote:
> On Dec 14, 11:22 pm, luserXtrog <mijo...@yahoo.com> wrote:
>
> > Thinking through my goal a little further, I'd like to
> > put all the options in an array, perhaps called $ or $$.
> > And I'd like to provide a shift procedure like a real shell.
>
> > I guess it all boils down to string-mangling in C. All of this
> > should fit into the -c argument, I think.
>

Here's how it looks with the shift proc.
A big problem with this way is it blocks
all options from being passed to gs.
Perhaps I could grab all the /^-/ arguments
in a vector, use the first /^[^^]/ argument
as the filename and pack the rest in another vector,
collate them with the default arguments,
and use execv. That sounds like a lot more work.

Anyway, the shift just makes it uglier!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int arc, char **arv) {
char c[500] = "";
char d[550];

char p[2][2] = { "(", ")" };


char s[2] = "/";
int i;
for (i = 2; i < arc; i++) {

//strcat(c, p[0]);


strcat(c, s);
strcat(c, arv[i]);

//strcat(c, p[1]);


}
sprintf(d,
"(#!)cvn{currentfile =string readline pop pop}bind def"
"/$$ { %s } cvlit def"

"/$shift {"
"$$ length 0 gt {"
"$$ 0 get "
"$$ length 1 ge {"
"/$$ $$ 1 $$ length 1 sub getinterval def"
"} if"
"}{ null } ifelse"


"} def",
c);
execl("/usr/bin/gs", "gs",
"-dQUIET",
"-c",
d,
"--",
arv[1], NULL);

return 0;
}

...

#!/home/olpc/gscmd
/fsld
[ 20 24 ]
%/small where { pop pop [ 10 11 ] } if

%false $$ {
%/small eq { pop true exit } if
%} forall { pop [ 10 11 ] } if
{
$shift
dup /small eq { pop true exit } if
null eq { false exit } if
} loop { pop [ 10 11 ] } if
def

/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def

--
down the rabbithole
or just a wild goosechase?

luserXtrog

unread,
Dec 15, 2010, 5:10:29 PM12/15/10
to
On Dec 15, 2:35 am, luserXtrog <mijo...@yahoo.com> wrote:
...

> Here's how it looks with the shift proc.
> A big problem with this way is it blocks
> all options from being passed to gs.
> Perhaps I could grab all the /^-/ arguments
> in a vector, use the first /^[^^]/ argument

I meant /^[^-]/ here. Got a little carrot crazy. ;)

> as the filename and pack the rest in another vector,
> collate them with the default arguments,
> and use execv. That sounds like a lot more work.

...

tlvp

unread,
Dec 15, 2010, 11:36:00 PM12/15/10
to
On Wed, 15 Dec 2010 17:10:29 -0500, luserXtrog <mij...@yahoo.com> wrote:

>
> I meant /^[^-]/ here. Got a little carrot crazy. ;)
>

Um ... that's *caret* (not carrot (the veggie), nor carat (the jeweler's measurement unit)) :-) .
But no offense taken; after all, what's a li'l typo amongst friends?

Cheers, -- tlvp
--
Avant de repondre, jeter la poubelle, SVP

luserXtrog

unread,
Dec 16, 2010, 2:54:07 AM12/16/10
to
On Dec 15, 10:36 pm, tlvp <tPlOvUpBErLeL...@hotmail.com> wrote:

> On Wed, 15 Dec 2010 17:10:29 -0500, luserXtrog <mijo...@yahoo.com> wrote:
>
> > I meant /^[^-]/ here. Got a little carrot crazy. ;)
>
> Um ... that's *caret* (not carrot (the veggie), nor carat (the jeweler's measurement unit)) :-) .
> But no offense taken; after all, what's a li'l typo amongst friends?
>
> Cheers, -- tlvp

Oh, that was deliberate.
It went along with the "down the rabbithole" signature.

But now that you mention it, the jeweller's measurement
has always bothered me.
1/4-carat diamond, 18-carat gold:
it's got to mean at least 2 different things, right?

--
Route 66 is a really long road.

Robert Bonomi

unread,
Dec 16, 2010, 3:19:18 AM12/16/10
to
In article <fd590218-aadd-4894...@o14g2000yqe.googlegroups.com>,

luserXtrog <mij...@yahoo.com> wrote:
>
>But now that you mention it, the jeweller's measurement
>has always bothered me.
> 1/4-carat diamond, 18-carat gold:
>it's got to mean at least 2 different things, right?


yes.

For gold, only, it is a measure of 'purity', Number of "24ths" by weight,
that is the metallic element with the symbol "Au".

For diamonds, and other things, it is a measure of weight - 205 milligrams.

luserXtrog

unread,
Dec 16, 2010, 3:41:33 AM12/16/10
to
On Dec 16, 2:19 am, bon...@host122.r-bonomi.com (Robert Bonomi) wrote:
> In article <fd590218-aadd-4894-88e6-65ec7c92a...@o14g2000yqe.googlegroups.com>,

>
> luserXtrog  <mijo...@yahoo.com> wrote:
>
> >But now that you mention it, the jeweller's measurement
> >has always bothered me.
> >    1/4-carat diamond, 18-carat gold:
> >it's got to mean at least 2 different things, right?
>
> yes.
>
> For gold, only, it is a measure of 'purity',   Number of "24ths" by weight,
> that is the metallic element with the symbol "Au".
>
> For diamonds, and other things, it is a measure of weight - 205 milligrams.

So my Ibuprophen tablets are 1-caret doses?! Awesome!

tlvp

unread,
Dec 16, 2010, 1:08:46 PM12/16/10
to

Well, to within under 3% and a couple of typos: yes, so it would seem :-) .

luserXtrog

unread,
Dec 16, 2010, 9:16:22 PM12/16/10
to

Why didn't I read the manpage just a little more closely?!!

OPTIONS
-- filename arg1 ...
Takes the next argument as a file name as usual,
but takes all remaining arguments (even if they
have the syntactic form of switches) and defines
the name "ARGUMENTS" in "userdict" (not "system-
dict") as an array of those strings, before run-
ning the file. When Ghostscript finishes exe-
cuting the file, it exits back to the shell.

That's just perfect!

luserXtrog

unread,
Dec 16, 2010, 10:14:01 PM12/16/10
to
On Dec 16, 8:16 pm, luserXtrog <mijo...@yahoo.com> wrote:

> Why didn't I read the manpage just a little more closely?!!
>
> OPTIONS
>        -- filename arg1 ...
>               Takes the next argument as a file name as usual,
>               but takes all remaining arguments (even if  they
>               have the syntactic form of switches) and defines
>               the name "ARGUMENTS" in "userdict" (not "system-
>               dict") as an array of those strings, before run-
>               ning the file.  When Ghostscript  finishes  exe-
>               cuting the file, it exits back to the shell.
>
> That's just perfect!

Now we're getting somewhere.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/*
gscmd [-shebang-opt] ps-script [ ARGUMENTS ]
*/
int main(int argc, char **argv) {
char **v;
unsigned shebang;
int i;
int o;

printf("%d\n", argc);
switch (argc) {
case 0: fprintf(stderr,"no program!\n"); exit(1);
case 1: fprintf(stderr,"no script!\n"); exit(1);
}

v = malloc( (argc+5) *sizeof*v);
if (!v) { fprintf(stderr,"no memory!\n"); exit(2); }

o = 0;
v[o++] = "gs";
//v[o++] = "echo";
v[o++] = "-q";

if (argv[1][0] == '-') {
shebang = 1;
v[o++] = argv[1];
}

v[o++] = "-c";
v[o++] = "(#!)cvn{currentfile =string readline pop pop}bind def";
v[o++] = "--";

if (!shebang) {
v[o++] = argv[1];
}

for (i=2; i<argc; i++) {
v[o++] = argv[i];
}
v[o++] = NULL;
//execvp("gs", v);
execv("/usr/bin/gs", v);
//execv("/bin/echo", v);

/*
gs -q -c '(#!)cvn{currentfile =string readline pop pop}bind def' -
shebang-opt -- ps-script ARGUMENTS
*/

return 0;
}


...

#!/home/olpc/gscmd -dsmall
/fsld
[ 20 24 ]

/small where { pop pop [ 10 11 ] } if

%false ARGUMENTS {
%cvn /small eq { pop true exit } if


%} forall { pop [ 10 11 ] } if

def

/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def


--or--

#!/home/olpc/gscmd
/fsld
[ 20 24 ]
%/small where { pop pop [ 10 11 ] } if

false ARGUMENTS {
cvn /small eq { pop true exit } if


} forall { pop [ 10 11 ] } if

def

/Palatino-Roman fsld 0 get selectfont
/lead fsld 1 get def


The first way passes the option to gs on the shebang line.
The second way lets you mention the options on the command line.
$ shelflife.ps small

But right now it allows at most one option to pass to gs.
So I'm not completely satisfied, yet. You can't tell the document
to convert itself:
$ shelflife.ps -sDEVICE=pdfwrite -sOutputFile=sl.pdf
It shouldn't be too hard, now; but I think I'll have to ponder
a bit more.

--
luser

luserXtrog

unread,
Dec 16, 2010, 10:33:08 PM12/16/10
to
On Dec 16, 9:14 pm, luserXtrog <mijo...@yahoo.com> wrote:

>     unsigned shebang;

Heisenbug!

This should be:
unsigned shebang = 0;

Sorry for any inconvenience.
Oh, also the comment at the end of the c program
doesn't show shebang-opt in the right place.

--
Day late, 2 pennies short.

Robert Bonomi

unread,
Dec 20, 2010, 6:27:44 AM12/20/10
to
In article <a0607773-6e65-46a1...@s4g2000yql.googlegroups.com>,

You could have carats of carotin (from carrots, also spelled carotene) in a
pill marked with a caret symbol.


Robert Bonomi

unread,
Dec 20, 2010, 6:31:58 AM12/20/10
to
In article <35d2a2a3-5047-4b9a...@m11g2000vbs.googlegroups.com>,

luserXtrog <mij...@yahoo.com> wrote:
>On Dec 16, 9:14 pm, luserXtrog <mijo...@yahoo.com> wrote:
>
>>     unsigned shebang;
>
>Heisenbug!
>
>This should be:
> unsigned shebang = 0;
>

One is tempted to shout "sexist!" and note that the "PC" language would be
'itbang'. *snicker.

luserXtrog

unread,
Dec 20, 2010, 9:13:38 PM12/20/10
to
On Dec 20, 5:31 am, bon...@host122.r-bonomi.com (Robert Bonomi) wrote:
> In article <35d2a2a3-5047-4b9a-9b8f-fea4a6135...@m11g2000vbs.googlegroups.com>,

>
> luserXtrog  <mijo...@yahoo.com> wrote:
> >On Dec 16, 9:14 pm, luserXtrog <mijo...@yahoo.com> wrote:
>
> >> unsigned shebang;
>
> >Heisenbug!
>
> >This should be:
> >    unsigned shebang = 0;
>
> One is tempted to shout "sexist!" and note that the "PC" language would be
> 'itbang'.    *snicker.

Yeah, I can see where you're coming from.
But as an unaccented vowel, it's really more of a schwa sound
and could be written with any vowel at all. I chose e because
I saw it that way elsewhere in the thread (originally I just
called it bang), but it could also be:
shabang
shubang
shybang
schaebang
schobangue!

Besides I think the term is from printer lingo for ?! as one
glyph with a common dot. Which is the punctuation sign for
doing a karate chop on the podium at the end of your sentence.

Robert Bonomi

unread,
Dec 21, 2010, 5:07:37 AM12/21/10
to
In article <9ccec25e-3576-4e0b...@d8g2000yqf.googlegroups.com>,

luserXtrog <mij...@yahoo.com> wrote:
>On Dec 20, 5:31 am, bon...@host122.r-bonomi.com (Robert Bonomi) wrote:
>> In article
><35d2a2a3-5047-4b9a-9b8f-fea4a6135...@m11g2000vbs.googlegroups.com>,
>>
>> luserXtrog  <mijo...@yahoo.com> wrote:
>> >On Dec 16, 9:14 pm, luserXtrog <mijo...@yahoo.com> wrote:
>>
>> >> unsigned shebang;
>>
>> >Heisenbug!
>>
>> >This should be:
>> >    unsigned shebang = 0;
>>
>> One is tempted to shout "sexist!" and note that the "PC" language would be
>> 'itbang'.    *snicker.
>
>Yeah, I can see where you're coming from.

I repeat: "*SNICKER*"

To quote Foghorn Leghorn, "it's a Joke, son. J O K E *JOKE*!"

I be poking fun at the "PC language nazis" not the particular term.

I ,_personally_ have been using that term for over 25 years -- for the magic
first two characters of a script file. And longer than that, casually, as a
synonym for 'the whole kit and kaboodle'.

"PC" I am not, most of what i do is on workstations, minicomputers, or
mainframes, with the occasional 'embedded' u-processor. :)

>Besides I think the term is from printer lingo for ?! as one
>glyph with a common dot.

Nope. the proper name for _that_ glyph is the "interrobang" (admixture
of 'interrogative' and 'bang') Invented by Martin K Speckter, in 1962.
First included as standard glyph in a commercial type face, in 1966.

I know the history/origin of the 'shebang' term --
"The name shebang comes from an inexact contraction of SHArp bang or
haSH bang, referring to the two typical Unix names of the two characters."

It, like Mopsy, "just grew". The gang at Murray Hill -- specifically Dennis
Ritchie, he who put the feature into UNIX -- did not have (as Dennis put
it) a 'pet name' for the interpreter directive at the beginning of a script.

0 new messages