https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97952

--- Comment #1 from eric-gcc at omnifarious dot org ---
Because you might not like Godbolt links, here is the C code:

//-------------------cut here-----------------------
/*** core string search routine ***/

typedef char *String;
typedef unsigned long    Index, Count, Size, Length, Limit, Extent, Mask, Bits;

typedef struct {
          const String   string;
          const Length   length;
          const  Index  *const table;
} SearchString_data;

typedef     SearchString_data   *SearchString,  SearchString_object[1];

enum {
    IAC         = (char) 255,
    WILL        = (char) 251,
    WONT        = (char) 252,
    DO          = (char) 253,
    DONT        = (char) 254,
};

static  Length  command_length( String s, String sn );
static  Length  command_length_unknown( String s, String sn );


String
skip_past( String input, String sn, SearchString ss ){
    const  Index *walkback = ss->table;
    const  Index  kn       = ss->length;
    const String  w        = ss->string;

    typedef String  Skip_f( String, Index );
    auto Skip_f
        skip_zero,           skip_one_half,   skip_one,
        command_skip_zero,   command_skip,    skip;

    return  skip_zero( input, 0 );

  String
  skip_zero( String s, Index k ){
    return  k == kn  ? s  : skip_one_half( s, k );
  }

  String
  skip_one_half( String s, Index k ){
    return  s == sn  ? 0   :  skip_one( s, k );
  }

  String
  skip_one( String s, Index k ){
    return  0[s] == IAC  ? command_skip_zero( s+1, k )  : skip( s, k );
  }

  String
  command_skip_zero( String s, Index k ){
    return  s == sn             ?  0
        :   0[s] != IAC         ?  command_skip( s, k )
        :   /** IAC IAC **/        skip( s, k );
  }

  String
  command_skip( String s, Index k ){
    Count m = command_length( s, sn );
    Count n = sn - s;

    return  m > n  ? 0  : skip_one_half( s+m, k );
  }

  String
  skip( String s, Index k ){
    return  0[s] == w[k]        ?  skip_zero( s+1, k+1 )
        :   k == 0              ?  skip_one_half( s+1, 0   )

        :   /** !=, k > 0 **/      skip( s, walkback[k] );
  }
}

Length
command_length( String s, String sn ){
    return  *s == IAC                   ?  1

        :   *s == WILL                  ?  2
        :   *s == WONT                  ?  2
        :   *s == DO                    ?  2
        :   *s == DONT                  ?  2

        :   /*** otherwise ***/            command_length_unknown( s, sn )
    ;
}

Length
command_length_unknown( String s, String sn ){
    return  1;  // TBD - is there something better here?                        
}
//-------------------cut here-----------------------

and here is the C++ code:

//-------------------cut here-----------------------
/*** core string search routine ***/

typedef char *String;
typedef unsigned long    Index, Count, Size, Length, Limit, Extent, Mask, Bits;

typedef struct {
          const String   string;
          const Length   length;
          const  Index  *const table;
} SearchString_data;

typedef     SearchString_data   *SearchString,  SearchString_object[1];

enum : char {
    IAC         = (char) 255,
    WILL        = (char) 251,
    WONT        = (char) 252,
    DO          = (char) 253,
    DONT        = (char) 254,
};


static  Length  command_length( String s, String sn );
static  Length  command_length_unknown( String s, String sn );


String
skip_past3( String input, String sn, SearchString ss ) {
   class search_closure {
    public:
      search_closure( String input, String sn, SearchString ss )
           : input(input), sn(sn), ss(ss),
             walkback(ss->table), kn(ss->length), w(ss->string)
      {}

      String operator ()() const { return skip_zero( input, 0); }

    private:
      const String input;
      const String sn;
      const SearchString ss;
      const Index *walkback;
      const Index kn;
      const String w;

      String
      skip_zero( String s, Index k ) const {
         return  k == kn  ? s  : skip_one_half( s, k );
      }

      String
      skip_one_half( String s, Index k ) const {
         return  s == sn  ? 0   :  skip_one( s, k );
      }

      String
      skip_one( String s, Index k ) const {
         return  0[s] == IAC  ? command_skip_zero( s+1, k )  : skip( s, k );
      }

      String
      command_skip_zero( String s, Index k ) const {
         return  s == sn             ?  0
            :   0[s] != IAC         ?  command_skip( s, k )
            :   /** IAC IAC **/        skip( s, k );
      }

      String
      command_skip( String s, Index k ) const {
         Count m = command_length( s, sn );
         Count n = sn - s;

         return  m > n  ? 0  : skip_one_half( s+m, k );
      }

      String
      skip( String s, Index k ) const {
         return  0[s] == w[k]        ?  skip_zero( s+1, k+1 )
            :   k == 0              ?  skip_one_half( s+1, 0   )

            :   /** !=, k > 0 **/      skip( s, walkback[k] );
      }
   };

   return search_closure{input, sn, ss}();
}


static Length
command_length( String s, String sn ){
    return  *s == IAC                   ?  1

        :   *s == WILL                  ?  2
        :   *s == WONT                  ?  2
        :   *s == DO                    ?  2
        :   *s == DONT                  ?  2

        :   /*** otherwise ***/            command_length_unknown( s, sn )
    ;
}

static Length
command_length_unknown( String s, String sn ){
    return  1;  // TBD - is there something better here?                        
}
//-------------------cut here-----------------------

Reply via email to