Merge changes Iec0be1c3,Iaa2a7653
* changes:
sourcedr: Fix Prism line alignment problem
sourcedr: Add temporary search
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/preprocess.py b/vndk/tools/source-deps-reviewer/sourcedr/preprocess.py
index fc19d97..9176fec 100755
--- a/vndk/tools/source-deps-reviewer/sourcedr/preprocess.py
+++ b/vndk/tools/source-deps-reviewer/sourcedr/preprocess.py
@@ -206,7 +206,6 @@
patt = re.compile(b'([^:]+):(\\d+):(.*)$')
suspect = collections.defaultdict(list)
for line in raw_grep.split(b'\n'):
-
match = patt.match(line)
if not match:
continue
@@ -265,21 +264,22 @@
for pattern, is_regex in zip(patterns, is_regexs):
if not is_regex:
pattern = re.escape(pattern)
- try:
- raw_grep = subprocess.check_output(
- ['csearch', '-n', pattern],
- cwd=os.path.expanduser(self.android_root),
- env=self.env)
- except subprocess.CalledProcessError as e:
- if e.output == b'':
- print('nothing found')
- return
+ raw_grep = self.raw_grep(pattern)
+ if raw_grep == b'':
+ continue
processed += self.process_grep(raw_grep, pattern, is_regex)
self.to_json(processed)
def add_pattern(self, pattern, is_regex):
if not is_regex:
pattern = re.escape(pattern)
+ raw_grep = self.raw_grep(pattern)
+ if raw_grep == b'':
+ return
+ processed = self.process_grep(raw_grep, pattern, is_regex)
+ self.add_to_json(processed)
+
+ def raw_grep(self, pattern):
try:
raw_grep = subprocess.check_output(
['csearch', '-n', pattern],
@@ -288,9 +288,13 @@
except subprocess.CalledProcessError as e:
if e.output == b'':
print('nothing found')
- return
- processed = self.process_grep(raw_grep, pattern, is_regex)
- self.add_to_json(processed)
+ return b''
+ return raw_grep
+
+ def raw_search(self, pattern, is_regex):
+ if not is_regex:
+ pattern = re.escape(pattern)
+ return self.raw_grep(pattern)
def to_json(self, processed):
data = {}
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/server.py b/vndk/tools/source-deps-reviewer/sourcedr/server.py
index 6cada2d..be4e323 100755
--- a/vndk/tools/source-deps-reviewer/sourcedr/server.py
+++ b/vndk/tools/source-deps-reviewer/sourcedr/server.py
@@ -6,9 +6,12 @@
from flask import Flask, jsonify, render_template, request
import argparse
import bisect
+import collections
+from functools import cmp_to_key
import hashlib
import json
import os
+import re
import subprocess
import sys
import webbrowser
@@ -95,6 +98,48 @@
save_new_pattern(patt, is_regex)
return jsonify(result='done')
+
+# This function does a temporary grep to the directory
+# Not adding the result to database
+@app.route('/temporary_search')
+def _temporary_search():
+ path = request.args.get('path')
+ patt = request.args.get('pattern')
+ is_regex = request.args.get('is_regex')
+ result = engine.raw_search(patt, is_regex).decode('utf-8')
+ dic = collections.defaultdict(list)
+ patt = re.compile('([^:]+):(\\d+):(.*)$')
+ for line in result.split('\n'):
+ match = patt.match(line)
+ if not match:
+ continue
+
+ file_path = match.group(1)
+ line_no = match.group(2)
+ code = match.group(3)
+ dic[file_path].append((line_no, code))
+
+ def compare(item1, item2):
+ key1, value1 = item1
+ key2, value2 = item2
+ cnt1 = os.path.commonprefix([path, key1]).count('/')
+ cnt2 = os.path.commonprefix([path, key2]).count('/')
+ e1 = os.path.relpath(key1, path).count('/')
+ e2 = os.path.relpath(key2, path).count('/')
+ # prefer smaller edit distance
+ if e1 < e2: return -1
+ if e2 < e1: return 1
+ # prefer deeper common ancestor
+ if cnt1 > cnt2: return -1
+ if cnt2 > cnt1: return 1
+ # lexicographical order
+ if key1 < key2: return -1
+ if key2 < key1: return 1
+ return 0
+
+ result = sorted(dic.items(), key=cmp_to_key(compare))
+ return jsonify(result=json.dumps(result))
+
@app.route('/')
def render():
return render_template('index.html')
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/static/css/main.css b/vndk/tools/source-deps-reviewer/sourcedr/static/css/main.css
index 933f73a..11bb7bc 100644
--- a/vndk/tools/source-deps-reviewer/sourcedr/static/css/main.css
+++ b/vndk/tools/source-deps-reviewer/sourcedr/static/css/main.css
@@ -1,13 +1,26 @@
h3, h4 {
- display: inline-block;
+ display: inline-block;
}
pre {
- white-space: pre-wrap; /* Since CSS 2.1 */
- white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
- white-space: -pre-wrap; /* Opera 4-6 */
- white-space: -o-pre-wrap; /* Opera 7 */
- word-wrap: break-word; /* Internet Explorer 5.5+ */
- background-color: #ffffff;
- margin: 0;
+ white-space: pre-wrap; /* Since CSS 2.1 */
+ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ word-wrap: break-word; /* Internet Explorer 5.5+ */
+ background-color: #ffffff;
+ margin: 0;
+}
+
+@media (min-width: 768px) {
+ .modal-xl {
+ width: 90%;
+ max-width:1200px;
+ }
+}
+
+.affix {
+ top:50px;
+ right:0;
+ position:fixed;
}
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/static/js/main.js b/vndk/tools/source-deps-reviewer/sourcedr/static/js/main.js
index e11d26c..db62041 100644
--- a/vndk/tools/source-deps-reviewer/sourcedr/static/js/main.js
+++ b/vndk/tools/source-deps-reviewer/sourcedr/static/js/main.js
@@ -37,6 +37,33 @@
return pretag;
}
+ function grepResultHtml(items) {
+ let ret = document.createElement('p');
+ for (let i = 0; i < items.length; i++) {
+ let path = document.createElement('span');
+ path.style.color = 'purple';
+ path.style.fontSize = '20px';
+ path.innerHTML = items[i][0];
+ ret.appendChild(path);
+ ret.appendChild(document.createElement('br'));
+ for (let j = 0; j < items[0][1].length; j++) {
+ let line_no = items[i][1][j][0];
+ let content = items[i][1][j][1];
+ let line_html = document.createElement('font');
+ line_html.style.color = 'green';
+ line_html.style.fontSize = '18px';
+ line_html.innerHTML = line_no + ':';
+ ret.appendChild(line_html);
+ let content_html = document.createElement('span');
+ content_html.style.fontSize = '18px';
+ content_html.appendChild(document.createTextNode(content));
+ ret.appendChild(content_html);
+ ret.appendChild(document.createElement('br'));
+ }
+ }
+ return ret;
+ }
+
function enterTask() {
let text = $('#enter_deps').val();
$('#deps_list').append(taskHtml(text, counter));
@@ -104,7 +131,6 @@
for (let i = 0; i < len; i++) {
$('#pattern_list').append('<li>' + pattern_lst[i] + '</li>');
}
-
$('#path_prefix').text(data.path_prefix);
});
}
@@ -199,6 +225,7 @@
setGotoPatternLine(line_no);
$('#selected_text').val('');
$('#code_file_path').val('');
+ $('#enter_deps').val('');
$('html,body').scrollTop(0);
return false;
}
@@ -227,8 +254,30 @@
pattern: values['pattern'],
is_regex: $('#is_regex').is(':checked') ? 1 : 0
});
+ return true;
+ });
+
+ $('#temporary_search').submit(function() {
+ const $inputs = $('#temporary_search :input');
+ let values = {};
+ $inputs.each(function () {
+ values[this.name] = $(this).val();
+ });
+ $('#modal_title').text(values['pattern']);
+ $.getJSON('/temporary_search', {
+ path: $('#file_path').text(),
+ pattern: values['pattern'],
+ is_regex: $('#is_regex2').is(':checked') ? 1 : 0
+ }, function (data) {
+ $('#modal_body').append(grepResultHtml(JSON.parse(data.result)));
+ $('#myModal').modal('show');
+ });
return false;
});
+ // clear previous html code in modal on hide
+ $('#myModal').on('hidden.bs.modal', function () {
+ $('#modal_body').empty();
+ })
$('#add_deps').submit(enterTask);
$('#add_code').submit(enterCode);
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/static/prism/js/prism.js b/vndk/tools/source-deps-reviewer/sourcedr/static/prism/js/prism.js
index 758b01b..743a225 100644
--- a/vndk/tools/source-deps-reviewer/sourcedr/static/prism/js/prism.js
+++ b/vndk/tools/source-deps-reviewer/sourcedr/static/prism/js/prism.js
@@ -635,9 +635,17 @@
}
}());
+function getOffsetById(id) {
+ var element = document.getElementById(id);
+ var bodyRect = document.body.getBoundingClientRect();
+ var elemRect = element.getBoundingClientRect();
+ var elementOffset = elemRect.top - bodyRect.top;
+ return elementOffset;
+}
+
function highlightLines(pre, lines, classes) {
- var ranges = lines.replace(/\s+/g, '').split(','),
- offset = +pre.getAttribute('data-line-offset') || 0;
+ var ranges = lines.replace(/\s+/g, '').split(',');
+ var offset = getOffsetById('browsing_file');
var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
@@ -663,7 +671,7 @@
}
}
- line.style.top = (start - offset - 1) * lineHeight + 'px';
+ line.style.top = (getOffsetById('line_no' + start) - offset) + 'px';
//allow this to play nicely with the line-numbers plugin
if(hasClass(pre, 'line-numbers')) {
@@ -734,33 +742,6 @@
}
});
-Prism.hooks.add('complete', function(env) {
- var pre = env.element.parentNode;
- var lines = pre && pre.getAttribute('data-line');
-
- if (!pre || !lines || !/pre/i.test(pre.nodeName)) {
- return;
- }
-
- clearTimeout(fakeTimer);
-
- highlightLines(pre, lines);
-
- fakeTimer = setTimeout(applyHash, 1);
-});
-
-if(window.addEventListener) {
- window.addEventListener('hashchange', applyHash);
-}
-
-})();
-
-(function() {
-
-if (typeof self === 'undefined' || !self.Prism || !self.document) {
- return;
-}
-
Prism.hooks.add('complete', function (env) {
if (!env.code) {
return;
@@ -795,8 +776,10 @@
var linesNum = match ? match.length + 1 : 1;
var lineNumbersWrapper;
- var lines = new Array(linesNum + 1);
- lines = lines.join('<span></span>');
+ var lines = '';
+ for (let i = 1; i < linesNum + 1; i++) {
+ lines += '<span id="line_no' + i + '"></span>';
+ }
lineNumbersWrapper = document.createElement('span');
lineNumbersWrapper.setAttribute('aria-hidden', 'true');
@@ -811,4 +794,31 @@
});
+Prism.hooks.add('complete', function(env) {
+ var pre = env.element.parentNode;
+ var lines = pre && pre.getAttribute('data-line');
+
+ if (!pre || !lines || !/pre/i.test(pre.nodeName)) {
+ return;
+ }
+
+ clearTimeout(fakeTimer);
+
+ highlightLines(pre, lines);
+
+ fakeTimer = setTimeout(applyHash, 1);
+});
+
+if(window.addEventListener) {
+ window.addEventListener('hashchange', applyHash);
+}
+
+})();
+
+(function() {
+
+if (typeof self === 'undefined' || !self.Prism || !self.document) {
+ return;
+}
+
}());
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/templates/index.html b/vndk/tools/source-deps-reviewer/sourcedr/templates/index.html
index e46b3bf..9cf75ec 100644
--- a/vndk/tools/source-deps-reviewer/sourcedr/templates/index.html
+++ b/vndk/tools/source-deps-reviewer/sourcedr/templates/index.html
@@ -32,8 +32,17 @@
</div>
<br>
- <div class="col-sm-4">
+ <div class="col-sm-4" data-spy="affix">
+
<div class="well">
+ <h3>Temporary search</h3>
+ <form id="temporary_search" class="input-group" style="padding-left:20px;">
+ <span class="input-group-addon">is regex</span>
+ <span class="input-group-addon">
+ <input type="checkbox" name="is_regex2" id="is_regex2">
+ </span>
+ <input type="text" name="pattern" class="form-control">
+ </form>
<h3>Add patterns to grep</h3>
<form id="add_pattern" class="input-group" style="padding-left:20px;">
<span class="input-group-addon">is regex</span>
@@ -43,12 +52,12 @@
<input type="text" name="pattern" class="form-control">
</form>
<ul id="pattern_list"></ul>
- <h3>File path:</h3>
+ </div>
+ <div class="well">
+ <h3>File labeling:</h3>
<pre style="padding-left:20px;"><h4 id="file_path"></h4></pre>
<h3>Pattern line number:</h3>
<h3 id="line_no"></h3><br>
- </div>
- <div class="well">
<h3>Library Dependencies</h3>
<form id="add_deps" class="input-group">
<input type="text" class="form-control" id="enter_deps" placeholder="Fill in * if undetermined"/>
@@ -57,15 +66,14 @@
</span>
</form>
<ul id="deps_list"></ul>
-
<h3>Code Dependencies</h3>
<form id="add_code">
<input class="btn btn-secondary" type="button" id="get_selection" value="Get selection"/>
<input class="btn btn-secondary" type="submit" id="add_code" value="Add"/><br>
<input type="text" id="code_file_path" style="margin: 0px; width: 100%;"/>
<textarea id="selected_text" name="selectedtext" rows="5" style="margin: 0px; width: 100%; height: 106px;"></textarea>
- <ul id="code_list"></ul>
</form>
+ <ul id="code_list"></ul>
<form id="save_all">
<input class="btn btn-secondary" type="submit" value="Save All"/>
</form>
@@ -74,11 +82,27 @@
</div>
</div>
+<!-- Modal -->
+<div class="modal fade" id="myModal" role="dialog">
+ <div class="modal-dialog modal-xl">
+ <!-- Modal content-->
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">×</button>
+ <h4 id="modal_title" class="modal-title"></h4>
+ </div>
+ <div id="modal_body" class="modal-body">
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+</div>
<script type="text/javascript" src="static/js/main.js"></script>
<!-- for code prettyify -->
<script src="static/prism/js/prism.js"></script>
-<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
</body>
</html>