print() without newline

7 views
Skip to first unread message

Christoph Dorn

unread,
Sep 21, 2011, 12:25:16 PM9/21/11
to gp...@googlegroups.com
How do I print() without appending a newline?

Christoph

Jeff Johnson

unread,
Sep 21, 2011, 1:01:10 PM9/21/11
to gp...@googlegroups.com

On Sep 21, 2011, at 12:25 PM, Christoph Dorn wrote:

> How do I print() without appending a newline?
>

You don't.

Here is the C, \n is always appended after last arg:

gpsee_printf(cx, "%s%s%s", i ? " " : "", JS_GetStringBytes(str), i+1==argc?"\n":"");

73 de Jeff

Christoph Dorn

unread,
Sep 21, 2011, 1:17:35 PM9/21/11
to gp...@googlegroups.com
How do I write to stdout then?

Christoph

Wes Garland

unread,
Sep 21, 2011, 2:12:43 PM9/21/11
to gp...@googlegroups.com
On 21 September 2011 13:17, Christoph Dorn <chri...@christophdorn.com> wrote:
How do I write to stdout then?

require('system').stdout.write('hello, world');

Wes

--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102

Jeff Johnson

unread,
Sep 21, 2011, 2:14:45 PM9/21/11
to gp...@googlegroups.com
You can always buffer your own string until next \n somehow.

Yoo likely can snatch /dev/stdout (or /proc/self/stdout) and didle
up a deviant I/O mechanism without too much pain.

print(…) as a global method is overrated (but way convenient and MUSTHAVE)

73 de Jeff

Christoph Dorn

unread,
Sep 21, 2011, 2:53:13 PM9/21/11
to gp...@googlegroups.com
Wes Garland
21 September, 2011 11:12 AM

How do I write to stdout then?

require('system').stdout.write('hello, world');
Getting an error now:

  git clone git://github.com/pinf/loader-js.git
  cd loader-js
  git checkout dev

  gsr -f ./pinf-loader.js -- -v ./demos/HelloWorld


$ gsr -f ./pinf-loader.js -- -v ./demos/HelloWorld
----------------------------------------------------------------------------
|  PINF Loader v0.0.2  ~  https://github.com/pinf/loader-js/
----------------------------------------------------------------------------
Loaded adapter: gpsee
No descriptor URI argument. Assuming: '[./]program.json'
Loading program descriptor from: /pinf/workspaces/github.com/pinf/loader-js/demos/HelloWorld/program.json
Using program cache directory: /pinf/pinf_packages
Using source overlay files:
  /pinf/etc/pinf/sources.json
Assembling program:
  Program URI: /pinf/workspaces/github.com/pinf/loader-js/demos/HelloWorld/program.json
gsr(56716,0x106c9a000) malloc: *** error for object 0x7fc6b2451480: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

Christoph

Wes Garland

unread,
Sep 21, 2011, 3:06:20 PM9/21/11
to gp...@googlegroups.com
MA MIA

Are you able to produce a reduced test case?

Wes
compose-unknown-contact.jpg

Christoph Dorn

unread,
Sep 21, 2011, 3:31:14 PM9/21/11
to gp...@googlegroups.com
Wes Garland
21 September, 2011 12:06 PM

MA MIA

Are you able to produce a reduced test case?
Hmm. Not sure about that one specifically yet, but here is a script that generates a segfault 11, 80% of the time:

var SYSTEM = require("system");
for (var i = 0 ; i< 100 ; i++)
    SYSTEM.stdout.write("Hello World: " + i + "\n");

Christoph




Christoph Dorn
21 September, 2011 11:53 AM

Christoph Dorn

unread,
Sep 21, 2011, 4:05:31 PM9/21/11
to gp...@googlegroups.com
Wes Garland
21 September, 2011 12:06 PM

MA MIA

Are you able to produce a reduced test case?
Ok, am a bit further.

The following breaks 100% of the time at some point before the end of the script:

            var fd = FS_BASE.openRaw("/dev/stdout", {write: true});
            fd.write(msg);
            fd.close();

            var fd = FS_BASE.openRaw("/dev/stdout", {write: true});
            fd.write(""+msg);
            fd.close();
 

            require("system").stdout.write(msg);           
 
           require("system").stdout.write(""+msg);      

gsr(56805,0x10ce10000) malloc: *** error for object 0x7fefa0525630: pointer being freed was not allocated

*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
    

The following seems to work except for the segfault at the end about 60 to 80% of the time:

            var fd = FS_BASE.openRaw("/dev/stdout", {write: true});
            fd.write(":"+msg);
            fd.close();
 

 
           require("system").stdout.write(":"+msg);      
 

Notice the ":" before `msg`.

Christoph

Wes Garland

unread,
Sep 21, 2011, 4:11:00 PM9/21/11
to gp...@googlegroups.com
Thanks for the bug report.

