* variable lenght strings @ 2004-10-21 17:52 fabio de francesco 2004-10-21 21:22 ` Martin Dowie ` (5 more replies) 0 siblings, 6 replies; 65+ messages in thread From: fabio de francesco @ 2004-10-21 17:52 UTC (permalink / raw) Hi, while studying from "Ada as a 2nd Language" I am having some problem to cope with Strings (Fixed, Unbounded and Bounded) manipulation and especially with assigning between different types of them and with overall with input/output. 1) Is it possible to use Get_Line with Unbounded and/or Bounded Strings? 2) If not, how should user input be managed when lines length isn't known a priori? 3) I have to write a program that parses a file in which there are lines that have to be "tokenized". I didn't find any Find_Token() usage example on the Book so I wrote a little piece of code in order to understand the procedure workings on a fixed string (Line A) that simulates file input. Think that I am used with C function strtok() and I must say that Ada Find_Token is much more elegant and not destructive as strtok() is. Ok, please let me know if the following is the correct usage: with Ada.Text_IO, Ada.Strings, Ada.Strings.Fixed, Ada.Strings.Maps, Ada.Strings.Maps.Constants; use Ada.Text_IO, Ada.Strings, Ada.Strings.Fixed, Ada.Strings.Maps, Ada.Strings.Maps.Constants; procedure Tokenize is S : constant String := ".symbol HP = High_Pressure "; -- Line A F : Positive := S'First; L : Natural := S'Last; W : String( 1..30 ); begin loop Find_Token(S(F..L), Alphanumeric_Set or To_Set("_."), Inside, F, L); if L /= 0 then Put_Line( Positive'Image( F ) & ( L - F ) * ' ' & Natural'Image( L ) ); Move( S( F..L ), W ); Put_Line( ' ' & W ); F := L + 1; L := S'Last; else exit; end if; end loop; end Tokenize; Is it correct to check the "L" value as a condition to exit the loop? Thank you in advance for any help, Fabio De Francesco ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 17:52 variable lenght strings fabio de francesco @ 2004-10-21 21:22 ` Martin Dowie 2004-10-21 22:42 ` Marius Amado Alves ` (4 subsequent siblings) 5 siblings, 0 replies; 65+ messages in thread From: Martin Dowie @ 2004-10-21 21:22 UTC (permalink / raw) "fabio de francesco" <fmdf@tiscali.it> wrote in message news:ba2f9c57.0410210952.438515d@posting.google.com... > Is it correct to check the "L" value as a condition to exit the loop? Don't have time to look at the logic in the code but it is more usual to say: exit when L = 0; rather than use an 'if'. Cheers -- Martin ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 17:52 variable lenght strings fabio de francesco 2004-10-21 21:22 ` Martin Dowie @ 2004-10-21 22:42 ` Marius Amado Alves 2004-10-21 23:14 ` Matthew Heaney 2004-10-22 7:29 ` Martin Krischik 2004-10-21 23:01 ` Marius Amado Alves ` (3 subsequent siblings) 5 siblings, 2 replies; 65+ messages in thread From: Marius Amado Alves @ 2004-10-21 22:42 UTC (permalink / raw) To: comp.lang.ada > 1) Is it possible to use Get_Line with Unbounded and/or Bounded > Strings? Not in the standard, but subprograms like those are usually around, e.g. in the GNAT Library, or end up being written in house. > 2) If not, how should usei input be managed when lines length isn't > known a priori? There's a way using the standard Get_Line, explained in AdaPower. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 22:42 ` Marius Amado Alves @ 2004-10-21 23:14 ` Matthew Heaney 2004-10-22 7:38 ` Martin Krischik 2004-10-22 12:30 ` fabio de francesco 2004-10-22 7:29 ` Martin Krischik 1 sibling, 2 replies; 65+ messages in thread From: Matthew Heaney @ 2004-10-21 23:14 UTC (permalink / raw) "Marius Amado Alves" <amado.alves@netcabo.pt> wrote in message news:mailman.46.1098398641.10401.comp.lang.ada@ada-france.org... >> 1) Is it possible to use Get_Line with Unbounded and/or Bounded >> Strings? > > Not in the standard, but subprograms like those are usually around, e.g. > in the GNAT Library, or end up being written in house. > >> 2) If not, how should usei input be managed when lines length isn't >> known a priori? > > There's a way using the standard Get_Line, explained in AdaPower. Mario is probably referring to an article I posted to CLA a few years' ago, and which is now archived at the adapower website. The basic idea is this: algorithms that consume input from a stream need a way a identify when all of the input has been consumed. Typically this is done using a special value that you know is outside the range of normal values, e.g. declare I : Natural; begin loop Get (Stream, I); exit when I = 0; --the special value ... -- do something with I end loop; end; Text_IO.Get_Line works just like this, except that it's not obvious what the termination condition is: declare Line : String (1 .. 81); Last : Natural; begin loop Get_Line (Line, Last); .. -- do something with Line (1 .. Last); exit when ??? end loop; end; The termination condition is as follows: you know that you've consumed the entire line when Last < Line'Last. We can now write: declare Line : String (1 .. 81); Last : Natural; begin loop Get_Line (Line, Last); .. -- do something with Line (1 .. Last); exit when Last < Line'Last; end loop; end; Typically you know what a normal line length is, so you declare Line with a length of Max + 1. (That's why Line'Last is 81 in the examples above.) Now that you know the termination condition, the next problem is deciding how to handle a line of input that is longer than your buffer. You can either handle it as an error, or just copy the buffer into an expandable string buffer such as Unbounded_String. If you want, you can use recursion to read the line, and return the string as a function result: declare function Get_Line (N : Positive := 80) return String is Line : String (1 .. N + 1); Last : Natural; begin Get_Line (Line, Last); if Last < Line'Last then return Line (1 .. Last); else return Line & Get_Line (2 * N); end if; end Get_Line; Line : constant String := Get_Line; begin This avoids the loop, and having to store intermediate results in a buffer. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 23:14 ` Matthew Heaney @ 2004-10-22 7:38 ` Martin Krischik 2004-10-22 12:30 ` fabio de francesco 1 sibling, 0 replies; 65+ messages in thread From: Martin Krischik @ 2004-10-22 7:38 UTC (permalink / raw) Matthew Heaney wrote: > > "Marius Amado Alves" <amado.alves@netcabo.pt> wrote in message > news:mailman.46.1098398641.10401.comp.lang.ada@ada-france.org... >>> 1) Is it possible to use Get_Line with Unbounded and/or Bounded >>> Strings? >> >> Not in the standard, but subprograms like those are usually around, e.g. >> in the GNAT Library, or end up being written in house. >> >>> 2) If not, how should usei input be managed when lines length isn't >>> known a priori? >> >> There's a way using the standard Get_Line, explained in AdaPower. > > Mario is probably referring to an article I posted to CLA a few years' > ago, and which is now archived at the adapower website. > > The basic idea is this: algorithms that consume input from a stream need > a > way a identify when all of the input has been consumed. Typically this is > done using a special value that you know is outside the range of normal > values, e.g. Well, you do not check for End_Of_File and that means your solution will fail if the last line is not terminated with CR/LF. And if you want to process files which have been edited by human beings than you have to care for that case The following version does work. It hast been tested on hundreds of files all edited by human beings: package body -- -- String IO Routienes. This are used because -- Ada.Strings.Unbounded.Text_IO and GNAT.IO_Aux both have a suttle -- little bug. -- AdaCL.Strings.IO is -- -- Shorten some names. -- package S_U renames Ada.Strings.Unbounded; package S_Maps renames Ada.Strings.Maps; package Latin_1 renames Ada.Characters.Latin_1; package IO renames Ada.Text_IO; -- Buffer length. Works for any non-zero value, larger values take -- more stack space, smaller values require more recursion. BufferSize : constant := 2000; -- -- Well, there are a lot of Get_Line routines around and GNAT -- certanly has its onwn, but all those I have seen have suttle bug: -- When the last line is not terminated with CR/LF and a multiple -- of buffersize long they will throw and end of file exception. -- -- This version need recursion! -- function Get_Line ( -- File to be read. File : in IO.File_Type) return String is -- Trace : AdaCL.Trace.Object := AdaCL.Trace.Function_Trace (AdaCL.Trace.Entity & ':' & AdaCL.Trace.Source); -- pragma Unreferenced (Trace); Buffer : String (1 .. BufferSize); Last : Natural; begin IO.Get_Line ( File => File, Item => Buffer, Last => Last); if Last < Buffer'Last then return Buffer (1 .. Last); elsif IO.End_Of_File (File) then return Buffer; else return Buffer & Get_Line (File); end if; end Get_Line; -- -- Well, there are a lot of Get_Line routines around and GNAT -- certanly has its onwn, but all those I have seen have suttle bug: -- When the last line is not terminated with CR/LF and a multiple -- of buffersize long they will throw and end of file exception. -- -- This version uses a loop. -- function Get_Line ( -- File to be read. File : in IO.File_Type) return S_U.Unbounded_String is -- Trace : AdaCL.Trace.Object := AdaCL.Trace.Function_Trace (AdaCL.Trace.Entity & ':' & AdaCL.Trace.Source); -- pragma Unreferenced (Trace); Retval : S_U.Unbounded_String := S_U.Null_Unbounded_String; Item : String (1 .. BufferSize); Last : Natural; begin GetWholeLine : loop IO.Get_Line ( File => File, Item => Item, Last => Last); S_U.Append ( Source => Retval, New_Item => Item (1 .. Last)); exit GetWholeLine when Last < Item'Last or IO.End_Of_File (File); end loop GetWholeLine; return Retval; end Get_Line; -- -- Get Next Word. -- procedure Get_Word ( -- File to be read. File : in Ada.Text_IO.File_Type; -- String into wich the word is to be read Item : out String; -- Actual amount of characters read. Last : out Natural; -- Word Delimiters Delimiters : in Ada.Strings.Maps.Character_Set := Word_Delimiters) is -- Trace : AdaCL.Trace.Object := AdaCL.Trace.Function_Trace (AdaCL.Trace.Entity & ':' & AdaCL.Trace.Source); -- pragma Unreferenced (Trace); Next_Char : Character := Latin_1.NUL; begin Last := Item'First; Skip_Blanks : loop IO.Get (File => File, Item => Next_Char); -- AdaCL.Trace.Write (Integer'Image (Character'Pos (Next_Char)) & "'" & String'(1 => Next_Char) & "'"); exit Skip_Blanks when not S_Maps.Is_In ( Element => Next_Char, Set => Delimiters); end loop Skip_Blanks; Read_Char : loop if S_Maps.Is_In (Element => Next_Char, Set => Delimiters) then Last := Natural'Pred (Last); exit Read_Char; end if; -- AdaCL.Trace.Write (Integer'Image (Character'Pos (Next_Char)) & "'" & String'(1 => Next_Char) & "'"); Item (Last) := Next_Char; -- AdaCL.Trace.Write (Item (Item'First .. Last)); Last := Natural'Succ (Last); exit Read_Char when Last = Item'Last; IO.Get (File => File, Item => Next_Char); end loop Read_Char; end Get_Word; -- -- Get Next Word. -- -- This version uses recursion! The actual version is garanteed to work -- up to words 2000 characters. -- function Get_Word ( -- File to be read. File : in IO.File_Type; -- Word Delimiters Delimiters : in S_Maps.Character_Set := Word_Delimiters) return String is -- Trace : AdaCL.Trace.Object := AdaCL.Trace.Function_Trace (AdaCL.Trace.Entity & ':' & AdaCL.Trace.Source); -- pragma Unreferenced (Trace); Buffer : String (1 .. BufferSize); Last : Natural; begin Get_Word (File => File, Item => Buffer, Last => Last, Delimiters => Delimiters); if Last < Buffer'Last then return Buffer (1 .. Last); elsif IO.End_Of_File (File) then return Buffer; else return Buffer & Get_Word (File, Delimiters); end if; end Get_Word; -- -- Get Next Word. -- -- This version uses a loop. The actual version is garanteed to work -- up to words 2000 characters. -- function Get_Word ( -- File to be read. File : in IO.File_Type; -- Word Delimiters Delimiters : in Ada.Strings.Maps.Character_Set := Word_Delimiters) return S_U.Unbounded_String is -- Trace : AdaCL.Trace.Object := AdaCL.Trace.Function_Trace (AdaCL.Trace.Entity & ':' & AdaCL.Trace.Source); -- pragma Unreferenced (Trace); Retval : S_U.Unbounded_String := S_U.Null_Unbounded_String; Item : String (1 .. BufferSize); Last : Natural; begin GetWholeLine : loop Get_Word (File => File, Item => Item, Last => Last, Delimiters => Delimiters); S_U.Append (Source => Retval, New_Item => Item (1 .. Last)); exit GetWholeLine when Last < Item'Last or IO.End_Of_File (File); end loop GetWholeLine; return Retval; end Get_Word; end AdaCL.Strings.IO; With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 23:14 ` Matthew Heaney 2004-10-22 7:38 ` Martin Krischik @ 2004-10-22 12:30 ` fabio de francesco 1 sibling, 0 replies; 65+ messages in thread From: fabio de francesco @ 2004-10-22 12:30 UTC (permalink / raw) "Matthew Heaney" <mheaney@on2.com> wrote in message news:<417842cd$0$74191$39cecf19@news.twtelecom.net>... Hi, I thank you all for your kind support, that is what you always give. This is one more reason to be added to the enjoyment of learning Ada. [CUT] > The termination condition is as follows: you know that you've consumed the > entire line when Last < Line'Last. Good! I didn't know. [CUT] > If you want, you can use recursion to read the line, and return the string > as a function result: > > declare > function Get_Line (N : Positive := 80) return String is > Line : String (1 .. N + 1); > Last : Natural; > begin > Get_Line (Line, Last); > > if Last < Line'Last then > return Line (1 .. Last); > else > return Line & Get_Line (2 * N); > end if; > end Get_Line; > > Line : constant String := Get_Line; > begin > > This avoids the loop, and having to store intermediate results in a buffer. I like the method you explained. I suppose that I have to change the function name in order not to collide with the standard Get_Line. So I renamed it My_Get_Line, but when compiling I get: 22. return Line & My_Get_Line (2 * N); | >>> ambiguous operand for concatenation >>> possible interpretation at line 13 >>> possible interpretation at line 13 Line 13 is the line that starts My_Get_Line definition. Why is the operand ambiguous? Fabio De Francesco ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 22:42 ` Marius Amado Alves 2004-10-21 23:14 ` Matthew Heaney @ 2004-10-22 7:29 ` Martin Krischik 2004-10-22 13:01 ` Matthew Heaney 1 sibling, 1 reply; 65+ messages in thread From: Martin Krischik @ 2004-10-22 7:29 UTC (permalink / raw) Marius Amado Alves wrote: >> 1) Is it possible to use Get_Line with Unbounded and/or Bounded >> Strings? > > Not in the standard, but subprograms like those are usually around, e.g. > in the GNAT Library, or end up being written in house. > >> 2) If not, how should usei input be managed when lines length isn't >> known a priori? > > There's a way using the standard Get_Line, explained in AdaPower. Which is buggy- It will fail if the length of the last line is a multiple of buffer length! I once send a correction but is was ignored. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-22 7:29 ` Martin Krischik @ 2004-10-22 13:01 ` Matthew Heaney 2004-10-24 15:46 ` Martin Krischik 0 siblings, 1 reply; 65+ messages in thread From: Matthew Heaney @ 2004-10-22 13:01 UTC (permalink / raw) Martin Krischik <krischik@users.sourceforge.net> writes: > > There's a way using the standard Get_Line, explained in AdaPower. > > Which is buggy- It will fail if the length of the last line is a > multiple of buffer length! I once send a correction but is was > ignored. Can you explain this problem in more detail? The algorithm I showed in my previous post should work irrespective of the length of the input line. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-22 13:01 ` Matthew Heaney @ 2004-10-24 15:46 ` Martin Krischik 2004-10-24 19:54 ` Jeffrey Carter 0 siblings, 1 reply; 65+ messages in thread From: Martin Krischik @ 2004-10-24 15:46 UTC (permalink / raw) Matthew Heaney wrote: > Martin Krischik <krischik@users.sourceforge.net> writes: > >> > There's a way using the standard Get_Line, explained in AdaPower. >> >> Which is buggy- It will fail if the length of the last line is a >> multiple of buffer length! I once send a correction but is was >> ignored. > > Can you explain this problem in more detail? The algorithm I showed in > my previous post should work irrespective of the length of the input > line. When the last line is missing a CR/LF - happens often in user edited files - and is a multiple of the internal buffer in lenght then an exception is raised. Bug or feature? If you need to read user edited files than it's a nuciance in any case. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-24 15:46 ` Martin Krischik @ 2004-10-24 19:54 ` Jeffrey Carter 2004-10-24 21:30 ` Larry Kilgallen 0 siblings, 1 reply; 65+ messages in thread From: Jeffrey Carter @ 2004-10-24 19:54 UTC (permalink / raw) Martin Krischik wrote: > When the last line is missing a CR/LF - happens often in user edited > files - and is a multiple of the internal buffer in lenght then an > exception is raised. Get_Line is specified in A.10.7: Reads successive characters from the specified input file and assigns them to successive characters of the specified string. Reading stops if the end of the string is met. Reading also stops if the end of the line is met before meeting the end of the string; in this case Skip_Line is (in effect) called with a spacing of 1. The end of the line seems to be specified in A.10.5, for End_Of_Line: Operates on a file of mode In_File. Returns True if a line terminator or a file terminator is next; otherwise returns False. Thus a missing line terminator (CR/LF for DOS/Windows) at the end of a file should be interpreted as end of line anyway, it seems, and any compiler which doesn't seems to have an error. Possibly an exception is raised because it is unable to skip the implied end of line. That may be a legal interpretation, but it would apply in all cases when the file lacks a final line terminator, not just when attempting to read a null string. Perhaps we should contact the ARG for clarification of this. -- Jeff Carter "Oh Lord, bless this thy hand grenade, that with it thou mayst blow thine enemies to tiny bits, in thy mercy." Monty Python and the Holy Grail 24 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-24 19:54 ` Jeffrey Carter @ 2004-10-24 21:30 ` Larry Kilgallen 2004-10-25 4:02 ` Jeffrey Carter 0 siblings, 1 reply; 65+ messages in thread From: Larry Kilgallen @ 2004-10-24 21:30 UTC (permalink / raw) In article <hMTed.5827$KJ6.5159@newsread1.news.pas.earthlink.net>, Jeffrey Carter <spam@spam.com> writes: > Martin Krischik wrote: > >> When the last line is missing a CR/LF - happens often in user edited >> files - and is a multiple of the internal buffer in lenght then an >> exception is raised. > > Get_Line is specified in A.10.7: > > Reads successive characters from the specified input file and assigns > them to successive characters of the specified string. Reading stops if > the end of the string is met. Reading also stops if the end of the line > is met before meeting the end of the string; in this case Skip_Line is > (in effect) called with a spacing of 1. > > The end of the line seems to be specified in A.10.5, for End_Of_Line: > > Operates on a file of mode In_File. Returns True if a line terminator or > a file terminator is next; otherwise returns False. > > Thus a missing line terminator (CR/LF for DOS/Windows) at the end of a > file should be interpreted as end of line anyway, it seems, and any > compiler which doesn't seems to have an error. But that would be specific to DOS/Windows. Is someone arguing that a carriage-return or line feed is supposed to be the implementation for "the end of line is met" in the section quoted above ? Certainly that was not the case for Ada83 on VMS, where there is an out-of-band end of line indication. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-24 21:30 ` Larry Kilgallen @ 2004-10-25 4:02 ` Jeffrey Carter 0 siblings, 0 replies; 65+ messages in thread From: Jeffrey Carter @ 2004-10-25 4:02 UTC (permalink / raw) Larry Kilgallen wrote: > > Is someone arguing that a carriage-return or line feed is supposed > to be the implementation for "the end of line is met" in the section > quoted above ? Certainly that was not the case for Ada83 on VMS, > where there is an out-of-band end of line indication. Certainly not. The post to which I was replying said that a missing CR/LF caused this behavior. I pointed out that CR/LF was the line terminator for DOS/Windows. It is not the line terminator for UNIX, for example, and there is a specific statement in the ARM that terminators need not be characters in the file, as is the case for VMS. -- Jeff Carter "I like it when the support group complains that they have insufficient data on mean time to repair bugs in Ada software." Robert I. Eachus 91 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 17:52 variable lenght strings fabio de francesco 2004-10-21 21:22 ` Martin Dowie 2004-10-21 22:42 ` Marius Amado Alves @ 2004-10-21 23:01 ` Marius Amado Alves 2004-10-21 23:05 ` Stephen Leake ` (2 subsequent siblings) 5 siblings, 0 replies; 65+ messages in thread From: Marius Amado Alves @ 2004-10-21 23:01 UTC (permalink / raw) To: comp.lang.ada > loop > Find_Token(S(F..L), Alphanumeric_Set or To_Set("_."), Inside, F, > L); > if L /= 0 then > Put_Line( Positive'Image( F ) & ( L - F ) * ' ' & > Natural'Image( L ) ); > Move( S( F..L ), W ); > Put_Line( ' ' & W ); > F := L + 1; > L := S'Last; > else > exit; > end if; > end loop; > > Is it correct to check the "L" value as a condition to exit the loop? Yes, but don't mix L and S'Last: ... > L : Natural; ... > Find_Token (S(F..S'Last), ... ... > -- L := S'Last; ERASE THIS LINE ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 17:52 variable lenght strings fabio de francesco ` (2 preceding siblings ...) 2004-10-21 23:01 ` Marius Amado Alves @ 2004-10-21 23:05 ` Stephen Leake 2004-10-22 7:25 ` Martin Krischik 2004-10-24 18:57 ` variable lenght strings Jeffrey Carter 5 siblings, 0 replies; 65+ messages in thread From: Stephen Leake @ 2004-10-21 23:05 UTC (permalink / raw) To: comp.lang.ada fmdf@tiscali.it (fabio de francesco) writes: > 1) Is it possible to use Get_Line with Unbounded and/or Bounded > Strings? If you are using GNAT, you can use Ada.Strings.Unbounded.Text_IO. > 2) If not, how should user input be managed when lines length isn't > known a priori? Ada.Text_IO.Get_Line takes a String argument; if it isn't filled, you can call Ada.Strings.Unbounded on it. The tricky part is what to do if your initial guess at a max length is too short. You can write a loop; keep appending chunks of input until Get_Line returns Last < Item'last. > <snip stuff about Find_Token> > > Ok, please let me know if the following is the correct usage: "Correct usage" is whatever works for your application! > > > with Ada.Text_IO, Ada.Strings, Ada.Strings.Fixed, > Ada.Strings.Maps, Ada.Strings.Maps.Constants; > use Ada.Text_IO, Ada.Strings, Ada.Strings.Fixed, > Ada.Strings.Maps, Ada.Strings.Maps.Constants; > > procedure Tokenize is > > S : constant String := ".symbol HP = High_Pressure "; -- Line A > F : Positive := S'First; > L : Natural := S'Last; > W : String( 1..30 ); > > begin > loop > Find_Token(S(F..L), Alphanumeric_Set or To_Set("_."), Inside, F, > L); It would be best to declare a variable to hold Alphanumeric_Set or To_Set("_."). > if L /= 0 then This could be 'exit when L = 0', but it's really a style issue. > Put_Line( Positive'Image( F ) & ( L - F ) * ' ' & > Natural'Image( L ) ); > Move( S( F..L ), W ); Named association is better here; I always forget which is the target and which the source. > Put_Line( ' ' & W ); > F := L + 1; > L := S'Last; > else > exit; > end if; > end loop; > end Tokenize; > > > Is it correct to check the "L" value as a condition to exit the > loop? Yes. -- -- Stephe ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 17:52 variable lenght strings fabio de francesco ` (3 preceding siblings ...) 2004-10-21 23:05 ` Stephen Leake @ 2004-10-22 7:25 ` Martin Krischik 2004-10-22 11:11 ` Martin Dowie 2004-10-24 18:57 ` variable lenght strings Jeffrey Carter 5 siblings, 1 reply; 65+ messages in thread From: Martin Krischik @ 2004-10-22 7:25 UTC (permalink / raw) fabio de francesco wrote: > Hi, > > while studying from "Ada as a 2nd Language" I am having some problem > to cope with Strings (Fixed, Unbounded and Bounded) manipulation and > especially with assigning between different types of them and with > overall with input/output. > > 1) Is it possible to use Get_Line with Unbounded and/or Bounded > Strings? Well the Standart overlooked that one. However it is quite easy to write your own - either a recursive solution for String or a loop solution with Unbounded_String. Beware of the examples in Textbooks: Most of them do not handle the last line properly when a final CR/LF is missing. AdaCL has a Get_Line for strings and unbounded strings. And unlike most other implementation it does not have the problem wiht the last line. AdaCL also has text filter classes for easy parsing of text files. see http://www.ada.krischik.com. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-22 7:25 ` Martin Krischik @ 2004-10-22 11:11 ` Martin Dowie 2004-10-24 15:43 ` Martin Krischik 2004-10-24 18:38 ` Why these "Drop" parameters? (was: variable lenght strings) Björn Persson 0 siblings, 2 replies; 65+ messages in thread From: Martin Dowie @ 2004-10-22 11:11 UTC (permalink / raw) Martin Krischik wrote: >> 1) Is it possible to use Get_Line with Unbounded and/or Bounded >> Strings? > > Well the Standart overlooked that one. However it is quite easy to > write your own - either a recursive solution for String or a loop > solution with Unbounded_String. Being added in Ada2005, see Ada.Text_IO.Unbounded_IO in http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT?rev=1.12 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-22 11:11 ` Martin Dowie @ 2004-10-24 15:43 ` Martin Krischik 2004-10-24 17:39 ` Martin Dowie 2004-10-24 18:37 ` Björn Persson 2004-10-24 18:38 ` Why these "Drop" parameters? (was: variable lenght strings) Björn Persson 1 sibling, 2 replies; 65+ messages in thread From: Martin Krischik @ 2004-10-24 15:43 UTC (permalink / raw) Martin Dowie wrote: > Martin Krischik wrote: >>> 1) Is it possible to use Get_Line with Unbounded and/or Bounded >>> Strings? >> >> Well the Standart overlooked that one. However it is quite easy to >> write your own - either a recursive solution for String or a loop >> solution with Unbounded_String. > > Being added in Ada2005, see Ada.Text_IO.Unbounded_IO in > http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT?rev=1.12 Cool. How will it handle a missing CR/LF at the end of file? With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-24 15:43 ` Martin Krischik @ 2004-10-24 17:39 ` Martin Dowie 2004-10-24 18:37 ` Björn Persson 1 sibling, 0 replies; 65+ messages in thread From: Martin Dowie @ 2004-10-24 17:39 UTC (permalink / raw) "Martin Krischik" <krischik@users.sourceforge.net> wrote in message news:1195374.UMjBCk7lO1@linux1.krischik.com... > Martin Dowie wrote: > >> Martin Krischik wrote: >>>> 1) Is it possible to use Get_Line with Unbounded and/or Bounded >>>> Strings? >>> >>> Well the Standart overlooked that one. However it is quite easy to >>> write your own - either a recursive solution for String or a loop >>> solution with Unbounded_String. >> >> Being added in Ada2005, see Ada.Text_IO.Unbounded_IO in >> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT?rev=1.12 > > Cool. How will it handle a missing CR/LF at the end of file? The AI defines: function Get_Line (File : in File_Type) return Strings.Unbounded.Unbounded_String; Returns Strings.Unbounded.To_Unbounded_String(Text_IO.Get_Line(File));So, I'm guessing it will be consistant with the current Get_Line behaviour.-- Martin ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-24 15:43 ` Martin Krischik 2004-10-24 17:39 ` Martin Dowie @ 2004-10-24 18:37 ` Björn Persson 2004-10-25 7:30 ` Martin Krischik 1 sibling, 1 reply; 65+ messages in thread From: Björn Persson @ 2004-10-24 18:37 UTC (permalink / raw) Martin Krischik wrote: > Martin Dowie wrote: > >>Being added in Ada2005, see Ada.Text_IO.Unbounded_IO in >>http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT?rev=1.12 > > Cool. How will it handle a missing CR/LF at the end of file? There is a brief discussion of that in the AI file. Randy said that the implementation has always been required to provide an implicit line terminator. -- Björn Persson PGP key A88682FD omb jor ers @sv ge. r o.b n.p son eri nu ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-24 18:37 ` Björn Persson @ 2004-10-25 7:30 ` Martin Krischik 2004-10-26 0:06 ` Randy Brukardt 0 siblings, 1 reply; 65+ messages in thread From: Martin Krischik @ 2004-10-25 7:30 UTC (permalink / raw) Bjï¿œrn Persson wrote: > Martin Krischik wrote: >> Martin Dowie wrote: >> >>>Being added in Ada2005, see Ada.Text_IO.Unbounded_IO in >>>http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT?rev=1.12 >> >> Cool. How will it handle a missing CR/LF at the end of file? > > There is a brief discussion of that in the AI file. Randy said that the > implementation has always been required to provide an implicit line > terminator. Well, last time i checked GNAT didn't and raised an end of file exception. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-25 7:30 ` Martin Krischik @ 2004-10-26 0:06 ` Randy Brukardt 2004-10-26 1:53 ` Larry Kilgallen ` (2 more replies) 0 siblings, 3 replies; 65+ messages in thread From: Randy Brukardt @ 2004-10-26 0:06 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1501 bytes --] "Martin Krischik" <krischik@users.sourceforge.net> wrote in message news:1154613.ipZcUgduzp@linux1.krischik.com... > Bj�rn Persson wrote: > > > Martin Krischik wrote: > >> Martin Dowie wrote: > >> > >>>Being added in Ada2005, see Ada.Text_IO.Unbounded_IO in > >>>http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT?rev=1.12 > >> > >> Cool. How will it handle a missing CR/LF at the end of file? > > > > There is a brief discussion of that in the AI file. Randy said that the > > implementation has always been required to provide an implicit line > > terminator. > > Well, last time i checked GNAT didn't and raised an end of file exception. My opinion is that GNAT is wrong in that case. A.10(7) makes it quite clear that you can't have a file terminator without a line and page terminator in front of it. I vaguely recall having argued this with Robert Dewar, and I think that they had a different interpretation, based on the idea that a file with a missing CR/LF is incorrect for use with Text_IO. I hope I misremember that, because it is stupid (even if it is logically correct) as it essentially says that you can't read outside generated text files with Text_IO (you can't know whether the file has CR/LFs as required). But I can understand why they wouldn't want to do this properly, because it is a pain to get right, and it saps the performance of Text_IO (since you have the be prepared to check for implied characters for each one you read). Randy. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 0:06 ` Randy Brukardt @ 2004-10-26 1:53 ` Larry Kilgallen 2004-10-26 8:49 ` Martin Krischik 2004-10-26 11:18 ` Marius Amado Alves 2004-10-26 8:43 ` variable lenght strings Jean-Pierre Rosen 2004-10-26 17:46 ` Jeffrey Carter 2 siblings, 2 replies; 65+ messages in thread From: Larry Kilgallen @ 2004-10-26 1:53 UTC (permalink / raw) In article <PaSdnX0j54BWCeDcRVn-jA@megapath.net>, "Randy Brukardt" <randy@rrsoftware.com> writes: > I vaguely recall having argued this with Robert Dewar, and I think that they > had a different interpretation, based on the idea that a file with a missing > CR/LF is incorrect for use with Text_IO. I hope I misremember that, because > it is stupid (even if it is logically correct) as it essentially says that > you can't read outside generated text files with Text_IO (you can't know > whether the file has CR/LFs as required). To say that Text_IO cannot read files generated by other languages seems illogical to me (from the vantage point on an operating system where the lingua franca is record-based files.) ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 1:53 ` Larry Kilgallen @ 2004-10-26 8:49 ` Martin Krischik 2004-10-26 11:18 ` Marius Amado Alves 1 sibling, 0 replies; 65+ messages in thread From: Martin Krischik @ 2004-10-26 8:49 UTC (permalink / raw) Larry Kilgallen wrote: > In article <PaSdnX0j54BWCeDcRVn-jA@megapath.net>, "Randy Brukardt" > <randy@rrsoftware.com> writes: > >> I vaguely recall having argued this with Robert Dewar, and I think that >> they had a different interpretation, based on the idea that a file with a >> missing CR/LF is incorrect for use with Text_IO. I hope I misremember >> that, because it is stupid (even if it is logically correct) as it >> essentially says that you can't read outside generated text files with >> Text_IO (you can't know whether the file has CR/LFs as required). > > To say that Text_IO cannot read files generated by other languages > seems illogical to me (from the vantage point on an operating system > where the lingua franca is record-based files.) Not just other languages. The real problem is user edited file. Users often delete the final CR/LF. It would be a shame of Text_IO could not read a file from an editor. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 1:53 ` Larry Kilgallen 2004-10-26 8:49 ` Martin Krischik @ 2004-10-26 11:18 ` Marius Amado Alves 2004-10-26 12:48 ` variable length strings Larry Kilgallen 1 sibling, 1 reply; 65+ messages in thread From: Marius Amado Alves @ 2004-10-26 11:18 UTC (permalink / raw) To: comp.lang.ada "To say that Text_IO cannot read files generated by other languages seems illogical to me (from the vantage point on an operating system where the lingua franca is record-based files.)" (Larry) Strictly, the RM allows that to happen. But implementations effectively avoid that problem by following the convention associated with the operative system. This however perpetuates another problem: text files cannot be shared between different OSes. Personally in this case I forget about Text_IO, define a central format (usually NEL for new line, no pages) and provide converters. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-26 11:18 ` Marius Amado Alves @ 2004-10-26 12:48 ` Larry Kilgallen 2004-10-26 16:11 ` Warren W. Gay VE3WWG 0 siblings, 1 reply; 65+ messages in thread From: Larry Kilgallen @ 2004-10-26 12:48 UTC (permalink / raw) In article <mailman.61.1098789536.10401.comp.lang.ada@ada-france.org>, Marius Amado Alves <amado.alves@netcabo.pt> writes: > This however perpetuates another problem: text files cannot be shared > between different OSes. The problem of variable length record text files is beyond the reach of any Ada standard. The possibilities VMS must handle are: Out-of-band record termination (as codified in ISO-9660 6.10.4) CRLF record termination (compatible with Microsoft) CR record termination (compatible with MacOS) LF record termination (compatible with Unix) I do not think any non-proprietary standard supports all of those (in the sense of providing an out-of-band indicator regarding which is in use). Solutions which involve rewriting the data into another format are only for people who have never seen a truly large file. ISO-9660, for example can use 32767 volumes to hold a single file, and even though the various DVD formats are limited to less than about 10 GB, the ISO-9660 format can also be used on magnetic disks. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-26 12:48 ` variable length strings Larry Kilgallen @ 2004-10-26 16:11 ` Warren W. Gay VE3WWG 2004-10-26 18:50 ` Björn Persson 0 siblings, 1 reply; 65+ messages in thread From: Warren W. Gay VE3WWG @ 2004-10-26 16:11 UTC (permalink / raw) Larry Kilgallen wrote: > In article <mailman.61.1098789536.10401.comp.lang.ada@ada-france.org>, Marius Amado Alves <amado.alves@netcabo.pt> writes: > > >>This however perpetuates another problem: text files cannot be shared >>between different OSes. > > > The problem of variable length record text files is beyond the reach > of any Ada standard. > > The possibilities VMS must handle are: > > Out-of-band record termination (as codified in ISO-9660 6.10.4) > CRLF record termination (compatible with Microsoft) > CR record termination (compatible with MacOS) > LF record termination (compatible with Unix) Conceptually, someone/OS could also create: LFCR record termination though I don't know of any in the wild. > I do not think any non-proprietary standard supports all of those (in > the sense of providing an out-of-band indicator regarding which is in > use). Agreed. I think it is reasonable that text files be in the correct format for the platform in use. If they are not, then they require conversion. I also accept that from a practical point of view, we all like it to adapt anyway ;-) Warren. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-26 16:11 ` Warren W. Gay VE3WWG @ 2004-10-26 18:50 ` Björn Persson 2004-10-26 19:46 ` Larry Kilgallen 0 siblings, 1 reply; 65+ messages in thread From: Björn Persson @ 2004-10-26 18:50 UTC (permalink / raw) Warren W. Gay VE3WWG wrote: > I think it is reasonable that text files be in the correct > format for the platform in use. If they are not, then they require > conversion. I also accept that from a practical point of view, we > all like it to adapt anyway ;-) The way I see it, the unfortunate reality is that any program that processes text files needs to handle both LF, CR and CR-LF, and maybe NEL too (and record-based files on such platforms I suppose), as well as both presence and absence of a line break at the end of the last line. In the Internet era it's not possible to keep all your files in one format. In the IO package for EAstrings I let the programmer configure the line break characters for each file. By default it uses the platform's convention on output and recognizes LF, CR, CR-LF and NEL on input. -- Björn Persson PGP key A88682FD omb jor ers @sv ge. r o.b n.p son eri nu ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-26 18:50 ` Björn Persson @ 2004-10-26 19:46 ` Larry Kilgallen 0 siblings, 0 replies; 65+ messages in thread From: Larry Kilgallen @ 2004-10-26 19:46 UTC (permalink / raw) In article <n0xfd.7175$d5.60027@newsb.telia.net>, =?ISO-8859-1?Q?Bj=F6rn_Persson?= <spam-away@nowhere.nil> writes: > Warren W. Gay VE3WWG wrote: > >> I think it is reasonable that text files be in the correct >> format for the platform in use. If they are not, then they require >> conversion. I also accept that from a practical point of view, we >> all like it to adapt anyway ;-) > > The way I see it, the unfortunate reality is that any program that=20 > processes text files needs to handle both LF, CR and CR-LF, and maybe=20 > NEL too (and record-based files on such platforms I suppose), as well as = > both presence and absence of a line break at the end of the last line.=20 VAX/DEC/Compaq/HP Ada on VMS (and presumably GNAT on VMS) have that under control just by making the operating system call that takes care of such differences. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 0:06 ` Randy Brukardt 2004-10-26 1:53 ` Larry Kilgallen @ 2004-10-26 8:43 ` Jean-Pierre Rosen 2004-10-26 13:15 ` Martin Krischik 2004-10-26 17:46 ` Jeffrey Carter 2 siblings, 1 reply; 65+ messages in thread From: Jean-Pierre Rosen @ 2004-10-26 8:43 UTC (permalink / raw) Randy Brukardt a écrit : > My opinion is that GNAT is wrong in that case. A.10(7) makes it quite clear > that you can't have a file terminator without a line and page terminator in > front of it. More precisely: a file that doesn't end with a line/page terminator is improperly formatted. > > I vaguely recall having argued this with Robert Dewar, and I think that they > had a different interpretation, based on the idea that a file with a missing > CR/LF is incorrect for use with Text_IO. I hope I misremember that, because > it is stupid (even if it is logically correct) as it essentially says that > you can't read outside generated text files with Text_IO (you can't know > whether the file has CR/LFs as required). > > But I can understand why they wouldn't want to do this properly, because it > is a pain to get right, and it saps the performance of Text_IO (since you > have the be prepared to check for implied characters for each one you read). No, it's simpler than that. In all my programs, I simply never check for End_Of_File, I catch End_Error instead. It is simpler in other cases too: if you read numbers, and the file is terminated with blank lines, you can get End_Error even when End_Of_File is false. -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Visit Adalog's web site at http://www.adalog.fr ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 8:43 ` variable lenght strings Jean-Pierre Rosen @ 2004-10-26 13:15 ` Martin Krischik 2004-10-26 17:37 ` Pascal Obry 2004-10-27 12:01 ` Jean-Pierre Rosen 0 siblings, 2 replies; 65+ messages in thread From: Martin Krischik @ 2004-10-26 13:15 UTC (permalink / raw) Jean-Pierre Rosen wrote: > Randy Brukardt a ᅵcrit : > >> My opinion is that GNAT is wrong in that case. A.10(7) makes it quite >> clear that you can't have a file terminator without a line and page >> terminator in front of it. > More precisely: a file that doesn't end with a line/page terminator is > improperly formatted. There is a world beyond Ada and you might like to read files from there too. >> I vaguely recall having argued this with Robert Dewar, and I think that >> they had a different interpretation, based on the idea that a file with a >> missing CR/LF is incorrect for use with Text_IO. I hope I misremember >> that, because it is stupid (even if it is logically correct) as it >> essentially says that you can't read outside generated text files with >> Text_IO (you can't know whether the file has CR/LFs as required). >> >> But I can understand why they wouldn't want to do this properly, because >> it is a pain to get right, and it saps the performance of Text_IO (since >> you have the be prepared to check for implied characters for each one you >> read). > No, it's simpler than that. > > In all my programs, I simply never check for End_Of_File, I catch > End_Error instead. It is simpler in other cases too: if you read > numbers, and the file is terminated with blank lines, you can get > End_Error even when End_Of_File is false. Well you could create a Get_Line with End_Error too. But I like to see where the "easier" part comes into play: ᅵᅵᅵpackageᅵIOᅵᅵᅵᅵᅵᅵrenamesᅵAda.Text_IO; ᅵᅵᅵfunctionᅵGet_Lineᅵ( ᅵᅵᅵᅵᅵᅵFileᅵ:ᅵinᅵIO.File_Type) ᅵᅵᅵreturn ᅵᅵᅵᅵᅵᅵString ᅵᅵᅵis ᅵᅵᅵᅵᅵᅵBufferᅵ:ᅵStringᅵ(1ᅵ..ᅵBufferSize); ᅵᅵᅵᅵᅵᅵLastᅵᅵᅵ:ᅵNatural; ᅵᅵᅵbegin ᅵᅵᅵᅵᅵᅵIO.Get_Lineᅵ( ᅵᅵᅵᅵᅵᅵᅵᅵᅵFileᅵ=>ᅵFile, ᅵᅵᅵᅵᅵᅵᅵᅵᅵItemᅵ=>ᅵBuffer, ᅵᅵᅵᅵᅵᅵᅵᅵᅵLastᅵ=>ᅵLast); ᅵᅵᅵᅵᅵᅵifᅵLastᅵ<ᅵBuffer'Lastᅵthen ᅵᅵᅵᅵᅵᅵᅵᅵᅵreturnᅵBufferᅵ(1ᅵ..ᅵLast); ᅵᅵᅵᅵᅵᅵelsifᅵIO.End_Of_Fileᅵ(File)ᅵthen ᅵᅵᅵᅵᅵᅵᅵᅵᅵreturnᅵBuffer; ᅵᅵᅵᅵᅵᅵelse ᅵᅵᅵᅵᅵᅵᅵᅵᅵreturnᅵBufferᅵ&ᅵGet_Lineᅵ(File); ᅵᅵᅵᅵᅵᅵendᅵif; ᅵᅵᅵendᅵGet_Line; I can see a just as easy - but easier... With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 13:15 ` Martin Krischik @ 2004-10-26 17:37 ` Pascal Obry 2004-10-26 18:07 ` Hyman Rosen 2004-10-26 18:13 ` variable lenght strings Martin Krischik 2004-10-27 12:01 ` Jean-Pierre Rosen 1 sibling, 2 replies; 65+ messages in thread From: Pascal Obry @ 2004-10-26 17:37 UTC (permalink / raw) Martin Krischik <krischik@users.sourceforge.net> writes: > ���function�Get_Line�( > ������File�:�in�IO.File_Type) > ���return > ������String > ���is > ������Buffer�:�String�(1�..�BufferSize); > ������Last���:�Natural; > ���begin > ������IO.Get_Line�( > ���������File�=>�File, > ���������Item�=>�Buffer, > ���������Last�=>�Last); > > ������if�Last�<�Buffer'Last�then > ���������return�Buffer�(1�..�Last); > ������elsif�IO.End_Of_File�(File)�then > ���������return�Buffer; > ������else > ���������return�Buffer�&�Get_Line�(File); ^^^^^^^^^^^^^^^^^^^^^^^^^^ This kind of recursivity is very dangerous and could cause a stack overflow. It is better to use a non recursive version and to store the result into an Unbounded_String for example. PAscal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 17:37 ` Pascal Obry @ 2004-10-26 18:07 ` Hyman Rosen 2004-10-26 20:10 ` Pascal Obry 2004-10-26 18:13 ` variable lenght strings Martin Krischik 1 sibling, 1 reply; 65+ messages in thread From: Hyman Rosen @ 2004-10-26 18:07 UTC (permalink / raw) Pascal Obry wrote: > This kind of recursivity is very dangerous and could cause a stack > overflow. Why is it dangerous? Won't Ada just raise a memory exception? ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 18:07 ` Hyman Rosen @ 2004-10-26 20:10 ` Pascal Obry 2004-10-27 10:26 ` variable length strings Jacob Sparre Andersen 0 siblings, 1 reply; 65+ messages in thread From: Pascal Obry @ 2004-10-26 20:10 UTC (permalink / raw) Hyman Rosen <hyrosen@mail.com> writes: > Pascal Obry wrote: > > This kind of recursivity is very dangerous and could cause a stack > > overflow. > > Why is it dangerous? Won't Ada just raise a memory exception? Because the object is on the stack. This is not a problem of memory but of stack space. A program using too much stack will likely got out of stack space and receive a Program_Error exception. There is no much you can do at this point, in many cases the only solution is to exit-as-soon-as-possible! Such program is creating a security hole anyway... if you know that somebody has used such algorithm just send him (file upload on a Web site for example) a file with a very long line! Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-26 20:10 ` Pascal Obry @ 2004-10-27 10:26 ` Jacob Sparre Andersen 2004-10-27 10:39 ` Pascal Obry ` (4 more replies) 0 siblings, 5 replies; 65+ messages in thread From: Jacob Sparre Andersen @ 2004-10-27 10:26 UTC (permalink / raw) Pascal Obry wrote: > Such program is creating a security hole anyway... if you know that > somebody has used such algorithm just send him (file upload on a Web > site for example) a file with a very long line! Please distinguish between security (unauthorized access) and denial-of-service. And will continuous appending to an Unbounded_String not give the same risks? Greetings, Jacob -- "It's not a question of whose habitat it is, it's a question of how fast you hit it." ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 10:26 ` variable length strings Jacob Sparre Andersen @ 2004-10-27 10:39 ` Pascal Obry 2004-10-27 11:47 ` Larry Kilgallen ` (3 subsequent siblings) 4 siblings, 0 replies; 65+ messages in thread From: Pascal Obry @ 2004-10-27 10:39 UTC (permalink / raw) Jacob Sparre Andersen <sparre@nbi.dk> writes: > And will continuous appending to an Unbounded_String not give the same > risks? Probably but a program has certainly lot more heap space than stack space. And if a chunk of memory can't be allocated you get a Storage_Error exception. At this point the program can still try to recover (the stack being clean) by calling some clean-up routines. Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 10:26 ` variable length strings Jacob Sparre Andersen 2004-10-27 10:39 ` Pascal Obry @ 2004-10-27 11:47 ` Larry Kilgallen 2004-10-28 7:18 ` Jacob Sparre Andersen 2004-10-27 11:50 ` Larry Kilgallen ` (2 subsequent siblings) 4 siblings, 1 reply; 65+ messages in thread From: Larry Kilgallen @ 2004-10-27 11:47 UTC (permalink / raw) In article <rlssm80bgp2.fsf_-_@jacob.crs4.it>, Jacob Sparre Andersen <sparre@nbi.dk> writes: > Please distinguish between security (unauthorized access) and > denial-of-service. Since the time of the Orange Book, security has long been divided into three segments in discussions: Confidentiality Integrity Availability Denial-of-service issues clearly fall under Availability. Unauthorized access is just a tiny part of Confidentiality. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 11:47 ` Larry Kilgallen @ 2004-10-28 7:18 ` Jacob Sparre Andersen 0 siblings, 0 replies; 65+ messages in thread From: Jacob Sparre Andersen @ 2004-10-28 7:18 UTC (permalink / raw) Larry Kilgallen wrote: > In article <rlssm80bgp2.fsf_-_@jacob.crs4.it>, Jacob Sparre Andersen > <sparre@nbi.dk> writes: > > Please distinguish between security (unauthorized access) and > > denial-of-service. > > Since the time of the Orange Book, security has long been divided > into three segments in discussions: > > Confidentiality > Integrity > Availability > > Denial-of-service issues clearly fall under Availability. > Unauthorized access is just a tiny part of Confidentiality. I stand corrected, apologise to Pascal, and go to the library to have a look at the �Orange Book� (what's its real title?). Jacob -- "simply because no one had discovered a cure for the universe as a whole - or rather the only one that did exist had been abolished" ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 10:26 ` variable length strings Jacob Sparre Andersen 2004-10-27 10:39 ` Pascal Obry 2004-10-27 11:47 ` Larry Kilgallen @ 2004-10-27 11:50 ` Larry Kilgallen [not found] ` <uwtxcla1n.fsf@obry.Organization: LJK Software <PTzuwe3GsIg6@eisner.encompasserve.org> 2004-10-28 10:31 ` Larry Kilgallen 4 siblings, 0 replies; 65+ messages in thread From: Larry Kilgallen @ 2004-10-27 11:50 UTC (permalink / raw) In article <uwtxcla1n.fsf@obry.org>, Pascal Obry <pascal@obry.org> writes: > > Jacob Sparre Andersen <sparre@nbi.dk> writes: > >> And will continuous appending to an Unbounded_String not give the same >> risks? > > Probably but a program has certainly lot more heap space than stack space. Your "certainly" is misplaced since you do not restrict your claim to a particular environment or program. On VMS (even VAX) the stack space for the main DEC Ada task is limited to roughly 1 Gigabyte (minus some overhead). The heap space is limited to the same size, minus the size of the program. As programs get larger the availability of stack space over heap space grows. ^ permalink raw reply [flat|nested] 65+ messages in thread
[parent not found: <uwtxcla1n.fsf@obry.Organization: LJK Software <PTzuwe3GsIg6@eisner.encompasserve.org>]
* Re: variable length strings [not found] ` <uwtxcla1n.fsf@obry.Organization: LJK Software <PTzuwe3GsIg6@eisner.encompasserve.org> @ 2004-10-27 12:12 ` Samuel Tardieu 2004-10-27 12:58 ` Pascal Obry 2004-10-27 13:04 ` Pascal Obry 1 sibling, 1 reply; 65+ messages in thread From: Samuel Tardieu @ 2004-10-27 12:12 UTC (permalink / raw) >>>>> "Larry" == Larry Kilgallen <Kilgallen@SpamCop.net> writes: Larry> In article <uwtxcla1n.fsf@obry.org>, Pascal Obry Larry> <pascal@obry.org> writes: >> Probably but a program has certainly lot more heap space than >> stack space. Larry> Your "certainly" is misplaced since you do not restrict your Larry> claim to a particular environment or program. Pascal was probably thinking about multi-tasking programs, where the default stack size per task is usually small while the heap is generally limited only by the available memory. Sam -- Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/sam ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 12:12 ` Samuel Tardieu @ 2004-10-27 12:58 ` Pascal Obry 0 siblings, 0 replies; 65+ messages in thread From: Pascal Obry @ 2004-10-27 12:58 UTC (permalink / raw) Samuel Tardieu <sam@rfc1149.net> writes: > Pascal was probably thinking about multi-tasking programs, where the > default stack size per task is usually small while the heap is > generally limited only by the available memory. Yes. Thanks for pointing this. Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings [not found] ` <uwtxcla1n.fsf@obry.Organization: LJK Software <PTzuwe3GsIg6@eisner.encompasserve.org> 2004-10-27 12:12 ` Samuel Tardieu @ 2004-10-27 13:04 ` Pascal Obry 2004-10-27 14:54 ` Dmitry A. Kazakov 1 sibling, 1 reply; 65+ messages in thread From: Pascal Obry @ 2004-10-27 13:04 UTC (permalink / raw) Kilgallen@SpamCop.net (Larry Kilgallen) writes: > Your "certainly" is misplaced since you do not restrict your claim to > a particular environment or program. I don't know all of them :) And since the goal is to develop programs that are *safe* (whatever it means for you) I think that such Get_Line implementation should be avoided. Moreover returning unconstraint objects on the stack uses lot of stack space (ok, this depends on the implementation). Now you are free to choose the implementation you like :) I will never accept such Get_Line implementation, that's all! Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 13:04 ` Pascal Obry @ 2004-10-27 14:54 ` Dmitry A. Kazakov 2004-10-27 16:38 ` Pascal Obry 0 siblings, 1 reply; 65+ messages in thread From: Dmitry A. Kazakov @ 2004-10-27 14:54 UTC (permalink / raw) On 27 Oct 2004 15:04:31 +0200, Pascal Obry wrote: > Kilgallen@SpamCop.net (Larry Kilgallen) writes: > >> Your "certainly" is misplaced since you do not restrict your claim to >> a particular environment or program. > > I don't know all of them :) And since the goal is to develop programs that > are *safe* (whatever it means for you) I think that such Get_Line > implementation should be avoided. Moreover returning unconstraint objects on > the stack uses lot of stack space (ok, this depends on the > implementation). But the existing Get_Line does not reaches the goal either. Normally it is used with the buffer allocated on the stack. So it is the stack again. Moreover, differently to the "unsafe" version you are forced to allocate more stack than actually needed, to read the longest possible line. Where that upper limit is quite often undeterminable: "as much as the computer can". > Now you are free to choose the implementation you like :) I > will never accept such Get_Line implementation, that's all! Huh, better to have something that works in 99% cases than to face a global memory optimization problem. (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 14:54 ` Dmitry A. Kazakov @ 2004-10-27 16:38 ` Pascal Obry 2004-10-28 8:14 ` Dmitry A. Kazakov 0 siblings, 1 reply; 65+ messages in thread From: Pascal Obry @ 2004-10-27 16:38 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > But the existing Get_Line does not reaches the goal either. Normally it is > used with the buffer allocated on the stack. So it is the stack again. That's wrong! procedure Get_Line(Item : out String; Last : out Natural); The buffer is bounded in this case, it's up to you to read a chunk of data (using a small buffer on the stack) and do whatever is needed with it. So I see not problem with the standard Get_Line. I never said that you can't use the stack, just that using a buggy Get_Line implementation as proposed here could heat too much stack space and is therefore unsafe. Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 16:38 ` Pascal Obry @ 2004-10-28 8:14 ` Dmitry A. Kazakov 2004-10-28 8:49 ` Pascal Obry 0 siblings, 1 reply; 65+ messages in thread From: Dmitry A. Kazakov @ 2004-10-28 8:14 UTC (permalink / raw) On 27 Oct 2004 18:38:29 +0200, Pascal Obry wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> But the existing Get_Line does not reaches the goal either. Normally it is >> used with the buffer allocated on the stack. So it is the stack again. > > That's wrong! > > procedure Get_Line(Item : out String; Last : out Natural); > > The buffer is bounded in this case, it's up to you to read a chunk of data > (using a small buffer on the stack) and do whatever is needed with it. So I > see not problem with the standard Get_Line. You (Get_Line) just push the problem to the user, who will write: declare Buffer : String (1..?); Length : Integer; begin Get_Line (Buffer, Length); 1) Buffer is on the stack. 2) Its upper bound is unknown except for very rare cases. The requirements usually as helpful as "it should work with reasonable files". Go figure out the upper bound! As for chunks of data, this is well another story. Note, if the parsing methods allow arbitrary splitting the lines <=> it can work with character stream <=> you need no Get_Line, the appropriate method is: procedure Get(Item : out Character); > I never said that you can't use > the stack, just that using a buggy Get_Line implementation as proposed here > could heat too much stack space and is therefore unsafe. I agree that it is a problem, but it is not the Get_Line's one. It is a more general language issue, which probably should be answered in the future. We cannot just dismiss T'Class, unconstrained containers etc. An ability to deal with them (on the stack) is quite important. It is also a question what compromises safety more: use of pointers or potential stack overflow. For large projects, I would say it is definitively pointers. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-28 8:14 ` Dmitry A. Kazakov @ 2004-10-28 8:49 ` Pascal Obry 2004-10-28 9:06 ` Dmitry A. Kazakov 0 siblings, 1 reply; 65+ messages in thread From: Pascal Obry @ 2004-10-28 8:49 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > You (Get_Line) just push the problem to the user, who will write: > > declare > Buffer : String (1..?); > Length : Integer; > begin > Get_Line (Buffer, Length); > > 1) Buffer is on the stack. 2) Its upper bound is unknown except for very > rare cases. The requirements usually as helpful as "it should work with > reasonable files". Go figure out the upper bound! You missed it ! Please have a look at the Get_Line documentation. Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-28 8:49 ` Pascal Obry @ 2004-10-28 9:06 ` Dmitry A. Kazakov 2004-10-28 16:07 ` Pascal Obry 0 siblings, 1 reply; 65+ messages in thread From: Dmitry A. Kazakov @ 2004-10-28 9:06 UTC (permalink / raw) On 28 Oct 2004 10:49:14 +0200, Pascal Obry wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> You (Get_Line) just push the problem to the user, who will write: >> >> declare >> Buffer : String (1..?); >> Length : Integer; >> begin >> Get_Line (Buffer, Length); >> >> 1) Buffer is on the stack. 2) Its upper bound is unknown except for very >> rare cases. The requirements usually as helpful as "it should work with >> reasonable files". Go figure out the upper bound! > > You missed it ! Please have a look at the Get_Line documentation. What have I missed? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-28 9:06 ` Dmitry A. Kazakov @ 2004-10-28 16:07 ` Pascal Obry 2004-10-28 22:05 ` Jeffrey Carter 2004-10-29 7:42 ` Dmitry A. Kazakov 0 siblings, 2 replies; 65+ messages in thread From: Pascal Obry @ 2004-10-28 16:07 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > > You missed it ! Please have a look at the Get_Line documentation. > > What have I missed? That when there is nothing more to read Last is set to 0. So I don't see the problem with Get_Line. You use a small buffer on the stack, and read chunk of data at a time. You are free to write those data where you want in memory or on disk or ... Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-28 16:07 ` Pascal Obry @ 2004-10-28 22:05 ` Jeffrey Carter 2004-10-28 22:41 ` Randy Brukardt 2004-10-29 7:42 ` Dmitry A. Kazakov 1 sibling, 1 reply; 65+ messages in thread From: Jeffrey Carter @ 2004-10-28 22:05 UTC (permalink / raw) More FWIW: I implemented a binding to the C function fgets, which behaves similarly to Ada.Text_IO.Get_Line (stops at end of buffer or end of line; in latter case, skips line terminator), and implemented a Get_Line function using it. It exhibits the same behavior as a Get_Line function using Ada.Text_IO.Get_Line for the case of a last line that is not properly terminated and is a multiple of the buffer length. Win98/GNAT 3.15p. -- Jeff Carter "My mind is a raging torrent, flooded with rivulets of thought, cascading into a waterfall of creative alternatives." Blazing Saddles 89 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-28 22:05 ` Jeffrey Carter @ 2004-10-28 22:41 ` Randy Brukardt 2004-10-29 1:11 ` Jeffrey Carter 0 siblings, 1 reply; 65+ messages in thread From: Randy Brukardt @ 2004-10-28 22:41 UTC (permalink / raw) "Jeffrey Carter" <spam@spam.com> wrote in message news:E2egd.10071$KJ6.6647@newsread1.news.pas.earthlink.net... > More FWIW: I implemented a binding to the C function fgets, which > behaves similarly to Ada.Text_IO.Get_Line (stops at end of buffer or end > of line; in latter case, skips line terminator), and implemented a > Get_Line function using it. It exhibits the same behavior as a Get_Line > function using Ada.Text_IO.Get_Line for the case of a last line that is > not properly terminated and is a multiple of the buffer length. > > Win98/GNAT 3.15p. C is broken so Ada should be too? That makes *no* sense. For the record, Janus/Ada inserts a (single) implied line terminator at the end of a file if there is not one explicitly there. So the OP's technique will work without any headstanding. Note that handling End_Error provides no help in this case, because doing so would cause the last line to be discarded (if there was no implicit line terminator). GNAT's implementation may be technically correct, but an implementation that doesn't allow reading the last line of a file without standing on your head is (practically) broken IMHO. How many people know to worry about this? Randy. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-28 22:41 ` Randy Brukardt @ 2004-10-29 1:11 ` Jeffrey Carter 0 siblings, 0 replies; 65+ messages in thread From: Jeffrey Carter @ 2004-10-29 1:11 UTC (permalink / raw) Randy Brukardt wrote: > > C is broken so Ada should be too? That makes *no* sense. It was certainly not my intention to imply that; I'm merely cataloguing the behavior of different systems. So far I've tried GNAT, ObjectAda, and gcc C. I have an old Janus/Ada 83 for DOS somewhere, but I'll take your word that it behaves differently. > Huh? A null line without a line terminator would be indistinguishable > from a line terminator at the end of a file. So it is perfectly > reasonable for an implementation to treat this as reading past the > end of a file (Janus/Ada certainly does too). Indeed, I'd argue that > it is impossible for there to be a null line without a line > terminator at the end of a file. I think we violently agree about this. > The case I'm talking about is when the last line is *not* null and > there is no explicit line terminator. In that case, the > implementation should provide an implicit line terminator, as the > logical view of a file is that it is always there (see A.10(7)), and > (IMHO) it is unreasonable to refuse to properly process a file that > is missing one. And about this, too. -- Jeff Carter "In the frozen land of Nador they were forced to eat Robin's minstrels, and there was much rejoicing." Monty Python & the Holy Grail 70 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-28 16:07 ` Pascal Obry 2004-10-28 22:05 ` Jeffrey Carter @ 2004-10-29 7:42 ` Dmitry A. Kazakov 1 sibling, 0 replies; 65+ messages in thread From: Dmitry A. Kazakov @ 2004-10-29 7:42 UTC (permalink / raw) On 28 Oct 2004 18:07:24 +0200, Pascal Obry wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >>> You missed it ! Please have a look at the Get_Line documentation. >> >> What have I missed? > > That when there is nothing more to read Last is set to 0. How do you know that there *will* be nothing more, when you allocate the buffer? > So I don't see the > problem with Get_Line. You use a small buffer on the stack, and read chunk of > data at a time. Re-read my post. If you *can* do it, then you need no Get_Line. > You are free to write those data where you want in memory or > on disk or ... The issue is: what is the best way to get one physical line in one *contiguous* piece of memory. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable length strings 2004-10-27 10:26 ` variable length strings Jacob Sparre Andersen ` (3 preceding siblings ...) [not found] ` <uwtxcla1n.fsf@obry.Organization: LJK Software <PTzuwe3GsIg6@eisner.encompasserve.org> @ 2004-10-28 10:31 ` Larry Kilgallen 4 siblings, 0 replies; 65+ messages in thread From: Larry Kilgallen @ 2004-10-28 10:31 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1164 bytes --] In article <rlsoeinb9ag.fsf@jacob.crs4.it>, Jacob Sparre Andersen <sparre@nbi.dk> writes: > Larry Kilgallen wrote: >> In article <rlssm80bgp2.fsf_-_@jacob.crs4.it>, Jacob Sparre Andersen >> <sparre@nbi.dk> writes: > >> > Please distinguish between security (unauthorized access) and >> > denial-of-service. >> >> Since the time of the Orange Book, security has long been divided >> into three segments in discussions: >> >> Confidentiality >> Integrity >> Availability >> >> Denial-of-service issues clearly fall under Availability. >> Unauthorized access is just a tiny part of Confidentiality. > > I stand corrected, apologise to Pascal, and go to the library to have > a look at the �Orange Book� (what's its real title?). Reverse engineering "TCSEC", I believe it is "Trusted Computer Security Evaluation Criteria". But I did not promise those exact words are in the Orange Book, just that the _timing_ of that terminology matched that of the Orange Book :-) While those words were widely used at the time, NSA employees might have felt it inappropriate to use three terms with that acronym. But it was the way the rest of us remembered them. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 17:37 ` Pascal Obry 2004-10-26 18:07 ` Hyman Rosen @ 2004-10-26 18:13 ` Martin Krischik 1 sibling, 0 replies; 65+ messages in thread From: Martin Krischik @ 2004-10-26 18:13 UTC (permalink / raw) Pascal Obry wrote: > > Martin Krischik <krischik@users.sourceforge.net> writes: > >> functionᅵGet_Lineᅵ( >> Fileᅵ:ᅵinᅵIO.File_Type) >> return >> String >> is >> Bufferᅵ:ᅵStringᅵ(1ᅵ..ᅵBufferSize); >> Lastᅵᅵᅵ:ᅵNatural; >> begin >> IO.Get_Lineᅵ( >> Fileᅵ=>ᅵFile, >> Itemᅵ=>ᅵBuffer, >> Lastᅵ=>ᅵLast); >> >> ifᅵLastᅵ<ᅵBuffer'Lastᅵthen >> returnᅵBufferᅵ(1ᅵ..ᅵLast); >> elsifᅵIO.End_Of_Fileᅵ(File)ᅵthen >> returnᅵBuffer; >> else >> returnᅵBufferᅵ&ᅵGet_Lineᅵ(File); > ^^^^^^^^^^^^^^^^^^^^^^^^^^ > > This kind of recursivity is very dangerous and could cause a stack > overflow. It is better to use a non recursive version and to store the > result into an Unbounded_String for example. In fact I have got an non recursive version returning an Unbounded_String as well: ᅵᅵᅵfunctionᅵGet_Lineᅵ( ᅵᅵᅵᅵᅵᅵFileᅵ:ᅵinᅵIO.File_Type) ᅵᅵᅵreturn ᅵᅵᅵᅵᅵᅵS_U.Unbounded_String ᅵᅵᅵis ᅵᅵᅵᅵᅵᅵRetvalᅵ:ᅵS_U.Unbounded_Stringᅵ:=ᅵS_U.Null_Unbounded_String; ᅵᅵᅵᅵᅵᅵItemᅵᅵᅵ:ᅵStringᅵ(1ᅵ..ᅵBufferSize); ᅵᅵᅵᅵᅵᅵLastᅵᅵᅵ:ᅵNatural; ᅵᅵᅵbegin ᅵᅵᅵᅵᅵᅵGetWholeLineᅵ: ᅵᅵᅵᅵᅵᅵloop ᅵᅵᅵᅵᅵᅵᅵᅵᅵIO.Get_Lineᅵ( ᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵFileᅵ=>ᅵFile, ᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵItemᅵ=>ᅵItem, ᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵLastᅵ=>ᅵLast); ᅵᅵᅵᅵᅵᅵᅵᅵᅵS_U.Appendᅵ( ᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵSourceᅵᅵᅵ=>ᅵRetval, ᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵNew_Itemᅵ=>ᅵItemᅵ(1ᅵ..ᅵLast)); ᅵᅵᅵᅵᅵᅵᅵᅵᅵexitᅵGetWholeLineᅵwhenᅵLastᅵ<ᅵItem'Last ᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵᅵorᅵᅵᅵIO.End_Of_Fileᅵ(File); ᅵᅵᅵᅵᅵᅵendᅵloopᅵGetWholeLine; ᅵᅵᅵᅵᅵᅵreturnᅵRetval; ᅵᅵᅵendᅵGet_Line; With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 13:15 ` Martin Krischik 2004-10-26 17:37 ` Pascal Obry @ 2004-10-27 12:01 ` Jean-Pierre Rosen 1 sibling, 0 replies; 65+ messages in thread From: Jean-Pierre Rosen @ 2004-10-27 12:01 UTC (permalink / raw) Martin Krischik a écrit : > Jean-Pierre Rosen wrote: >>In all my programs, I simply never check for End_Of_File, I catch >>End_Error instead. It is simpler in other cases too: if you read >>numbers, and the file is terminated with blank lines, you can get >>End_Error even when End_Of_File is false. > > > Well you could create a Get_Line with End_Error too. But I like to see where > the "easier" part comes into play: > [snip] I think you missed the point; I was talking about reading *numbers*. In that case, End_Of_File is of no use, because Get will skip any number of line terminators, and may well hit an End_Of_File. Catching End_Of_File is a lot easier than skipping all the line terminators before reading a number -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Visit Adalog's web site at http://www.adalog.fr ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 0:06 ` Randy Brukardt 2004-10-26 1:53 ` Larry Kilgallen 2004-10-26 8:43 ` variable lenght strings Jean-Pierre Rosen @ 2004-10-26 17:46 ` Jeffrey Carter 2004-10-28 22:50 ` Randy Brukardt 2 siblings, 1 reply; 65+ messages in thread From: Jeffrey Carter @ 2004-10-26 17:46 UTC (permalink / raw) Randy Brukardt wrote: > My opinion is that GNAT is wrong in that case. A.10(7) makes it quite > clear that you can't have a file terminator without a line and page > terminator in front of it. Shouldn't that be "... without an implied line ..."? Clearly text files from external sources can lack the explicit terminators, or we wouldn't be having this discussion. FWIW, ObjectAda 7.2.2 SE gives the same behavior. Get_Line successfully reads a non-null line shorter than the string at the end of the file without the line-terminator characters, but fails on a null line at the same place. I can see the logic of that: If you've just skipped the line terminator of the last line, you have the same situation, and an attempt to read should raise End_Error. To get this correct, you have to keep track of what you just read. If it's a line or page terminator, you raise End_Error; if not, you return a null string. Is there any chance the ARG could rule on this, one way or another? Also FWIW, AFAIK PragmARC.Get_Line has been used successfully since 1991 without ever encountering this situation. -- Jeff Carter "Help! Help! I'm being repressed!" Monty Python & the Holy Grail 67 ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-26 17:46 ` Jeffrey Carter @ 2004-10-28 22:50 ` Randy Brukardt 2004-10-28 23:01 ` Larry Kilgallen 2004-10-29 8:48 ` Dale Stanbrough 0 siblings, 2 replies; 65+ messages in thread From: Randy Brukardt @ 2004-10-28 22:50 UTC (permalink / raw) "Jeffrey Carter" <spam@spam.com> wrote in message news:a4wfd.3107$kM.1044@newsread3.news.pas.earthlink.net... > Randy Brukardt wrote: > > > My opinion is that GNAT is wrong in that case. A.10(7) makes it quite > > clear that you can't have a file terminator without a line and page > > terminator in front of it. > > Shouldn't that be "... without an implied line ..."? Clearly text files > from external sources can lack the explicit terminators, or we wouldn't > be having this discussion. > > FWIW, ObjectAda 7.2.2 SE gives the same behavior. Get_Line successfully > reads a non-null line shorter than the string at the end of the file > without the line-terminator characters, but fails on a null line at the > same place. I can see the logic of that: If you've just skipped the line > terminator of the last line, you have the same situation, and an attempt > to read should raise End_Error. Huh? A null line without a line terminator would be indistinguishable from a line terminator at the end of a file. So it is perfectly reasonable for an implementation to treat this as reading past the end of a file (Janus/Ada certainly does too). Indeed, I'd argue that it is impossible for there to be a null line without a line terminator at the end of a file. The case I'm talking about is when the last line is *not* null and there is no explicit line terminator. In that case, the implementation should provide an implicit line terminator, as the logical view of a file is that it is always there (see A.10(7)), and (IMHO) it is unreasonable to refuse to properly process a file that is missing one. But I don't think that there is anything that the ARG can say here, because what is actually in a file is not defined by the language, and an implementor can simply say that the file is misformatted. That may be bad for users, but it certainly fits within the language. Note that implementations have to have implicit page terminators at the end of the file (putting in explicit ones would be awful, and there are ACATS tests which check that the one at the end of the file actually exists), so supporting implicit line terminators isn't that much extra work. Randy. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-28 22:50 ` Randy Brukardt @ 2004-10-28 23:01 ` Larry Kilgallen 2004-10-29 21:52 ` Randy Brukardt 2004-10-29 8:48 ` Dale Stanbrough 1 sibling, 1 reply; 65+ messages in thread From: Larry Kilgallen @ 2004-10-28 23:01 UTC (permalink / raw) In article <o-CdnddJwfPP6hzcRVn-pw@megapath.net>, "Randy Brukardt" <randy@rrsoftware.com> writes: > Huh? A null line without a line terminator would be indistinguishable from a > line terminator at the end of a file. So it is perfectly reasonable for an > implementation to treat this as reading past the end of a file (Janus/Ada > certainly does too). Indeed, I'd argue that it is impossible for there to be > a null line without a line terminator at the end of a file. So on this general subject, how do implementations which use a special character for line termination handle the situation where that character is in the middle of a line ? Is there a special escape character to mean "the next character is real" ? Is that special escape character the same for all implementations ? ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-28 23:01 ` Larry Kilgallen @ 2004-10-29 21:52 ` Randy Brukardt 0 siblings, 0 replies; 65+ messages in thread From: Randy Brukardt @ 2004-10-29 21:52 UTC (permalink / raw) "Larry Kilgallen" <Kilgallen@SpamCop.net> wrote in message news:39q24nDZNOOB@eisner.encompasserve.org... > In article <o-CdnddJwfPP6hzcRVn-pw@megapath.net>, "Randy Brukardt" <randy@rrsoftware.com> writes: > > > Huh? A null line without a line terminator would be indistinguishable from a > > line terminator at the end of a file. So it is perfectly reasonable for an > > implementation to treat this as reading past the end of a file (Janus/Ada > > certainly does too). Indeed, I'd argue that it is impossible for there to be > > a null line without a line terminator at the end of a file. > > So on this general subject, how do implementations which use a special > character for line termination handle the situation where that character > is in the middle of a line ? Is there a special escape character to > mean "the next character is real" ? Is that special escape character > the same for all implementations ? There's no requirement that the line terminator character(s) (if that's how its done) be allowed in the middle of a line. A.10(8) says that the effect of Get or Put of control characters other than TAB is not specified by the language. So Put(LF) can be read as a line terminator, or raise Program_Error, or whatever. Randy. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-28 22:50 ` Randy Brukardt 2004-10-28 23:01 ` Larry Kilgallen @ 2004-10-29 8:48 ` Dale Stanbrough 2004-10-29 9:11 ` Larry Kilgallen 1 sibling, 1 reply; 65+ messages in thread From: Dale Stanbrough @ 2004-10-29 8:48 UTC (permalink / raw) Randy Brukardt wrote: > Note that implementations have to have implicit page terminators at the end > of the file (putting in explicit ones would be awful, and there are ACATS > tests which check that the one at the end of the file actually exists), so > supporting implicit line terminators isn't that much extra work. I'm surprised that we didn't get another Text_IO package in Ada0Y which would get rid of all the crufty old stuff and create a much faster package. Ada.Chars_IO or similar. Dale -- dstanbro@spam.o.matic.bigpond.net.au ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-29 8:48 ` Dale Stanbrough @ 2004-10-29 9:11 ` Larry Kilgallen 0 siblings, 0 replies; 65+ messages in thread From: Larry Kilgallen @ 2004-10-29 9:11 UTC (permalink / raw) In article <MrNoSpam-4944E7.18485729102004@news-server.bigpond.net.au>, Dale Stanbrough <MrNoSpam@bigpoop.net.au> writes: > Randy Brukardt wrote: > > >> Note that implementations have to have implicit page terminators at the end >> of the file (putting in explicit ones would be awful, and there are ACATS >> tests which check that the one at the end of the file actually exists), so >> supporting implicit line terminators isn't that much extra work. > > I'm surprised that we didn't get another Text_IO package in Ada0Y > which would get rid of all the crufty old stuff and create a much > faster package. Ada.Chars_IO or similar. Whether something different would be faster or not depends on the underlying OS file system. The record boundaries come "for free" in RMS. ^ permalink raw reply [flat|nested] 65+ messages in thread
* Why these "Drop" parameters? (was: variable lenght strings) 2004-10-22 11:11 ` Martin Dowie 2004-10-24 15:43 ` Martin Krischik @ 2004-10-24 18:38 ` Björn Persson 2004-10-26 0:13 ` Randy Brukardt 1 sibling, 1 reply; 65+ messages in thread From: Björn Persson @ 2004-10-24 18:38 UTC (permalink / raw) Martin Dowie wrote: > Being added in Ada2005, see Ada.Text_IO.Unbounded_IO in > http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT?rev=1.12 Reading that file I see these declarations: procedure Set_Bounded_String (Target : out Bounded_String; Source : in String; Drop : in Truncation := Error); function Bounded_Slice (Source : in Bounded_String; Low : in Positive; High : in Natural; Drop : in Truncation := Error) return Bounded_String; procedure Bounded_Slice (Source : in Bounded_String; Target : out Bounded_String; Low : in Positive; High : in Natural; Drop : in Truncation := Error); procedure Set_Unbounded_String (Target : out Unbounded_String; Source : in String; Drop : in Truncation := Error); function Unbounded_Slice (Source : in Unbounded_String; Low : in Positive; High : in Natural; Drop : in Truncation := Error) return Unbounded_String; procedure Unbounded_Slice (Source : in Unbounded_String; Target : out Unbounded_String; Low : in Positive; High : in Natural; Drop : in Truncation := Error); For Set_Bounded_String it is quite obvious that Drop specifies what should happen if Source is longer than the maximum length of Target, but can anyone explain what all the other "Drop" parameters are for? In the case of Bounded_Slice, shouldn't a slice of Source always fit in Target? Aren't they the same type, with the same max length? Unbounded strings are supposed to be unbounded. Their only limit should be the available memory, no? So, are the "Drop" parameters there meant as a way to avoid Storage_Error? -- Björn Persson PGP key A88682FD omb jor ers @sv ge. r o.b n.p son eri nu ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: Why these "Drop" parameters? (was: variable lenght strings) 2004-10-24 18:38 ` Why these "Drop" parameters? (was: variable lenght strings) Björn Persson @ 2004-10-26 0:13 ` Randy Brukardt 2004-11-01 1:02 ` Why these "Drop" parameters? Björn Persson 0 siblings, 1 reply; 65+ messages in thread From: Randy Brukardt @ 2004-10-26 0:13 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 2468 bytes --] I think it is a typo for the Bounded_Slice and Unbounded_Slice routines; nowhere can I find any description of what it means (the text description of these functions never mentions "Drop"). Nor do any of the meeting minutes that I checked. Could you submit your comment to Ada-Comment (e-mail it to ada-comment@ada-auth.org)? We need to get it on the record so this can be fixed. Randy Brukardt ARG Editor. "Bj�rn Persson" <spam-away@nowhere.nil> wrote in message news:lESed.6963$d5.58967@newsb.telia.net... Martin Dowie wrote: > Being added in Ada2005, see Ada.Text_IO.Unbounded_IO in > http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT?rev=1.12 Reading that file I see these declarations: procedure Set_Bounded_String (Target : out Bounded_String; Source : in String; Drop : in Truncation := Error); function Bounded_Slice (Source : in Bounded_String; Low : in Positive; High : in Natural; Drop : in Truncation := Error) return Bounded_String; procedure Bounded_Slice (Source : in Bounded_String; Target : out Bounded_String; Low : in Positive; High : in Natural; Drop : in Truncation := Error); procedure Set_Unbounded_String (Target : out Unbounded_String; Source : in String; Drop : in Truncation := Error); function Unbounded_Slice (Source : in Unbounded_String; Low : in Positive; High : in Natural; Drop : in Truncation := Error) return Unbounded_String; procedure Unbounded_Slice (Source : in Unbounded_String; Target : out Unbounded_String; Low : in Positive; High : in Natural; Drop : in Truncation := Error); For Set_Bounded_String it is quite obvious that Drop specifies what should happen if Source is longer than the maximum length of Target, but can anyone explain what all the other "Drop" parameters are for? In the case of Bounded_Slice, shouldn't a slice of Source always fit in Target? Aren't they the same type, with the same max length? Unbounded strings are supposed to be unbounded. Their only limit should be the available memory, no? So, are the "Drop" parameters there meant as a way to avoid Storage_Error? -- Bj�rn Persson PGP key A88682FD omb jor ers @sv ge. r o.b n.p son eri nu ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: Why these "Drop" parameters? 2004-10-26 0:13 ` Randy Brukardt @ 2004-11-01 1:02 ` Björn Persson 2004-11-01 19:59 ` Randy Brukardt 0 siblings, 1 reply; 65+ messages in thread From: Björn Persson @ 2004-11-01 1:02 UTC (permalink / raw) Randy Brukardt wrote: > Could you submit your comment to Ada-Comment (e-mail it to > ada-comment@ada-auth.org)? We need to get it on the record so this can be > fixed. Well, I got around to subscribe to Ada-Comment today, and was going to send the question, but I see you've done it already. (I've been rather busy this week.) -- Björn Persson PGP key A88682FD omb jor ers @sv ge. r o.b n.p son eri nu ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: Why these "Drop" parameters? 2004-11-01 1:02 ` Why these "Drop" parameters? Björn Persson @ 2004-11-01 19:59 ` Randy Brukardt 0 siblings, 0 replies; 65+ messages in thread From: Randy Brukardt @ 2004-11-01 19:59 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 710 bytes --] Yes, I was afraid that it would get lost, so I sent it myself after noting that you hadn't done so. Randy. "Bj�rn Persson" <spam-away@nowhere.nil> wrote in message news:hWfhd.7622$d5.63812@newsb.telia.net... Randy Brukardt wrote: > Could you submit your comment to Ada-Comment (e-mail it to > ada-comment@ada-auth.org)? We need to get it on the record so this can be > fixed. Well, I got around to subscribe to Ada-Comment today, and was going to send the question, but I see you've done it already. (I've been rather busy this week.) -- Bj�rn Persson PGP key A88682FD omb jor ers @sv ge. r o.b n.p son eri nu ^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: variable lenght strings 2004-10-21 17:52 variable lenght strings fabio de francesco ` (4 preceding siblings ...) 2004-10-22 7:25 ` Martin Krischik @ 2004-10-24 18:57 ` Jeffrey Carter 5 siblings, 0 replies; 65+ messages in thread From: Jeffrey Carter @ 2004-10-24 18:57 UTC (permalink / raw) fabio de francesco wrote: > 1) Is it possible to use Get_Line with Unbounded and/or Bounded > Strings? Not in the standard, but many compilers come with packages to provide this. GNAT, for example, comes with such a package. > 2) If not, how should user input be managed when lines length isn't > known a priori? You can use a function such as PragmARC.Get_Line, based on an Ada Letters article I wrote from 1989. The PragmAda Reusable Components are available from http://home.earthlink.net/~jrcarter010/pragmarc.htm -- Jeff Carter "You cheesy lot of second-hand electric donkey-bottom biters." Monty Python & the Holy Grail 14 ^ permalink raw reply [flat|nested] 65+ messages in thread
end of thread, other threads:[~2004-11-01 19:59 UTC | newest] Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-10-21 17:52 variable lenght strings fabio de francesco 2004-10-21 21:22 ` Martin Dowie 2004-10-21 22:42 ` Marius Amado Alves 2004-10-21 23:14 ` Matthew Heaney 2004-10-22 7:38 ` Martin Krischik 2004-10-22 12:30 ` fabio de francesco 2004-10-22 7:29 ` Martin Krischik 2004-10-22 13:01 ` Matthew Heaney 2004-10-24 15:46 ` Martin Krischik 2004-10-24 19:54 ` Jeffrey Carter 2004-10-24 21:30 ` Larry Kilgallen 2004-10-25 4:02 ` Jeffrey Carter 2004-10-21 23:01 ` Marius Amado Alves 2004-10-21 23:05 ` Stephen Leake 2004-10-22 7:25 ` Martin Krischik 2004-10-22 11:11 ` Martin Dowie 2004-10-24 15:43 ` Martin Krischik 2004-10-24 17:39 ` Martin Dowie 2004-10-24 18:37 ` Björn Persson 2004-10-25 7:30 ` Martin Krischik 2004-10-26 0:06 ` Randy Brukardt 2004-10-26 1:53 ` Larry Kilgallen 2004-10-26 8:49 ` Martin Krischik 2004-10-26 11:18 ` Marius Amado Alves 2004-10-26 12:48 ` variable length strings Larry Kilgallen 2004-10-26 16:11 ` Warren W. Gay VE3WWG 2004-10-26 18:50 ` Björn Persson 2004-10-26 19:46 ` Larry Kilgallen 2004-10-26 8:43 ` variable lenght strings Jean-Pierre Rosen 2004-10-26 13:15 ` Martin Krischik 2004-10-26 17:37 ` Pascal Obry 2004-10-26 18:07 ` Hyman Rosen 2004-10-26 20:10 ` Pascal Obry 2004-10-27 10:26 ` variable length strings Jacob Sparre Andersen 2004-10-27 10:39 ` Pascal Obry 2004-10-27 11:47 ` Larry Kilgallen 2004-10-28 7:18 ` Jacob Sparre Andersen 2004-10-27 11:50 ` Larry Kilgallen [not found] ` <uwtxcla1n.fsf@obry.Organization: LJK Software <PTzuwe3GsIg6@eisner.encompasserve.org> 2004-10-27 12:12 ` Samuel Tardieu 2004-10-27 12:58 ` Pascal Obry 2004-10-27 13:04 ` Pascal Obry 2004-10-27 14:54 ` Dmitry A. Kazakov 2004-10-27 16:38 ` Pascal Obry 2004-10-28 8:14 ` Dmitry A. Kazakov 2004-10-28 8:49 ` Pascal Obry 2004-10-28 9:06 ` Dmitry A. Kazakov 2004-10-28 16:07 ` Pascal Obry 2004-10-28 22:05 ` Jeffrey Carter 2004-10-28 22:41 ` Randy Brukardt 2004-10-29 1:11 ` Jeffrey Carter 2004-10-29 7:42 ` Dmitry A. Kazakov 2004-10-28 10:31 ` Larry Kilgallen 2004-10-26 18:13 ` variable lenght strings Martin Krischik 2004-10-27 12:01 ` Jean-Pierre Rosen 2004-10-26 17:46 ` Jeffrey Carter 2004-10-28 22:50 ` Randy Brukardt 2004-10-28 23:01 ` Larry Kilgallen 2004-10-29 21:52 ` Randy Brukardt 2004-10-29 8:48 ` Dale Stanbrough 2004-10-29 9:11 ` Larry Kilgallen 2004-10-24 18:38 ` Why these "Drop" parameters? (was: variable lenght strings) Björn Persson 2004-10-26 0:13 ` Randy Brukardt 2004-11-01 1:02 ` Why these "Drop" parameters? Björn Persson 2004-11-01 19:59 ` Randy Brukardt 2004-10-24 18:57 ` variable lenght strings Jeffrey Carter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox