My_strtoul



  • Although converting strings to numbers is a common WTF, this one -- which I found when debugging some code that was giving bizarre unexpected results, and presented exactly as it is in our code -- has some real gems.

    Possibly my favorite part is that based on the function names, whoever wrote this code knew that standard library functions existed to do this job, but they decided that they could do a better job of it themselves. Bonus points for defining my_atoi which one would expect to be a reimplementation of atoi(), but in fact does something completely different.

    unsigned long my_strtoul(char* str, int base) {
      int str_size = strlen(str);
    
      #define MAX_STR_LEN  8
    
      int ival[MAX_STR_LEN] = {0};
    
      unsigned long ret_long = 0;
      int i,j;
      unsigned long tmp_val;
    
    
      if (str_size > 8) {
        str_size = MAX_STR_LEN;
      }
    
      for (i=0; i<str_size; i++) {
        if (base == 10) {
          if (!my_isdigit(str[i])) {
            str_size = i;
            break;
          }
        }
        else {
          if (!my_isxdigit(str[i])) {
            str_size = i;
            break;
          }
        }
      } /* end for */
    
    
      for (i=0; i<str_size; i++) {
        ival[i] = my_atoi(str[i], base);
      }
      
      if (base == 10) {
        for (i=0; i<str_size; i++) {
          tmp_val = ival[i];
          for (j = (str_size-1); j>i; j--) {
            tmp_val *= base;
          }
          ret_long += tmp_val;
        }
      } /* base 10 */
    
    
      else if (base == 16) {
        ret_long = 0;
        for (i=0; i<str_size; i++) {
          ret_long |= (unsigned long) ival[i];
          if (i != (str_size -1))
            ret_long <<= 4;    /* shift by 4 bit */
        }
      } /* base 16 */
      
      return ret_long;
    }
    
    int my_isdigit(char c) {
      return ((c - '0') < 10);
    }
    
    int my_isxdigit(char c) {
      return ( ((c - '0') < 10) ||
               ((c - 'a') < 6)  ||
               ((c - 'A') < 6) );
    }
    
    int my_atoi(char a, int base) {
      
      int i = 0;
      
      if (base == 10) { 
        if (!my_isdigit(a))
          return -1; 
      }
      else if (base == 16) {
        if ( !my_isxdigit(a) )
          return -1;
      }
    
      i = a - '0';
    
      if (base == 16) {
        if ( (a == 'a') || (a == 'A'))
           i = 10;
        else if ( (a == 'b') || (a == 'B'))
           i = 11;
        else if ( (a == 'c') || (a == 'C'))
           i = 12;
        else if ( (a == 'd') || (a == 'D'))
           i = 13;
        else if ( (a == 'e') || (a == 'E'))
           i = 14;
        else if ( (a == 'f') || (a == 'F'))
           i = 15;
      } /* end if (base == 16) */
    
      return i;
    }
    

  • Discourse touched me in a no-no place

    @Strolskon said:

    int my_isdigit(char c) {
    return ((c - '0') < 10);
    }
    So “!” is a digit?


  • Trolleybus Mechanic

     1) Anything in computers that stats with "my" is shit. I dare you to find a counterexample.

    2) I keep glance-reading that function as "my_stool", and not the kind you sit on.



  • @dkf said:

    @Strolskon said:
    int my_isdigit(char c) {
    return ((c - '0') < 10);
    }
    So “!” is a digit?

    That one's fun because whether or not it works depends on the compiler. ('char' may be signed or unsigned.)

    And we've switched compilers over the years on this project. Guess what one of the differences between them is...



  • @Lorne Kates said:

    and not the kind you sit on.
     

    You can do both at once.



  • @Lorne Kates said:

    1) Anything in computers that stats with "my" is shit.

    Local variables in Perl?



  • @Zemm said:

    @Lorne Kates said:
    1) Anything in computers that stats with "my" is shit.

    Local variables in Perl?

    Probably a poor choice of counterexample (assuming you intended it to be a counterexample). Some on here would say, "Anything in computers that stats with "my" Perl is shit."



  • @HardwareGeek said:

    @Zemm said:
    @Lorne Kates said:
    1) Anything in computers that stats with "my" is shit.

    Local variables in Perl?

    Probably a poor choice of counterexample (assuming you intended it to be a counterexample). Some on here would say, "Anything in computers that stats with "my" Perl is shit."

    My Windows Phone



  • @Lorne Kates said:

    "my_stool", and not the kind you sit on.
    I wouldn't be so sure about that... Rule 34 exists for a reason.



  • @Lorne Kates said:

    Anything in computers that starts with "my" is shit. I dare you to find a counterexample.

    I always hear bad things about MySQL.


  • Considered Harmful

    @Lorne Kates said:

     1) Anything in computers that stats with "my" is shit.

    phpMyAdmin doesn't start with "my".



  • @joe.edwards said:

    phpMyAdmin doesn't start with "my".
    It starts with php, which is worse.


  • Discourse touched me in a no-no place

    @Lorne Kates said:

    Anything in computers that stats with "my" is shit.
    One of our products matches that name, but it's not quite that bad. (OK, so it's a website driven by spreadsheet… I'm not doing my cause any good here, am I?)


Log in to reply