[PATCH] Preserve #name across Stream decorators

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Preserve #name across Stream decorators

Paolo Bonzini
This will allow to have a Stream decorator that limits the "view" to a
particular segment of the underlying Stream, thus speeding up loading
from .star files if the members of the .star file are uncompressed (and
removing the dependency on unzip).

Paolo

M  packages/zlib/zlib.st
M  kernel/StreamOps.st
M  ChangeLog
M  kernel/Stream.st
M  libgst/ChangeLog
M  libgst/input.c
M  libgst/input.h
M  libgst/prims.def

2007-07-19  Paolo Bonzini  <[hidden email]>

        * kernel/Stream.st: Add #name, implement #fileIn in Smalltalk.
        * kernel/StreamOps.st: Add #name.
        * packages/zlib/zlib.st: Add #name.

        * libgst/input.h: Turn second parameter of _gst_set_stream_info to OOP.
        * libgst/input.c: Likewise.
        * libgst/prims.def: Remove fileIn primitive.  Remove check on
        file validity from fileInLine primitive.  Adjust call to
        _gst_set_stream_info.
 


--- orig/kernel/Stream.st
+++ mod/kernel/Stream.st
@@ -49,6 +49,13 @@ provide for writing collections sequenti
 
 !Stream methodsFor: 'accessing-reading'!
 
+name
+    "Return nil by default; not all streams have a name."
+    ^nil
+! !
+
+!Stream methodsFor: 'accessing-reading'!
+
 next
     "Return the next object in the receiver"
     self subclassResponsibility
@@ -492,12 +499,16 @@ fileIn
      in the namespace, so that the old references will automagically point
      to the new value."
 
-    <primitive: VMpr_Stream_fileIn>
-    self primitiveFailed!
+    | pos |
+    pos := [ self position ]
+ on: MessageNotUnderstood
+ do: [ :ex | ex return: 0 ].
+
+    ^self fileInLine: 1 fileName: self name at: pos!
 
 fileInLine: lineNum fileName: aString at: charPosInt
-    "Private - Much like a preprocessor #line directive; it is used
-     by the Emacs Smalltalk mode."
+    "Private - Much like a preprocessor #line directive; it is used internally
+     by #fileIn, and explicitly by the Emacs Smalltalk mode."
 
     <primitive: VMpr_Stream_fileInLine>
     self primitiveFailed


--- orig/kernel/StreamOps.st
+++ mod/kernel/StreamOps.st
@@ -238,6 +238,10 @@ peekFor: aCharacter
 
 !FilteringStream methodsFor: 'basic'!
 
+name
+    ^stream name
+!
+
 species
     ^stream species
 ! !
@@ -303,6 +307,10 @@ position: anInteger
 
 !CollectingStream methodsFor: 'basic'!
 
+name
+    ^stream name
+!
+
 species
     ^stream species
 ! !
@@ -315,6 +323,10 @@ on: aStream
 
 !PeekableStream methodsFor: 'basic'!
 
+name
+    ^stream name
+!
+
 next
     | char |
     ^haveLookahead
@@ -373,6 +385,10 @@ on: aStream
 
 !LineStream methodsFor: 'basic'!
 
+name
+    ^stream name
+!
+
 next
     ^charStream nextLine
 !




--- orig/libgst/input.c
+++ mod/libgst/input.c
@@ -267,15 +267,7 @@ _gst_push_stream_oop (OOP oop)
   newStream->st_oop.buf = NULL;
   newStream->st_oop.ptr = NULL;
   newStream->st_oop.end = NULL;
-  if (is_a_kind_of (OOP_CLASS (oop), _gst_file_descriptor_class))
-    {
-      gst_file_stream fileStream = (gst_file_stream) OOP_TO_OBJ (oop);
-      newStream->fileNameOOP = fileStream->name;
-      in_stream->fileOffset = lseek (TO_INT (fileStream->file), 0, SEEK_CUR);
-      _gst_register_oop (newStream->fileNameOOP);
-    }
-  else
-    newStream->fileName = "a Smalltalk Stream";
+  newStream->fileName = "a Smalltalk Stream";
 
   _gst_register_oop (oop);
 }
@@ -353,16 +345,18 @@ push_new_stream (stream_type type)
 
 void
 _gst_set_stream_info (int line,
-      const char *fileName,
+      OOP fileNameOOP,
       int fileOffset)
 {
   in_stream->line = line;
   in_stream->column = 0;
-  if (fileName)
+  if (!IS_NIL (fileNameOOP))
     {
-      in_stream->fileName = fileName;
-      in_stream->fileNameOOP = _gst_nil_oop;
+      in_stream->fileName = _gst_to_cstring (fileNameOOP);
+      _gst_register_oop (in_stream->fileNameOOP);
     }
+
+  in_stream->fileNameOOP = fileNameOOP;
   in_stream->fileOffset = fileOffset;
 }
 
