📜 ⬆️ ⬇️

How I searched for dependencies through include files in java

Good day. Today I will talk about how to perform part of the work on the certification of the code according to the requirements of the FDEC RD (control of the absence of undated capabilities). In the static analysis requirements there is a requirement to control the compilation of files or answer the question whether all files are compiled into object files and whether there are any files that are not compiled. To do this, make lists of files cpp, c, h. To do this, go to the source folder and execute the “find. -iname * .cpp "," find. -iname * .c "," find. -iname * .o "write the output in the files" c_cpp_files.txt "and" h_files.txt ".

We will have files with the following contents:

./arch/powerpc/math-emu/fmul.c
./arch/powerpc/math-emu/lfd.c
./arch/powerpc/math-emu/fsqrt.c
./arch/powerpc/math-emu/fsub.c
./arch/powerpc/math-emu/fnmsub.c
./arch/powerpc/math-emu/frsqrte.c
./arch/powerpc/math-emu/mtfsb0.c
...

and accordingly the following:

./arch/powerpc/include/asm/udbg.h
./arch/powerpc/include/asm/termios.h
./arch/powerpc/include/asm/immap_cpm2.h
./arch/powerpc/include/asm/linkage.h
./arch/powerpc/include/asm/rio.h
./arch/powerpc/include/asm/dma-mapping.h
...


Next, we analyze which Include s are found in which * .c or * .cpp files. To do this, use the following code:
')
Incl.java file:

 /*         */ public class Incl { public String text; public int line; } 

InclPoints.java file:

 import java.io.File; import java.util.List; public class InclPoints { public File headers; public List<Point> points; } 

