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

posted @ 2020-07-24 16:38  一本正经-胡说八道  阅读(251)  评论(0编辑  收藏  举报