about summary refs log tree commit diff stats
path: root/subx/071read-line.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-03-08 17:15:19 -0800
committerKartik Agaram <vc@akkartik.com>2019-03-08 17:15:19 -0800
commit7a22a21995001cbdf72c5e3b92f52c9abcee3202 (patch)
treeb876c36d1788ee8d3c091e1ee05dacb6b839c44c /subx/071read-line.subx
parent092cede5da0f329f2b624d31cfe76136cfc6a6ed (diff)
downloadmu-7a22a21995001cbdf72c5e3b92f52c9abcee3202.tar.gz
4996 - back on pack.subx
Yet another redrawing of responsibilities between convert and its helpers.

In the process I discovered a bug in `write-stream-buffered` which ended
up taking me through a detour to extract `browse_trace` into its own tool.
It turns out just having long buffers is enough to need browse_trace. Simple
operations like clearing a stream swamp a flat view of the trace.
Diffstat (limited to 'subx/071read-line.subx')
-rw-r--r--subx/071read-line.subx94
1 files changed, 22 insertions, 72 deletions
diff --git a/subx/071read-line.subx b/subx/071read-line.subx
index eff6f9c4..b16170b6 100644
--- a/subx/071read-line.subx
+++ b/subx/071read-line.subx
@@ -3,10 +3,17 @@
 # . op          subop               mod             rm32          base        index         scale       r32
 # . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
 
+#? Entry:  # run a single test, while debugging
+#?     e8/call test-read-line/disp32
+#?     # syscall(exit, Num-test-failures)
+#?     8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
+#?     b8/copy-to-EAX  1/imm32/exit
+#?     cd/syscall  0x80/imm8
+
 # read bytes from 'f' until (and including) a newline and store them into 's'
-# return true if no data found, false otherwise
+# 's' fails to grow if and only if no data found
 # just abort if 's' is too small
-read-line:  # f : (address buffered-file), s : (address stream byte) -> eof?/EAX
+read-line:  # f : (address buffered-file), s : (address stream byte) -> <void>
     # pseudocode:
     #   loop:
     #     if (s->write >= s->length) abort
@@ -21,6 +28,7 @@ read-line:  # f : (address buffered-file), s : (address stream byte) -> eof?/EAX
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
     # . save registers
+    50/push-EAX
     51/push-ECX
     52/push-EDX
     56/push-ESI
@@ -58,13 +66,11 @@ $read-line:loop:
     e8/call  read/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # if (f->write == 0) return true
+    # if (f->write == 0) break
     # since f->read was initially 0, EAX is the same as f->write
     # . if (EAX == 0) return true
     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
-    75/jump-if-not-equal  $read-line:from-stream/disp8
-    b8/copy-to-EAX  0xffffffff/imm32/Eof
-    eb/jump  $read-line:end/disp8
+    74/jump-if-equal  $read-line:end/disp8
 $read-line:from-stream:
     # AL = f->data[f->read]
     31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
@@ -75,10 +81,9 @@ $read-line:from-stream:
     41/increment-ECX
     # ++s->write
     42/increment-EDX
-    # if (AL == '\n') return false
+    # if (AL == '\n') return
     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0xa/imm32         # compare EAX
     75/jump-if-not-equal  $read-line:loop/disp8
-    31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
 $read-line:end:
     # save f->read
     89/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   8/disp8         .                 # copy ECX to *(ESI+8)
@@ -89,6 +94,7 @@ $read-line:end:
     5e/pop-to-ESI
     5a/pop-to-EDX
     59/pop-to-ECX
+    58/pop-to-EAX
     # . epilog
     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
     5d/pop-to-EBP
@@ -103,6 +109,14 @@ $read-line:abort:
     e8/call  _write/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . _write(2/stderr, Newline)
+    # . . push args
+    68/push  Newline/imm32
+    68/push  2/imm32/stderr
+    # . . call
+    e8/call  _write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # . syscall(exit, 1)
     bb/copy-to-EBX  1/imm32
     b8/copy-to-EAX  1/imm32/exit
@@ -169,15 +183,6 @@ test-read-line:
     e8/call  read-line/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, 0/not-at-Eof, msg)
-    # . . push args
-    68/push  "F - test-read-line: return value"/imm32
-    68/push  0/imm32/not-at-Eof
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
     # check-next-stream-line-equal(_test-tmp-stream, "ab", msg)
     # . . push args
     68/push  "F - test-read-line"/imm32
@@ -190,52 +195,6 @@ test-read-line:
     # end
     c3/return
 
-test-read-line-returns-true-on-Eof:
-    # setup
-    # . clear-stream(_test-stream)
-    # . . push args
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # . clear-stream(_test-buffered-file+4)
-    # . . push args
-    b8/copy-to-EAX  _test-buffered-file/imm32
-    05/add-to-EAX  4/imm32
-    50/push-EAX
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # . clear-stream(_test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-    # write nothing
-    # EAX = read-line(_test-buffered-file, _test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    68/push  _test-buffered-file/imm32
-    # . . call
-    e8/call  read-line/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, Eof, msg)
-    # . . push args
-    68/push  "F - test-read-line-returns-true-on-Eof"/imm32
-    68/push  0xffffffff/imm32/Eof
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    # end
-    c3/return
-
 test-read-line-reads-final-line-until-Eof:
     # setup
     # . clear-stream(_test-stream)
@@ -278,15 +237,6 @@ test-read-line-reads-final-line-until-Eof:
     e8/call  read-line/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, Eof, msg)
-    # . . push args
-    68/push  "F - test-read-line-reads-final-line-until-Eof: return value"/imm32
-    68/push  0xffffffff/imm32/Eof
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
     # check-stream-equal(_test-tmp-stream, "cd", msg)
     # . . push args
     68/push  "F - test-read-line-reads-final-line-until-Eof"/imm32