ben@epmooch.UUCP (Rev. Ben A. Mesander) (02/08/91)
>In article <874@cbmger.UUCP> peterk@cbmger.UUCP (Peter Kittel GERMANY) writes: >Now it should be possible to have a set of functions which initialize >a memory area and allocate dynamically all my strings in that space >just as a Basic interpreter does. Plus a good and fast garbage collection. >And plus all the nice string functions that make Basic programming such >a fun. And if you would add further flexibility over the Basic approach, >then one could add dynamic growth of the whole string area, where you >in Basic once and for all must decide for a certain amount by CLEAR. > >So, is there such a beast out there? > Try creative use of the C libraries realloc() function call. >BTW: Converting Basic to C by hand isn't that difficult! Just take any >editor, do some global search and replace (":" --> ";", "IF " --> "if(", >"END IF" --> "}", and so on), and do some recoding on things like >OPEN or WINDOW, and you already have most of the work done. Worse is >it with such simple things like INPUT or INKEY$ :-(. Yes, AND strings. Sounds like you might be able to write a sed, awk, perl, or MicroEMACS program to do most of the grunt work. >-- >Best regards, Dr. Peter Kittel // E-Mail to \\ Only my personal opinions... >Commodore Frankfurt, Germany \X/ {uunet|pyramid|rutgers}!cbmvax!cbmger!peterk -- ben@epmooch.UUCP ben%servalan.UUCP@uokmax.ecn.uoknor.edu {chinet,uokmax}!servalan!epmooch!ben (Ben Mesander) War in gulf: newpath 288 396 216 0 360 arc 288 612 moveto 288 180 lineto 288 396 moveto 136 244 lineto 288 396 moveto 440 244 lineto 36 setlinewidth stroke showpage
peterk@cbmger.UUCP (Peter Kittel GERMANY) (02/09/91)
As a died-in-the-wool user of Basic (yes, AmigaBasic :-), who does also a little in C by porting some of my Basic programs to C, I always find it the most tedious thing to deal with strings. Well, I have that article by Ralph Babel somewhere where he explains which functions in C resemble which Basic string functions. But this doesn't help with the principal problem of declaring and handling of dynamically sized strings. You must know, in AmigaBasic a string can grow as big as 32 KB, and it is absolutely impossible to declare every C string by default with 32 K elements. Now it should be possible to have a set of functions which initialize a memory area and allocate dynamically all my strings in that space just as a Basic interpreter does. Plus a good and fast garbage collection. And plus all the nice string functions that make Basic programming such a fun. And if you would add further flexibility over the Basic approach, then one could add dynamic growth of the whole string area, where you in Basic once and for all must decide for a certain amount by CLEAR. So, is there such a beast out there? BTW: Converting Basic to C by hand isn't that difficult! Just take any editor, do some global search and replace (":" --> ";", "IF " --> "if(", "END IF" --> "}", and so on), and do some recoding on things like OPEN or WINDOW, and you already have most of the work done. Worse is it with such simple things like INPUT or INKEY$ :-(. Yes, AND strings. -- Best regards, Dr. Peter Kittel // E-Mail to \\ Only my personal opinions... Commodore Frankfurt, Germany \X/ {uunet|pyramid|rutgers}!cbmvax!cbmger!peterk
jbickers@templar.actrix.gen.nz (John Bickers) (02/11/91)
Quoted from <874@cbmger.UUCP> by peterk@cbmger.UUCP (Peter Kittel GERMANY): > As a died-in-the-wool user of Basic (yes, AmigaBasic :-), who does > also a little in C by porting some of my Basic programs to C, I always > find it the most tedious thing to deal with strings. Well, I have You mean you don't consider moving character pointers around like crazy fun? :) > Best regards, Dr. Peter Kittel // E-Mail to \\ Only my personal opinions... -- *** John Bickers, TAP, NZAmigaUG. jbickers@templar.actrix.gen.nz *** *** "Patterns multiplying, re-direct our view" - Devo. ***
bernie@metapro.DIALix.oz.au (Bernd Felsche) (02/15/91)
In <874@cbmger.UUCP> peterk@cbmger.UUCP (Peter Kittel GERMANY) writes: >Now it should be possible to have a set of functions which initialize >a memory area and allocate dynamically all my strings in that space >just as a Basic interpreter does. Plus a good and fast garbage collection. >And plus all the nice string functions that make Basic programming such >a fun. And if you would add further flexibility over the Basic approach, >then one could add dynamic growth of the whole string area, where you >in Basic once and for all must decide for a certain amount by CLEAR. >So, is there such a beast out there? This is what I use under UNIX, though it should work under AmigaDOS as well. It doesn't do any garbage collection, but it's fast! Also, there is no mechanism to grow a string, though that should be a bit easier to implement (for somebody else :-)). It works by having a linked list pointing to a cluster of malloc'd memory chunks, the size of which can be "defined" at the start. When addstring() is called, it stores the nominated string in an allocated memory chunks, before returning a pointer to it. If there is insufficient space in existing chunks, then a new one is allocated, along with another linked-list element. If the string to be stored is larger than the nominal chunks size, then it is stored in its own chunk. The bad news is that there is no garbage collection, or indeed code to free up space. See my notes at the end of the listing. I'm relying on malloc'd chunks being cleaned up automatically upon exit. P.S. the missing fatal() and sysfatal() routines do nothing more than displaying the error text somewhere convenient, and exiting with an error condition. ___________________________________space.c_____________________________________ /* * Buffer some strings in dynamically allocated RAM chunks */ #define NULL 0 #include <sys/types.h> #include <string.h> char *malloc(); /* * allocated in ALLOC_SPACE chunks, and expanded * dynamically, if it isn't eno...ugh */ #define ALLOC_SPACE 8000 #define ALLOC_LOW 16 struct p_space { char *free; /* next free space in this chunk */ int avail; /* amount of available space in this chunk*/ struct p_space *next; /* next p_space chunk */ char *stuff; /* this space chunk */ }; static struct p_space *MEMLIST; /* the head of the linked list */ static struct p_space *MEMLAST; /* the head of the mostly - free linked list */ char *addstring(string) char *string; /* text string */ { struct p_space *chunk; int length; char *place; length = strlen(string) + 1; /* remember null! */ if( MEMLIST == NULL ) { /* no space yet allocated */ if( !(MEMLIST = (struct p_space *) malloc(sizeof(struct p_space))) ) sysfatal("cannot allocate space for string"); MEMLIST->avail = (length < ALLOC_SPACE ? ALLOC_SPACE : length); if( !(MEMLIST->stuff = malloc(MEMLIST->avail)) ) sysfatal("cannot allocate chunk"); MEMLIST->free = MEMLIST->stuff; MEMLIST->next = NULL; MEMLAST = MEMLIST; chunk = MEMLAST; } chunk = MEMLAST; /* search for enough free space in any chunk */ while ( length >= chunk->avail && chunk->next ) { if( chunk->avail < ALLOC_LOW ) MEMLAST = chunk->next; /* speedup if low water reached */ chunk = chunk->next; } if( !chunk->next && length >= chunk->avail ) { /* can't find enough space */ if( !(chunk->next = (struct p_space *) malloc(sizeof(struct p_space))) ) sysfatal("cannot allocate space for string"); chunk = chunk->next; chunk->avail = (length < ALLOC_SPACE ? ALLOC_SPACE : length); if( !(chunk->stuff = malloc(chunk->avail)) ) sysfatal("cannot allocate chunk"); chunk->free = chunk->stuff; chunk->next = NULL; } /* copy string to chunk */ place = strcpy(chunk->free, string); if ( place != chunk->free ) fatal("error in string copy"); chunk->free += length; chunk->avail -= length; return(place); } char *delstring(string) char *string; { /* an exercise for the programmer :-) */ } ___________________________________the.end_____________________________________ How's that for some pointers in C? -- _--_|\ Bernd Felsche #include <std/disclaimer.h> / \ Metapro Systems, 328 Albany Highway, Victoria Park, Western Australia \_.--._/ Fax: +61 9 472 3337 Phone: +61 9 362 9355 TZ=WST-8 v E-Mail: bernie@metapro.DIALix.oz.au | bernie@DIALix.oz.au
peterk@cbmger.UUCP (Peter Kittel GERMANY) (02/18/91)
In article <1991Feb15.050640.15436@metapro.DIALix.oz.au> bernie@metapro.DIALix.oz.au (Bernd Felsche) writes: >In <874@cbmger.UUCP> peterk@cbmger.UUCP (Peter Kittel GERMANY) writes: > >>Now it should be possible to have a set of functions which initialize >>a memory area and allocate dynamically all my strings in that space >>just as a Basic interpreter does. Plus a good and fast garbage collection. > >This is what I use under UNIX, though it should work under AmigaDOS as >well. It doesn't do any garbage collection, but it's fast! Also, there >is no mechanism to grow a string, though that should be a bit easier >to implement (for somebody else :-)). > >It works by having a linked list pointing to a cluster of malloc'd >memory chunks, the size of which can be "defined" at the start. Thanks for the code, I'll look into it. Well, being lazy, I already thought about something similar, but the management of all those linked lists together with string growing plus garbage collection really frightens me. Now: How about an approach similar to the one AmigaBasic takes it? It has one heap space like any Basic interpreter from the old days. This space is for prog + all variables, strings included. If you need more space, you reserve some with the CLEAR statement. Now something peculiar with this statement: It doesn't throw away the old space and then allocates new one (it could, because it clears all variables as the name implies), but first allocates the new area and only then frees the old one. (So to get big chunks in tight memory situations you have to use the trick to call it twice, once with the minimum memory for your program (to free as much of system memory as possible), and only then issue the real CLEAR statement.) So I could do all this space reserving for my strings in a similar manner: Initially reserve one big chunk of some arbitrary size, say 25 K, like in AmigaBasic. Like in an old Basic interpreter, store your string pointers from the bottom of this area, the strings themselves from the top. To speed up garbage collection, store a back pointer into the pointer table with every string like in the CBM 8032 Basic. Now when you run out of space, then allocate a bigger chunk of memory in some arbitrary step, completely copy the old area into the new one (you must do heavy pointer recalculations then), and only thereafter free the old area. Well, this is not extremely system and multitasking friendly and you risk to run out of memory earlier, because you a) need it in contiguous chunks, and b) need nearly twice the space temporarily, but it all appears much easier to me. Any comments? -- Best regards, Dr. Peter Kittel // E-Mail to \\ Only my personal opinions... Commodore Frankfurt, Germany \X/ {uunet|pyramid|rutgers}!cbmvax!cbmger!peterk
andrew@teslab.lab.OZ (Andrew Phillips) (02/20/91)
In <874@cbmger.UUCP> by peterk@cbmger.UUCP (Peter Kittel) writes: > [Idea to (re?)write C string routines to look like BASIC ones] You couldn't rewrite the standard string routines (strcpy, strcat etc) to work like the BASIC ones but you could write a new set of routines to do exactly what BASIC does (I think I heard of someone doing that a long time ago). Actually you would be much better off using C++. Then you could use your own string type in code like: str a, b, c; a = "Name: "; -- assign C string to "str" type putstr(a); -- output of str b = getstr(); -- input of str c = a + b; -- concatenation of str by having a string type which would be a sort of pointer to a real string and overloading operators "+", "=" etc. Most C programmers prefer the standard C string routines because they know what they are doing exactly internally whereas the BASIC ones are a bit unknown/unpredictable, especially when they decide to do a bit of garbage collection. I have a whole lot of string routines that I wrote that make using normal C strings a lot easier. If anybody is interested in them I could get them posted to c.s.a. Andrew. -- Andrew Phillips (andrew@teslab.lab.oz.au) Phone +61 (Aust) 2 (Sydney) 289 8712
peterk@cbmger.UUCP (Peter Kittel GERMANY) (02/21/91)
In article <1206@teslab.lab.OZ> andrew@teslab.lab.oz.au (Andrew Phillips) writes: > > I have a whole lot of string routines >that I wrote that make using normal C strings a lot easier. If >anybody is interested in them I could get them posted to c.s.a. You guess: I *AM* interested :-) -- Best regards, Dr. Peter Kittel // E-Mail to \\ Only my personal opinions... Commodore Frankfurt, Germany \X/ {uunet|pyramid|rutgers}!cbmvax!cbmger!peterk
bernie@metapro.DIALix.oz.au (Bernd Felsche) (02/25/91)
In <900@cbmger.UUCP> peterk@cbmger.UUCP (Peter Kittel GERMANY) writes: >In article <1991Feb15.050640.15436@metapro.DIALix.oz.au> bernie@metapro.DIALix.oz.au (Bernd Felsche) writes: >>This is what I use under UNIX, though it should work under AmigaDOS as >>well. It doesn't do any garbage collection, but it's fast! Also, there >>is no mechanism to grow a string, though that should be a bit easier >>to implement (for somebody else :-)). >> >>It works by having a linked list pointing to a cluster of malloc'd >>memory chunks, the size of which can be "defined" at the start. >Thanks for the code, I'll look into it. Well, being lazy, I already >thought about something similar, but the management of all those >linked lists together with string growing plus garbage collection >really frightens me. Now: Not that I'm really motivated to do it right now, but; the freeing up and garbage collection routines can be handled by adding new (fake) space headers, and coalescing these when appropriate. This is easier said than done, unless you're drunk :-) Regarding your pointer-angst; it's really not _that_ hard. Besides, it's only ONE linked list of headers. You can add a new free header list, or tag it on the end of the others. >How about an approach similar to the one AmigaBasic takes it? [stuff about AmigaBasic and others zapped] Yuk.... A MicroSloth product! Wash your mouth out! :-) This can be almost as complicated, if not more complicated. You will notice that my code pre-allocates chunks of memory, the size of which can be selected at compile time. The reason for this approach is that a minimum of memory is pre-allocated, leaving as much as (reasonably) possible, for other processes. The mechanism for "growing" strings in the schemes you mentioned would be just as complicated, virtually independent of how memory is pre-allocated. (As far as I can tell.) Garbage collection might be simpler. Pointers to strings are stored in variables, in the calling routines. There is no need to store them in the allocated space. I'm still thinking about it, though. Certainly worth a closer look. All ideas gratefully accepted, as long as they're free. -- Bernd Felsche, _--_|\ #include <std/disclaimer.h> Metapro Systems, / sale \ Fax: +61 9 472 3337 328 Albany Highway, \_.--._/ Phone: +61 9 362 9355 Victoria Park, Western Australia v Email: bernie@metapro.DIALix.oz.au