common: port more functions and fix one
[gtk-doc.git] / gtkdoc / common.py
blobef61574e37c1716c634cdd06efdb5af8fd2fb218
1 # -*- python -*-
3 # gtk-doc - GTK DocBook documentation generator.
4 # Copyright (C) 2001 Damon Chaplin
5 # 2007-2016 Stefan Sauer
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 import logging
23 import os
24 import re
25 import subprocess
27 from . import config
30 def UpdateFileIfChanged(old_file, new_file, make_backup):
31 """Compares the old version of the file with the new version and if the
32 file has changed it moves the new version into the old versions place. This
33 is used so we only change files if needed, so we can do proper dependency
34 tracking.
36 Args:
37 old_file (string): The pathname of the old file.
38 new_file (string): The pathname of the new version of the file.
39 make_backup (bool): True if a backup of the old file should be kept.
40 It will have the .bak suffix added to the file name.
42 Returns:
43 bool: It returns False if the file hasn't changed, and True if it has.
44 """
46 logging.debug("Comparing %s with %s...", old_file, new_file)
48 if os.path.exists(old_file):
49 old_contents = open(old_file, 'rb').read()
50 new_contents = open(new_file, 'rb').read()
51 if old_contents == new_contents:
52 return False
54 if make_backup:
55 backupname = old_file + '.bak'
56 if os.path.exists(backupname):
57 os.unlink(backupname)
58 os.rename(old_file, backupname)
59 else:
60 os.unlink(old_file)
62 os.rename(new_file, old_file)
63 return True
66 def GetModuleDocDir(module_name):
67 """Get the docdir for the given module via pkg-config
69 Args:
70 module_name (string): The module, e.g. 'glib-2.0'
72 Returns:
73 string: the doc directory
74 """
75 path = subprocess.check_output([config.pkg_config, '--variable=prefix', module_name], universal_newlines=True)
76 return os.path.join(path.strip(), 'share/gtk-doc/html')
79 def LogWarning(file, line, message):
80 """Log a warning in gcc style format
82 Args:
83 file (string): The file the error comes from
84 line (int): line number in the file
85 message (string): the error message to print
86 """
87 file = file or "unknown"
89 # TODO: write to stderr
90 print ("%s:%d: warning: %s" % (file, line, message))
93 def CreateValidSGMLID(id):
94 """Creates a valid SGML 'id' from the given string.
96 According to http://www.w3.org/TR/html4/types.html#type-id "ID and NAME
97 tokens must begin with a letter ([A-Za-z]) and may be followed by any number
98 of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"),
99 and periods (".")."
101 When creating SGML IDS, we append ":CAPS" to all all-caps identifiers to
102 prevent name clashes (SGML ids are case-insensitive). (It basically never is
103 the case that mixed-case identifiers would collide.)
105 Args:
106 id (string): The text to be converted into a valid SGML id.
108 Returns:
109 string: The converted id.
112 # Special case, '_' would end up as '' so we use 'gettext-macro' instead.
113 if id is "_":
114 return "gettext-macro"
116 id = id.strip(',;')
117 id = re.sub(r'[_ ]', '-', id)
118 id = re.sub(r'^-+', '', id)
119 id = id.replace('::', '-')
120 id = id.replace(':', '--')
122 # Append ":CAPS" to all all-caps identifiers
123 # FIXME: there are some inconsistencies here, we have index files containing e.g. TRUE--CAPS
124 if id.isupper() and not id.endswith('-CAPS'):
125 id += ':CAPS'
127 return id