jdp@caleb.UUCP (Jim Pritchett) (06/06/89)
Recently, Chuck McManis posted a program which shows the active Locks on a volume. The program calls a function called strins(). Could someone out there provide a description of what this function does? I assume that it is a Lattice supplied function. However, since I have the Aztec compiler so I will need to write a substitute function. By the way, does anyone out there know when/if a new version of the Aztec C compiler and SDB will be available? (I have 3.6A) Thanks, -- Jim Pritchett UUCP: {killer!texbell}!letni!caleb!jdp or killer!gtmvax!dms3b1!caleb!jdp
cmcmanis%pepper@Sun.COM (Chuck McManis) (06/12/89)
SUMMARY:
(void) strins(s1, s2)
char *s1, *s2;
Null terminated string s2 is copied into the front of null terminated
string s1. So if s2 had a pointer to "foo" in it and s1 had a pointer
to "bar" in it, after the call s1 will point to a string "foobar".
Probably the best way to simulate this is with :
string(s1, s2)
char *s1, *s2;
{
char tmp[80];
strcpy(tmp, s1);
strcat(tmp, s2);
strcpy(s1, tmp);
return;
}
--Chuck McManis
uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.
"A most excellent barbarian ... Genghis Kahn!"
jmsc@inesc.UUCP (Miguel Casteleiro) (06/13/89)
In article <109394@sun.Eng.Sun.COM>, cmcmanis%pepper@Sun.COM (Chuck McManis) writes: > > SUMMARY: > (void) strins(s1, s2) > char *s1, *s2; > > Null terminated string s2 is copied into the front of null terminated > string s1. So if s2 had a pointer to "foo" in it and s1 had a pointer > to "bar" in it, after the call s1 will point to a string "foobar". ^^^^^^^^ Shouldn't it be "barfoo" ?? > Probably the best way to simulate this is with : > string(s1, s2) > char *s1, *s2; > { > char tmp[80]; > > strcpy(tmp, s1); > strcat(tmp, s2); > strcpy(s1, tmp); > return; > } > > --Chuck McManis Am I missing something, or this is exactly wath strcat is suppose to do !! From the UNIX manual: SYNTAX char *strcat(s1, s2) char *s1, *s2; DESCRIPTION The arguments s1 and s2 point to strings (arrays of characters terminated by a null character). The strcat subroutine appends a copy of string s2 to the end of string s1. -- __ Miguel Casteleiro at __ /// INESC, Lisboa, Portugal. \\\/// Only UUCP: ...!mcvax!inesc!jmsc "Life is hard and then you die." \XX/ Amiga
doug@xdos.UUCP (Doug Merritt) (06/13/89)
In article <10285@watcgl.waterloo.edu> gswan@watcgl.waterloo.edu (Geo Swan) writes: >I have seen lots of code that builds strings, particularly pathnames >through the use of several calls to strcat. I have never been able >to understand why people didn't use sprintf. Particularly in the >case of building pathnames. One perfectly valid reason is that sprintf() is much higher overhead than simpler routines. It runs slower and takes up a fair amount of space. I dunno about Manx and Lattice on the Amiga, but on many systems, the existence of %f/%e/%g in {s,f,}printf means that a lot of unneeded floating point code overhead will get thrown in. Doug -- Doug Merritt {pyramid,apple}!xdos!doug Member, Crusaders for a Better Tomorrow Professional Wildeyed Visionary
cmcmanis%pepper@Sun.COM (Chuck McManis) (06/14/89)
In article <10285@watcgl.waterloo.edu> (Geo Swan) writes: > I have never been able to understand why people didn't use sprintf. The answer is fairly simple. sprintf(3) is often entangled with the stdio library. When you use it, it depends on a bunch of other stuff that pulls in most of stdio. Your "simple" function suddenly yanks 14K of code out of the library into your executable. Plus it is a lot more efficient to use strxxx() routines which are simply loops where as sprintf() invokes the _doprnt() parser to figure out how to put together your strings. Generally, sprintf() is easier but strxxx() routines are smaller. If your compiler/linker is smart enough to recognize the difference between when you want full stdio versus just simple printf's that helps. --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you. "A most excellent barbarian ... Genghis Kahn!"
cmcmanis%pepper@Sun.COM (Chuck McManis) (06/14/89)
In article <897@inesc.UUCP> jmsc@inesc.UUCP (Miguel Casteleiro) writes: > Am I missing something, or this is exactly wath strcat is suppose to do !! Your missing something, it is the _inverse_ of strcat(). strins() _prepends_ strings, whereas strcat() _appends_ strings. --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you. "A most excellent barbarian ... Genghis Kahn!"
jms@tardis.Tymnet.COM (Joe Smith) (06/14/89)
[I predict there will be over 25 followups to Geo's article.] In article <10285@watcgl.waterloo.edu> gswan@watcgl.waterloo.edu (Geo Swan) writes: >Let me suggest that our original poster consider using the following macro: >#define strins( s1, s2 ) sprintf( s1, "%s%s", s2, s1 ) Can you guarantee that the above macro will work when s2 is longer than s1? Example: Let's say s1 is a pointer to an array of 80 bytes, and only the first two bytes have any characters, the rest are null. Let's say s2 is a pointer to a string of 4 bytes. As sprintf copies s2 into s1, it overwrites the original string. If sprintf copies until len(s1), then it will return a pointer to an 8 byte string - s2 concatenated with s2. If sprintf copies until it gets to the null byte, it will never find it - s1 will get an infinite number of copies of s2. Or guru. It's OK to use sprintf as long as the destination does not include any of the sources. -- Joe Smith (408)922-6220 | SMTP: JMS@F74.TYMNET.COM or jms@tymix.tymnet.com McDonnell Douglas FSCO | UUCP: ...!{ames,pyramid}!oliveb!tymix!tardis!jms PO Box 49019, MS-D21 | PDP-10 support: My car's license plate is "POPJ P," San Jose, CA 95161-9019 | narrator.device: "I didn't say that, my Amiga did!"
root@dialog.UUCP (Christian Motz) (06/14/89)
In article <109394@sun.Eng.Sun.COM> cmcmanis%pepper@Sun.COM (Chuck McManis) writes: > > [...] > >Probably the best way to simulate this is with : >string(s1, s2) > char *s1, *s2; >{ > char tmp[80]; > > strcpy(tmp, s1); > strcat(tmp, s2); > strcpy(s1, tmp); > return; >} Maybe so, but isn't this a little bit inflexible? I usually use the following routine: char *strins(at, str) char *at, *str; { movmem(at, at+strlen(str), strlen(at)+1); movmem(str, at, strlen(str)); return at; } There is no limit to your string length imposed by this routine, you don't need a lot of valuable stack space, and who knows, it might even be a tick faster ... -- Christian Motz uucp: ...!uunet!mcvax!unido!pfm!nadia!dialog!root "Trust me, I know what I'm doing!" -- Sledge Hammer Bix: cmotz
giguere@aries5.uucp (Eric Giguere) (06/14/89)
In article <10285@watcgl.waterloo.edu> gswan@watcgl.waterloo.edu (Geo Swan) writes: >I have seen lots of code that builds strings, particularly pathnames >through the use of several calls to strcat. I have never been able >to understand why people didn't use sprintf. Particularly in the >case of building pathnames. If you're trying to write small programs with as little library overhead as possible you should avoid any of the (f/s/v)printf routines if at all possible. As anyone who's looked through the bowels of a C compiler knows, the printf routines are some of the largest routines around and non-trivial to code. That's why the standard program main() { printf( "hello, world\n" ); } is actually more of a test for the C compiler than you'd normally think. A routine like strcat is for the most part just a tight loop that moves characters around and is very economical. Having said that, once you've used printf even once in a program you might as well use the others if convenient (and if not too slow for you) since the code is there already (fprintf, sprintf, vprintf and printf are all front-ends to a central format routine). At least in Aztec C (and Lattice, I assume) printf isn't too bad if you don't use any floating-point functions. Eric Giguere 268 Phillip St #CL-46 For the curious: it's French ("jee-gair") Waterloo, Ontario N2L 6G9 Bitnet : GIGUERE at WATCSG (519) 746-6565 Internet: giguere@aries5.UWaterloo.ca "Nothing but urges from HELL!!"
doug@xdos.UUCP (Doug Merritt) (06/15/89)
In article <109819@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes: >In article <897@inesc.UUCP> jmsc@inesc.UUCP (Miguel Casteleiro) writes: >> Am I missing something, or this is exactly wath strcat is suppose to do !! > >Your missing something, it is the _inverse_ of strcat(). strins() _prepends_ >strings, whereas strcat() _appends_ strings. > He's not missing as much as you think; your posted example definition of strins() had a bug in it such that it actually implemented the functionality of strcat()! I didn't say anything at the time because I figured it was an obvious mistake and somebody else would probably nitpick it anyway. If anyone's still confused, this is what he *meant*: strins(d, s) char *d, *s; { char tmp[256]; strcpy(tmp, s); strcat(tmp, d); strcpy(d, tmp); } Doug -- Doug Merritt {pyramid,apple}!xdos!doug Member, Crusaders for a Better Tomorrow Professional Wildeyed Visionary
C506634@UMCVMB.BITNET ("Eric Edwards") (06/15/89)
Sorry about the duplicate in comp.sys.amiga. I hit "reply" and amiga-relay only sends to comp.sys.amiga. Now back to our regulary scheduled posting... - - The original note follows - - In Measage ID<256@maytag.waterloo.edu> giguere@aries5.uucp says: >If you're trying to write small programs with as little library >overhead as possible you should avoid any of the (f/s/v)printf routines >if at all possible. As anyone who's looked through the bowels of a C >compiler knows, the printf routines are some of the largest routines >around and non-trivial to code. That's why the standard program > > main() > { > printf( "hello, world\n" ); > } > >is actually more of a test for the C compiler than you'd normally think. Lattice uses a bultin function to get arround this problem in printf. I quote from the Lattice manual, _Lattice C Compiler_ version 4.0 " printf When this function is called, the compiler examines the formatting string: * When it is a constant string with no substitutions, the compiler changes the printf call to a _write call. * When it is a constant string AND only contains %s, %d and p% formats a call is made to _tinyprintf " Disclaimer: All typos are assumed to be mine, not the manual's. Further they say they may do similar tricks for scanf, sprintf and fprintf but upon checking my 5.0 manual I don't thing they have done this to date. >Eric Giguere 268 Phillip St #CL-46 >For the curious: it's French ("jee-gair") Waterloo, Ontario N2L 6G9 Bitnet: C506634@umcvmb.bitnet __________________________ Internet: C506634@umcvmb.missouri.edu / \.--------. / \ "The Amiga just isn't reliable enough unless you | | Eric |---------+ | know a lot about the machine" -- Jerry Pournelle | `--------' ! | ================================================|| .--------. ! | "I did notice that at my party people stood in | | Edwards|_________+ | line to play with the Amiga"-- Jerry Pournelle | /`--------' ^ | BYTE, October '88 \__________________________/ \\\ Note Forwarded on: 06/14/89 19:16:30 /// \\\ To: AMIGATEC ///
peter@sugar.hackercorp.com (Peter da Silva) (06/15/89)
In article <8906150029.AA22430@jade.berkeley.edu>, C506634@UMCVMB.BITNET ("Eric Edwards") writes: > Lattice uses a bultin function to get arround this problem in printf. What problem? > I quote from the Lattice manual, _Lattice C Compiler_ version 4.0 > " printf > * When it is a constant string with no substitutions, the compiler changes the > printf call to a _write call. What if you have your own version of printf? Say, one that understands more escape sequences (%e -- error text, %t -- absolute tab, %l -- length byte)? Can you freely interleave _write with stdio routines? Does it work if you have freopened stdout? This sounds like a pretty dubious optimisation. -- Peter "Have you hugged your wolf today" da Silva `-_-' ...texbell!sugar!peter, or peter@sugar.hackercorp.com 'U`
new@udel.EDU (Darren New) (06/16/89)
In article <3930@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes: >In article <8906150029.AA22430@jade.berkeley.edu>, C506634@UMCVMB.BITNET ("Eric Edwards") writes: >> Lattice uses a bultin function to get arround this problem in printf. >> " printf >> * When it is a constant string with no substitutions, the compiler changes the >> printf call to a _write call. > >What if you have your own version of printf? Say, one that understands more >escape sequences (%e -- error text, %t -- absolute tab, %l -- length byte)? The way this works in LC4.0 (and I would suspect 5.0) is that stdio.h has a #define printf __builtin_printf. Taking this line out (or #undef) would turn this back into a normal function. Redefining printf seems kind of dubious to me, knowing the little I do about ANSI. This is also used to inline strcpy, strcat, and a couple others (in 4.0). >Can you freely interleave _write with stdio routines? Not standardly. I would think that you would change it to puts(), myself. >Does it work if you have freopened stdout? Which would cure this problem also. I'm interested in seeing what they do in 5.0 also (just ordered it today..) -- Darren
gay_d@elma.epfl.ch (06/16/89)
In article <17740@louie.udel.edu: new@udel.edu (Darren New) writes: ->In article <3930@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Si lva) writes: ->>In article <8906150029.AA22430@jade.berkeley.edu>, C506634@UMCVMB.BITNET ("Er ic Edwards") writes: ->>> Lattice uses a bultin function to get arround this problem in printf. ->>> " printf ->>> * When it is a constant string with no substitutions, the compiler changes the ->>> printf call to a _write call. I think it's called _writes ->>What if you have your own version of printf? Say, one that understands more ->>escape sequences (%e -- error text, %t -- absolute tab, %l -- length byte)? -> ->[...] Redefining printf seems kind of dubious ->to me, knowing the little I do about ANSI. This is also used to inline ->strcpy, strcat, and a couple others (in 4.0). From the little I know about ANSI, you can't portably redefine printf, as other library routines may use it ... Also, I think that they suggest that you inline strcat, et al (though not printf). ->>Can you freely interleave _write with stdio routines? ->Not standardly. I would think that you would change it to puts(), myself. Seeing that it isn't _write, you can freely intermix _writes with stdio routines! Also, don't forget that puts() adds a newline. David Gay GAY_D@ELMA.EPFL.CH <-- Note the change of address
limonce@pilot.njin.net (Tom Limoncelli) (06/17/89)
My understanding of the ANSI standard is as follows: The original draft insisted that if you create a function that has the same name as something in the standard library, the behavior was implementation defined with the warning that you might have problems if you write a function called printf() that (for example) formats disks. Pray that none of the other library routines use your printf instead of their intended one. The second draft states that "the library names are (in principle) [now] reserved names. If you write your own version of fopen, say, your program MIGHT work in some environment that you know well, but it would have slim chances of being generally portable." {footnote: The C Journal, Summer 1985, "Draft ANSI C Scorecard -- Second Round" by Thomas Plum, pg 29-34} Of course, this is not completely helpful nor is it a generally good way of dealing with this problem. So, in a later draft [no footnote here, this is "as I understand it"] the X3J11 committee decided to adopt a better method. Now if you want to write your own "fopen" routine, that is, if you want to write a routine named "fopen", not replace "fopen"'s functionality with a function of your own: #undef fopen then you have full access to that reserved word. If you think about it, it makes sence. Basically, fopen has a definition. If you want to change it, undefine it and redefine it yourself. Just like if you want to (eeek!) change the value of EOF. #undef EOF #define EOF (-69) This is also very easy to implement. If a vender wants to implement a function as inline code, they use a very long #define. If the user doesn't want it to be inlined, they simply #undef it and now the linker will try to find that routine first in the current module (.o file) then in one of the libraries. ANSI also dictates that the linkers must perform in this way. If the vender doesn't want the function to be inlined, they call it (for example) __stlib_fopen and do a #define fopen __stlib_fopen. All identifiers beginning with "__" are the domain of the vender, so there will be no namespace conflict. I don't recall how they deal with the #undef'ed identifier, I wouldn't expect them to put __stlib_fopen and fopen in the library (duplicate code). Maybe someone can follow up on this. Simple? I think it's very workable. I hope this explanation is helpful, I know it was a bit long winded but I think it covered all the bases. Please correct me if I'm wrong. As I said, this is how I understand it. -Tom -- Tom Limoncelli -- tlimonce@drunivac.Bitnet -- limonce@pilot.njin.net Drew University -- Box 1060, Madison, NJ -- 201-408-5389 Standard Disclaimer: I am not the mouth-piece of Drew University
jyegiguere@lion.waterloo.edu (Eric Giguere) (06/18/89)
In article <Jun.16.23.36.52.1989.29150@pilot.njin.net> limonce@pilot.njin.net (Tom Limoncelli) writes: >If the user doesn't want it to be inlined, they simply #undef it >and now the linker will try to find that routine first in the >current module (.o file) then in one of the libraries. ANSI also >dictates that the linkers must perform in this way. Frankly I don't like the idea of having the compiler rename printf() on me by default... I think defining a macro that would turn ON the "tiny printf" substitution would be better. One thing I'm curious about, though, is where you got the idea that the ANSI specs say anything about the linkers? I can't find that statement about the linkers having to perform that way at all. If that's true then none of the C compilers on IBM mainframes can be conforming compilers because the standard IBM linker (on CMS at least) will not link a set of files with duplicate identifiers.... I think this discussion has passed the scope of this group... further comments should go to comp.lang.c.... Eric Giguere 268 Phillip St #CL-46 For the curious: it's French ("jee-gair") Waterloo, Ontario N2L 6G9 Bitnet : GIGUERE at WATCSG (519) 746-6565 Internet: giguere@aries5.UWaterloo.ca "Nothing but urges from HELL!!"
cmcmanis%pepper@Sun.COM (Chuck McManis) (06/20/89)
To kick a completely dead horse, another 10' out into the pasture ... The question : "Why use strxxx() routines when sprintf() is easier to read/use ?" The answer : (from several sources) "Because the stdio printf is _huge_." In article <8906150029.AA22430@jade.berkeley.edu> ("Eric Edwards") writes: > Lattice uses a bultin function to get arround this problem in printf. Good for Lattice, unfortunately they don't define the standard for the world. In general when designing useful utility routines like strins() you must work from the assumption that the compiler is minimally compliant and doesn't play any games with the library routines. --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you. "A most excellent barbarian ... Genghis Kahn!"