The Mark of a Serious programmer.

From: Jeff Relf (Usenet_at_JeffRelf.Cotse.NET)
Date: 10/10/04


Date: 10 Oct 2004 19:22:45 GMT

Hi Myxococcus xanthus,

You told me: <<

  Using macros, you've defined your own private language.
  Because of this, everything you state is completely irrelevant
  to any discussion about the relative merits of C versus C++.

  I doubt anybody reading your code
  has bothered trying to decipher your logic.
  Your code violates practically
  every single principle of modern software design. >>

You, Myxococcus, do not sound like a Serious programmer to me.

Would you try to understand the source code to Linux
by simply reading it, never handling it, never compiling it,
never putting it through it's paces,
never examining it in the debugger ?

That's how a Serious programmer reads code.

And no, I am not saying that you should try to read my code,
nor am I suggesting that you should run it.

I can use macros because I've been coding professionally
for the last 23 years... I'm still delivering code.

Macros make the code look a Thousand times better,
it simplifies the source code and reduces complexity.

Use #define... You Idiot !

As an example of how macros clarify source code,
take a look at this code which
extracts a server name from an article's Path line:
( taken from X.CPP http://www.Cotse.NET/users/jeffrelf/X.CPP )

// XHd() sets P ( char * ) to the raw Path line
// and B to a free buffer.
// Path is one of the XHdr commands that I used:
// enum { XOver, Path, User_Agent, X_Newsreader, H_Cnt };

XHd ( Path );

 LnP DN = 0, TLDp = 0, E = B ; __int64 UID = 0 ;
 char Bangs = - 1 ;

LOOP {

  // Make B point to the Beginning of the server name.

  LnP B = P ;

  // Next_Word advances P to the next Bang ( " ! " )

  Next_Word if ( P == B ) break; Bangs ++ ;

  // This memmove() preserves the original Path line
  // by copying a raw server name into a buffer
  // before modifying it.

  memmove ( E, B, rv = P - B - ( P[ -1 ] == '!' ) );

  // Make E point to the End of the server name,
  // null terminated.

  B = E ; E += rv ; * E ++ = 0 ;

  { LnP P = B - 1 ; __int64 I = 0 ;

    while ( * ++ P && * P != '.'
    && ( rv = HexToN ( * P ) ) >= 0 )

       I = ( I << 4 ) + rv ;

    // If it's a hex number 8 digits or longer
    // ending in null or dot, then it identifies a user.
    // One can score on this UID instead of the From line.

    if ( ! * P || * P == '.' && P - B >= 8 ) {

      UID = I ; continue; } }
  
  { LnP P = E - 1, T = 0 ;

    // FnDot Finds the next '.' looking backwards from P.

    FnDot
  
    if ( Eqi( P, "GBL") || Eqi( P, "MISMATCH") ) break ;
    if ( Eqi( P, "POSTED") || Eqi( P, "LOCALNET") ) {

       * -- P = 0 ; FnDot }

    if ( ! P [ 2 ] && ( P [ -4 ] == '.' || P [ -5 ] == '.' ) )
  
      // If the TLD is a two letter country code
      // and the name on the left is only 2 or 3 chars long
      // the get more names.

      FnDot

    // Make T point to extended TLD ( instead of zero ).

    T = P ;
    
    // Get the name to the left of the extended TLD.

    FnDot

    // Make DN point to a server name for later printing.

    TLDp = T ; DN = P ;

    // Alt.NET allows the Path line to be stuffed,
    // so rank it ' Z '.

    if ( Eqi( DN,"ALT.NET" ) ) Bangs = 50 ; } }

// Capitalize the names and the extended TLD.

if ( ! DN ) DN = "??"; else strupr( TLDp ), ToCaps( DN );

// Printout ( to a buffer ) the server name
// along with a letter from A to Z indicating
// how close to Individual.NET it is, and the user's UID.

Sh ( "%c %s%s%s", Bangs >= 50 ? 'Z' : Bangs / 2 + 'A',
  ! UID ? "" : B62 ( UID ), ! UID ? "" : " ", DN );
............

Here are some macros and functions that were used:

#define LOOP while ( 1 )

#define Eqi ! stricmp

typedef char * LnP ;

#define FnDot { \
  \
  while ( -- P > B && P [ -1 ] != '.' ); \
  if ( ! T && ( P == B || ! isalpha( P [ 1 ] ) ) ) \
    \
    continue; }

#define XHd( Hd ) \
  ( S = B = Buff + 1024, _XHd ( Hd == Path, Ln_H [ Hd ], P ) )

int _XHd ( int Path, int & LnI, LnP & P ) {

  static __int64 _ID, ID ;
  LOOP {

    // Ln.B [ -- LnI ] is an element in the array of lines
    // holding the raw data from the server

    ID = _atoi64( P = Ln.B [ -- LnI ] );
    if ( Path ) _ID = ID ; if ( ID == _ID ) break ;
    if ( ID < _ID ) {

      // The server has no data with this article ID,
      // so back out.

      LnI ++ ; return 0 ; } }

  Next_Word return 1 ; }

int HexToN( int C ) {

  if ( isdigit( C ) ) return C - '0' ;
  if ( RaisC ( ( LnP ) & C ) >= 'A' && C <= 'F' )

    return 10 + C - 'A' ; return -1 ; }

int RaisC ( LnP P ) { return * P = toupper( * P ); }



Relevant Pages

  • The Mark of a Serious programmer.
    ... Using macros, you've defined your own private language. ... Would you try to understand the source code to Linux ... extracts a server name from an article's Path line: ... // and B to a free buffer. ...
    (comp.os.linux.development.apps)
  • [UNIX] Syslog-NG Buffer Overflow
    ... The number of bytes exceeding the allocated buffer ... characters are present in the template string. ... The problem lies in the way macro expansion handles constant characters ... As syslog-ng expands macros ...
    (Securiteam)
  • HttpRequest.Filter and how best to use it
    ... I have built a web app where I need to parse the entire http page before it ... which looks for any predefined macros and changes them to actual values. ... I accomplished by setting the HttpRequest.Filter property to a stream class ... Stream's Write property I simply scan through the buffer and replace the ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: [PATCH 13/22] 2.6.22-rc3 perfmon2 : common core functions
    ... without too much trouble: ... Don't use such non standard macros please. ... So there can potentially be a race with the perfmon init. ... buffers and export of the buffer via /dev/oprofile works like before. ...
    (Linux-Kernel)
  • Re: O_BINARY.....
    ... Except, those are actually macros. ... are moved from one stdio buffer to the other... ... And fread() uses macros (or the same internal knowledge of the ...
    (comp.unix.programmer)