Package qm :: Module label
[hide private]
[frames] | no frames]

Source Code for Module qm.label

  1  ######################################################################## 
  2  # 
  3  # File:   label.py 
  4  # Author: Alex Samuel 
  5  # Date:   2001-03-17 
  6  # 
  7  # Contents: 
  8  #   Label 
  9  # 
 10  # Copyright (c) 2001, 2002 by CodeSourcery, LLC.  All rights reserved.  
 11  # 
 12  # For license terms see the file COPYING. 
 13  # 
 14  ######################################################################## 
 15   
 16  ######################################################################## 
 17  # Imports 
 18  ######################################################################## 
 19   
 20  from   __future__ import nested_scopes 
 21  import os 
 22  import re 
 23  import string 
 24  import types 
 25   
 26  ######################################################################## 
 27  # Classes 
 28  ######################################################################## 
 29   
30 -class Label:
31 """A 'Label' identifies an entity. 32 33 A 'Label' is a generalization of a filename. Like filenames, labels 34 consist of one or more directories followed by a basename. However, 35 the format used for a label need not be the same as that used by 36 filenames. 37 38 Each label class defines a separator character to take the place of 39 the '/' character used by many file systems. 40 41 All labels are relative labels; no label may begin with a separator 42 character.""" 43
44 - def __init__(self, label):
45 """Construct a new 'Label'. 46 47 'label' -- A string giving the value of the label.""" 48 49 assert type(label) in (types.StringType, types.UnicodeType) 50 self._label = label
51 52
53 - def Join(self, *labels):
54 """Combine this label and the 'labels' into a single label. 55 56 'labels' -- A sequence of strings giving the components of the 57 new label. All but the last are taken as directory names; the 58 last is treated as a basename.""" 59 60 result = self._label 61 for l in labels: 62 if not result: 63 # If the label is empty so far, l is the first component. 64 result = l 65 elif result and result[-1] == self._sep: 66 # If the label thus far ends with a separator, we do not 67 # want to add another one. 68 result += l 69 else: 70 result = result + self._sep + l 71 72 return self.__class__(result)
73 74
75 - def Split(self):
76 """Split the label into a pair '(directory, basename)'. 77 78 returns -- A pair '(directory, basename)', each of which is 79 a label. 80 81 It is always true that 'directory.join(basename)' will return a 82 label equivalent to the original label.""" 83 84 last_sep = self._label.rfind(self._sep) 85 if last_sep != -1: 86 return (self.__class__(self._label[:last_sep]), 87 self.__class__(self._label[last_sep + 1:])) 88 else: 89 return (self.__class__(""), 90 self.__class__(self._label))
91 92
93 - def SplitLeft(self):
94 """Split the label into a pair '(parent, subpath)'. This is 95 the same operation as Split, except the split occurs at the 96 leftmost separator, not the rightmost. 97 98 returns -- A pair '(directory, basename)', each of which is 99 a label. 100 101 It is always true that 'directory.join(basename)' will return a 102 label equivalent to the original label.""" 103 104 first_sep = self._label.find(self._sep) 105 if first_sep != -1: 106 return (self.__class__(self._label[:first_sep]), 107 self.__class__(self._label[first_sep + 1:])) 108 else: 109 return (self.__class__(self._label), 110 self.__class__(""))
111 112
113 - def Basename(self):
114 """Return the basename for the label. 115 116 returns -- A string giving the basename for the label. The 117 value returned for 'l.basename()' is always the same as 118 'l.split()[1]'.""" 119 120 return self.Split()[1]
121 122
123 - def Dirname(self):
124 """Return the directory name for the 'label'. 125 126 returns -- A string giving the directory name for the 'label'. 127 The value returned for 'l.dirname()' is always the same as 128 'l.split()[0]'.""" 129 130 return self.Split()[0]
131 132
133 - def IsValid(self, label, is_component):
134 """Returns true if 'label' is valid. 135 136 'label' -- The string being tested for validity. 137 138 'is_component' -- True if the string being tested is just a 139 single component of a label path. 140 141 returns -- True if 'label' is not valid.""" 142 143 if label and label[0] == self._sep: 144 # All labels are relative; a valid label cannot begin with a 145 # separator. 146 return 0 147 elif is_component and self._sep in label: 148 # A component label cannot contain a separator. 149 return 0 150 elif label.find(self._sep + self._sep) != -1: 151 # It is invalid to have two separators in a row. 152 return 0 153 154 return 1
155 156
157 - def __str__(self):
158 """Return the string form of this label.""" 159 160 return self._label
161 162 ######################################################################## 163 # Functions 164 ######################################################################## 165 166 __thunk_regex = re.compile("[^a-z0-9_]") 167
168 -def thunk(label):
169 """Sanitize and convert 'label' to a valid label. 170 171 Makes a best-effort attempt to keep 'label' recognizable during 172 the conversion. 173 174 returns -- A valid label.""" 175 176 # Strip leading and trailing whitespace. 177 label = string.strip(label) 178 # Lower capital letters. 179 label = string.lower(label) 180 # Replace all invalid characters with underscores. 181 label = string.replace(label, "+", "x") 182 label = __thunk_regex.sub("_", label) 183 # Trim leading underscores. 184 while len(label) > 0 and label[0] == "_": 185 label = label[1:] 186 # Make sure the label isn't empty. 187 if label == "": 188 raise ValueError, "Empty label" 189 return label
190 191 ######################################################################## 192 # Local Variables: 193 # mode: python 194 # indent-tabs-mode: nil 195 # fill-column: 72 196 # End: 197