]> git.lyx.org Git - lyx.git/blobdiff - development/scons/scons_utils.py
fix scons for Andre's LYX_DATE changes
[lyx.git] / development / scons / scons_utils.py
index a8e582237e88576f86c6af7910fc731c9f0c046a..9fa18265c49a960c712b0640f2138ebef96d9efd 100644 (file)
@@ -17,7 +17,9 @@ from SCons.Util import *
 
 
 def getVerFromConfigure(path):
-    " get lyx version from the AC_INIT line of configure.ac "
+    ''' get lyx version from the AC_INIT line of configure.ac,
+        and LYX_DATE from an AC_SUBST line.
+    '''
     try:
         config = open(os.path.join(path, 'configure.ac'))
     except:
@@ -25,14 +27,41 @@ def getVerFromConfigure(path):
         return 'x.x.x'
     # find a line like follows
     # AC_INIT(LyX,1.4.4svn,[lyx-devel@lists.lyx.org],[lyx])
-    pat = re.compile('AC_INIT\([^,]+,([^,]+),')
+    ver_pat = re.compile('AC_INIT\([^,]+,([^,]+),')
+    date_pat = re.compile('AC_SUBST\(LYX_DATE, \["(.*)"\]\)')
+    version = 'x.x.x'
+    date = 'Not released'
     for line in config.readlines():
-        if pat.match(line):
-            (version,) = pat.match(line).groups()
-            return version.strip()
-    return 'x.x.x'
+        if ver_pat.match(line):
+            (version,) = ver_pat.match(line).groups()
+        if date_pat.match(line):
+            (date,) = date_pat.match(line).groups()
+        if version != 'x.x.x' and date != 'Not released':
+            break
+    return version.strip(), date.strip()
+
+
+def relativePath(path, base):
+    '''return relative path from base, which is usually top source dir'''
+    # full pathname of path
+    path1 = os.path.normpath(os.path.realpath(path)).split(os.sep)
+    path2 = os.path.normpath(os.path.realpath(base)).split(os.sep)
+    if path1[:len(path2)] != path2:
+        print "Path %s is not under top source directory" % path
+    if len(path2) == len(path1):
+        return ''
+    path3 = os.path.join(*path1[len(path2):]);
+    # replace all \ by / such that we get the same comments on Windows and *nix
+    path3 = path3.replace('\\', '/')
+    return path3
 
 
+def isSubDir(path, base):
+    '''Whether or not path is a subdirectory of base'''
+    path1 = os.path.normpath(os.path.realpath(path)).split(os.sep)
+    path2 = os.path.normpath(os.path.realpath(base)).split(os.sep)
+    return len(path2) <= len(path1) and path1[:len(path2)] == path2
+
 
 def writeToFile(filename, lines, append = False):
     " utility function: write or append lines to filename "
@@ -113,124 +142,6 @@ def env_toc(target, source, env):
     doc_toc.build_toc(str(target[0]), [file.abspath for file in source])
     
     
-def relativePath(env, path):
-    '''return relative path from top source dir'''
-    # full pathname of path
-    path1 = os.path.normpath(env.File(path).abspath).split(os.sep)
-    path2 = os.path.normpath(env.Dir('$TOP_SRCDIR').abspath).split(os.sep)
-    if path1[:len(path2)] != path2:
-        print "Path %s is not under top source directory" % path
-    return os.path.join(*path1[len(path2):])
-
-
-def env_language_l10n(target, source, env):
-    '''Generate pot file from lib/language'''
-    input = open(env.File(source[0]).abspath)
-    output = open(env.File(target[0]).abspath, 'w')
-    for lineno, line in enumerate(input.readlines()):
-        if line[0] == '#':
-            continue
-        items = line.split('"')
-        # empty lines?
-        if len(items) != 5:
-            print 'Warning: this line looks strange:'
-            print line
-        # From:
-        #   afrikaans   afrikaans      "Afrikaans"     false  iso8859-15 af_ZA  ""
-        # To:
-        #   #: lib/languages:2
-        #   msgid "Afrikaans"
-        #   msgstr ""
-        print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % (relativePath(env, source[0]), lineno+1, items[1])
-    input.close()
-    output.close()
-
-
-def env_qt4_l10n(target, source, env):
-    '''Generate pot file from src/frontends/qt4/ui/*.ui'''
-    output = open(env.File(target[0]).abspath, 'w')
-    pat = re.compile(r'\s*<string>(.*)</string>')
-    prop = re.compile(r'\s*<property.*name.*=.*shortcut')
-    for src in source:
-        input = open(env.File(src).abspath)
-        skipNextLine = False
-        for lineno, line in enumerate(input.readlines()):
-            # looking for a line with <string></string>
-            if skipNextLine:
-                skipNextLine = False
-                continue
-            # skip the line after <property name=shortcut>
-            if prop.match(line):
-                skipNextLine = True
-                continue
-            # get lines that match <string>...</string>
-            if pat.match(line):
-                (string,) = pat.match(line).groups()
-                string = string.replace('&amp;', '&').replace('&lt;', '<').replace('&gt;', '>').replace('"', r'\"')
-                print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
-                    (relativePath(env, src), lineno+1, string) 
-        input.close()
-    output.close()
-
-
-def env_layouts_l10n(target, source, env):
-    '''Generate pot file from lib/layouts/*.layout and *.inc'''
-    output = open(env.File(target[0]).abspath, 'w')
-    Style = re.compile(r'^Style\s+(.*)')
-    # include ???LabelString???, but exclude comment lines
-    LabelString = re.compile(r'^[^#]*LabelString\S*\s+(.*)')
-    GuiName = re.compile(r'\s*GuiName\s+(.*)')
-    ListName = re.compile(r'\s*ListName\s+(.*)')
-    for src in source:
-        input = open(env.File(src).abspath)
-        for lineno, line in enumerate(input.readlines()):
-            # get lines that match <string>...</string>
-            if Style.match(line):
-                (string,) = Style.match(line).groups()
-                string = string.replace('_', ' ')
-            elif LabelString.match(line):
-                (string,) = LabelString.match(line).groups()
-            elif GuiName.match(line):
-                (string,) = GuiName.match(line).groups()
-            elif ListName.match(line):
-                (string,) = ListName.match(line).groups()
-            else:
-                continue
-            string = string.replace('\\', '\\\\').replace('"', '')
-            if string != "":
-                print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
-                    (relativePath(env, src), lineno+1, string)
-        input.close()
-    output.close()
-
-
-def env_ui_l10n(target, source, env):
-    '''Generate pot file from lib/ui/*'''
-    output = open(env.File(target[0]).abspath, 'w')
-    Submenu = re.compile(r'^[^#]*Submenu\s+"([^"]*)"')
-    Toolbar = re.compile(r'^[^#]*Toolbar\s+"[^"]+"\s+"([^"]*)"')
-    Item = re.compile(r'[^#]*Item\s+"([^"]*)"')
-    for src in source:
-        input = open(env.File(src).abspath)
-        for lineno, line in enumerate(input.readlines()):
-            # get lines that match <string>...</string>
-            if Submenu.match(line):
-                (string,) = Submenu.match(line).groups()
-                string = string.replace('_', ' ')
-            elif Toolbar.match(line):
-                (string,) = Toolbar.match(line).groups()
-            elif Item.match(line):
-                (string,) = Item.match(line).groups()
-            else:
-                continue
-            string = string.replace('\\', '\\\\').replace('"', '')
-            if string != "":
-                print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
-                    (relativePath(env, src), lineno+1, string)
-        input.close()
-    output.close()
-
-
 def env_cat(target, source, env):
     '''Cat source > target. Avoid pipe to increase portability'''
     output = open(env.File(target[0]).abspath, 'w')
@@ -241,6 +152,23 @@ def env_cat(target, source, env):
     output.close()
 
 
+def env_potfiles(target, source, env):
+    '''Build po/POTFILES.in'''
+    # command 
+    #   grep -l '_(\".*\")' `find src \( -name '*.h' -o -name '*.cpp' -o -name '*.cpp.in' \) -print` | grep -v -e "src/support/Package.cpp$$" | sort | uniq
+    # is used under *nix but windows users have to do these all in python
+    target_file = open(str(target[0]), "w")
+    potfiles = []
+    trans = re.compile('_\(".*"\)', re.M)
+    for file in source:
+        rel_file = relativePath(str(file), env.subst('$TOP_SRCDIR'))
+        if rel_file not in potfiles and trans.search(open(str(file)).read()):
+            potfiles.append(rel_file)
+    potfiles.sort()
+    print >> target_file, '\n'.join(potfiles)
+    target_file.close()
+
+    
 def createResFromIcon(env, icon_file, rc_file):
     ''' create a rc file with icon, and return res file (windows only) '''
     if os.name == 'nt':
@@ -512,9 +440,26 @@ int main()
     return ret
 
 
+def checkDeclaration(conf, func, headers):
+    ''' check if a function is declared in given headers '''
+    check_decl = '''
+#include <%%s>
+int main()
+{
+#ifndef %s
+    char *p = (char *) %s;
+#endif
+}
+''' % (func, func)
+    conf.Message('Checking for the declaration of function %s... ' % func)
+    ret = True in [conf.TryLink(check_decl % header, '.c') for header in headers]
+    conf.Result(ret)
+    return ret
+
+    
 def createConfigFile(conf, config_file,
     config_pre = '', config_post = '',
-    headers = [], functions = [], types = [], libs = [],
+    headers = [], functions = [], declarations = [], types = [], libs = [],
     custom_tests = [], extra_items = []):
     ''' create a configuration file, with options
         config_file: which file to create
@@ -524,6 +469,8 @@ def createConfigFile(conf, config_file,
             ('file', 'HAVE_FILE', 'c'/'c++')
         functions: functions to check, in the form of a list of
             ('func', 'HAVE_func', 'include lines'/None)
+        declarations: function declarations to check, in the form of a list of
+            ('func', 'HAVE_DECL_func', header_files)
         types: types to check, in the form of a list of
             ('type', 'HAVE_TYPE', 'includelines'/None)
         libs: libraries to check, in the form of a list of
@@ -572,6 +519,14 @@ def createConfigFile(conf, config_file,
         else:
             result[func[1]] = 0
             cont += configString('/* #undef %s */' % func[1], desc = description)
+    for decl in declarations:
+        description = "Define to 1 if you have the declaration of `%s', and to 0 if you don't." % decl[0]
+        if conf.CheckDeclaration(decl[0], decl[2]):
+            result[decl[1]] = 1
+            cont += configString('#define %s 1' % decl[1], desc = description)
+        else:
+            result[decl[1]] = 0
+            cont += configString('/* #undef %s */' % decl[1], desc = description)
     # types
     for t in types:
         description = "Define to 1 if you have the `%s' type." % t[0]