Skip to content

Commit

Permalink
Make indent.py able to detect logic error
Browse files Browse the repository at this point in the history
  • Loading branch information
38 committed Jul 25, 2018
1 parent 348202f commit dc7315f
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 91 deletions.
109 changes: 74 additions & 35 deletions indent.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,19 @@
import os
import argparse

def format(fp, verbose = False, color = False):
class StackToken(object):
def __init__(self, expect_cond, stop_set, diff, kind):
self.expect_cond = expect_cond
self.stop_set = stop_set
self.diff = diff
self.kind = kind
def __repr__(self):
return "Token(kind = %s, cond = %d, expecting = %s)"%(self.kind, self.expect_cond, self.stop_set)
def should_pop(self, lit, consume = True):
stop_lit = lit if consume else "~" + lit
return stop_lit in self.stop_set

def format(fp, verbose = False, color = False, should_warn = False):
comment = False
string = False
escape = False
Expand All @@ -35,8 +47,12 @@ def format(fp, verbose = False, color = False):
idlevel = -1
result = ""
changed = False
was_strict = False
warned = False
for line in fp:
idlevel = -1
strict = was_strict
was_strict = False
pp = True if recent[-2] == "\\" and pp else False
if re.match("[\t ]*[A-Z0-9_]*:[\t ]*\n",line):
#a label
Expand Down Expand Up @@ -76,45 +92,54 @@ def format(fp, verbose = False, color = False):
else:
if word:
if not pc:
if stack and not stack[-1][0] and not pc and word in stack[-1][1]:
if (stack and
not stack[-1].expect_cond and
not pc and
stack[-1].should_pop(word, True)):
stack = stack[:-1]
if word == "if":
stack.append((1, set(["{", "~;", "~}"]), 1))
stack.append(StackToken(True, set(["{", "~;", "~}"]), 1, "if"))
elif word == "else":
stack.append((0, set(["{", "~;", "~}", "if", "while", "for", "switch", "do"]), 1))
stack.append(StackToken(False, set(["{", "~;", "~}", "if", "while", "for", "switch", "do"]), 1, "else"))
elif word == "while":
stack.append((1, set(["{", "~;", "~}"]), 1))
stack.append(StackToken(True, set(["{", "~;", "~}"]), 1, "else"))
elif word == "for":
stack.append((1, set(["{", "~;", "~}"]), 1))
stack.append(StackToken(True, set(["{", "~;", "~}"]), 1, "for"))
elif word == "case" or word == "default":
stack.append((0, set(["case", "default", "~}"]), 1))
stack.append(StackToken(False, set(["case", "default", "~}"]), 1, "case"))
if idlevel == -1:
idlevel = len(stack) - (0 if not stack else stack[-1][2])
idlevel = len(stack) - (0 if not stack else stack[-1].diff)
word = ""
if stack and stack[-1][0]:
if ch not in "\r\n\t " and not pc:
was_strict = (ch in ";}")
if stack and stack[-1].expect_cond:
if pc == 0 and ch == '(':
stack[-1] = (0, stack[-1][1], stack[-1][2])
pc = 1
elif stack and (stack[-1][0] or pc > 0):
if(ch == '('): pc += 1
if(ch == ')'): pc -= 1
if stack and pc == 0 and stack[-1][0] == 0:
stack[-1] = (stack[-1][0], stack[-1][1], 0)
while stack and not stack[-1][0] and not pc and ("~" + ch) in stack[-1][1]:
stack[-1].expect_cond = False
if(ch == '('): pc += 1
if(ch == ')' and pc > 0): pc -= 1
if stack and pc == 0 and not stack[-1].expect_cond:
stack[-1].diff = 0
while (stack and
not stack[-1].expect_cond and
not pc and
stack[-1].should_pop(ch, False)):
stack = stack[:-1]
if stack and not stack[-1][0] and not pc and ch in stack[-1][1]:
if (stack and
not stack[-1].expect_cond and
not pc and
stack[-1].should_pop(ch, True)):
stack = stack[:-1]
if ch == '{':
if stack and "case" in stack[-1][1] and re.match(".*:[\\n\\r\\t ]*{$", recent):
if stack and stack[-1].kind == "case" and re.match(".*:[\\n\\r\\t ]*{$", recent):
stack = stack[:-1]
stack.append((0, set(["}"]), 1))
stack.append(StackToken(False, set(["}"]), 1, "block"))
if ch not in "\t \n\r" and idlevel == -1:
idlevel = len(stack) - (0 if not stack else stack[-1][2])
idlevel = len(stack) - (0 if not stack else stack[-1].diff)
while (stack and
not stack[-1][0] and
not pc
and ("~" + ch) in stack[-1][1] and
"case" not in stack[-1][1]):
not stack[-1].expect_cond and
not pc and
"case" != stack[-1].kind and
stack[-1].should_pop(ch, False)):
stack = stack[:-1]
if idlevel == -1:
idlevel = 0 if not line.strip() else len(stack)
Expand All @@ -123,13 +148,21 @@ def format(fp, verbose = False, color = False):
if ch == ' ': spaces += 1
elif ch == '\t': spaces += ts
else: break
if should_warn and ((spaces - idlevel * ts > 0 and strict and line.strip()) or (spaces - idlevel * ts < 0)):
changed = True
warn_line = "// Indent warnning: Suspicious Alignment (stack_size = %d, space_diff = %d)" % (idlevel, spaces - idlevel * ts)
warned = True
if verbose:
if color:
sys.stdout.write("\033[32m+%s\033[0m\n" % warn_line)
else:
sys.stdout.write("+%s\n" % warn_line)
result += warn_line + "\n"
spaces = max(0, spaces - idlevel * 4)
if not line.strip():
spaces = 0
was_strict = strict
new_line = "%s%s%s\n"%('\t' * idlevel, ' ' * spaces, line.strip())
if not pc and spaces and not comment and not string and not char:
changed = True
result += "// Indent warnning: Suspicous Alighment!\n"
if new_line != line:
changed = True
if color:
Expand All @@ -141,20 +174,22 @@ def format(fp, verbose = False, color = False):
else:
if verbose: sys.stdout.write(" " + line.replace(' ', '_').replace('\t', ' '))
result += new_line
return (changed, result)
return (changed, result, warned)

fn=r'.*\.(c|h|cpp|cxx|hpp|pss)$'
fn=r'.*\.(c|h|cpp|cxx|hpp)$'
ts = 4
dry_run = False
verbose = False
color = False

strict_mode = True

parser = argparse.ArgumentParser(description = "Correct the indentation of source code under current working directory")
parser.add_argument('--dry-run', action = 'store_true', dest="dry_run", help = 'Do not actually modify the file')
parser.add_argument('--verbose', action = 'store_true', dest="verbose", help = 'Print the modified file to screen')
parser.add_argument('--color', action = 'store_true', dest="color" , help = 'Show the colored output')
parser.add_argument('--tab-stop', type = int, dest = "tabstop", metavar = "TABSTOP" ,default = 4, help = 'Set the tab-stop')
parser.add_argument('--include', type = str, dest = "pattern", metavar = "PATTERN", default = fn, help = 'The regex that mathces all the files that should be processed')
parser.add_argument('--no-strict', action = 'store_true', dest='no_strict', help = 'Turn off the strict mode, which detect unexpected indentations/alignments')

options = parser.parse_args(sys.argv[1:])

Expand All @@ -163,18 +198,22 @@ def format(fp, verbose = False, color = False):
if options.color: color = True
fn = options.pattern
ts = options.tabstop
strict_mode = not options.no_strict

for root, _, files in os.walk("."):
for f in files:
if root.split("/")[1:][:1] == ["thirdparty"]: continue
if not re.match(fn,f): continue
path="%s/%s"%(root,f)
ch, result = format(file(path), verbose, color)
ch, result, warned = format(file(path), verbose, color, strict_mode)
if not dry_run:
if ch: sys.stderr.write("Info: file %s has been changed\n"%path)
if ch and not verbose:
sys.stdout.write("Info: file %s has been changed\n"%path)
f = file(path, "w")
f.write(result)
f.close()
else:
if ch: sys.stderr.write("Info: file %s would be changed\n"%path)

if ch and not verbose:
sys.stdout.write("Info: file %s would be changed\n"%path)
if warned:
sys.stderr.write("Warnning: Suspicious Indentation/Alignment has been found in file %s\n" % path)
4 changes: 3 additions & 1 deletion lib/proto/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ static inline const char* _adhoc_typename(_primitive_desc_t p)
static char* float_name[] = {[4] = "float", [8] = "double"};

for(;result_buf[p] == NULL;)
{
if(_PD_FLOAT(p)) result_buf[p] = float_name[_PD_SIZE(p)];
else snprintf(result_buf[p] = memory[p], 7, "%sint%d", _PD_SIGNED(p) ? "" : "u", _PD_SIZE(p) * 8);
else snprintf(result_buf[p] = memory[p], 7, "%sint%d", _PD_SIGNED(p) ? "" : "u", _PD_SIZE(p) * 8);
}

return result_buf[p];
}
Expand Down
6 changes: 4 additions & 2 deletions lib/pss/bytecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1021,10 +1021,12 @@ int pss_bytecode_segment_logdump(const pss_bytecode_segment_t* segment, FILE* fi
fprintf(file, "+Segment(%s)\n", buf);

for(i = 0; i < segment->code_table->header.size; i ++)
{
if(file == NULL)
LOG_INFO("| 0x%.6x %s", i, pss_bytecode_segment_inst_str(segment, i, buf, sizeof(buf)));
else
fprintf(file,"| 0x%.6x %s\n", i, pss_bytecode_segment_inst_str(segment, i, buf, sizeof(buf)));
else
fprintf(file,"| 0x%.6x %s\n", i, pss_bytecode_segment_inst_str(segment, i, buf, sizeof(buf)));
}
return 0;
}

Expand Down
12 changes: 7 additions & 5 deletions lib/pss/comp/lex.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,15 @@ static inline pss_comp_lex_keyword_t _id_or_keyword(pss_comp_lex_t* lexer, char*
int warnned = 0, len = 0;

for(;_in_id_charset(_peek(lexer, 0)); _consume(lexer, 1))
{
if(size > 1)
*(buffer ++) = (char)_peek(lexer, 0), size --, len ++;
else if(!warnned)
{
LOG_WARNING("identifer truncated");
warnned = 1;
}
else if(!warnned)
{
LOG_WARNING("identifer truncated");
warnned = 1;
}
}
buffer[0] = 0;
if(len == 0)
{
Expand Down
66 changes: 35 additions & 31 deletions lib/pss/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,26 @@ char* pss_string_literal(const char* str, char* buf, size_t sz)
size_t actual_size = 0;
const char* this;
for(this = str; *this; this ++)
{
switch(*this)
{
case '\a':
case '\b':
case '\f':
case '\r':
case '\n':
case '\t':
case '\v':
case '\'':
case '\"':
case '\?':
case '\\':
actual_size ++;
FALLTHROUGH("For the escape char, we need an additional space for the backslash");
default:
actual_size ++;
}
{
case '\a':
case '\b':
case '\f':
case '\r':
case '\n':
case '\t':
case '\v':
case '\'':
case '\"':
case '\?':
case '\\':
actual_size ++;
FALLTHROUGH("For the escape char, we need an additional space for the backslash");
default:
actual_size ++;
}
}

int truncate = 0;
if(NULL != buf)
Expand All @@ -132,21 +134,23 @@ char* pss_string_literal(const char* str, char* buf, size_t sz)

#define _ESC(ch) *(buf++) = '\\'; *(buf++) = ch; break
for(this = str; *this; this ++)
{
switch(*this)
{
case '\a': _ESC('a');
case '\b': _ESC('b');
case '\f': _ESC('f');
case '\r': _ESC('r');
case '\n': _ESC('n');
case '\t': _ESC('t');
case '\v': _ESC('v');
case '\\': _ESC('\\');
case '\'': _ESC('\'');
case '\"': _ESC('\"');
case '\?': _ESC('\?');
default: *(buf++) = *this;
}
{
case '\a': _ESC('a');
case '\b': _ESC('b');
case '\f': _ESC('f');
case '\r': _ESC('r');
case '\n': _ESC('n');
case '\t': _ESC('t');
case '\v': _ESC('v');
case '\\': _ESC('\\');
case '\'': _ESC('\'');
case '\"': _ESC('\"');
case '\?': _ESC('\?');
default: *(buf++) = *this;
}
}
#undef _ESC
buf[0] = '\"';
buf[1] = 0;
Expand Down
6 changes: 4 additions & 2 deletions servlets/network/http/parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,10 +770,12 @@ static inline uint64_t _parse_u64(const char* s)
uint64_t ret = 0;

for(;*s;s ++, empty = 0)
{
if(*s >= '0' && *s <= '9')
ret = ret * 10u + (uint64_t)(*s - '0');
else
return (uint64_t)-1;
else
return (uint64_t)-1;
}
return empty ? ERROR_CODE(uint64_t) : ret;
}

Expand Down
4 changes: 3 additions & 1 deletion src/lang/service.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,10 @@ int64_t lang_service_add_node(lang_service_t* service, const char* init_args)
int escape = 0;
int empty = 1;
for(;*ptr && !((*ptr == ' ' || *ptr == '\t') && !escape); ptr ++, empty = 0)
{
if(!escape) escape = (*ptr == '\\');
else escape = 0;
else escape = 0;
}
if(!empty) argc ++;
}

Expand Down
16 changes: 8 additions & 8 deletions src/module/mem/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,14 @@ static int _get_internal_buf(void* __restrict ctx, void const** __restrict resul

if(handle->current_page != NULL)
{
actual_size = handle->current_page->size - handle->page_offset;

if(actual_size == 0 && handle->current_page->next != NULL)
{
handle->page_offset = 0;
handle->current_page = handle->current_page->next;
actual_size = handle->current_page->size;
}
actual_size = handle->current_page->size - handle->page_offset;

if(actual_size == 0 && handle->current_page->next != NULL)
{
handle->page_offset = 0;
handle->current_page = handle->current_page->next;
actual_size = handle->current_page->size;
}

if(actual_size < *min_size) goto RET_EMPTY;

Expand Down
6 changes: 4 additions & 2 deletions src/sched/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,10 +802,12 @@ int sched_loop_start(sched_service_t** service, int fork_twice)


for(ptr = _scheds; ptr != NULL; ptr = ptr->next)
{
if(_start_loop(ptr) == ERROR_CODE(int))
LOG_WARNING("Cannot start the scheduler thread %d", ptr->thread_id);
else
LOG_INFO("Scheduler thread %d is started", ptr->thread_id);
else
LOG_INFO("Scheduler thread %d is started", ptr->thread_id);
}

const sched_service_pipe_descriptor_t* sdesc = sched_service_to_pipe_desc(*service);

Expand Down
Loading

0 comments on commit dc7315f

Please sign in to comment.