@@ -708,11 +702,8 @@ line_stamp (int line)
  {
   if (in_stream->fileName)
     fprintf (stderr, "%s:", in_stream->fileName);
-  else if (in_stream->fileNameOOP != _gst_nil_oop)
-    {
-      char *s = _gst_to_cstring (in_stream->fileNameOOP);
-      fprintf (stderr, "%s:", s);
-    }
+  else if (!IS_NIL (in_stream->fileNameOOP))
+    fprintf (stderr, "%#O:", in_stream->fileNameOOP);
 
   fprintf (stderr, "%d: ", line);
  }


--- orig/libgst/input.h
+++ mod/libgst/input.h
@@ -115,7 +115,7 @@ extern void _gst_pop_stream (mst_Boolean
    a subsection of a real file via a temporary file what the real
    source of the text is.  */
 extern void _gst_set_stream_info (int line,
-  const char *fileName,
+  OOP fileNameOOP,
   int fileOffset)
   ATTRIBUTE_HIDDEN;
 


--- orig/libgst/prims.def
+++ mod/libgst/prims.def
@@ -5108,25 +5108,6 @@ primitive VMpr_Object_makeWeak [succeed,
   PRIM_SUCCEEDED;
 }
 
-/* Stream fileIn */
-
-primitive VMpr_Stream_fileIn [succeed,fail]
-{
-  enum undeclared_strategy old;
-  OOP streamOOP = STACKTOP ();
-  _gst_primitives_executed++;
-
-  if (!RECEIVER_IS_OOP (streamOOP))
-    PRIM_FAILED;
-
-  _gst_push_stream_oop (streamOOP);
-  old = _gst_set_undeclared (UNDECLARED_GLOBALS);
-  parse_stream_with_protection (false);
-  _gst_set_undeclared (old);
-  _gst_pop_stream (false); /* we didn't open it, so we don't close it */
-  PRIM_SUCCEEDED;
-}
-
 /* Stream fileInLine: lineNum fileName: aString at: charPosInt */
 
 primitive VMpr_Stream_fileInLine [succeed,fail]
@@ -5135,49 +5116,26 @@ primitive VMpr_Stream_fileInLine [succee
   OOP oop2 = POP_OOP ();
   OOP oop1 = POP_OOP ();
   OOP streamOOP = STACKTOP ();
-  char *realFileName;
+  enum undeclared_strategy old;
   
   if (!RECEIVER_IS_OOP (streamOOP))
     PRIM_FAILED;
 
-  if (is_a_kind_of (OOP_CLASS (streamOOP), _gst_file_descriptor_class))
-    {
-      gst_file_stream fileStream = (gst_file_stream) OOP_TO_OBJ (streamOOP);
-      char *fileName = _gst_to_cstring (fileStream->name);
-      if (!_gst_file_is_readable (fileName))
- {
-  xfree (fileName);
-  PRIM_FAILED;
- }
-      else
- xfree (fileName);
-    }
-
   if (IS_INT (oop1)
       && (IS_NIL (oop2)
   || (IS_CLASS (oop2, _gst_string_class) && IS_INT (oop3))))
     {
-      intptr_t arg2;
-      intptr_t arg4;
-      arg2 = TO_INT (oop1);
-      if (!IS_NIL (oop2))
- {
-  realFileName = _gst_to_cstring (oop2);
-  arg4 = TO_INT (oop3);
- }
-      else
- {
-  realFileName = NULL;
-  arg4 = 0;
- }
+      intptr_t arg1;
+      intptr_t arg3;
+      arg1 = TO_INT (oop1);
+      arg3 = TO_INT (oop3);
 
       _gst_push_stream_oop (streamOOP);
-      _gst_set_stream_info (arg2, realFileName, arg4);
+      _gst_set_stream_info (arg1, oop2, arg3);
+      old = _gst_set_undeclared (UNDECLARED_GLOBALS);
       parse_stream_with_protection (false);
+      _gst_set_undeclared (old);
       _gst_pop_stream (false);
-
-      if (realFileName)
- xfree (realFileName);
     }
 
   PRIM_SUCCEEDED;


--- orig/packages/zlib/zlib.st
+++ mod/packages/zlib/zlib.st
@@ -189,6 +189,11 @@ position
      streams support random access to the stream data."
     ^delta + ptr!
 
+name
+    "Return the name of the underlying stream."
+    ^source name
+!
+
 species
     "Return the type of the collections returned by #upTo: etc."
     ^source species! !




_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk