File: unescape1.cc

package info (click to toggle)
bobcat 2.08.01-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 5,668 kB
  • ctags: 953
  • sloc: cpp: 10,403; makefile: 9,042; perl: 401; sh: 195
file content (128 lines) | stat: -rw-r--r-- 3,823 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "string.ih"

namespace
{
    char const escapeChars[] = "abfnrtv";
    char const escapeValue[] = {'\a', '\b', '\f', '\n', '\r', '\t', '\v'};

    size_t handleOctal(string *dest, string const &src, size_t pos)
    {
        size_t pos2 = min(src.length(), 
                          src.find_first_not_of("01234567", pos));

        if (pos2 == pos + 1 && src[pos] == '0') // saw \0
        {
            *dest += static_cast<char>(0);
            return pos2;
        }

        size_t const nOct = 3;                // need exactly 3 octals

        pos2 = min(pos + nOct, pos2);

        if (pos2 != pos + nOct)                 // need exactly nOct octals
        {
            *dest += src[pos];                  // add next char if not so
            return pos + 1;                     // next to handle
        }

        A2x a2x(src.substr(pos, nOct));

        size_t ch;
        a2x >> oct >> ch;                       // convert substr. to octal
        *dest += static_cast<char>(ch);         // append the octal value
        return pos2;                            // pos. of next to handle
    }

    size_t handleHex(string *dest, string const &src, size_t pos)
    {
        size_t const nHex = 2;                // need exactly 2 hex digits

        ++pos;                                  // skip the 'x'
        size_t pos2 = min(pos + nHex, 
                            src.find_first_not_of(
                                "0123456789abcdefABCDEF", pos));

        if (pos2 != pos + nHex)                 // found a hex character?
        {
            *dest += src[pos - 1];              // add next char if so
            return pos;                         // next char to handle
        }

        A2x a2x(src.substr(pos, nHex));
        size_t ch;
        a2x >> hex >> ch;                       // convert substr. to hex
        *dest += static_cast<char>(ch);         // append the hex value

        return pos2;                            // pos. of next to handle
    }
}

string String::unescape(string const &str)
{
    string ret;

    size_t prefix = 0;                    // prefix text before \-char
    size_t pos = 0;

    while (true)
    {
        pos = str.find('\\', pos);
        ret += str.substr(prefix, pos - prefix);// append prefix

        if (pos == string::npos)            // done if no more \-chars
            return ret;

        ++pos;                              // skip \-char

        if (pos == str.length())            // \-char terminates: remove it
            return ret;                     // since we're removing \-chars


        int next = str[pos];                // determine next char

        if (char const *cp = strchr(escapeChars, next))// escape sequence ?
        {
            ret += escapeValue[cp - escapeChars];// then assign escape char
            ++pos;                          // next character to handle
        }
        else if (strchr("01234567", next))  // handle octal values
            pos = handleOctal(&ret, str, pos);

        else if (next == 'x')               // handle hex values
            pos = handleHex(&ret, str, pos);
        else                                // handle lone characters
            ret += str[pos++];     

        prefix = pos; 
    }
}

//#include <string>
//#include <iostream>
//using namespace std;
//using namespace FBB;
//
//void out(char ch)
//{
//    cout << static_cast<size_t>(static_cast<unsigned char>(ch)) << ", ";
//}
//
//int main()
//{
//    while (true)
//    {
//        cout << "? ";
//        string str;
//
//        if (!getline(cin, str))
//            return(0);
//
//        cout << str << " -> ";
//        str = String::unescape(str);
//        cout << str << '\n';
//
//        for_each(str.begin(), str.end(), out);
//        cout << '\n';
//    }
//}