Newer
Older
Import / applications / HighwayDash / Tools / code-utils.py
#!/usr/bin/python
######################################################
# Code Utils
# Generates boilerplate code/files
# Created by John Ryland on 7/02/2016.
# Copyright (C) 2016 John Ryland. All rights reserved.
######################################################
import sys, os, glob, argparse, re, datetime, pwd


parser = argparse.ArgumentParser()
parser.add_argument('--new-project',  help='create folder, main.cpp and .pro file for the new project')
parser.add_argument('--new-class',    help='create H and CPP files for the new class')
parser.add_argument('--new-widget',   help='create H and CPP files for the new width')
parser.add_argument('--new-method',   help='add new method to H and CPP files')
#parser.add_argument('--project',   help='specify which pro file to edit (if multiple)')
args = parser.parse_args()
args.project = None # auto-detect


def copyrightString(project):
    author=pwd.getpwuid(os.getuid())[4].split(',')[0]  # TODO: probably non-portable
    date=datetime.datetime.today().strftime("%d/%m/%Y")
    return '\n    '+project+'\n    Created by '+author+' on '+date+'\n    Copyright (C) 2016 '+author+'. All rights reserved.\n'


def detectProject():
  if args.project == None:
    print 'detecting project...'
    files = glob.glob("*.pro")
    if len(files) == 1:
      args.project = str(files[0][:-4])
  print "project=" + str(args.project)


def addProject():
  p = args.new_project
  print "adding project " + str(p)
  if not os.path.exists(p):
    os.makedirs(p)
  os.chdir(p)
  with open(p+".pro", 'a') as f:
    copyright = '#' + re.sub('\n  ', '\n#', copyrightString(p)) + '#\n'
    f.write(copyright + "TEMPLATE=app\nTARGET="+p+"\nCONFIG += c++11\nQT += gui widgets\n\nSOURCES+=main.cpp")
  with open("main.cpp", 'a') as f:
    var=p.lower()[:1]
    copyright = '/*' + copyrightString(p + ' - main.cpp') + '*/\n'
    f.write(copyright + '#include <QApplication>\n#include "'+p+'.h"\n\n\nint main(int argc, char* argv[])\n'
             + '{\n  QApplication app(argc, argv);\n  '+p+' '+var+';\n  '+var+'.show();\n  return app.exec();\n}\n\n')
  addWidgetClass(p)
  # svn add


def addWidgetClass(newClassName):
  detectProject()
  l = newClassName
  u = l.upper()
  copyright = '/*' + copyrightString(args.new_project + ' - ' + l) + '*/\n'
  print "adding widget " + str(l)
  with open(l+".h", 'a') as f:
    f.write("#ifndef "+u+"_H\n#define "+u+"_H\n\n\n"+copyright+"\n\n#include <memory>\n#include <QWidget>\n\n\n"
      + "class "+l+" : public QWidget\n{\npublic:\n  "+l+"(QWidget* a_parent=0);\n  ~"+l+"();\n"
      + "  void paintEvent(QPaintEvent* pe) override;\n"
      + "  void timerEvent(QTimerEvent* te) override;\n"
      + "  void keyPressEvent(QKeyEvent* ke) override;\n"
      + "  void mousePressEvent(QMouseEvent* me) override;\n"
      + "private:\n"
      + "  struct Pimpl;\n"
      +  "  std::unique_ptr<Pimpl> m_pimpl;\n};\n\n\n#endif // "+u+"_H\n\n")
  with open(l+".cpp", 'a') as f:
    f.write(copyright+'#include "'+l+'.h"\n\n\nstruct '+l+'::Pimpl\n{\n  // private implementation details here\n};'
      + '\n\n\n'+l+'::'+l+'(QWidget* a_parent)\n  : QWidget(a_parent)'
      + '\n  , m_pimpl(std::unique_ptr<Pimpl>(new Pimpl()))\n{\n}\n\n\n'+l+'::~'+l+'()\n{\n}\n\n'
      + '\nvoid '+l+'::paintEvent(QPaintEvent* /*pe*/)\n{\n}\n\n'
      + '\nvoid '+l+'::timerEvent(QTimerEvent* /*pe*/)\n{\n}\n\n'
      + '\nvoid '+l+'::keyPressEvent(QKeyEvent* /*pe*/)\n{\n}\n\n'
      + '\nvoid '+l+'::mousePressEvent(QMouseEvent* /*pe*/)\n{\n}\n\n')
  if args.project != None:
    with open(args.project+".pro", 'a') as f:
      f.write('\nSOURCES += '+l+'.cpp')
  # svn add


def addClass(newClassName):
  detectProject()
  l = newClassName
  u = l.upper()
  copyright = '/*' + copyrightString(args.new_project + ' - ' + l) + '*/\n'
  print "adding class " + str(l)
  with open(l+".h", 'a') as f:
    f.write("#ifndef "+u+"_H\n#define "+u+"_H\n\n\n"+copyright+"\n\n#include <memory>\n\n\n"
      + "class "+l+"\n{\npublic:\n  "+l+"();\n  ~"+l+"();\nprivate:\n  struct Pimpl;\n"
      +  "  std::unique_ptr<Pimpl> m_pimpl;\n};\n\n\n#endif // "+u+"_H\n\n")
  with open(l+".cpp", 'a') as f:
    f.write(copyright+'#include "'+l+'.h"\n\n\nstruct '+l+'::Pimpl\n{\n  // private implementation details here\n};'
      + '\n\n\n'+l+'::'+l+'() : m_pimpl(std::unique_ptr<Pimpl>(new Pimpl()))\n{\n}\n\n\n'+l+'::~'+l+'()\n{\n}\n\n')
  if args.project != None:
    with open(args.project+".pro", 'a') as f:
      f.write('\nSOURCES += '+l+'.cpp')
  # svn add


def addMethod(newMethodName):
  m = newMethodName
  print 'detecting class...'
  c = re.sub('.* ([a-zA-Z][0-9a-zA-Z]*)::[0-9a-zA-Z]*\(.*', '\\1', m)
  m = re.sub(' [a-zA-Z][0-9a-zA-Z]*::([0-9a-zA-Z]*)\(', ' \\1(', m)
  print "adding method " + m + " to class " + c
  header = ''
  with open(c+".h", 'r') as f:
    header = f.read()
  header = re.sub('private:', '  ' + m + ';\nprivate:', header)
  if header != '':
    with open(c+".h", 'w') as f:
      f.write(header)
  with open(c+".cpp", 'a') as f:
    f.write('\n' + re.sub(' ([a-zA-Z][0-9a-zA-Z]*)\(', ' ' + c + '::\\1(', m) + '\n{\n}\n\n')


def findReferences():
  print 'finding method references...'
  print 'not implemented'


def renameMethod():
  print 'renaming method...'
  print 'not implemented'


if args.new_project:
  addProject()

if args.new_widget:
  addWidgetClass(args.new_widget)

if args.new_class:
  addClass(args.new_class)

if args.new_method:
  addMethod(args.new_method)