Bugzilla – Attachment 54059 Details for
Bug 43460
Replace rtl::OUString getLength()==0 with isEmpty() etc.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
plugin script
emptylength.py (text/plain), 4.84 KB, created by
Stephan Bergmann
on 2011-12-02 01:56:04 UTC
(
hide
)
Description:
plugin script
Filename:
MIME Type:
Creator:
Stephan Bergmann
Created:
2011-12-02 01:56:04 UTC
Size:
4.84 KB
patch
obsolete
># Find calls of rtl::O[U]String::getLength() that check for an empty string (and ># that would better use calls to rtl::O[U]String::isEmpty) in the LibreOffice ># code base. ># ># Emits GCC notes prefixed with "[EmptyLength plugin]". The re-constructed ># original comparison and the suggested improvement should be taken with a grain ># of salt. ># ># * See <https://fedorahosted.org/gcc-python-plugin/> for details about the GCC ># Python plugin. ># ># * Requires a recent gcc-python-plugin.git version (post v0.7) including ># <http://git.fedorahosted.org/git/?p=gcc-python-plugin.git;a=commit;h= ># 2bb77306c37bb03a616c2554cfbf25dc02640b43> adding "fullname" support. ># ># * Can be enabled in a LibreOffice build via ># ># ./autogen.sh ... CXX='g++ -fplugin=</path-to>/gcc-python-plugin/python.so ># -fplugin-arg-python-script=</path-to>/emptylength.py' ># ># * Produces false positives like in (sal/rtl/source/bootstrap.cxx:237): ># ># inline void EnsureNoFinalSlash (rtl::OUString & url) ># { ># sal_Int32 i = url.getLength(); ># if (i > 0 && url[i - 1] == '/') { ># url = url.copy(0, i - 1); ># } ># } ># ># sal/rtl/source/bootstrap.cxx:240:5: note: [EmptyLength plugin] replace ># "getLength() > 0" with "!isEmpty()" ># ># * Disable ccache (beware g++ pointing to /usr/lib64/ccache/g++, etc.) if you ># want to modify this script and re-run GCC. Otherwise, your script might not ># be re-run. > >import gcc > >verbose = False > >class EmptyLength(gcc.GimplePass): > def execute(self, fun): > for bb in fun.cfg.basic_blocks: > if bb.gimple: > processBlock(bb.gimple) > >def processBlock(statements): > calls = set () > for stmt in statements: > verbose and stmt.loc and gcc.inform(stmt.loc, 'XXX stmt: "%s"' % stmt) > if isinstance(stmt, gcc.GimpleCall): > if isSimpleVar(stmt.lhs) and stmt.fndecl \ > and isLength(stmt.fndecl.fullname): > verbose and gcc.inform(stmt.loc, 'XXX match call'); > calls.add(stmt.lhs.addr) > elif isinstance(stmt, gcc.GimpleAssign): > if len(stmt.rhs) == 1: > if isSimpleVar(stmt.lhs) and stmt.exprcode == gcc.VarDecl \ > and isCall(calls, stmt.rhs[0]): > verbose and gcc.inform(stmt.loc, 'XXX match assign'); > calls.add(stmt.lhs.addr) > elif len(stmt.rhs) == 2: > verbose and gcc.inform(stmt.loc, 'XXX check assign'); > checkLength( > stmt.loc, calls, stmt.exprcode, stmt.rhs[0], stmt.rhs[1]) > elif isinstance(stmt, gcc.GimpleCond): > verbose and gcc.inform(stmt.loc, 'XXX check cond'); > checkLength(stmt.loc, calls, stmt.exprcode, stmt.lhs, stmt.rhs) > >def checkLength(location, calls, exprcode, lhs, rhs): > if isCall(calls, lhs): > if exprcode == gcc.EqExpr and isConst(rhs, 0): > replace(location, 'getLength() == 0', 'isEmpty()') > elif exprcode == gcc.GeExpr and isConst(rhs, 1): > replace(location, 'getLength() >= 1', '!isEmpty()') > elif exprcode == gcc.GtExpr and isConst(rhs, 0): > replace(location, 'getLength() > 0', '!isEmpty()') > elif exprcode == gcc.LeExpr and isConst(rhs, 0): > replace(location, 'getLength() <= 0', 'isEmpty()') > elif exprcode == gcc.LtExpr and isConst(rhs, 1): > replace(location, 'getLength() < 1', 'isEmpty()') > elif exprcode == gcc.NeExpr and isConst(rhs, 0): > replace(location, 'getLength() != 0', '!isEmpty()') > elif isCall(calls, rhs): > if exprcode == gcc.EqExpr and isConst(lhs, 0): > replace(location, '0 == getLength()', 'isEmpty()') > elif exprcode == gcc.GeExpr and isConst(lhs, 0): > replace(location, '0 >= getLength()', 'isEmpty()') > elif exprcode == gcc.GtExpr and isConst(lhs, 1): > replace(location, '1 > getLength()', 'isEmpty()') > elif exprcode == gcc.LeExpr and isConst(lhs, 1): > replace(location, '1 <= getLength()', '!isEmpty()') > elif exprcode == gcc.LtExpr and isConst(lhs, 0): > replace(location, '0 < getLength()', '!isEmpty()') > elif exprcode == gcc.NeExpr and isConst(lhs, 0): > replace(location, '0 != getLength()', '!isEmpty()') > >def isLength(fullname): > return fullname == 'sal_Int32 rtl::OString::getLength() const' \ > or fullname == 'sal_Int32 rtl::OUString::getLength() const'; > >def isCall(calls, tree): > return isSimpleVar(tree) and tree.addr in calls > >def isSimpleVar(tree): > return isinstance(tree, gcc.VarDecl) and tree.addr > >def isConst(tree, value): > return isinstance(tree, gcc.Constant) and tree.constant == value > >def replace(location, found, better): > gcc.inform( > location, > '[EmptyLength plugin] replace "%s" with "%s"' % (found, better)) > >ps = EmptyLength(name='EmptyLength') >ps.register_after('cfg')
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 43460
: 54059 |
54060
|
76242