aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Dependencies.py149
-rw-r--r--scripts/LexGen.py9
-rw-r--r--scripts/__init__.py0
3 files changed, 158 insertions, 0 deletions
diff --git a/scripts/Dependencies.py b/scripts/Dependencies.py
new file mode 100644
index 000000000..86a2d3b22
--- /dev/null
+++ b/scripts/Dependencies.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+# Dependencies.py - discover, read, and write dependencies file for make.
+# The format like the output from "g++ -MM" which produces a
+# list of header (.h) files used by source files (.cxx).
+# As a module, provides
+# FindPathToHeader(header, includePath) -> path
+# FindHeadersInFile(filePath) -> [headers]
+# FindHeadersInFileRecursive(filePath, includePath, renames) -> [paths]
+# FindDependencies(sourceGlobs, includePath, objExt, startDirectory, renames) -> [dependencies]
+# ExtractDependencies(input) -> [dependencies]
+# TextFromDependencies(dependencies)
+# WriteDependencies(output, dependencies)
+# UpdateDependencies(filepath, dependencies)
+# PathStem(p) -> stem
+# InsertSynonym(dependencies, current, additional) -> [dependencies]
+# If run as a script reads from stdin and writes to stdout.
+# Only tested with ASCII file names.
+# Copyright 2019 by Neil Hodgson <neilh@scintilla.org>
+# The License.txt file describes the conditions under which this software may be distributed.
+# Requires Python 2.7 or later
+
+import codecs, glob, os, sys
+
+from . import FileGenerator
+
+continuationLineEnd = " \\"
+
+def FindPathToHeader(header, includePath):
+ for incDir in includePath:
+ relPath = os.path.join(incDir, header)
+ if os.path.exists(relPath):
+ return relPath
+ return ""
+
+fhifCache = {} # Remember the includes in each file. ~5x speed up.
+def FindHeadersInFile(filePath):
+ if filePath not in fhifCache:
+ headers = []
+ with codecs.open(filePath, "r", "utf-8") as f:
+ for line in f:
+ if line.strip().startswith("#include"):
+ parts = line.split()
+ if len(parts) > 1:
+ header = parts[1]
+ if header[0] != '<': # No system headers
+ headers.append(header.strip('"'))
+ fhifCache[filePath] = headers
+ return fhifCache[filePath]
+
+def FindHeadersInFileRecursive(filePath, includePath, renames):
+ headerPaths = []
+ for header in FindHeadersInFile(filePath):
+ if header in renames:
+ header = renames[header]
+ relPath = FindPathToHeader(header, includePath)
+ if relPath and relPath not in headerPaths:
+ headerPaths.append(relPath)
+ subHeaders = FindHeadersInFileRecursive(relPath, includePath, renames)
+ headerPaths.extend(sh for sh in subHeaders if sh not in headerPaths)
+ return headerPaths
+
+def RemoveStart(relPath, start):
+ if relPath.startswith(start):
+ return relPath[len(start):]
+ return relPath
+
+def ciKey(f):
+ return f.lower()
+
+def FindDependencies(sourceGlobs, includePath, objExt, startDirectory, renames={}):
+ deps = []
+ for sourceGlob in sourceGlobs:
+ sourceFiles = glob.glob(sourceGlob)
+ # Sorting the files minimizes deltas as order returned by OS may be arbitrary
+ sourceFiles.sort(key=ciKey)
+ for sourceName in sourceFiles:
+ objName = os.path.splitext(os.path.basename(sourceName))[0]+objExt
+ headerPaths = FindHeadersInFileRecursive(sourceName, includePath, renames)
+ depsForSource = [sourceName] + headerPaths
+ depsToAppend = [RemoveStart(fn.replace("\\", "/"), startDirectory) for
+ fn in depsForSource]
+ deps.append([objName, depsToAppend])
+ return deps
+
+def PathStem(p):
+ """ Return the stem of a filename: "CallTip.o" -> "CallTip" """
+ return os.path.splitext(os.path.basename(p))[0]
+
+def InsertSynonym(dependencies, current, additional):
+ """ Insert a copy of one object file with dependencies under a different name.
+ Used when one source file is used to create two object files with different
+ preprocessor definitions. """
+ result = []
+ for dep in dependencies:
+ result.append(dep)
+ if (dep[0] == current):
+ depAdd = [additional, dep[1]]
+ result.append(depAdd)
+ return result
+
+def ExtractDependencies(input):
+ """ Create a list of dependencies from input list of lines
+ Each element contains the name of the object and a list of
+ files that it depends on.
+ Dependencies that contain "/usr/" are removed as they are system headers. """
+
+ deps = []
+ for line in input:
+ headersLine = line.startswith(" ") or line.startswith("\t")
+ line = line.strip()
+ isContinued = line.endswith("\\")
+ line = line.rstrip("\\ ")
+ fileNames = line.strip().split(" ")
+ if not headersLine:
+ # its a source file line, there may be headers too
+ sourceLine = fileNames[0].rstrip(":")
+ fileNames = fileNames[1:]
+ deps.append([sourceLine, []])
+ deps[-1][1].extend(header for header in fileNames if "/usr/" not in header)
+ return deps
+
+def TextFromDependencies(dependencies):
+ """ Convert a list of dependencies to text. """
+ text = ""
+ indentHeaders = "\t"
+ joinHeaders = continuationLineEnd + "\n" + indentHeaders
+ for dep in dependencies:
+ object, headers = dep
+ text += object + ":"
+ for header in headers:
+ text += joinHeaders
+ text += header
+ if headers:
+ text += "\n"
+ return text
+
+def UpdateDependencies(filepath, dependencies, comment=""):
+ """ Write a dependencies file if different from dependencies. """
+ FileGenerator.UpdateFile(filepath, comment+TextFromDependencies(dependencies))
+
+def WriteDependencies(output, dependencies):
+ """ Write a list of dependencies out to a stream. """
+ output.write(TextFromDependencies(dependencies))
+
+if __name__ == "__main__":
+ """ Act as a filter that reformats input dependencies to one per line. """
+ inputLines = sys.stdin.readlines()
+ deps = ExtractDependencies(inputLines)
+ WriteDependencies(sys.stdout, deps)
diff --git a/scripts/LexGen.py b/scripts/LexGen.py
index ae7ae99d5..82eb39182 100644
--- a/scripts/LexGen.py
+++ b/scripts/LexGen.py
@@ -14,6 +14,12 @@ from FileGenerator import Regenerate, UpdateLineInFile, \
import ScintillaData
import HFacer
import uuid
+import sys
+
+sys.path.append("../")
+
+import win32.DepGen
+import gtk.DepGen
def UpdateVersionNumbers(sci, root):
UpdateLineInFile(root + "win32/ScintRes.rc", "#define VERSION_SCINTILLA",
@@ -115,6 +121,9 @@ def RegenerateAll(root):
Regenerate(root + "src/Catalogue.cxx", "//", sci.lexerModules)
Regenerate(root + "win32/scintilla.mak", "#", sci.lexFiles)
+ win32.DepGen.Generate()
+ gtk.DepGen.Generate()
+
RegenerateXcodeProject(root + "cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj",
sci.lexFiles, sci.lexersXcode)
diff --git a/scripts/__init__.py b/scripts/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/scripts/__init__.py