Purtill@MIT-MULTICS.ARPA (Mark Purtill) (05/04/85)
<Fnord> Re: mod.std.c, various. #define CTRL(XX) ( ($XX)[0] & '\037') works (I think) in ANSI C. (For those of you who've forgotten, this replaces #define CTRL(XX) 'XX' & '\037' I.e., it converts CTRL(A) to '\001', CTRL(B) to '\002' and so forth, possibly even doing CTRL([) et. al. (Not having a copy of the ANSI standard, I'm not sure.) (Nb: I've tried to post this twice to cbosgd!std-c@BERKELEY.ARPA, but it has disapeared without a trace both times. Hence, I'm posting it to INFO-C.) Mark ^.-.^ Purtill at MIT-MULTICS.ARPA **Insert favorite disclaimer here** ((")) 2-032 MIT Cambrige MA 02139
mike@whuxl.UUCP (BALDWIN) (05/05/85)
> #define CTRL(XX) ( ($XX)[0] & '\037') > replaces > #define CTRL(XX) ('XX' & '\037') A more reasonable definition without any weirdness would be #define CTRL(c) ((c) & '\037') So you use CTRL('g') instead of CTRL(g). This way it looks more like a real function call (rather than passing some nonexistent variable g). Here's a silly though: since '\xFC' has been added to ANSI C for hex characters, how about '\^G' for control characters, ala ICON? I never did like the CTRL macro. Michael Baldwin AT&T Bell Labs harpo!whuxl!mike
henry@utzoo.UUCP (Henry Spencer) (05/06/85)
> Here's a silly though: since '\xFC' has been added to ANSI C for hex > characters, how about '\^G' for control characters, ala ICON? I never > did like the CTRL macro. As has been said before, the right way to do this is: #define BEL '\007' or something along those lines. The character is "BEL", numbered 7 decimal in the ASCII code; control-G is just the way you type it on many (but not necessarily all) terminals. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
mike@whuxl.UUCP (BALDWIN) (05/08/85)
> > [use '\^X' instead of CTRL(x) or CTRL('x')] > As has been said before, the right way to do this is: > #define BEL '\007' I was thinking mainly about programs that use curses or otherwise read characters one at a time and do special things with ctrl chars. E.g., switch (c) { case '\^U': /* up code */ case '\^D': /* down code */ Etc. #define's (other than CTRL) just won't do. And the #define for CTRL moves around, so you have to use #ifndef. Glick. Also, it is easier to think in terms of ctrl chars rather than their octal values when dealing with funny terminal sequences. For instance, the cursor motion sequence on mime's is ^T row col, and using printf("\^T%c%c", row, col) is a bit more obvious than printf("\024%c%c", row, col). Michael Baldwin AT&T Bell Labs harpo!whuxl!mike
Purtill@MIT-MULTICS.ARPA (Mark Purtill) (05/11/85)
<Fnord> Yes, CTRL('F') beats CTRL(F) any day, but the idea was to replace an existing macro WITHOUT having to change all of the calls to it. I really didn't expect any changes made to the standard to replace this silliness, but when I noticed that it could be done, I felt I ought to let everyone know. Mark ^.-.^ Purtill at MIT-MULTICS.ARPA **Insert favorite disclaimer here** ((")) 2-032 MIT Cambrige MA 02139 Mark ^.-.^ Purtill at MIT-MULTICS.ARPA **Insert favorite disclaimer here** ((")) 2-032 MIT Cambrige MA 02139
Purtill@MIT-MULTICS.ARPA (Mark Purtill) (05/11/85)
<Fnord> > >> [use '\^X' instead of CTRL(x) or CTRL('x')] > > As has been said before, the right way to do this is: > > #define BEL '\007' > I was thinking mainly about programs that use curses or otherwise read > characters one at a time and do special things with ctrl chars. E.g., Actually, that's no problem. You just say #define UP_CHAR '\025' #define DOWN_CHAR '\004' ... switch( c) { case UP_CHAR: ... Case DOWN_CHAR: ... ... } This is actually BETTER, since you don't have magic numbers in the code. > using >printf("\^T%c%c", row, col) is a bit more obvious than >printf("\024%c%c", row, col). This brings up a real problem: if you have a magic CHARACTER, you can't use it in a STRING. Under ANSI C, at least you can get by with #define MAGIC_CHAR '\024' #define MAGIC_CHAR_STRING "\024" and then say printf( MAGIC_CHAR_STRING "%c%c", row, col) ; but that's not really satisfactory. (It *is* better that printf( "%c%c%c", MAGIC_CHAR,...) ; or printf( "\666%c%c",...) ; tho.) How about making a string adjacent to a character constant absorb said character constant? Then "foo" '\001' => "foo\001", and '\001' "foo" => "\001foo", just as in the standard, "foo" "\001" => "foo\001". Then printf( MAGIC_CHAR "%c%c",...) ; works like one would like. Mark ^.-.^ Purtill at MIT-MULTICS.ARPA **Insert favorite disclaimer here** ((")) 2-032 MIT Cambrige MA 02139
Purtill@MIT-MULTICS.ARPA (Mark Purtill) (05/17/85)
<Fnord> I'm suprised no one caught me on this. When I said >#define CTRL(XX) ( ($XX)[0] & '\037') I should have said >#define CTRL(XX) ( (#XX)[0] & '\037') (ie, the $ should have been a #!!) Sorry about that... Mark ^.-.^ Purtill at MIT-MULTICS.ARPA **Insert favorite disclaimer here** ((")) 2-032 MIT Cambrige MA 02139
arnold@ucsfcgl.UUCP (Ken Arnold%CGL) (05/22/85)
In article <10747@brl-tgr.ARPA> Purtill@MIT-MULTICS.ARPA (Mark Purtill) writes: >I'm suprised no one caught me on this. When I said >>#define CTRL(XX) ( ($XX)[0] & '\037') >I should have said >>#define CTRL(XX) ( (#XX)[0] & '\037') >(ie, the $ should have been a #!!) Sorry about that... Unless the compiler is incredibly smart, this won't work in 'case' statements, which is rather important. Although "a"[0] is, in fact, a constant, it is only a constant because it is a constant offset into a *constant array*, which is a rather unusual beast. The VAX pcc doesn't figure this out. Try this on your compiler and see if it does: switch (i) { case "a"[0]: break; } Actually, when you think about it, since strings are writeable, "a"[0] is NOT a constant, since someone else might modify the string. It is an indirection off of a constant location, but it is not a constant. Face it. We are going to have to kill ourselves trying to work around the standard committee's refusal to let C work the way it has been working. I have made my opinion on this known ad nauseum, I'm sure, so I'll just leave it alone for now... Ken Arnold
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (05/23/85)
> Face it. We are going to have to kill ourselves trying to work around > the standard committee's refusal to let C work the way it has been working. What "C"? Using undocumented (indeed, unintended) features present in one particular implementation is not the same as using C the way it was defined; programmers who stuck to the rules should not have problems with the ANSI addition of a more carefully designed way to achieve substitution "within" strings. The ANSI approach is designed to support reasonable implementations other than the Reiser CPP, including token-based CPPs, several of which exist and cannot readily be made to support Resierisms. C != BSD
arnold@ucsfcgl.UUCP (Ken Arnold%CGL) (05/25/85)
In article <10948@brl-tgr.ARPA> gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) writes: >> Face it. We are going to have to kill ourselves trying to work around >> the standard committee's refusal to let C work the way it has been working. >What "C"? Using undocumented (indeed, unintended) features present >in one particular implementation is not the same as using C the way >it was defined; ... > >C != BSD Unintended? That ain't the way I heard it. In fact, if Reiser hadn't put some way to do this in, someone else would have invented it, since it is so useful. Undocumented is only moderately correct, but neither hither nor yon. It is used this way in every Reiser-based preprocessor, and that means not just BSD (BSD got it from Bell), but every Bell-derived C implementation as well, and some other compilers, including some for micros. So what should be standardized on; most compilers or a few compilers? And, if you think that there are more compilers that DON'T do it Reiser's way (an interesting idea), you might ask about how many lines of code are written under Reiser-style vs. non-Reiser. However, I promised myself I wouldn't get into this debate, so this is the last net.lang.c will hear from me on this unles someone says something truly wacko and I can't help myself. Ken Arnold
guy@sun.uucp (Guy Harris) (05/25/85)
> The ANSI approach is designed to support reasonable implementations other > than the Reiser CPP, including token-based CPPs, several of which exist > and cannot readily be made to support Resierisms. > > C != BSD (X is a feature of the Reiser "cpp") != (X is a BSDism). Let's be fair here. Guy Harris
ado@elsie.UUCP (Arthur David Olson) (05/28/85)
In regard to #define CTRL(XX) ( (#XX)[0] & '\037') in article <507@ucsfcgl.UUCP>, arnold@ucsfcgl.UUCP (Ken Arnold%CGL) writes: > . . .Unless the compiler is incredibly smart, this won't work in 'case' > statements, which is rather important. . . > Actually, when you think about it, since strings are writeable, "a"[0] > is NOT a constant, since someone else might modify the string. . . Although if I understand aright the draft standard treats unadorned doubly- quoted strings as if they were cast to "const", which means that constructs like "a"[0] would be constants under the draft standard. As for me, I still favor the #define Ctrl(X) ((X) & '\037') approach. Change your source once and be done with it. -- Ken is a Kenner Corporation trademark. -- UUCP: ..decvax!seismo!elsie!ado ARPA: elsie!ado@seismo.ARPA DEC, VAX and Elsie are Digital Equipment and Borden trademarks
henry@utzoo.UUCP (Henry Spencer) (06/02/85)
> ... And, if you > think that there are more compilers that DON'T do it Reiser's way (an > interesting idea), you might ask about how many lines of code are written > under Reiser-style vs. non-Reiser. Actually, the correct version of the latter question is to ask how many lines of code *care* whether they are written under Reiser-style or non-Reiser, since the vast bulk of the code written under the Bell-derived Reiser-style compilers doesn't use Reiserisms. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
ado@elsie.UUCP (Arthur David Olson) (10/21/86)
Sorry if this has gone around before. With the Reiser cpp, you can (and "/usr/include/sys/tty.h" does) #define CTRL(c) ('c'&037) so that a line such as CTRL(z) turns into ('z'&037) With ANSI cpp, if you keep the define as above and have a line such as CTRL(z) it turns into ('c'&037) which isn't what's wanted. One possibility is to establish a new macro, #define Ctrl(c) ((c)&037) and change all uses such as CTRL(z) into uses such as Ctrl('z') But. . .is there a way to write an ANSI cpp version of #define CTRL(c) that will work like the old Reiser version? If you know, please mail me the answer. Thanks. -- ANSI may be an ANSI trademark. -- UUCP: ..decvax!seismo!elsie!ado ARPA: elsie!ado@seismo.ARPA DEC, VAX, Elsie & Ado are Digital, Borden & Ampex trademarks.
kb5mu@NOSC.ARPA (10/24/86)
>But. . .is there a way to write an ANSI cpp version of > #define CTRL(c) I don't have an ANSI cpp handy (does anybody?), so I can't test this, but how about using the ANSI invention of # for "string-izing": #define CTRL(c) (#c[0] & 037) This should turn CTRL(z) into ("z"[0] & 037) which would get what you wanted, except that relatively stupid compilers might allocate storage for the string literal "z".
greg@utcsri.UUCP (Gregory Smith) (10/29/86)
In article <4880@brl-smoke.ARPA> kb5mu@NOSC.ARPA writes: >>But. . .is there a way to write an ANSI cpp version of >> #define CTRL(c) > >I don't have an ANSI cpp handy (does anybody?), so I can't test >this, but how about using the ANSI invention of # for "string-izing": > #define CTRL(c) (#c[0] & 037) >This should turn > CTRL(z) >into > ("z"[0] & 037) >which would get what you wanted, except that relatively stupid >compilers might allocate storage for the string literal "z". It's worse than that. "z"[0] is *("z"), and unary * is not allowed in constant expressions. So ALL compilers would allow storage for "z" and then generate code to read that storage at run-time. Of course, ``case CTRL(c):'' wouldn't work either. You don't expect C compilers to pull constants out of string literals, do you? [ I don't have an Ansi draft, so as far as I know there may be a rule saying that constant expressions may contain string literals indexed by constants. But I doubt it]. -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg
colonel@sunybcs.UUCP (Col. G. L. Sicherman) (10/31/86)
) >But. . .is there a way to write an ANSI cpp version of ) > #define CTRL(c) ) ) I don't have an ANSI cpp handy (does anybody?), so I can't test ) this, but how about using the ANSI invention of # for "string-izing": ) #define CTRL(c) (#c[0] & 037) Not everybody has it. What's wrong with this old trick? #define Q " #define CTRL(z) (Q z "[1]^0100) -- Col. G. L. Sicherman UU: ...{rocksvax|decvax}!sunybcs!colonel CS: colonel@buffalo-cs BI: colonel@sunybcs, csdsiche@sunyabvc
meissner@dg_rtp.UUCP (Michael Meissner) (11/03/86)
In article <4880@brl-smoke.ARPA> kb5mu@NOSC.ARPA writes: >>But. . .is there a way to write an ANSI cpp version of >> #define CTRL(c) > >I don't have an ANSI cpp handy (does anybody?), so I can't test >this, but how about using the ANSI invention of # for "string-izing": > #define CTRL(c) (#c[0] & 037) >This should turn > CTRL(z) >into > ("z"[0] & 037) >which would get what you wanted, except that relatively stupid >compilers might allocate storage for the string literal "z". The problem with using string-izing, is that it is not a constant expression, and can't be used in switch statements. Many of the places CTRL(x) is currently used ARE in switch statements. Another approach would be to use token pasting, instead of string-izing: enum _ctrl_chars { _ctrl_a = 1, _ctrl_b = 2, /* c, d, etc. */ _ctrl_z = 26, _ctrl_A = 1, _ctrl_B = 2, /* C, D, etc. */ _ctrl_Z = 26 }; #define CTRL(x) (int)( _ctrl_ ## x) The problem with the above is that people have also used CTRL([) to represent the escape character. Michael Meissner, Data General ...mcnc!rti-sel!dg_rtp!meissner
levy@ttrdc.UUCP (Daniel R. Levy) (11/05/86)
In article <666@dg_rtp.UUCP>, meissner@dg_rtp.UUCP (Michael Meissner) writes: >In article <4880@brl-smoke.ARPA> kb5mu@NOSC.ARPA writes: >> #define CTRL(c) (#c[0] & 037) >>This should turn >> CTRL(z) >>into >> ("z"[0] & 037) >The problem with using string-izing, is that it is not a constant expression, >and can't be used in switch statements. Many of the places CTRL(x) is >currently used ARE in switch statements. Another approach would be to use >token pasting, instead of string-izing: > > enum _ctrl_chars { > _ctrl_a = 1, > ... > _ctrl_Z = 26 > }; > #define CTRL(x) (int)( _ctrl_ ## x) >The problem with the above is that people have also used CTRL([) to >represent the escape character. > Michael Meissner, Data General At this point, I begin to wonder out loud why all the contortions people are going to just to avoid typing two silly little single quotes when using a CTRL macro, i.e.: #define CTRL(x) (x & 037) char c; switch (c) { CTRL('A'): blah blah blah...; break; CTRL('E'): bleh bleh bleh...; break; ... This even lets you have your CTRL('@') for NUL and CTRL('[') for escape, etc. I contend this is just as useful as anyone else's suggestion and doesn't rely on any large list of values or fancy-ANSI [:-)] preprocessor either. -- ------------------------------- Disclaimer: The views contained herein are | dan levy | yvel nad | my own and are not at all those of my em- | an engihacker @ | ployer or the administrator of any computer | at&t computer systems division | upon which I may hack. | skokie, illinois | -------------------------------- Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, go for it! allegra,ulysses,vax135}!ttrdc!levy