Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.23 KB | None | 0 0
  1. /*Author: Leonidas Reppas, 2202389r
  2.  * Advanced Programming (H) Assessed Exercise 2
  3.  * This is my own work as defined in the Academic Ethics agreement I have signed.
  4. */
  5.  
  6. import java.io.*;
  7. import java.nio.*;
  8. import java.util.*;
  9. import java.util.concurrent.ConcurrentHashMap;
  10. import java.util.concurrent.ConcurrentLinkedQueue;
  11. import java.util.concurrent.locks.ReentrantLock;
  12.  
  13. public class dependencyDiscoverer implements Runnable{
  14.  
  15.     private static ConcurrentHashMap<String, ArrayList<String>> master;
  16.     private static ConcurrentLinkedQueue<String> workQ;
  17.     private static ArrayList<String> dirs;
  18.     private static int threadCount;
  19.     ReentrantLock lock = new ReentrantLock();
  20.    
  21.     public static void main(String[] args) {
  22.         /*
  23.          * general design of main()
  24.          * ========================
  25.          *
  26.          * 1. look up CPATH in environment
  27.          * 2. assemble dir[] array from ".", any -Idir flags, and fields in CPATH (if it is defined)
  28.          * 3. create a master hash table to map from file name to files upon which it depends
  29.          * 4. create a workQ of files that need to be processed for #include lines
  30.          * 5. for each file argument (after -Idir flags)
  31.          *    a. insert mapping from file.o to file.ext (where ext is c, y, or l) into table
  32.          *    b. insert mapping from file.ext to empty list into table
  33.          *    c. append file.ext on workQ
  34.          * 6. for each file on the workQ
  35.          *    a. create a linked list for names of files #include'd
  36.          *    b. invoke process(name, linkedlist)
  37.          * 7. for each file argument (after -Idir flags)
  38.          *    a. create a hash table in which to track file names already printed
  39.          *    b. create a linked list to track dependencies yet to print
  40.          *    c. print "foo.o:", insert "foo.o" into hash table and append "foo.o" to linked list
  41.          *    d. invoke printDependencies()
  42.          *    e. return the table and its contents to the heap
  43.          */
  44.  
  45.         String CPATH = System.getenv("CPATH");
  46.        
  47.         dirs = new ArrayList<String>();
  48.         ArrayList<String> dependsOn;
  49.         dirs.add("./");
  50.  
  51.  
  52.         if(CPATH != null) {
  53.             for(int index = -1; (index=CPATH.indexOf(':', index + 1)) != -1; index++) {
  54.                 dirs.add(CPATH.substring(index));
  55.             }
  56.         }
  57.  
  58.         int start = 0;
  59.         boolean IdirFlag = false;
  60.         if(args[0].startsWith("-I")){
  61.             IdirFlag = true;
  62.             dirs.add(args[0].substring(2) + "/");
  63.             start = 1;
  64.         }
  65.  
  66.         master = new ConcurrentHashMap<String, ArrayList<String>>();
  67.         workQ = new ConcurrentLinkedQueue<String>();
  68.         int suffixIndex;
  69.         String currentFile;
  70.         String fileO;
  71.         String suffix;
  72.        
  73.         for(int i = start; i < args.length; i++){
  74.             dependsOn = new ArrayList<String>();
  75.             currentFile = args[i];
  76.             suffixIndex = (currentFile.length()) - 2;
  77.             fileO = currentFile.substring(0, suffixIndex) + ".o";
  78.             suffix = currentFile.substring(suffixIndex);
  79.  
  80.             if((!suffix.equals(".c")) && (!suffix.equals(".y")) && (!suffix.equals(".l"))){
  81.                 return;
  82.             }
  83.  
  84.             dependsOn.add(currentFile);
  85.             master.put(fileO, dependsOn);
  86.             master.put(currentFile, new ArrayList<String>());
  87.             workQ.add(currentFile);
  88.  
  89.  
  90.         }
  91.        
  92.         ArrayList<Thread> eventPool = new ArrayList<Thread>();
  93.         String threadNum = System.getenv("CRAWLER_THREADS");
  94.        
  95.         if(threadNum != null){
  96.             threadCount = Integer.parseInt(threadNum);
  97.         }
  98.        
  99.         for(int i = 0; i < threadCount; i++){
  100.             Thread thread = new Thread(new dependencyDiscoverer());
  101.             thread.start();
  102.             eventPool.add(thread);
  103.         }
  104.        
  105.         for( Thread thread: eventPool){
  106.             try{
  107.                 thread.join();
  108.             }catch(Exception e){
  109.                 e.printStackTrace();
  110.             }
  111.         }
  112.        
  113.         for(int i = start; i < args.length; i++){
  114.             String FileO = args[i].split("\\.")[0] + ".o";
  115.             String output = "";
  116.             output = output + FileO + ": ";
  117.            
  118.             ConcurrentLinkedQueue<String> toProcessToPrint = new ConcurrentLinkedQueue<String>();
  119.             toProcessToPrint.add(FileO);
  120.            
  121.             ConcurrentHashMap<String, ArrayList<String>> toPrint = new ConcurrentHashMap<String, ArrayList<String>>();
  122.             toPrint.put(FileO, new ArrayList<String>());
  123.            
  124.             printDependencies(toPrint, toProcessToPrint);
  125.         }
  126.        
  127.     }
  128.  
  129.     public static void process(String fileName, ArrayList<String> dependsOn){
  130.         /*
  131.          * general design for process()
  132.          * ============================
  133.          *
  134.          * 1. open the file
  135.          * 2. for each line of the file
  136.          *    a. skip leading whitespace
  137.          *    b. if match "#include"
  138.          *       i. skip leading whitespace
  139.          *       ii. if next character is '"'
  140.          *           * collect remaining characters of file name (up to '"')
  141.          *           * append file name to dependency list for this open file
  142.          *           * if file name not already in the master Table
  143.          *             - create empty linked list of dependencies
  144.          *             - insert mapping from file name to empty list in master table
  145.          *             - append file name to workQ
  146.          * 3. close file
  147.          *
  148.          */
  149.  
  150.         File f = null;
  151.         String file;
  152.         for(String directory: dirs){
  153.             file = directory + "/" + fileName;
  154.             f = new File(file);
  155.  
  156.             if(f.exists()){
  157.                 break;
  158.             }
  159.         }
  160.  
  161.         String temp;
  162.  
  163.         try{
  164.             Scanner sc = new Scanner(f);
  165.             Scanner lines;
  166.  
  167.             while(sc.hasNextLine()){
  168.                 lines = new Scanner(sc.nextLine());
  169.  
  170.                 if(!lines.hasNext()){
  171.                     continue;
  172.                 }
  173.                 temp = lines.next();
  174.  
  175.                 if(!temp.endsWith("#include") || lines.hasNext()){
  176.                     continue;
  177.                 }
  178.  
  179.                 temp = lines.next();
  180.                 if(!(temp.startsWith("\""))){
  181.                     continue;
  182.                 }
  183.  
  184.                 temp = temp.substring(1, temp.length() - 1);
  185.                 dependsOn.add(temp);
  186.  
  187.                 if(master.containsKey(temp)){
  188.                     continue;
  189.                 }
  190.  
  191.                 master.put(temp, new ArrayList<String>());
  192.  
  193.                 workQ.add(temp);
  194.                 workQ.notifyAll();
  195.  
  196.                 lines.close();
  197.  
  198.  
  199.             }
  200.             sc.close();
  201.         } catch(IOException e){
  202.             System.out.println("Cannot find given file: " + fileName);
  203.         }
  204.  
  205.     }
  206.  
  207.     public static void printDependencies(ConcurrentHashMap<String, ArrayList<String>> toPrint, ConcurrentLinkedQueue<String> toProcess){
  208.         /*
  209.          * general design for printDependencies()
  210.          * ======================================
  211.          *
  212.          * 1. while there is still a file in the toProcess linked list
  213.          * 2. fetch next file from toProcess
  214.          * 3. lookup up the file in the master table, yielding the linked list of deps
  215.          * 4. create an iterator over the linked list
  216.          * 5. while there is a next element
  217.          *    a. if the filename is already in the printed hash table, continue
  218.          *    b. print the filename
  219.          *    c. insert into printed
  220.          *    d. append to toProcess
  221.          * 6. delete the iterator
  222.          *
  223.          */
  224.  
  225.         String output = "";
  226.         String currentFile = toProcess.poll();
  227.         String f = currentFile;
  228.  
  229.         while(f != null){
  230.             ArrayList<String> deps = master.get(f);
  231.             for(String dep: deps){
  232.                 if(!toPrint.containsKey(dep)){
  233.                     output = output + " " + dep;
  234.                     toPrint.put(dep, new ArrayList<String>());
  235.                     toProcess.add(dep);
  236.                 }
  237.             }
  238.             f = toProcess.poll();
  239.         }
  240.         output = output.trim();
  241.         output = currentFile + ": " + output + "\n";
  242.         System.out.println(output);
  243.     }
  244.    
  245.     @Override
  246.     public void run(){
  247.         lock.lock();
  248.         String currentFile;
  249.         currentFile = workQ.poll();
  250.         while(currentFile != null){
  251.             ArrayList<String> dependsOn = master.get(currentFile);
  252.             process(currentFile, dependsOn);
  253.             master.put(currentFile, dependsOn);
  254.             currentFile = workQ.poll();
  255.         }
  256.         lock.unlock();
  257.     }
  258.  
  259.  
  260.  
  261. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement