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:
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 "
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('&', '&').replace('<', '<').replace('>', '>').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')
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':
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
('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
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]