Based on your troubleshooting, I have a couple of ideas where this is hiding, will try to look at it relatively soon. Hopefully this reproduces easily for me. :)

Wes
compose-unknown-contact.jpg

Christoph Dorn

unread,
Sep 21, 2011, 4:43:41 PM9/21/11
to gp...@googlegroups.com
Wes Garland wrote:
Thanks for the bug report.

Based on your troubleshooting, I have a couple of ideas where this is hiding, will try to look at it relatively soon. Hopefully this reproduces easily for me. :)
If you need to you can test with the loader to verify:


    git clone git://github.com/pinf/loader-js.git
    cd loader-js
    git checkout dev

    gsr -f ./pinf-loader.js -- -v ./demos/HelloWorld


The lines in question: https://github.com/pinf/loader-js/blob/dev/lib/pinf-loader-js/adapter/gpsee.js#L58-65

A successful run currently looks like:



Christoph

Wes Garland

unread,
Sep 22, 2011, 7:45:09 AM9/22/11
to gp...@googlegroups.com
Hi, Christoph;

I've made some progress on this bug but haven't got a resolution yet.  Is there any chance you use the BinaryString constructor from binary/b without the 'new' operator ?

Wes
image.png

Christoph Dorn

unread,
Sep 22, 2011, 11:12:53 AM9/22/11
to gp...@googlegroups.com
Wes Garland wrote:
> Hi, Christoph;
>
> I've made some progress on this bug but haven't got a resolution yet.
> Is there any chance you use the BinaryString constructor from binary/b
> without the 'new' operator ?
No chance. My only interface with GPSEE is through the adapter. Unless
GPSEE's "fs-base" or "system" modules do that.

Christoph

Donny Viszneki

unread,
Sep 22, 2011, 11:55:51 AM9/22/11
to gp...@googlegroups.com
On Wed, Sep 21, 2011 at 2:14 PM, Jeff Johnson <n3...@mac.com> wrote:
overrated
 
MUSTHAVE


:P :P :P 

Jeff Johnson

unread,
Sep 22, 2011, 12:14:13 PM9/22/11
to gp...@googlegroups.com
Perhaps I should explain the RPM embedding pain.

RPM embeds perl/python/tcl/ruby/ficl/squirrel interpreters,
and also has embedded sqlite/augeaus/... and several
other tools.

To make it easier to use (what I'm calling embedding is largely
just "diverts" as in system(3) used for templating), whatever
is spewed onto stdout is captured in a buffer, and inserted into
a template.

That is KISS design imho (or at least KISS and WYSIWYG "support"
easily expressed, my utlterior motive for choosing)

BUt I utterly loathe TCL which is inserting an extra \n somehow,
and JavaSCRIPT (and other eveal like langues where everything
returns something that can be coerced and spewed by interpreters)
I have this totally mysterious JS turd that ends up being inserted
into templates.

And the manner by which all these interpreters choose to
map I/O into a buffer is, well, all organically grown SUre
I know you to create a pipe, dup to stout, and slurp the goop,
but then *I* would have to respond to all sorts of bizarre
requests, sigh. SO when in Rome, speak Latin, and do whatevr'
the interpreters are choosing to do instead.

So yes print is "overrated" and MUSTHAVE for KISS design
(as used in RPM and uglix pipes and stdout and …)

hth

73 de Jeff

Wes Garland

unread,
Sep 22, 2011, 1:15:50 PM9/22/11
to gp...@googlegroups.com
On 22 September 2011 12:14, Jeff Johnson <n3...@mac.com> wrote:
So yes print is "overrated" and MUSTHAVE for KISS design
(as used in RPM and uglix pipes and stdout and …)

Have you seen GPSEE's consume-and-yield pipelines?  They're the first attempt at an idiom I am trying to use to replace | pipes.  One key element is that they are implemented with generators, so we don't have get stuck with event-loop-paradigm and don't need to do something stupid like read the entire file in before we can deal with it.

Here is a completely contrived example:

CAY = require("shellalike").cay;

function NOP(pipeline)
{
  for each (let line in pipeline)
    yield line;
}

function killNL(pipeline)
{
  for each (let line in pipeline)
    yield line.substr(0,line.indexOf('\n'));
}

for (let line in CAY
        ("ls -l /etc/")
        ("sed 's/passwd/*** PASSWD ***/'")
        ("egrep -i '^t|ssw'")
        (NOP)
        (NOP)
        (NOP)
        (killNL)
  ){
  print(line);
}

Wes

Jeff Johnson

unread,
Sep 22, 2011, 1:40:18 PM9/22/11
to gp...@googlegroups.com
On Sep 22, 2011, at 1:15 PM, Wes Garland wrote:

On 22 September 2011 12:14, Jeff Johnson <n3...@mac.com> wrote:
So yes print is "overrated" and MUSTHAVE for KISS design
(as used in RPM and uglix pipes and stdout and …)

Have you seen GPSEE's consume-and-yield pipelines?  They're the first attempt at an idiom I am trying to use to replace | pipes.  One key element is that they are implemented with generators, so we don't have get stuck with event-loop-paradigm and don't need to do something stupid like read the entire file in before we can deal with it.


Not looked yet. What is of interest to me is
How to add RPMIO to bindings intelligently?

(aside)
RPMIO is basically "capitalized POSIX wrappers", like stat -> Stat,
where the path argument permits a URI, and various HTML tags
like ContentLength: are mapped into st->st_size etc.

For I/O its Fopen instead of open and its starts to get interesting
when Fts(3) can walk a remote web site easily.

But just like POSIX, these are all synchronous interfaces, and
O_NONBLOCK and aio(3) are too narrow to generalize nicely.

Here is a completely contrived example:

CAY = require("shellalike").cay;

function NOP(pipeline)
{
  for each (let line in pipeline)
    yield line;
}

function killNL(pipeline)
{
  for each (let line in pipeline)
    yield line.substr(0,line.indexOf('\n'));
}

for (let line in CAY
        ("ls -l /etc/")
        ("sed 's/passwd/*** PASSWD ***/'")
        ("egrep -i '^t|ssw'")
        (NOP)
        (NOP)
        (NOP)
        (killNL)
  ){
  print(line);
}


A consume-and-yield is the right conceptual approach, very RESTfull etc etc.

But personally I'd look seriously at node.js and event loops and "Don't need no stinking threads!"
type approaches. node.js is kinda nice.

As a design paradigm, this means that consume-and-yield isn't the right solution:
instead focus on the even dispatcher and registration, the other pieces
will fall into place as needed.

Make sense?

73 de jeff

Donny Viszneki

unread,
Sep 22, 2011, 2:02:44 PM9/22/11
to gp...@googlegroups.com
I agree 100%, just teasing

Wes Garland

unread,
Sep 22, 2011, 3:11:00 PM9/22/11
to gp...@googlegroups.com
On 22 September 2011 13:40, Jeff Johnson <n3...@mac.com> wrote:
Not looked yet. What is of interest to me is
How to add RPMIO to bindings intelligently?

Can you elaborate?  Are you looking for information on how to write JS classes that work with RPMIO rather than POSIX-directly?   (I thought you already had that?)

If so -- the shortest path to solution is actually a GFFI'd module   (note that GFFI is not a pure FFI like js-ctypes: pure FFI is not robust enough for portable code IMHO).  Since you control RPMIO, you can guarantee that GFFI will not suffer ABI-changing-breakage, and since you would be using GFFI, you also get the GFFI memory storage semantics etc.   The overhead of GFFI is a few mallocs per call, so probably not measurable for I/O-related routines.  Then you could port fs-base.js to use RPMIO and all of a sudden you'd have CommonJS I/O on top of RPMIO.

If you're doing anything with C buffers and not using GFFI, I'd suggest looking into ByteThings, they give you equivalent flexibility.

> when Fts(3) can walk a remote web site easily.

Does FTS still want to traverse the entire tree before letting you read a dir? I remember troubleshooting a problem with the FTS I ported from BSDI to Solaris back in '97 or '98; our sun boxes had some directories with 32K files; the FTS calls were taking multiple seconds to return...  I liked the API but finally wound up re-working with readdir() and friends because I needed working code now.


But just like POSIX, these are all synchronous interfaces, and
O_NONBLOCK and aio(3) are too narrow to generalize nicely.

You know, I have ideas for O_NONBLOCK -- basically, select -- and would love at some point to jam AIO interfaces into an event-loop setup.


> But personally I'd look seriously at node.js and event loops

Yup. Have looked at Node in depth.  There's lots of lessons it can teach us.  GSR -- or something like it -- will get an event loop some day.   But probably no before I ship GPSEE in an Apache module; that's higher on my list.  (FWIW, you may be interested in Googling v8monkey and spidernode).


As a design paradigm, this means that consume-and-yield isn't the right solution:
instead focus on the even dispatcher and registration, the other pieces
will fall into place as needed.

CAY lets me port shell scripts to JS without altering the "shape" of the program, just the syntax.  So they do they were built for.  They fall flat on their face when you want to do something like watch stderr AND stdout.  Always good to have a variety of tools in the toolbox, though. :)

Wes

Jeff Johnson

unread,
Sep 22, 2011, 2:43:39 PM9/22/11
to gp...@googlegroups.com

On Sep 22, 2011, at 2:02 PM, Donny Viszneki wrote:

> I agree 100%, just teasing
>

Understood: just be careful with my fetishes please.

Just in case: I have a very dry sense of humor, don't take anything I say personally.

73 de Jeff

Reply all
Reply to author
Forward
0 new messages