Print this page
11972 resync smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/char.c
+++ new/usr/src/tools/smatch/src/char.c
1 1 #include <string.h>
2 2 #include "target.h"
3 3 #include "lib.h"
4 4 #include "allocate.h"
5 5 #include "token.h"
6 6 #include "expression.h"
7 7 #include "char.h"
8 8
9 9 static const char *parse_escape(const char *p, unsigned *val, const char *end, int bits, struct position pos)
10 10 {
11 11 unsigned c = *p++;
12 12 unsigned d;
13 13 if (c != '\\') {
14 14 *val = c;
15 15 return p;
16 16 }
17 17
18 18 c = *p++;
19 19 switch (c) {
20 20 case 'a': c = '\a'; break;
21 21 case 'b': c = '\b'; break;
22 22 case 't': c = '\t'; break;
23 23 case 'n': c = '\n'; break;
24 24 case 'v': c = '\v'; break;
25 25 case 'f': c = '\f'; break;
26 26 case 'r': c = '\r'; break;
27 27 case 'e': c = '\e'; break;
28 28 case 'x': {
29 29 unsigned mask = -(1U << (bits - 4));
30 30 for (c = 0; p < end; c = (c << 4) + d) {
31 31 d = hexval(*p);
32 32 if (d > 16)
33 33 break;
34 34 p++;
35 35 if (c & mask) {
36 36 warning(pos,
37 37 "hex escape sequence out of range");
38 38 mask = 0;
39 39 }
40 40 }
41 41 break;
42 42 }
43 43 case '0'...'7': {
44 44 if (p + 2 < end)
45 45 end = p + 2;
46 46 c -= '0';
47 47 while (p < end && (d = *p - '0') < 8) {
48 48 c = (c << 3) + d;
49 49 p++;
50 50 }
51 51 if ((c & 0400) && bits < 9)
52 52 warning(pos,
53 53 "octal escape sequence out of range");
54 54 break;
55 55 }
56 56 default: /* everything else is left as is */
57 57 warning(pos, "unknown escape sequence: '\\%c'", c);
58 58 break;
59 59 case '\\':
60 60 case '\'':
61 61 case '"':
62 62 case '?':
63 63 break; /* those are legal, so no warnings */
64 64 }
65 65 *val = c & ~((~0U << (bits - 1)) << 1);
66 66 return p;
67 67 }
68 68
69 69 void get_char_constant(struct token *token, unsigned long long *val)
70 70 {
71 71 const char *p = token->embedded, *end;
72 72 unsigned v;
73 73 int type = token_type(token);
74 74 switch (type) {
75 75 case TOKEN_CHAR:
76 76 case TOKEN_WIDE_CHAR:
↓ open down ↓ |
76 lines elided |
↑ open up ↑ |
77 77 p = token->string->data;
78 78 end = p + token->string->length - 1;
79 79 break;
80 80 case TOKEN_CHAR_EMBEDDED_0 ... TOKEN_CHAR_EMBEDDED_3:
81 81 end = p + type - TOKEN_CHAR;
82 82 break;
83 83 default:
84 84 end = p + type - TOKEN_WIDE_CHAR;
85 85 }
86 86 p = parse_escape(p, &v, end,
87 - type < TOKEN_WIDE_CHAR ? bits_in_char : bits_in_wchar, token->pos);
87 + type < TOKEN_WIDE_CHAR ? bits_in_char : wchar_ctype->bit_size, token->pos);
88 88 if (p != end)
89 89 warning(token->pos,
90 90 "multi-character character constant");
91 91 *val = v;
92 92 }
93 93
94 94 struct token *get_string_constant(struct token *token, struct expression *expr)
95 95 {
96 96 struct string *string = token->string;
97 97 struct token *next = token->next, *done = NULL;
98 98 int stringtype = token_type(token);
99 99 int is_wide = stringtype == TOKEN_WIDE_STRING;
100 100 static char buffer[MAX_STRING];
101 101 int len = 0;
102 102 int bits;
103 103 int esc_count = 0;
104 104
105 105 while (!done) {
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
106 106 switch (token_type(next)) {
107 107 case TOKEN_WIDE_STRING:
108 108 is_wide = 1;
109 109 case TOKEN_STRING:
110 110 next = next->next;
111 111 break;
112 112 default:
113 113 done = next;
114 114 }
115 115 }
116 - bits = is_wide ? bits_in_wchar : bits_in_char;
116 + bits = is_wide ? wchar_ctype->bit_size: bits_in_char;
117 117 while (token != done) {
118 118 unsigned v;
119 119 const char *p = token->string->data;
120 120 const char *end = p + token->string->length - 1;
121 121 while (p < end) {
122 122 if (*p == '\\')
123 123 esc_count++;
124 124 p = parse_escape(p, &v, end, bits, token->pos);
125 125 if (len < MAX_STRING)
126 126 buffer[len] = v;
127 127 len++;
128 128 }
129 129 token = token->next;
130 130 }
131 131 if (len > MAX_STRING) {
132 132 warning(token->pos, "trying to concatenate %d-character string (%d bytes max)", len, MAX_STRING);
133 133 len = MAX_STRING;
134 134 }
135 135
136 136 if (esc_count || len >= string->length) {
137 137 if (string->immutable || len >= string->length) /* can't cannibalize */
138 138 string = __alloc_string(len+1);
139 139 string->length = len+1;
140 140 memcpy(string->data, buffer, len);
141 141 string->data[len] = '\0';
142 142 }
143 143 expr->string = string;
144 144 expr->wide = is_wide;
145 145 return token;
146 146 }
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX