Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*Author: Leonidas Reppas, 2202389r
- * Advanced Programming (H) Assessed Exercise 2
- * This is my own work as defined in the Academic Ethics agreement I have signed.
- */
- import java.io.*;
- import java.nio.*;
- import java.util.*;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentLinkedQueue;
- import java.util.concurrent.locks.ReentrantLock;
- public class dependencyDiscoverer implements Runnable{
- private static ConcurrentHashMap<String, ArrayList<String>> master;
- private static ConcurrentLinkedQueue<String> workQ;
- private static ArrayList<String> dirs;
- private static int threadCount;
- ReentrantLock lock = new ReentrantLock();
- public static void main(String[] args) {
- /*
- * general design of main()
- * ========================
- *
- * 1. look up CPATH in environment
- * 2. assemble dir[] array from ".", any -Idir flags, and fields in CPATH (if it is defined)
- * 3. create a master hash table to map from file name to files upon which it depends
- * 4. create a workQ of files that need to be processed for #include lines
- * 5. for each file argument (after -Idir flags)
- * a. insert mapping from file.o to file.ext (where ext is c, y, or l) into table
- * b. insert mapping from file.ext to empty list into table
- * c. append file.ext on workQ
- * 6. for each file on the workQ
- * a. create a linked list for names of files #include'd
- * b. invoke process(name, linkedlist)
- * 7. for each file argument (after -Idir flags)
- * a. create a hash table in which to track file names already printed
- * b. create a linked list to track dependencies yet to print
- * c. print "foo.o:", insert "foo.o" into hash table and append "foo.o" to linked list
- * d. invoke printDependencies()
- * e. return the table and its contents to the heap
- */
- String CPATH = System.getenv("CPATH");
- dirs = new ArrayList<String>();
- ArrayList<String> dependsOn;
- dirs.add("./");
- if(CPATH != null) {
- for(int index = -1; (index=CPATH.indexOf(':', index + 1)) != -1; index++) {
- dirs.add(CPATH.substring(index));
- }
- }
- int start = 0;
- boolean IdirFlag = false;
- if(args[0].startsWith("-I")){
- IdirFlag = true;
- dirs.add(args[0].substring(2) + "/");
- start = 1;
- }
- master = new ConcurrentHashMap<String, ArrayList<String>>();
- workQ = new ConcurrentLinkedQueue<String>();
- int suffixIndex;
- String currentFile;
- String fileO;
- String suffix;
- for(int i = start; i < args.length; i++){
- dependsOn = new ArrayList<String>();
- currentFile = args[i];
- suffixIndex = (currentFile.length()) - 2;
- fileO = currentFile.substring(0, suffixIndex) + ".o";
- suffix = currentFile.substring(suffixIndex);
- if((!suffix.equals(".c")) && (!suffix.equals(".y")) && (!suffix.equals(".l"))){
- return;
- }
- dependsOn.add(currentFile);
- master.put(fileO, dependsOn);
- master.put(currentFile, new ArrayList<String>());
- workQ.add(currentFile);
- }
- ArrayList<Thread> eventPool = new ArrayList<Thread>();
- String threadNum = System.getenv("CRAWLER_THREADS");
- if(threadNum != null){
- threadCount = Integer.parseInt(threadNum);
- }
- for(int i = 0; i < threadCount; i++){
- Thread thread = new Thread(new dependencyDiscoverer());
- thread.start();
- eventPool.add(thread);
- }
- for( Thread thread: eventPool){
- try{
- thread.join();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- for(int i = start; i < args.length; i++){
- String FileO = args[i].split("\\.")[0] + ".o";
- String output = "";
- output = output + FileO + ": ";
- ConcurrentLinkedQueue<String> toProcessToPrint = new ConcurrentLinkedQueue<String>();
- toProcessToPrint.add(FileO);
- ConcurrentHashMap<String, ArrayList<String>> toPrint = new ConcurrentHashMap<String, ArrayList<String>>();
- toPrint.put(FileO, new ArrayList<String>());
- printDependencies(toPrint, toProcessToPrint);
- }
- }
- public static void process(String fileName, ArrayList<String> dependsOn){
- /*
- * general design for process()
- * ============================
- *
- * 1. open the file
- * 2. for each line of the file
- * a. skip leading whitespace
- * b. if match "#include"
- * i. skip leading whitespace
- * ii. if next character is '"'
- * * collect remaining characters of file name (up to '"')
- * * append file name to dependency list for this open file
- * * if file name not already in the master Table
- * - create empty linked list of dependencies
- * - insert mapping from file name to empty list in master table
- * - append file name to workQ
- * 3. close file
- *
- */
- File f = null;
- String file;
- for(String directory: dirs){
- file = directory + "/" + fileName;
- f = new File(file);
- if(f.exists()){
- break;
- }
- }
- String temp;
- try{
- Scanner sc = new Scanner(f);
- Scanner lines;
- while(sc.hasNextLine()){
- lines = new Scanner(sc.nextLine());
- if(!lines.hasNext()){
- continue;
- }
- temp = lines.next();
- if(!temp.endsWith("#include") || lines.hasNext()){
- continue;
- }
- temp = lines.next();
- if(!(temp.startsWith("\""))){
- continue;
- }
- temp = temp.substring(1, temp.length() - 1);
- dependsOn.add(temp);
- if(master.containsKey(temp)){
- continue;
- }
- master.put(temp, new ArrayList<String>());
- workQ.add(temp);
- workQ.notifyAll();
- lines.close();
- }
- sc.close();
- } catch(IOException e){
- System.out.println("Cannot find given file: " + fileName);
- }
- }
- public static void printDependencies(ConcurrentHashMap<String, ArrayList<String>> toPrint, ConcurrentLinkedQueue<String> toProcess){
- /*
- * general design for printDependencies()
- * ======================================
- *
- * 1. while there is still a file in the toProcess linked list
- * 2. fetch next file from toProcess
- * 3. lookup up the file in the master table, yielding the linked list of deps
- * 4. create an iterator over the linked list
- * 5. while there is a next element
- * a. if the filename is already in the printed hash table, continue
- * b. print the filename
- * c. insert into printed
- * d. append to toProcess
- * 6. delete the iterator
- *
- */
- String output = "";
- String currentFile = toProcess.poll();
- String f = currentFile;
- while(f != null){
- ArrayList<String> deps = master.get(f);
- for(String dep: deps){
- if(!toPrint.containsKey(dep)){
- output = output + " " + dep;
- toPrint.put(dep, new ArrayList<String>());
- toProcess.add(dep);
- }
- }
- f = toProcess.poll();
- }
- output = output.trim();
- output = currentFile + ": " + output + "\n";
- System.out.println(output);
- }
- @Override
- public void run(){
- lock.lock();
- String currentFile;
- currentFile = workQ.poll();
- while(currentFile != null){
- ArrayList<String> dependsOn = master.get(currentFile);
- process(currentFile, dependsOn);
- master.put(currentFile, dependsOn);
- currentFile = workQ.poll();
- }
- lock.unlock();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement