deps/kb_meme/meme-5.0.1/src/alph-in.c
/*
 * decode_string
 * Do an in-place decoding of the backslash escaped, UTF-8 encoded string.
 * The backslash escapes will be converted into UTF-8. Any control characters
 * will be removed. The text will be truncated to 30 codepoints.
 * When an empty string is provided it will be freed and NULL returned.
 */
decode_string
Do an in-place decoding of the backslash escaped, UTF-8 encoded string.
The backslash escapes will be converted into UTF-8. Any control characters
will be removed. The text will be truncated to 30 codepoints.
When an empty string is provided it will be freed and NULL returned.
decode_string Do an in - place decoding of the backslash escaped UTF - 8 encoded string . The backslash escapes will be converted into UTF - 8 . Any control characters will be removed . The text will be truncated to 30 codepoints . When an empty string is provided it will be freed and NULL returned .
static char* decode_string(char* str, bool *warn_length, bool *warn_disallowed) {
  int32_t codepoint;
  int name_bytes, char_count, offset, dest_offset, code_unit_length, name_length;
  bool keep_letter;
  char hexnum[5];
  *warn_disallowed = false;
  *warn_length = false;
  if (str != NULL && str[0] != '\0') {
    name_bytes = strlen(str);
    name_length = 0;
    offset = 0;
    dest_offset = 0;
    while (offset < name_bytes) {
      keep_letter = true;
      codepoint = unicode_from_string(str+offset, name_bytes - offset, &char_count);
      if (codepoint < 0) die("Encoding of alphabet is not valid UTF-8");
      if (str[offset] == '\\') {
        if ((offset + 1) >= name_bytes) die("Not enough characters to handle escape sequence");
        switch(str[offset+1]) {
          case '"':
          case '\\':
          case '/':
            codepoint = str[offset+1] - 0x0;
            char_count = 2;
            break;
          case 'b':
          case 'f':
          case 'n':
          case 'r':
          case 't':
            char_count = 2;
            keep_letter = false;
            break;
          case 'u':
            if ((offset + 5) >= name_bytes) die("Not enough characters to handle escape sequence");
            char_count = 6;
            strncpy(hexnum, str+(offset+2), 4);
            hexnum[4] = '\0';
            codepoint = strtol(hexnum, NULL, 16);
            break;
        }
      }
      if ((codepoint >= 0x0 && codepoint <= 0x1F) || codepoint == 0x7F || 
          (codepoint >= 0x80 && codepoint <= 0x9F) || 
          codepoint == 0x2028 || codepoint == 0x2029 || 
          codepoint == 0x200E || codepoint == 0x200F || (codepoint >= 0x202A && codepoint <= 0x202E) 
      ) {
        keep_letter = false;
      }
      if (keep_letter) {
        if (name_length < 40) {
          unicode_to_string(codepoint, str+dest_offset, &code_unit_length);
          dest_offset += code_unit_length;
          name_length++;
        } else {
          *warn_length = true;
        }
      } else {
        *warn_disallowed = true;
      }
      offset += char_count;
    }
    str[dest_offset] = '\0';
    if (dest_offset < name_bytes) {
      str = mm_realloc(str, sizeof(char) * (dest_offset + 1));
    }
  }
  if (str != NULL && str[0] == '\0') {
    free(str);
    str = NULL;
  }
  return str;
}
static char * decode_string ( char * str , bool * warn_length , bool * warn_disallowed ) { int32_t codepoint ; int name_bytes , char_count , offset , dest_offset , code_unit_length , name_length ; bool keep_letter ; char hexnum [ 5 ] ; * warn_disallowed = false ; * warn_length = false ; if ( str != NULL && str [ 0 ] != ' \0 ' ) { name_bytes = strlen ( str ) ; name_length = 0 ; offset = 0 ; dest_offset = 0 ; while ( offset < name_bytes ) { keep_letter = true ; codepoint = unicode_from_string ( str + offset , name_bytes - offset , & char_count ) ; if ( codepoint < 0 ) die ( " " ) ; if ( str [ offset ] == ' \\ ' ) { if ( ( offset + 1 ) >= name_bytes ) die ( " " ) ; switch ( str [ offset + 1 ] ) { case ' ' : case ' \\ ' : case ' ' : codepoint = str [ offset + 1 ] - 0x0 ; char_count = 2 ; break ; case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : char_count = 2 ; keep_letter = false ; break ; case ' ' : if ( ( offset + 5 ) >= name_bytes ) die ( " " ) ; char_count = 6 ; strncpy ( hexnum , str + ( offset + 2 ) , 4 ) ; hexnum [ 4 ] = ' \0 ' ; codepoint = strtol ( hexnum , NULL , 16 ) ; break ; } } if ( ( codepoint >= 0x0 && codepoint <= 0x1F ) || codepoint == 0x7F || ( codepoint >= 0x80 && codepoint <= 0x9F ) || codepoint == 0x2028 || codepoint == 0x2029 || codepoint == 0x200E || codepoint == 0x200F || ( codepoint >= 0x202A && codepoint <= 0x202E ) ) { keep_letter = false ; } if ( keep_letter ) { if ( name_length < 40 ) { unicode_to_string ( codepoint , str + dest_offset , & code_unit_length ) ; dest_offset += code_unit_length ; name_length ++ ; } else { * warn_length = true ; } } else { * warn_disallowed = true ; } offset += char_count ; } str [ dest_offset ] = ' \0 ' ; if ( dest_offset < name_bytes ) { str = mm_realloc ( str , sizeof ( char ) * ( dest_offset + 1 ) ) ; } } if ( str != NULL && str [ 0 ] == ' \0 ' ) { free ( str ) ; str = NULL ; } return str ; }
decode_string
 Do an in-place decoding of the backslash escaped, UTF-8 encoded string.
decode_string Do an in - place decoding of the backslash escaped UTF - 8 encoded string .
// need to parse as UTF-8 with backslash escapes to get correct string // length and remove disallowed characters // first convert to a codepoint // the regular expression should ensure this is a valid escape sequence // we accept these normal characters // these are all control characters so we reject them // this unicode escape could be anything so we convert it to a codepoint // ASCII range control characters (aka C0) // C1 // line separator and paragraph separator // Bidirectional text control // these characters are not allowed because they could stuff things up... // when the str is empty, set it to null