예제 #1
0
def main():
    for top in find_src_dirs():
        assert os.path.exists(top)
        retval = 0
        for root, dirs, files in os.walk(top):
            # Sort dirs
            dirs.sort()
            for item in files:
                # Skip some dirs
                ignored = 0
                for dd in IGNORED_DIRS:
                    if root.find(dd) != -1: ignored = 1

                    if ignored == 0:
                        if re_srcfile.search(item):
                            path = os.path.join(root, item)
                            with open(path, "rt") as fh:
                                src_data = fh.read()
                            src_count = len(re.findall(re_config, src_data))

                            if src_count == 0:
                                sys.stderr.write(
                                    "%s/%s: missing include of config.h\n" %
                                    (root, item))
                                retval = 1
                            elif src_count > 1:
                                sys.stdout.write(
                                    "%s/%s: %d includes of config.h\n" %
                                    (root, item, src_count))

    return retval
예제 #2
0
def main():
  print("-------------------------------------------------------")
  print(" Searching for inlined CPP macros in ABINIT src files  ")
  print("-------------------------------------------------------")
  exit_status = 0
  for top in find_src_dirs():
      assert os.path.isdir(top)
      for dirpath, dirnames, files in os.walk(top):
        for src in files:
            if not is_srcfile(dirpath, src): continue
            fpath = os.path.join(dirpath,src)
            with open(fpath, "rt") as fh:
                for lno, line in enumerate(fh):
                    s = wrong_string(line)
                    if s:
                        print("(INLINED MACRO at %s:%d):  %s " % (src, lno+1, line))
                        exit_status += 1

  if exit_status > 0:
    err_msg = """
  Please, avoid instructions like:

    if (allocated(arr)) ABI_DEALLOCATE(arr)

  When the code is compiled in profile mode, indeed, ABI_DEALLOCATE expands to 
  the set of Fortran instructions:

    deallocate(arr)
    call memocc_abi()

  These instructions MUST be placed inside an "if then" "end if" block.
  This limitation can be lifted, but we need support at the level of the build system.
  For the time being, one has to use the more verbose form:

    if (allocated(arr)) then 
      ABI_DEALLOCATE(arr)
    end if

  This is the list of macros that cannot be inlined:

  %(MACRO_NAMES)s
""" % globals()
    print(err_msg)

  return exit_status
예제 #3
0
def main():
    print("--------------------------------------------------------")
    print(" Searching for non-ASCII characters in ABINIT src files ")
    print("--------------------------------------------------------")

    exit_status = 0
    for top in find_src_dirs():
        for dirpath, dirnames, files in os.walk(top):
            for src in files:
                if is_srcfile(dirpath, src):
                    fpath = os.path.join(dirpath, src)
                    with open(fpath, "rt") as fh:
                        lines = fh.readlines()
                    for lno, line in enumerate(lines):
                        if not isascii(line):
                            exit_status += 1
                            print(">>> Non-ASCII character at: ", fpath, ":",
                                  lno + 1)
                            print(line)
    return exit_status
예제 #4
0
def main():
    retval = 0
    for top in find_src_dirs():
        for root, dirs, files in os.walk(top):
            # Check line lengths in Fortran source files
            for item in files:
                if re_srcfile.search(item) and item != "m_build_info.F90":
                    lineno = 1
                    path = os.path.join(root, item)
                    with open(path, "rt") as fh:
                        for line in fh:
                            line = re.sub("!.*", "", line)
                            line = re.sub("\n", "", line)
                            if len(line) > len_limit:
                                sys.stderr.write(
                                    "%s: line %d has more than %d characters\n" % (path, lineno, len_limit))
                                sys.stdout.write(
                                    "%s: line %d has more than %d characters\n" % (path, lineno, len_limit))
                                retval = 1
                            lineno += 1
    return retval
예제 #5
0
def main():
  top = find_abinit_toplevel_directory()
  verbose = 0

  # Extract CPP options from the libPAW header files
  #libpaw_dir = os.path.join(top, "src", "39_libpaw")
  libpaw_dir = os.path.join(top, "shared", "libpaw")
  assert os.path.isdir(libpaw_dir)
  cpp_libpaw = list()
  for root,dirs,files in os.walk(libpaw_dir):
    for src in files:
      if ( re_hdrfile.search(src) ):
        with open(os.path.join(root,src), "rt") as fh:
            for line in fh:
              if ( re_cppdef.search(line) ):
                tmp_def = re.sub("^[# ]*define[ ]*([0-9A-Z_]*).*","\\1",line).strip()
                if ( not tmp_def in cpp_libpaw ):
                  cpp_libpaw.append(tmp_def)

  # Extract CPP options from the libTetra header files
  libtetra_dir = os.path.join(top, "shared", "common", "src", "17_libtetra_ext")
  assert os.path.isdir(libtetra_dir)
  cpp_libtetra = list()
  for root,dirs,files in os.walk(libtetra_dir):
    for src in files:
      if ( re_hdrfile.search(src) ):
        with open(os.path.join(root,src), "rt") as fh:
            for line in fh:
              if ( re_cppdef.search(line) ):
                tmp_def = re.sub("^[# ]*define[ ]*([0-9A-Z_]*).*","\\1",line).strip()
                if ( not tmp_def in cpp_libtetra ):
                  cpp_libtetra.append(tmp_def)

  # Extract CPP options from the build system
  cpp_buildsys = list()
  m4_path = os.path.join(top, "config", "m4")
  assert os.path.isdir(m4_path)
  for root,dirs,files in os.walk(m4_path):
    for src in files:
      if ( src.endswith(".m4") ):
        with open(os.path.join(root, src), "rt") as fh:
            for line in fh:
              if re_acdef.search(line):
                tmp_def = re.sub(".*AC_DEFINE\\([\\[]?([^\\],]*).*","\\1",line).strip()
                if not tmp_def in cpp_buildsys:
                  cpp_buildsys.append(tmp_def)
  with open(os.path.join(top, "configure.ac"), "rt") as fh:
      for line in fh:
        if ( re_acdef.search(line) ):
          tmp_def = re.sub(".*AC_DEFINE\\([\\[]?([^\\],]*).*","\\1",line).strip()
          if ( not tmp_def in cpp_buildsys ):
            cpp_buildsys.append(tmp_def)

  cpp_buildsys = cpp_buildsys + cpp_libpaw + cpp_libtetra
  cpp_buildsys.sort()

  # Create CPP naming blocks
  for opt in cpp_buildsys:
    tmp = opt.split("_")
    for i in range(len(tmp)):
      if ( i >= len(cpp_blocks) ):
        cpp_blocks.append(list())
      if ( not tmp[i] in cpp_blocks[i] ):
        cpp_blocks[i].append(tmp[i])

  # Extract CPP options from the includes
  incs_dir = os.path.join(top, "src", "incs")
  assert os.path.isdir(incs_dir)
  cpp_includes = list()
  for root,dirs,files in os.walk(incs_dir):
    for src in files:
      if not re_hdrfile.search(src): continue
      with open(os.path.join(root,src), "rt") as fh:
        for line in fh:
          if re_cppdef.search(line):
            tmp_def = re.sub("^[# ]*define[ ]*([0-9A-Z_]*).*","\\1",line).strip()
            if not tmp_def in cpp_includes:
              cpp_includes.append(tmp_def)

  cpp_includes.sort()

  # Merge CPP information
  cpp_allowed = cpp_explicit + cpp_buildsys
  cpp_allowed.sort()

  # Explore the source files
  cpp_source = dict()
  #src_dir = os.path.join(top, "src")
  #assert os.path.isdir(src_dir)
  for src_dir in find_src_dirs():
      for root,dirs,files in os.walk(src_dir):
        files.sort()
        for src in files:
          if re_f90file.search(src):
            with open(os.path.join(root, src), "rt") as fh:
              f90_buffer = fh.readlines()
            cpp_load = False
            for i in range(len(f90_buffer)):
              line = f90_buffer[i]

              # Record CPP lines
              if ( re_cppline.search(line) ):
                if ( cpp_load ):
                  sys.stderr.write("%s: %s:%d: Error: unterminated CPP directive\n" % \
                    (my_name,src,i+1))
                  sys.exit(1)
                cpp_load = True
                cpp_buffer = ""

              # Process CPP lines
              if ( cpp_load ):
                cpp_buffer += line
                if ( not re_cppcont.search(line) ):
                  if ( not re_cppskip.search(line) ):

                    # Extract CPP options
                    for kwd in cpp_keywords:
                      cpp_buffer = re.sub(kwd,"",cpp_buffer)
                    cpp_buffer = re.sub("[\n\t ]+"," ",cpp_buffer)
                    cpp_buffer = cpp_buffer.strip()
                    cpp_buffer = cpp_buffer.split()

                    # Register CPP options
                    for opt in cpp_buffer:
                      if ( not opt in cpp_ignored ):
                        if ( not opt in cpp_source ):
                          cpp_source[opt] = list()
                        cpp_source[opt].append("%s/%s:%d" % (root,src,i+1))

                  # Reset
                  cpp_load = False

  # Process CPP option information
  cpp_keys = list(cpp_source.keys())
  cpp_keys.sort()
  cpp_devel = [opt for opt in cpp_keys \
    if ( opt in cpp_explicit or re_cppdev.match(opt) )]
  cpp_undefined = [opt for opt in cpp_keys \
    if not ( (opt in cpp_allowed) or (opt in cpp_devel) )]

  cpp_misnamed = [opt for opt in cpp_keys \
    if not ( check_name(opt,cpp_blocks) or (opt in cpp_undefined) or
      (opt in cpp_devel) ) ]
  cpp_misnamed += [opt for opt in cpp_includes \
    if ( opt in cpp_source and not (check_name(opt,cpp_blocks) or opt in cpp_devel))]
  cpp_misnamed.sort()

  # Display forbidden CPP options
  if ( (verbose and (len(cpp_devel) > 0)) or (len(cpp_undefined) > 0) ):
    sys.stderr.write("%s: reporting preprocessing option discrepancies\n\n" % \
      (os.path.basename(sys.argv[0])))
    sys.stderr.write("X: N=Wrong Naming / U=Undefined\n\n")

  if ( verbose and (len(cpp_devel) > 0) ):
    sys.stderr.write("%s  %-24s  %-44s\n" % ("X","Developer option","Location"))
    sys.stderr.write("%s  %-24s  %-44s\n" % ("-","-" *24,"-" * 48))
    for opt in cpp_devel:
      if ( len(cpp_source[opt]) <= 50 ):
        for src in cpp_source[opt]:
          sys.stderr.write("*  %-24s  %-48s\n" % (opt,src))
      else:
        sys.stderr.write("*  %-24s  Not shown (referenced %d times)\n" % \
          (opt,len(cpp_source[opt])))
    sys.stderr.write("\n")

  retval = len(cpp_undefined) + len(cpp_misnamed)

  if retval != 0:
    sys.stderr.write("%s  %-24s  %-44s\n" % ("X","Forbidden option","Location"))
    sys.stderr.write("%s  %-24s  %-44s\n" % ("-","-" *24,"-" * 48))
    for opt in cpp_undefined:
      if ( len(cpp_source[opt]) <= 50 ):
        for src in cpp_source[opt]:
          sys.stderr.write("U  %-24s  %-48s\n" % (opt,src))
      else:
        sys.stderr.write("U  %-24s  Not shown (referenced %d times)\n" % \
          (opt,len(cpp_source[opt])))
    for opt in cpp_misnamed:
      sys.stderr.write("N  %-24s  N/A\n" % (opt))
    sys.stderr.write("\n")

  return retval
예제 #6
0
def main():

    print()
    print(
        '---------------------------------------------------------------------'
    )
    print(
        ' Looking for forbidden statements in ABINIT src files:               '
    )
    if ACTIVATE_TEST1 or ACTIVATE_TEST2:
        print(
            '  - forbidden access to standard output/standard error               '
        )
    if ACTIVATE_TEST3:
        print(
            '  - forbidden allocate/deallocate statements                         '
        )
    if ACTIVATE_TEST4:
        print(
            '  - forbidden explicit MPI_COMM_WORLD communicator                   '
        )
    if ACTIVATE_TEST5:
        print(
            '  - forbidden call statements not placed at the start of the line    '
        )
    print(
        '---------------------------------------------------------------------'
    )

    re_srcfile = re.compile("\.([Ff]|[Ff]90|finc|h)$")

    #Initialize counters
    file_total_count = 0
    stat_forbidden_write_count = 0
    file_forbidden_write_count = 0
    stat_notrecommended_write_count = 0
    file_notrecommended_write_count = 0
    stat_forbidden_commworld_count = 0
    file_forbidden_commworld_count = 0
    stat_forbidden_allocate_count = 0
    file_forbidden_allocate_count = 0
    stat_forbidden_call_count = 0
    file_forbidden_call_count = 0

    # Loop over files in src folder
    for top in find_src_dirs():
        for root, dirs, files in os.walk(top):
            for src in files:
                if re_srcfile.search(src):
                    file_total_count += 1
                    filename = os.path.join(root, src)
                    with open(filename, "rt") as fh:
                        src_data = fh.readlines()

                    #Loop over lines in the file
                    lineno = 0
                    icount_forbidden_write = 0
                    icount_notrecommended_write = 0
                    icount_forbidden_commworld = 0
                    icount_forbidden_allocate = 0
                    icount_forbidden_call = 0
                    for line_orig in src_data:
                        lineno += 1

                        #Transform line to lower case + eliminate whitespaces
                        line_lower = line_orig.lower()
                        line = re.sub(" ", "", line_lower)

                        #Skip lines beginning with an authorized character
                        ignored = 0
                        for strg in NO_ERROR_LIST:
                            if line.find(strg) == 0: ignored = 1

                        if ignored == 0:
                            #Look for forbidden write statements
                            if ACTIVATE_TEST1 and (not src
                                                   in IGNORED_WRITE_FILES):
                                for strg in WRITE_FORBIDDEN_LIST:
                                    if line.find(strg) != -1:
                                        print(
                                            '  Error: %s, line %d: found \"%s\" !'
                                            % (filename, lineno, strg))
                                        icount_forbidden_write += 1

                            #Look for not recommended write statements
                            if ACTIVATE_TEST2 and (not src
                                                   in IGNORED_WRITE_FILES):
                                for strg in WRITE_NOTRECOMMENDED_LIST:
                                    if line.find(strg) != -1 and src not in [
                                            "m_specialmsg.F90"
                                    ]:
                                        print(
                                            '- Warning: %s, line %d: found \"%s\" !'
                                            % (filename, lineno, strg))
                                        icount_notrecommended_write += 1

                            #Look for forbidden MPI_COMM_WORLD statements
                            if ACTIVATE_TEST3 and (not src
                                                   in IGNORED_COMMWORLD_FILES):
                                for strg in COMMWORLD_FORBIDDEN_LIST:
                                    if line.find(strg) != -1:
                                        print(
                                            '  Error: %s, line %d: found \"%s\" !'
                                            % (filename, lineno, strg))
                                        icount_forbidden_commworld += 1

                            #Look for forbidden allocate/deallocate statements
                            if ACTIVATE_TEST4 and (not src
                                                   in IGNORED_ALLOCATE_FILES):
                                ifound = 0
                                for strg in ALLOCATE_FORBIDDEN_LIST:
                                    ialloc = line.find(strg)
                                    if ifound == 0 and ialloc != -1:
                                        ifound = 1
                                        if not '_' + strg in line:
                                            if ialloc + len(strg) < len(line):
                                                if line[ialloc - 4:
                                                        ialloc] != "abi_" and line[
                                                            ialloc +
                                                            len(strg)] == "(":
                                                    print(
                                                        '  Error: %s, line %d: found \"%s\" !'
                                                        % (filename, lineno,
                                                           strg))
                                                    icount_forbidden_allocate += 1

                            #Look for forbidden call statements (not placed at the start of the line)
                            if ACTIVATE_TEST5 and (not src
                                                   in IGNORED_CALL_FILES):
                                for strg in CALL_STATEMENT_LIST:
                                    icall = line_lower.find(" " + strg + " ")
                                    if icall > 0:
                                        line_before = re.sub(
                                            " ", "", line_lower[:icall])
                                        line_after = re.sub(
                                            " ", "",
                                            line_lower[icall +
                                                       3:len(line_lower) - 1])
                                        nothing_before = (
                                            len(line_before) == 0)
                                        comment_before = (line_before.find("!")
                                                          != -1)
                                        label_before = (not (re.match(
                                            '[0-9]+', line_before) == None))
                                        quote_before = (
                                            (line_before.find("'") != -1)
                                            or (line_before.find('"') != -1))
                                        problem_before = ((not nothing_before)
                                                          and
                                                          (not label_before)
                                                          and
                                                          (not quote_before))
                                        problem_after = (re.match(
                                            '[^\;\:\>\<\=\+\-\*\/\!\,]*(\(.*[\)\&]+|)',
                                            line_after) == None)
                                        if (not comment_before) and (
                                                problem_before
                                                or problem_after):
                                            print('  Error: %s, line %d: found \"%s\" not placed at the start of the line !' \
                                                  % (filename,lineno,strg))
                                            icount_forbidden_call += 1

                    #Update counters
                    stat_forbidden_write_count += icount_forbidden_write
                    stat_notrecommended_write_count += icount_notrecommended_write
                    stat_forbidden_commworld_count += icount_forbidden_commworld
                    stat_forbidden_allocate_count += icount_forbidden_allocate
                    stat_forbidden_call_count += icount_forbidden_call
                    if icount_forbidden_write > 0:
                        file_forbidden_write_count += 1
                    if icount_notrecommended_write > 0:
                        file_notrecommended_write_count += 1
                    if icount_forbidden_commworld > 0:
                        file_forbidden_commworld_count += 1
                    if icount_forbidden_allocate > 0:
                        file_forbidden_allocate_count += 1
                    if icount_forbidden_call > 0:
                        file_forbidden_call_count += 1

    # Print final message
    print('----------->')
    print('- There are %d F90 or header files in the complete set.' %
          file_total_count)
    assert file_total_count

    exit_status = (stat_forbidden_write_count +
                   stat_notrecommended_write_count +
                   stat_forbidden_commworld_count +
                   stat_forbidden_allocate_count + stat_forbidden_call_count)

    if stat_forbidden_write_count==0 and stat_notrecommended_write_count==0 and \
       stat_forbidden_commworld_count==0 and stat_forbidden_allocate_count==0 and \
       stat_forbidden_call_count==0:
        print('- No Error or Warning !')
    else:

        if stat_forbidden_write_count > 0:
            print()
            print( '>>>  %d error(s) (forbidden write statement(s)), appearing in %d different file(s)!' % \
                  (stat_forbidden_write_count,file_forbidden_write_count))
            print()
            print('  Replace the forbidden statement(s) by allowed ones:\n')
            print(
                '      "write(std_out,", "write(std_err," or "write(ab_out,".\n'
            )
            print('  Note that std_out redirects to the ABINIT log file')
            print('  while ab_out redirects to the ABINIT output file')
            print('  while std_err redirects to number 0 unit.')

        if stat_notrecommended_write_count > 0:
            print()
            print( '>>> %d WARNINGS (not recommended write statement(s)), appearing in %d different file(s) !' % \
                  (stat_notrecommended_write_count,file_notrecommended_write_count))
            print()
            print(
                '  Writing to the standard error is allowed in the following cases:\n'
            )
            print(
                '      - Within debugging sections of ABINIT, not activated in the production version;'
            )
            print(
                '      - In case an error has been detected, causing stop to ABINIT.\n'
            )
            print(
                '  In other cases, writing to std_err is not recommended, and should be avoided.'
            )

        if stat_forbidden_commworld_count > 0:
            print()
            print( '>>> %d ERRORS(s) (forbidden MPI_COMM_WORLD statement(s)), appearing in %d different file(s)!' % \
                  (stat_forbidden_commworld_count,file_forbidden_commworld_count))
            print()
            print(
                '  Replace the MPI_COMM_WORLD forbidden statement(s) by allowed ones:\n'
            )
            print('      - "xmpi_world" or "mpi_enreg%world_comm".')
            print(
                '      - MPI_COMM_WORLD is not allowed because it may be redefined in some cases\n'
            )

        if stat_forbidden_allocate_count > 0:
            print()
            print( '>>> %d ERROR(s) (forbidden allocate/deallocate statement(s)), appearing in %d different file(s)!\n' % \
                  (stat_forbidden_allocate_count,file_forbidden_allocate_count))
            print()
            print(
                '   Replace the forbidden allocate statement(s) by the ABI_ALLOCATE macro defined in abi_common.h'
            )
            print(
                '   Replace the forbidden deallocate statement(s) by the ABI_DEALLOCATE macro defined in abi_common.h'
            )
            print(
                '   You need to add `#include "abi_common.h"` and `use m_errors` to have access to these macros.'
            )
            print(
                '   Note that the syntax of the ABI_ALLOCATE macro is not exactly the same as the allocate statement:\n'
            )
            print(
                '       - only one array to be allocated in each ABI_ALLOCATE')
            print(
                '      - separate the array from the parenthesis and size with a comma'
            )
            print(
                '      - example: instead of allocate(arr1(3,N), arr2(20)), you should write the allocations separately using:\n'
            )
            print('              ABI_ALLOCATE(arr1,(3,N))')
            print('              ABI_ALLOCATE(arr2,(20))\n')
            print(
                '  Note that the syntax of the ABI_DEALLOCATE macro is not exactly the same as the deallocate statement:\n'
            )
            print(
                '      - only one array to be deallocated in each ABI_DEALLOCATE'
            )
            print(
                '      - example: instead of deallocate(arr1,arr2), you should write the deallocations separately using:\n'
            )
            print('              ABI_DEALLOCATE(arr1)')
            print('              ABI_DEALLOCATE(arr2)\n')
            print(
                '  Finally, use ABI_MALLOC_SCALAR and ABI_FREE_SCALAR to allocate/free scalar entities.'
            )
            print('  and ABI_MOVE_ALLOC instead of Fortran move_alloc.')

        if stat_forbidden_call_count > 0:
            # MG: Why? Besides there are several macros doing this...
            print()
            print( '>> %d ERROR(s) (badly placed call statement(s)), appearing in %d different file(s) !' % \
                  (stat_forbidden_call_count,file_forbidden_call_count))
            print()
            print(
                '  Please place the CALL statement at the start of the line.')
            print('      Avoid: "statement 1 ; call subroutine()"')
            print('      Avoid: "if (condition) call subroutine()"')

    return exit_status