C 循环将牵引文件加入到变量中
C 代码分析工具最基础的一步吧,预处理把编译文件整理到一个文件中。
1 //这个demo最终要输出一个预处理后的编译树。 2 3 #include <io.h> 4 #include <time.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <fcntl.h> 9 #include <sys/stat.h> 10 #include <unistd.h> 11 #include <tchar.h> 12 #include <dirent.h> 13 #include <wchar.h> 14 #include <winsock2.h> 15 #include <Windows.h> 16 17 struct chainFile{ 18 struct chainFile *next; 19 char hfilepath[260]; //h头文件路径 20 }; 21 22 struct extFile{ 23 struct extFile *next; 24 char cfilepath[260]; //c文件路径 25 struct chainFile *chain; 26 }; 27 28 struct chainFile *cF; 29 struct extFile *eP,eF; 30 //后期做环境变量处理 31 char incpath[4096]; 32 33 int lstat(const char *str, struct stat *sb) 34 { 35 int fd, rv; 36 37 if ((fd = open(str, 0)) < 0) 38 return (-1); 39 rv = fstat(fd, sb); 40 (void)close(fd); 41 return (rv); 42 } 43 44 //只能通过扩展名去判断,也有一些人会把定义写在h里面!但是一个c文件可以牵引出所有相关联的h来。 45 int is_c_file(char *filename) 46 { 47 int len = strlen(filename); 48 49 //暂时只对C文件做分析 50 if(filename[len-2] == '.' && (filename[len-1] == 'c' || filename[len-1] == 'C')) 51 { 52 printf("........................001\n"); 53 return 1; 54 } 55 return 0; 56 } 57 58 //检查文件是否存在,并能正常打开。 59 int incfileCheck(char *filename) 60 { 61 int fd; 62 63 fd = open(filename,O_RDONLY|O_BINARY,00700); 64 if(fd == -1)return 0; 65 close(fd); 66 return 1; 67 } 68 69 int printInclist() 70 { 71 int fp; 72 73 printf("Output INC list...\n"); 74 fp = open("./inc.txt",O_WRONLY|O_TRUNC|O_CREAT,00700); 75 if(fp==-1)return printf("open file error...\n"); 76 77 for(eP=&eF;eP;eP=eP->next) 78 { 79 write(fp,eP->cfilepath,strlen(eP->cfilepath)); 80 for(cF=eP->chain;cF;cF=cF->next) 81 write(fp,cF->hfilepath,strlen(cF->hfilepath)); 82 } 83 write(fp,"\n\n",strlen("\n\n")); 84 close(fp); 85 } 86 87 // 88 int filesarray(char *file) 89 { 90 int fd; 91 char *pl; 92 struct stat fst; 93 unsigned int i,j,k,n,s,len,ret; 94 unsigned char tstr[260],fpath[512],buf[3200000]; 95 96 printf("-------------|00|----------------\n"); 97 #if 0 98 //如果是C文件 99 if(is_c_file(file)) 100 { 101 //return printf("Not a definition file...\n",file); 102 if(eF.next==0) 103 { 104 eP = &eF; 105 strcpy(eF.cfilepath,file); 106 printf("-------------00----------------\n"); 107 eF.next = malloc(sizeof(struct extFile)); 108 memset(eF.next,0,sizeof(struct extFile)); 109 //初始化inc牵引链 110 eF.chain = malloc(sizeof(struct chainFile)); 111 memset(eF.chain,0,sizeof(struct chainFile)); 112 } 113 else 114 { 115 eP = &eF; 116 while(eP=eP->next); 117 strcpy(eP->cfilepath,file); 118 eP->next = malloc(sizeof(struct extFile)); 119 memset(eP->next,0,sizeof(struct extFile)); 120 //初始化inc牵引链 121 eP->chain = malloc(sizeof(struct chainFile)); 122 memset(eP->chain,0,sizeof(struct chainFile)); 123 } 124 } 125 else 126 {printf("-------------|00----------------\n"); 127 for(cF=eP->chain;cF;cF=cF->next) 128 { 129 if(strcasecmp( cF->hfilepath, file ) == 0) 130 return 0;//已存在不用加入 131 } 132 strcpy(cF->hfilepath,file); 133 cF->next = malloc(sizeof(struct chainFile)); 134 memset(cF->next,0,sizeof(struct chainFile)); 135 } 136 printf("-------------01----------------\n"); 137 //注意这个只是用来做分析工具并非编译器所以不需要关心#elif #else #endif #if #ifdef #ifndef 138 //... 139 140 //如果是C定义文件打开然后去寻找加入要编译的H头文件 141 fd = open(file,O_RDONLY|O_BINARY,00700); 142 if(fd == -1)return printf("open file - %s error...\n",file); 143 fstat( fd, &fst ); 144 145 lseek( fd, 0, SEEK_SET );//再定位文件指针到文件头 146 //我们不考虑大文件了直接分配一个3M空间。 147 if(fst.st_size == 0)return printf("file size is zeero...\n"); 148 else if(fst.st_size > 3200000)return printf("sory file size too large...\n"); 149 //直接读内存缓冲区 150 ret=read(fd,&buf,fst.st_size); 151 if(ret != fst.st_size)return printf("file read size is something the matter...\n"); 152 // 153 for(i=0;i<ret;i++) 154 { 155 pl=&buf[i]; 156 //pl 就是一行的数据 #include <io.h> or #include <" .... 157 for(;pl[i]!='#';i++); 158 for(i++;pl[i]==0x20 || pl[i]== 0x09;i++); 159 //跳过 " "Space //判断后面6个字母include 160 if(pl[i]=='i' && pl[i+1]=='n' && pl[i+2]=='c' && pl[i+3]=='l' && 161 pl[i+4]=='u' && pl[i+5]=='d' && pl[i+6]=='e') 162 {printf("-------------%d----------------\n",i); 163 i+=7; 164 //兼容#include_next 165 if(pl[i]=='_' && pl[i+1]=='n' && pl[i+2]=='e' && pl[i+3]=='x' && pl[i+4]=='t')i+=5; 166 //直接跳过< or " or Space tab... 167 for(;pl[i]==0x3c || pl[i]== 0x22 || pl[i]==0x20 || pl[i]== 0x09;i++); 168 //文件名是连续的不可能出现断行。 169 for(n=0;pl[i]!=0x3e && pl[i]!= 0x22 && pl[i]!=0x20 && pl[i]!= 0x09 && pl[i];i++,n++) 170 { 171 tstr[n] = pl[i]; 172 } 173 tstr[n] = 0; 174 //sys/mman.h //转换成 sys\mman.h 175 for(n=0;tstr[n];n++)if(tstr[n]==0x2f)tstr[n]=0x5c; 176 177 //当前路径需要排最优先位置进行一次搜索 178 if( !GetModuleFileName( GetModuleHandle(NULL), fpath, 256 ) ) 179 { 180 return printf("Cannot install service (%d)\n", GetLastError()); 181 } 182 for(len=strlen(fpath);len>0;len--) 183 if(fpath[len]==0x5c){fpath[len+1]=0;break;} 184 //判断该路径的文件是否存在 185 if(incfileCheck(fpath))return filesarray(fpath); 186 187 len = strlen(incpath); 188 for(j=n=0;n<len;n++) 189 { 190 if(incpath[n]==0x20 || ((n+1)==len)) 191 { 192 for(k=j,s=0;tstr[s];s++,k++) 193 fpath[k] = tstr[s]; 194 fpath[k] = 0; 195 //判断该路径的文件是否存在 196 if(incfileCheck(fpath))return filesarray(fpath); 197 j = 0; 198 continue; 199 } 200 fpath[j] = incpath[n]; 201 j++; 202 } 203 //跳过文件包含符号 204 for(i++;pl[i]==0x3e || pl[i]== 0x22 || pl[i]==0x20 || pl[i]== 0x09;i++); 205 } 206 //#后面可能是 #define #elif #else #endif #error #if #ifdef #ifndef #line #pragma #undef #include #include_next 207 //... 208 for(;pl[i]== 0x0d || pl[i]== 0x0a;i++); 209 } 210 close(fd); 211 #endif 212 } 213 214 //递归循环指定目录下一个所有文件 215 void ListFolderContents(const char *root) 216 { 217 DIR *sdir; 218 DWORD attrib; 219 char subdir[512],dupdir[1024]; 220 struct dirent *ptr; 221 struct stat stbuf; 222 223 sdir = opendir(root); 224 225 while((ptr = readdir(sdir))!=NULL) 226 { 227 if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0)continue; 228 //判断是目录还是文件或者链接 229 sprintf(subdir,"%s%s",root,ptr->d_name); 230 lstat(subdir,&stbuf); 231 //printf("[root=%s]\nsubdir: %s stbuf.st_mode=%x isdir=%d\n",root,subdir,stbuf.st_mode,S_ISDIR(stbuf.st_mode)); 232 //Sleep(3000);//调试 233 unsigned len = MultiByteToWideChar(0, 0, subdir, strlen(subdir), NULL, 0); 234 if (len == 0) return printf("error ---001----------\n"); 235 else 236 { 237 memset(dupdir,0,1024); 238 len = MultiByteToWideChar(0, 0, subdir, strlen(subdir), dupdir, len); 239 if (len == 0) return printf("error ---002----------\n"); 240 } 241 printf("%s\n",subdir);//遍历输出全部的文件 242 //Sleep(1000); 243 attrib = GetFileAttributesW(dupdir); 244 //printf("[attrib=%d][attrib=%ul]\n",attrib,attrib); 245 //遍历子目录 246 //if(S_ISDIR(stbuf.st_mode)) //linux 247 if(attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) 248 { 249 strcat(subdir,"\\"); 250 ListFolderContents(subdir); 251 } 252 else 253 { 254 if(is_c_file(subdir))filesarray(subdir); 255 } 256 } 257 closedir(sdir); 258 } 259 260 261 int main(int argc, char *argv[]) 262 { 263 int len; 264 static char ServicePath[512]; 265 266 memset(&eF,0,sizeof(struct extFile)); 267 if( !GetModuleFileName( GetModuleHandle(NULL), ServicePath, 256 ) ) 268 { 269 return printf("Cannot install service (%d)\n", GetLastError()); 270 } 271 for(len=strlen(ServicePath);len>0;len--) 272 if(ServicePath[len]==0x5c){ServicePath[len+1]=0;break;} 273 274 //手动在这里配置一个inc目录,当前项目路径默认是没加入的 275 //strcpy(incpath,ServicePath); 276 //...strcpy(incpath,"d:\\include\\"); 277 278 279 ListFolderContents(ServicePath);//windows 280 281 282 //输出排列好的文件预编译列表 283 printInclist(); 284 }
下载地址:printInclist
Serious. Nonsense