File indexing completed on 2024-12-08 04:20:01
0001 /* 0002 Copyright (C) 2006 Justin Karneges <justin@affinix.com> 0003 0004 Permission is hereby granted, free of charge, to any person obtaining a copy 0005 of this software and associated documentation files (the "Software"), to deal 0006 in the Software without restriction, including without limitation the rights 0007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 0008 copies of the Software, and to permit persons to whom the Software is 0009 furnished to do so, subject to the following conditions: 0010 0011 The above copyright notice and this permission notice shall be included in 0012 all copies or substantial portions of the Software. 0013 0014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0017 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 0018 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 0019 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0020 */ 0021 0022 #include <stdio.h> 0023 #include <stdlib.h> 0024 #include <string.h> 0025 0026 static char *read_file(const char *fname) 0027 { 0028 FILE *f; 0029 char *buf; 0030 int size; 0031 0032 f = fopen(fname, "r"); 0033 if (!f) 0034 return 0; 0035 0036 fseek(f, 0l, SEEK_END); 0037 size = ftell(f); 0038 rewind(f); 0039 buf = malloc(size + 1); 0040 if (!buf) { 0041 fclose(f); 0042 return 0; 0043 } 0044 0045 fread(buf, size, 1, f); 0046 buf[size] = 0; 0047 fclose(f); 0048 0049 return buf; 0050 } 0051 0052 static void write_file(const char *fname, const char *buf) 0053 { 0054 FILE *f; 0055 0056 f = fopen(fname, "w"); 0057 fwrite(buf, strlen(buf), 1, f); 0058 fclose(f); 0059 } 0060 0061 static char *insert_string(char *buf, char *str, int at) 0062 { 0063 int bsize, slen; 0064 bsize = strlen(buf) + 1; 0065 slen = strlen(str); 0066 0067 buf = realloc(buf, bsize + slen); 0068 if (!buf) 0069 return 0; 0070 memmove(buf + at + slen, buf + at, bsize - at); 0071 memcpy(buf + at, str, slen); 0072 return buf; 0073 } 0074 0075 static int is_include(const char *buf) 0076 { 0077 char *p, *sub; 0078 int len; 0079 0080 if (buf[0] != '#') 0081 return 0; 0082 0083 p = strchr(buf, '\n'); 0084 if (!p) 0085 return 0; 0086 0087 // take the substring 0088 ++buf; 0089 len = p - buf; 0090 sub = malloc(len + 1); 0091 memcpy(sub, buf, len); 0092 sub[len] = 0; 0093 0094 if (strstr(sub, "include")) { 0095 free(sub); 0096 return 1; 0097 } 0098 free(sub); 0099 return 0; 0100 } 0101 0102 static const char *find_include(const char *buf) 0103 { 0104 const char *p = buf; 0105 0106 if (p[0] == '#') { 0107 if (is_include(p)) 0108 return p; 0109 } 0110 0111 while (1) { 0112 p = strstr(p, "\n#"); 0113 if (!p) 0114 break; 0115 ++p; 0116 if (is_include(p)) 0117 return p; 0118 } 0119 0120 return 0; 0121 } 0122 0123 static const char *find_std(const char *buf) 0124 { 0125 const char *p; 0126 p = strstr(buf, "namespace std"); 0127 return p; 0128 } 0129 0130 static const char *skip_to_next_curly(const char *buf) 0131 { 0132 int n; 0133 for (n = 0; buf[n]; ++n) { 0134 if (buf[n] == '{' || buf[n] == '}') 0135 return (buf + n); 0136 } 0137 return 0; 0138 } 0139 0140 static const char *skip_over_curlies(const char *buf) 0141 { 0142 const char *p; 0143 int opened; 0144 0145 p = strchr(buf, '{'); 0146 if (!p) 0147 return buf; 0148 0149 ++p; 0150 opened = 1; 0151 while (opened) { 0152 p = skip_to_next_curly(p); 0153 if (!p) 0154 return 0; 0155 if (*p == '{') 0156 ++opened; 0157 else if (*p == '}') 0158 --opened; 0159 ++p; 0160 } 0161 return p; 0162 } 0163 0164 void do_it(char *buf, char *ns) 0165 { 0166 char str[256], str_end[256]; 0167 const char *p, *p2; 0168 int slen, slen_end; 0169 int at; 0170 0171 sprintf(str, "namespace %s { // WRAPNS_LINE\n", ns); 0172 slen = strlen(str); 0173 0174 sprintf(str_end, "} // WRAPNS_LINE\n", ns); 0175 slen_end = strlen(str_end); 0176 0177 at = 0; 0178 while (1) { 0179 // make sure there is a line left 0180 p = strchr(buf + at, '\n'); 0181 if (!p) 0182 break; 0183 0184 // open the namespace 0185 buf = insert_string(buf, str, at); 0186 at += slen; 0187 0188 // find an #include, "namespace std", or the end 0189 int f = 0; 0190 p = find_include(buf + at); 0191 p2 = find_std(buf + at); 0192 if (p && (!p2 || p < p2)) { 0193 f = 1; 0194 } else if (p2) { 0195 f = 2; 0196 p = p2; 0197 } 0198 0199 if (f == 0) { 0200 // point to the end 0201 at = strlen(buf); 0202 } else if (f == 1) { 0203 printf("found include\n"); 0204 at = p - buf; 0205 } else if (f == 2) { 0206 printf("found std\n"); 0207 at = p - buf; 0208 } 0209 0210 // close it 0211 buf = insert_string(buf, str_end, at); 0212 at += slen_end; 0213 0214 if (f == 1) { 0215 // go to next line 0216 p = strchr(buf + at, '\n'); 0217 if (!p) 0218 break; 0219 at = p - buf + 1; 0220 } else if (f == 2) { 0221 p = skip_over_curlies(buf + at); 0222 if (!p) 0223 break; 0224 at = p - buf; 0225 0226 // go to next line 0227 p = strchr(buf + at, '\n'); 0228 if (!p) 0229 break; 0230 at = p - buf + 1; 0231 } 0232 } 0233 } 0234 0235 int main(int argc, char **argv) 0236 { 0237 char *buf; 0238 0239 if (argc < 3) { 0240 printf("usage: wrapns [file] [namespace]\n\n"); 0241 return 1; 0242 } 0243 0244 buf = read_file(argv[1]); 0245 do_it(buf, argv[2]); 0246 write_file(argv[1], buf); 0247 free(buf); 0248 0249 return 0; 0250 }