Includes.java file:

 import java.io.File; import java.util.ArrayList; import java.util.List; public class Includes { public File file; //      public List<Incl> incl=new ArrayList<>(); //   } 

Point.java file:

 import java.io.File; public class Point { public File src; public Incl incl; } 

and the file Main.java:

 import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static File reportFile; public static File header_file; public static File sources_file; public static Map<Integer,File> headers_nouse; public static Map<Integer,File> headers_withuse; public static int header_nouse_counter; public static int header_withuse_counter; private static List<InclPoints> incpo_lst; //public List<InclPoints> incpo_lst; public static void main(String[] args) { func1(args); } public static Map<Integer,File> readCodeList(String path_to_code) { Map<Integer,File> code_files= new TreeMap<>(); int file_counter=0; try (BufferedReader br = new BufferedReader(new FileReader(path_to_code))) { String current_source_line; while ((current_source_line = br.readLine()) != null) { current_source_line=current_source_line.trim(); code_files.put(file_counter, new File(current_source_line)); file_counter++; } } catch(IOException ex){ System.out.println(ex.getMessage()); } return code_files; } public static Map<Integer,File> readheadersFile(String header_file_path) { Map<Integer,File> header_files= new TreeMap<>(); int headers_counter=0; try (BufferedReader br = new BufferedReader(new FileReader(header_file_path))) { String current_header_line; while ((current_header_line = br.readLine()) != null) { current_header_line=current_header_line.trim(); header_files.put(headers_counter,new File(current_header_line)); headers_counter++; } } catch(IOException ex){ System.out.println(ex.getMessage()); } return header_files; } public static void func1(String[] args){ String header_file_name=args[0]; String sources_file_name=args[1]; reportFile=new File("Report.txt"); header_file=new File(header_file_name); sources_file=new File(sources_file_name); Map<Integer,File> code_files= readCodeList( sources_file.toPath().toString() ); System.out.println("Total number of source files="+code_files.size()); //     Map<Integer,File> header_files=readheadersFile(header_file.toPath().toString()); System.out.println("Total number of header files = "+header_files.size()); //     System.out.println("Proccessing Level 1 dependencies"); List<InclPoints> result1=search_headers2(header_files,code_files); headers_nouse=new TreeMap<Integer,File>(); headers_withuse = new TreeMap<Integer,File>(); int headers_nouse_counter=0; int headers_withuse_counter=0; for(InclPoints ip:result1) { if(ip.points.size() ==0) { headers_nouse.put(headers_nouse_counter, ip.headers); headers_nouse_counter++; } else { headers_withuse.put(headers_withuse_counter,ip.headers); headers_withuse_counter++; } } System.out.println("Proccessing Level 2 dependencies"); List<InclPoints> result2=search_headers2(headers_nouse,headers_withuse); for(InclPoints ip: result1) { appendUsingOutputStream(reportFile.toPath().toString(),"Header file : "+ip.headers+"\n"); for(Point p: ip.points) { appendUsingOutputStream(reportFile.toPath().toString(), " usage : "+p.src.toPath().toString()+" \n"); appendUsingOutputStream(reportFile.toPath().toString(), " line "+p.incl.line+" : "+p.incl.text+" \n"); } appendUsingOutputStream(reportFile.toPath().toString(), "Number of entries = "+ip.points.size()+" \n\n"); } for(InclPoints ip: result2) { appendUsingOutputStream(reportFile.toPath().toString(),"Header file : "+ip.headers+"\n"); for(Point p: ip.points) { appendUsingOutputStream(reportFile.toPath().toString(), " usage : "+p.src.toPath().toString()+" \n"); appendUsingOutputStream(reportFile.toPath().toString(), " line "+p.incl.line+" : "+p.incl.text+" \n"); } appendUsingOutputStream(reportFile.toPath().toString(), "Number of entries = "+ip.points.size()+" \n\n"); } } public static List<InclPoints> search_headers2(Map<Integer,File> headers,Map<Integer,File> sources) { List<Includes> incs_lst=new ArrayList<Includes>(); incpo_lst = new ArrayList<InclPoints>(); for(File curFilePath : sources.values()) { Includes incs=new Includes(); incs.file=curFilePath; try{ BufferedReader cur_file = new BufferedReader(new FileReader(curFilePath)); int line_number=0; for(String cur_line; (cur_line = cur_file.readLine()) != null; line_number++) { Pattern p1 = Pattern.compile("#include.+?\\W.+\\W"); Matcher m2 = p1.matcher(cur_line); if(m2.find()) { Incl incl=new Incl(); incl.text = cur_line.trim(); incl.line = line_number; incs.incl.add(incl); } } cur_file.close(); incs_lst.add(incs); }catch(IOException e) { System.out.println(e.getMessage()); } } //  heiders      for(File current_header: headers.values()) { InclPoints point=new InclPoints(); point.headers=current_header; point.points= new ArrayList<Point>(); String header=""; Pattern p = Pattern.compile("\\/?([\\w\\-\\.]+?)\\.h"); String text=current_header.getPath(); Matcher m = p.matcher(text); if(m.find()) { System.out.println(String.format("|%-100s|",current_header)); header=current_header.getPath().substring(m.start(), m.end()); for(Includes inc:incs_lst) { for(Incl incl:inc.incl) { Pattern p1 = Pattern.compile("#include.+?\\W" + header + "\\W"); Matcher m2 = p1.matcher(incl.text); if (m2.find()) { Point po= new Point(); po.src= inc.file; po.incl=incl; point.points.add(po); System.out.println(String.format("|%-60s| %-40s |",po.src.toString() ,po.incl.text)); } } } } incpo_lst.add(point); } return incpo_lst; } //     FileWriter private static void appendUsingOutputStream(String fileName, String data) { OutputStream os = null; try { //  FileOutputStream   true,      os = new FileOutputStream(new File(fileName), true); os.write(data.getBytes(), 0, data.length()); } catch (IOException e) { e.printStackTrace(); }finally{ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } 

The algorithm is as follows:

First, we look at the files with / cpp and look for the directive #include <...> with the help of a regular expression, we remember this drain and the line number for the file. Next, for each found construct, check for include for h files. As a result, we check the same for * .h files. If the h file is not where it was not connected, then there is a possibility that it was connected in the used * .h files, for this we check one more time the presence of the * .h connections in the connected * .h files.

As a result, we make a report of the following form:

Proccessing Level 1 dependencies
Header file : ./arch/powerpc/include/asm/udbg.h
usage : ./arch/powerpc/platforms/85xx/izgib.c
line : #include <asm/udbg.h>
usage : ./arch/powerpc/sysdev/cpm_common.c
line : #include <asm/udbg.h>
usage : ./arch/powerpc/kernel/legacy_serial.c
line : #include <asm/udbg.h>
usage : ./arch/powerpc/kernel/setup-common.c
line : #include <asm/udbg.h>
usage : ./arch/powerpc/kernel/setup_32.c
line : #include <asm/udbg.h>
usage : ./arch/powerpc/kernel/udbg.c
line : #include <asm/udbg.h>
usage : ./arch/powerpc/kernel/irq.c
line : #include <asm/udbg.h>
usage : ./arch/powerpc/kernel/udbg_16550.c
line : #include <asm/udbg.h>
Number of entries = 8

Header file : ./arch/powerpc/include/asm/termios.h
usage : ./net/unix/af_unix.c
line : #include <linux/termios.h>
usage : ./net/netlink/af_netlink.c
line : #include <linux/termios.h>
usage : ./drivers/tty/tty_ioctl.c
line : #include <linux/termios.h>
Number of entries = 3

Source: https://habr.com/ru/post/346506/


All Articles