c_str.c
author viric@llimona
Wed, 04 Jul 2007 21:45:12 +0200
changeset 13 fd73b72d5752
parent 8 4ecd557ebebf
permissions -rw-r--r--
Added tag v0.1 for changeset f81dd70a9b0b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     1
#include <stdio.h>
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     2
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     3
#include "sreplace.h"
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     4
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     5
/* Complete set of backslash sequences:
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     6
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     7
 From K&R, The C Programming Language, Chapter 2, Constants.
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     8
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
     9
 \b backspace
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    10
 \?  question mark
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    11
 \f formfeed
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    12
  \' single quote
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    13
 \n newline
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    14
 \" double quote
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    15
 \r carriage return
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    16
 \ooo octal number
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    17
 \t horizontal tab
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    18
 \xhh hexadecimal number 
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    19
 \v vertical tab
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    20
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    21
 (\\ backslash)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    22
*/
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    23
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    24
/* Returns length */
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    25
int parse_backslashes(unsigned char *str)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    26
{
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    27
  int was_backslash = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    28
  int was_octal = 0; /* 0 to 3 */
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    29
  int was_hex = 0; /* 0 to 2 */
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    30
  unsigned char *write_str = str;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    31
  unsigned char *start = str;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    32
  unsigned char newchar;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    33
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    34
  while (*str != 0)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    35
  {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    36
    if (*str == '\\' && !was_backslash)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    37
      was_backslash = 1;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    38
    else
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    39
    {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    40
      if (was_octal)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    41
      {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    42
        if (was_octal < 3 && *str >= '0' && *str <= '7')
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    43
        {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    44
          newchar = (newchar * 8) + (*str - '0');
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    45
          was_octal += 1;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    46
          if (was_octal == 3)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    47
          {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    48
            *(write_str++) = newchar;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    49
            was_octal = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    50
          }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    51
        } else /* Didn't come octal char. End of oct string. */
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    52
        {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    53
          *(write_str++) = newchar;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    54
          *(write_str++) = *str;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    55
          was_octal = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    56
        }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    57
      }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    58
      else if (was_hex)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    59
      {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    60
        unsigned char base = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    61
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    62
        if (*str >= '0' && *str <= '9')
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    63
          base = '0';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    64
        else if (*str >= 'a' && *str <= 'f')
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    65
          base = 'a' - 10;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    66
        else if (*str >= 'A' && *str <= 'F')
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    67
          base = 'A' - 10;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    68
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    69
        if (base != 0) /* Came hex char */
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    70
        {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    71
          newchar = (newchar * 16) + (*str - base);
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    72
          was_hex += 1;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    73
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    74
          if (was_hex == 3) /* End of hex string */
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    75
          {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    76
            *(write_str++) = newchar;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    77
            was_hex = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    78
          }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    79
        }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    80
        else /* Non-hex char came. End of hex string */
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    81
        {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    82
          *(write_str++) = newchar;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    83
          *(write_str++) = *str;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    84
          was_hex = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    85
        }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    86
      }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    87
      else if (was_backslash)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    88
      { switch(*str)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    89
        {
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    90
          case '\\':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    91
            *(write_str++) = '\\';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    92
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    93
          case 'n':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    94
            *(write_str++) = '\n';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    95
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    96
          case 't':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    97
            *(write_str++) = '\t';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    98
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
    99
          case 'r':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   100
            *(write_str++) = '\r';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   101
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   102
          case 'v':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   103
            *(write_str++) = '\v';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   104
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   105
          case 'f':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   106
            *(write_str++) = '\f';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   107
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   108
          case 'b':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   109
            *(write_str++) = '\b';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   110
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   111
          case '0':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   112
          case '1':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   113
          case '2':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   114
          case '3':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   115
          case '4':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   116
          case '5':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   117
          case '6':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   118
          case '7':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   119
            was_octal = 1;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   120
            newchar = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   121
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   122
          case 'x':
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   123
            was_hex = 1;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   124
            newchar = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   125
            break;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   126
          default:
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   127
            *(write_str++) = *str;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   128
        }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   129
        was_backslash = 0;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   130
      }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   131
      else
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   132
        *(write_str++) = *str;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   133
    }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   134
    ++str;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   135
  }
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   136
  *(write_str) = '\0';
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   137
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   138
  /* We calculate length with distance between the last
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   139
   * written char and the start of the string */
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   140
  return write_str - start;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   141
}
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   142
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   143
void print_hex(FILE *out, const struct String *str)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   144
{
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   145
    int i;
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   146
8
4ecd557ebebf Removing debug info in stderr.
lbatlle@npdl268.bpo.hp.com
parents: 7
diff changeset
   147
    /*
7
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   148
    fprintf(out, "Length: %i\n", str->length);
8
4ecd557ebebf Removing debug info in stderr.
lbatlle@npdl268.bpo.hp.com
parents: 7
diff changeset
   149
    */
7
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   150
    for (i = 0; i < str->length; ++i)
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   151
        fprintf(out, "%02hhx", str->ptr[i]);
fcde17ef6af6 Separated backslash C parser library.
viric@llimona
parents:
diff changeset
   152
}