diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index bef2d00..0000000 --- a/Gopkg.lock +++ /dev/null @@ -1,9 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "ab4fef131ee828e96ba67d31a7d690bd5f2f42040c6766b1b12fe856f87e0ff7" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index 9425a54..0000000 --- a/Gopkg.toml +++ /dev/null @@ -1,22 +0,0 @@ - -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" - diff --git a/Thoughts.md b/Thoughts.md new file mode 100644 index 0000000..2e527b8 --- /dev/null +++ b/Thoughts.md @@ -0,0 +1,21 @@ +A place to convey my thoughts. + +Feb 4th 2019\ +DiffParser is mostly "complete" functionally speaking but some of the regex are hard coded and untested.\ +Before moving to ASTParser I will do a small check. Then once both AST and Diff are complete, I will do another sweep to refactor the code.\ +- I tried allowing users to input a flag they wanted to log information on, but allowing users to manipulate the regex seems to be opening up the program a bit too much, instead the information should be kept within\ +- Is there any way I can group the list of "if" statements? \ +- I think I have misunderstood what functionCalls is asking for.\ +- Commas are optional for regions\ +- Replaced [^n]* with .* +- For some reason it catches 196480 in * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80). as a function call.\ + +Feb 16th 2019\ +DiffParser FunctionCall is still incorrect, but I have moved on to ASTParser.\ +ASTParser seems relatively simple, because we are only looking for declared variables. +- Recursive traversal of AST should return a node instead of variable_declaration +- Should variable_declaration be in ast_result? Would a tuple suffice? + +Feb 21st 2019\ +DiffParser is complete, but functionCall captures "8" as a functional when parsing assembly offset such as 8(%rdi). +ASTParser is complete, not sure if the tree traversal is too hardcoded. \ No newline at end of file diff --git a/astResult.go b/astResult.go deleted file mode 100644 index 345ea18..0000000 --- a/astResult.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import ( - "bytes" - "fmt" -) - -//astResult contains the result of the AST analysis -type astResult struct { - //array of all variable declarations - variablesDeclarations []variableDescription -} - -type variableDescription struct { - //type name, in a short version, ex: int, float, Foo... - typeName string - //variable name - varName string -} - -//String returns the value of results as a formatted string -func (v *variableDescription) String() string { - return fmt.Sprintf("{%s}{%s}", v.varName, v.typeName) -} - -//String returns the value of results as a formatted string -func (r *astResult) String() string { - var buffer bytes.Buffer - for _, e := range r.variablesDeclarations { - buffer.WriteString(fmt.Sprintf("%s\n", e.String())) - } - - return buffer.String() -} diff --git a/ast_parser.py b/ast_parser.py new file mode 100644 index 0000000..69873e2 --- /dev/null +++ b/ast_parser.py @@ -0,0 +1,64 @@ +import json +from ast_result import ASTResult + +# *Goal* +# Parse an AST to return all the declared variables in the following format +# {int}{myInt} +# {string}{myInt} +# {Foo}{myFooObject} + + +class ASTParser: + def __init__(self): + print("ASTParser created") + + def parse(self, file): + """ Load JSON file into dictionary and parse """ + tree_json = json.load(file) + ast_res = ASTResult() + root = tree_json['Root'] + var_nodes = [] + # Returns a list of nodes from the AST that are variables + traverse_search(root, 'VariableDeclaration', var_nodes) + # Parses each variable node to a variable tuple and returns a list of tuples + ast_res.variableDeclarations = node_to_var(var_nodes) + return ast_res + + +def node_to_var(var_nodes): + """Converts each variable node to a variable tuple""" + var_array = [] + for node in var_nodes: + array_variables = [] + traverse_search(node, 'ArrayCreationExpression', array_variables) + var_type = find_val(node, 'PredefinedType') + var_name = find_val(node, 'VariableDeclarator') + if array_variables: + var_type += "[]" + var_array.append((var_type, var_name)) + return var_array + + +def traverse_search(root, look_for, result_list): + """ + Recursive traversal of AST to find a node with Type == lookfor + Appends all nodes that match to resultList which is maintained because python is pass by reference + """ + for child in root['Children']: + if child['Type'] == look_for: + result_list.append(child) + else: + traverse_search(child, look_for, result_list) + + +def find_val(var_node, look_for): + """ + Use traverseSearch() to find... + Variable Name found under node VariableDeclarator + Variable Type found under node PredefinedType + """ + found = [] + traverse_search(var_node, look_for, found) + if found: + return found[0]['Children'][0]['ValueText'] + diff --git a/ast_result.py b/ast_result.py new file mode 100644 index 0000000..4ba7b46 --- /dev/null +++ b/ast_result.py @@ -0,0 +1,8 @@ +class ASTResult: + def __init__(self): + self.variableDeclarations = [] + + def to_text(self): + with open('astResult.txt', 'w') as output: + for variable in self.variableDeclarations: + output.write("{" + variable[0] + "}{" + variable[1] + "}\n") diff --git a/diffResult.go b/diffResult.go deleted file mode 100644 index 95943c5..0000000 --- a/diffResult.go +++ /dev/null @@ -1,50 +0,0 @@ -package main - -import ( - "bytes" - "strconv" -) - -//result contains an analysis of a set of commit -type diffResult struct { - //The name of the files seen - files []string - //How many region we have (i.e. seperated by @@) - regions int - //How many line were added total - lineAdded int - //How many line were deleted totla - lineDeleted int - //How many times the function seen in the code are called. - functionCalls map[string]int -} - -//String returns the value of results as a formated string -func (r *diffResult) String() string { - - var buffer bytes.Buffer - buffer.WriteString("Files: \n") - for _, file := range r.files { - buffer.WriteString(" -") - buffer.WriteString(file) - buffer.WriteString("\n") - } - r.appendIntValueToBuffer(r.regions, "Regions", &buffer) - r.appendIntValueToBuffer(r.lineAdded, "LA", &buffer) - r.appendIntValueToBuffer(r.lineDeleted, "LD", &buffer) - - buffer.WriteString("Functions calls: \n") - for key, value := range r.functionCalls { - r.appendIntValueToBuffer(value, key, &buffer) - } - - return buffer.String() -} - -//appendIntValueToBuffer appends int value to a bytes buffer -func (r diffResult) appendIntValueToBuffer(value int, label string, buffer *bytes.Buffer) { - buffer.WriteString(label) - buffer.WriteString(" : ") - buffer.WriteString(strconv.Itoa(value)) - buffer.WriteString("\n") -} diff --git a/diff_parser.py b/diff_parser.py new file mode 100644 index 0000000..d827c9e --- /dev/null +++ b/diff_parser.py @@ -0,0 +1,59 @@ +import re +from diff_result import DiffResult +from difflib import SequenceMatcher + +# *Goal* +# Parse a diff files in the most efficient way possible. +# Keep these in mind, speed, maintainability, evolvability, etc.... +# Compute the following +# - List of files in the diffs +# - number of regions +# - number of lines added +# - number of lines deleted +# - list of function calls seen in the diffs and their number of calls + + +class DiffParser: + + def __init__(self): + print("DiffParser created") + + def parse(self, file): + # Regex Patterns + filelist_rgx = r'^diff --[^\s]* (.*)' + region_rgx = r'^@@ -\d+(,\d+)? \+\d+(,\d+)? @@.*' + added_rgx = r'^(\+).*' + deleted_rgx = r'^(\-).*' + fnlist_rgx = r'(?<=(?:\s|\.))([\w]+)(?=\()' + + # Object holding results + diff_res = DiffResult() + + lines = file.readlines() + # Lines such as + # +++ + # --- + # are caught in the regex for added lines + # having a "bubble" after a region starts allows us to manually filter those out. + area_start = 0 + for line in lines: + if re.search(filelist_rgx, line): + path_a = re.search(filelist_rgx, line).group(1).split(" ")[0] + path_b = re.search(filelist_rgx, line).group(1).split(" ")[1] + if len(path_a) is 0 or len(path_b) is 0: + raise ValueError + match = SequenceMatcher(None, path_a, path_b).find_longest_match(0, len(path_a), 0, len(path_b)) + diff_res.files.append(path_a[match.a: match.a + match.size]) + + area_start = 4 + if re.search(region_rgx, line): + diff_res.regions += 1 + if re.search(added_rgx, line) and area_start < 0: + diff_res.lineAdded += 1 + if re.search(deleted_rgx, line) and area_start < 0: + diff_res.lineDeleted += 1 + if re.search(fnlist_rgx, line): + diff_res.functionCalls[re.search(fnlist_rgx, line).group(1)] += 1 + area_start -= 1 + return diff_res + diff --git a/diff_result.py b/diff_result.py new file mode 100644 index 0000000..07ec436 --- /dev/null +++ b/diff_result.py @@ -0,0 +1,31 @@ +from collections import defaultdict + +class DiffResult: + def __init__(self): + self.files = [] + self.regions = 0 + self.lineAdded = 0 + self.lineDeleted = 0 + self.functionCalls = defaultdict(int) + + def to_text(self): + with open('diffResult.txt', 'w') as output: + output.write("Files: \n") + for file in self.files: + output.write(" - ") + output.write(file) + output.write("\n") + output.write("Regions: " + str(self.regions) + "\n") + output.write("Lines Added: " + str(self.lineAdded) + "\n") + output.write("Lines Deleted: " + str(self.lineDeleted) + "\n") + output.write("Function Calls: \n") + for key,value in self.functionCalls.items(): + output.write(" - ") + output.write(key + ": " + str(value)) + output.write("\n") + + + + + + diff --git a/diffs/diff4.diff b/diffs/diff4.diff new file mode 100644 index 0000000..c9b7101 --- /dev/null +++ b/diffs/diff4.diff @@ -0,0 +1,108 @@ +*TEST FILE FOR DIFF* + + +diff --git a/Documentation/accelerators/ocxl.rst b/Documentation/accelerators/ocxl.rst +index 4f7af84..ddcc58d 100644 +--- a/Documentation/accelerators/ocxl.rst ++++ b/Documentation/accelerators/ocxl.rst +@@ -152,6 +152,11 @@ OCXL_IOCTL_IRQ_SET_FD: + Associate an event fd to an AFU interrupt so that the user process + can be notified when the AFU sends an interrupt. + ++OCXL_IOCTL_GET_METADATA: ++ ++ Obtains configuration information from the card, such at the size of ++ MMIO areas, the AFU version, and the PASID for the current context. ++ +- +- +- +--testing +-testing +---testing +------------------- +- continued line + - on the next place with a + + sign +@@ +diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c +index 3a2ca0f..d0c34df 100644 +--- a/drivers/cpufreq/acpi-cpufreq.c ++++ b/drivers/cpufreq/acpi-cpufreq.c +@@ -629,7 +629,7 @@ static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) + if (c->x86_vendor == X86_VENDOR_INTEL) { + if ((c->x86 == 15) && + (c->x86_model == 6) && +- (c->x86_mask == 8)) { ++ (c->x86_stepping == 8)) { + pr_info("Intel(R) Xeon(R) 7100 Errata AL30, processors may lock up on frequency changes: disabling acpi-cpufreq\n"); + return -ENODEV; + } +diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c +index 3a2ca0f..d0c34df 100644 +--- a/drivers/cpufreq/acpi-cpufreq.c ++++ b/drivers/cpufreq/acpi-cpufreq.c +@@ -629,7 +629,7 @@ static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) + if (c->x86_vendor == X86_VENDOR_INTEL) { + if ((c->x86 == 15) && + (c->x86_model == 6) && +- (c->x86_mask == 8)) { ++ (c->x86_stepping == 8)) { + pr_info("Intel(R) Xeon(R) 7100 Errata AL30, processors may lock up on frequency changes: disabling acpi-cpufreq\n"); + return -ENODEV; + } +diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c +index 3a2ca0f..d0c34df 100644 +--- a/drivers/cpufreq/acpi-cpufreq.c ++++ b/drivers/cpufreq/acpi-cpufreq.c +@@ -629,7 +629,7 @@ static int bcpi_cpufreq_blacklist(struct cpuinfo_x86 *c) + if (c->x86_vendor == X86_VENDOR_INTEL) { + if ((c->x86 == 15) && + (c->x86_model == 6) && +- (c->x86_mask == 8)) { ++ (c->x86_stepping == 8)) { + pr_info("Intel(R) Xeon(R) 7100 Errata AL30, processors may lock up on frequency changes: disabling acpi-cpufreq\n"); + return -ENODEV; + } ++void dell_smbios_unregister_device(struct device *d) ++{ ++ struct smbios_device *priv; ++ ++ mutex_lock(&smbios_mutex); ++ list_for_each_entry(priv, &smbios_device_list, list) { ++ if (priv->device == d) { ++ list_del(&priv->list); ++ put_device(d); ++ break; ++ } ++ } ++ mutex_unlock(&smbios_mutex); ++ dev_dbg(d, "Remove device: %s\n", d->driver->name); ++} +- pushq %rdi /* pt_regs->di */ ++ pushq 6*8(%rdi) /* regs->ss */ ++ pushq 5*8(%rdi) /* regs->rsp */ ++ pushq 4*8(%rdi) /* regs->eflags */ ++ pushq 3*8(%rdi) /* regs->cs */ ++ pushq 2*8(%rdi) /* regs->ip */ ++ pushq 1*8(%rdi) /* regs->orig_ax */ +- "pushf \n\t" +- "push %es \n\t" +- "push %ds \n\t" +- "pop %es \n\t" +- "movl 8(%ebp),%eax \n\t" +- "movl 4(%eax),%ebx \n\t" +- "movl 8(%eax),%ecx \n\t" +- "movl 12(%eax),%edx \n\t" +- "movl 16(%eax),%esi \n\t" +- "movl 20(%eax),%edi \n\t" +- "movl (%eax),%eax \n\t" +- "push %cs \n\t" +- "call *12(%ebp) \n\t" +- "pushf \n\t" +- "pushl %eax \n\t" +- "movl 8(%ebp),%eax \n\t" +- "movl %ebx,4(%eax) \n\t" +- "movl %ecx,8(%eax) \n\t" +- "movl %edx,12(%eax) \n\t" +- "movl %esi,16(%eax) \n\t" \ No newline at end of file diff --git a/main.go b/main.go deleted file mode 100644 index ac77289..0000000 --- a/main.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "fmt" - "time" -) - -//timeTrack tracks the time it took to do things. -//It's a convenient method that you can use everywhere -//you feel like it -func timeTrack(start time.Time, name string) { - elapsed := time.Since(start) - fmt.Printf("%s took %s\n", name, elapsed) -} - -//main is the entry point of our go program. It defers -//the execution of timeTrack so we can know how long it -//took for the main to complete. -//It also calls the compute and output the returned struct -//to stdout. -func main() { - defer timeTrack(time.Now(), "compute diff") - fmt.Println(computeDiff()) - - defer timeTrack(time.Now(), "compute AST") - fmt.Println(computeAST()) -} - -//compute parses the git diffs in ./diffs and returns -//a diffResult struct that contains all the relevant informations -//about these diffs -// list of files in the diffs -// number of regions -// number of line added -// number of line deleted -// list of function calls seen in the diffs and their number of calls -func computeDiff() *diffResult { - - return nil -} - -//computeAST go through the AST and returns -//a astResult struct that contains all the variable declarations -func computeAST() *astResult { - - return nil -} diff --git a/main.py b/main.py new file mode 100644 index 0000000..1a169a3 --- /dev/null +++ b/main.py @@ -0,0 +1,29 @@ +import argparse +from diff_parser import DiffParser +from ast_parser import ASTParser + + +def main(): + if part == "1": + print("Running Part 1 - Parsing diff files from... diffs/" + filename + "\n") + diff_parser = DiffParser() + with open("diffs/" + filename) as file: + result = diff_parser.parse(file) + result.to_text() + + elif part == "2": + print("Running Part 2 - AST ") + ast_parser = ASTParser() + with open("ast/" + filename) as file: + result = ast_parser.parse(file) + result.to_text() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('-p', '--part', required=True) + parser.add_argument('-f', '--filename', required=True) + args = parser.parse_args() + part = args.part + filename = args.filename + main()