Closed
Bug 300841
Opened 20 years ago
Closed 19 years ago
Provide a readline function to read a line from stdin
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
RESOLVED
FIXED
People
(Reporter: mrbkap, Assigned: mrbkap)
References
()
Details
Attachments
(1 file, 2 obsolete files)
|
7.04 KB,
patch
|
brendan
:
review+
brendan
:
approval1.8b4+
|
Details | Diff | Splinter Review |
Apparently, the great language shootout requires a readline function. I've
written one which I'll attach.
Note that this function might be slightly unnecessary (The Great Language
Shootout is vague on requirements), since I notice that I can do:
echo "print('hello, world')" | js
and it prints "hello, world".
| Assignee | ||
Comment 1•20 years ago
|
||
Attachment #189360 -
Flags: review?(brendan)
| Assignee | ||
Comment 2•20 years ago
|
||
Comment on attachment 189360 [details] [diff] [review]
readline, v1
>+ size_t readlength = strlen(ret + retlength);
>+ retlength += readlength;
I've replaced these two lines with:
retlength += strlen(ret + retlength);
Updated•20 years ago
|
OS: Linux → All
Hardware: PC → All
| Assignee | ||
Comment 3•20 years ago
|
||
*** Bug 300835 has been marked as a duplicate of this bug. ***
Comment 4•20 years ago
|
||
Comment on attachment 189360 [details] [diff] [review]
readline, v1
> static JSBool
>+ReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
>+{
>+#define BUFSIZE 256
>+ /* function readline() */
>+ FILE *from = stdin;
>+ char *ret = NULL, *tmp;
>+ size_t retsize = BUFSIZE, retlength = 0;
>+ JSString *str;
>+
>+ ret = JS_malloc(cx, retsize);
>+ if (!ret)
>+ return JS_FALSE;
Hiding initialization in a forest of declarations hid the unnecessary ret =
NULL here. I'd just move initializers down to nearest basic block leader that
dominates all uses. But I think like a compiler too much.
The ret naming is not adding value, in my eyes, and it clashes with buf/BUF.
Why not s/ret/buf/g?
>+ while (fgets(ret + retlength, retsize - retlength, from)) {
So fgets sucks (so does gets, fgets just sucks differently, and less). It
doesn't return the line length, as jsscan.c's my_fgets does. How about making
that a JS_FRIEND_API(int) js_fgets(...) export and using it here?
>+ size_t readlength = strlen(ret + retlength);
Then you can save a strlen.
[snip]
> static JSFunctionSpec shell_functions[] = {
> {"version", Version, 0},
> {"options", Options, 0},
> {"load", Load, 1},
>+ {"readline", ReadLine, 0},
> {"print", Print, 0},
> {"help", Help, 0},
> {"quit", Quit, 0},
> {"gc", GC, 0},
> {"trap", Trap, 3},
> {"untrap", Untrap, 2},
> {"line2pc", LineToPC, 0},
> {"pc2line", PCToLine, 0},
> #ifdef DEBUG
> {"dis", Disassemble, 1},
D'oh, you forgot to update the parallel shell_help_messages array!
/be
Attachment #189360 -
Flags: review?(brendan) → review-
| Assignee | ||
Comment 5•20 years ago
|
||
Attachment #189360 -
Attachment is obsolete: true
Attachment #189387 -
Flags: review?(brendan)
Comment 6•20 years ago
|
||
Comment on attachment 189387 [details] [diff] [review]
readline, v2
> static JSBool
>+ReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
>+{
>+#define BUFSIZE 256
>+ /* function readline() */
These comments seem to me more helpful before the entire function. They might
say a bit more, too ;-).
>+ FILE *from;
>+ char *buf, *tmp;
>+ size_t bufsize, buflength;
>+ JSString *str;
>+
>+ from = stdin;
>+ buflength = 0;
>+ bufsize = BUFSIZE;
>+ buf = JS_malloc(cx, bufsize);
>+ if (!buf)
>+ return JS_FALSE;
>+
>+ while ((buflength +=
>+ js_fgets(buf + buflength, bufsize - buflength, from)) > 0) {
Need a separate int count or whatever to capture js_fgets's return value and
compare > 0, otherwise error or EOF without a \n just before EOF will loop
wrongly, infinitely in the latter case.
>+ /* Are we done? */
>+ if (buf[buflength - 1] == '\n') {
>+ buf[buflength - 1] = '\0';
>+ break;
>+ }
>+
>+ /* Else, grow our buffer for another pass. */
>+ tmp = JS_realloc(cx, buf, bufsize * 2);
>+ if (!tmp) {
>+ JS_free(cx, buf);
>+ return JS_FALSE;
>+ }
>+
>+ bufsize *= 2;
>+ buf = tmp;
>+ }
>+
>+ /* Shrink the buffer to the real size */
>+ tmp = JS_realloc(cx, buf, buflength);
>+ if (!tmp) {
>+ JS_free(cx, buf);
>+ return JS_FALSE;
>+ }
Oops, forgot buf = tmp after this paragraph (shrinking realloc may fail).
>+
>+ /*
>+ * Turn buf into a JSString. Note that buflength includes the trailing null
>+ * character.
>+ */
>+ str = JS_NewString(cx, buf, buflength - 1);
>+ if (!str) {
>+ JS_free(cx, buf);
>+ return JS_FALSE;
>+ }
>+
>+ *rval = STRING_TO_JSVAL(str);
>+ return JS_TRUE;
>+}
Fix those and patch once more, I'll r+a=.
/be
Attachment #189387 -
Flags: review?(brendan) → review-
Comment 7•20 years ago
|
||
> Oops, forgot buf = tmp after this paragraph (shrinking realloc may fail).
Tired, meant to write "may move", not "may fail". Randell Jesup observed this
with the BSD size-classifying malloc.
/be
| Assignee | ||
Comment 8•20 years ago
|
||
All comments should addressed. Also fixed a problem dealing with the empty line
(it's too bad realloc can't assert on a zero-sized request!). I really need to
sit and look at my patches more carefully to avoid these sorts of silly
mistakes.
| Assignee | ||
Updated•20 years ago
|
Attachment #189387 -
Attachment is obsolete: true
Attachment #189400 -
Flags: review?(brendan)
Comment 9•20 years ago
|
||
Comment on attachment 189400 [details] [diff] [review]
readline, v3
Nits:
- gotlength instead of readlength? Anyway, wrap so the js_fgets underhangs the
first letter of the variable name in the nested assignment in the while loop's
condition).
- Period at end of "Shrink the buffer to the real size".
Fix those and r+a=me.
/be
Attachment #189400 -
Flags: review?(brendan)
Attachment #189400 -
Flags: review+
Attachment #189400 -
Flags: approval1.8b4+
| Assignee | ||
Comment 10•20 years ago
|
||
Fix checked in.
It occurs to me that xpcshell might want this function as well. Should I port
this to the xpcshell?
Status: NEW → ASSIGNED
Comment 11•20 years ago
|
||
Sure, unless you are inclined to make a libjsshell that both js and xpcshell can
link against (might not be hard, given the descent of xpcshell.cpp from js.c
long ago, with mostly additive mutations ;-). If you're not inclined to do that
just now, how about at least filing a bug on that? Thanks,
/be
Updated•20 years ago
|
Flags: testcase-
| Assignee | ||
Comment 12•19 years ago
|
||
This is really fixed.
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
Comment 13•17 years ago
|
||
(In reply to comment #10)
> It occurs to me that xpcshell might want this function as well. Should I port
> this to the xpcshell?
I could need that, it's appreciated.
You need to log in
before you can comment on or make changes to this bug.
Description
•