mercurial/patch.py
changeset 24265 dc655360bccb
parent 24264 c4205452f1b7
child 24268 cf7d252d8c30
equal deleted inserted replaced
24264:c4205452f1b7 24265:dc655360bccb
  1188     if i < 0:
  1188     if i < 0:
  1189         i = s.find(' ')
  1189         i = s.find(' ')
  1190         if i < 0:
  1190         if i < 0:
  1191             return s
  1191             return s
  1192     return s[:i]
  1192     return s[:i]
       
  1193 
       
  1194 def parsepatch(fp):
       
  1195     """patch -> [] of headers -> [] of hunks """
       
  1196     class parser(object):
       
  1197         """patch parsing state machine"""
       
  1198         def __init__(self):
       
  1199             self.fromline = 0
       
  1200             self.toline = 0
       
  1201             self.proc = ''
       
  1202             self.header = None
       
  1203             self.context = []
       
  1204             self.before = []
       
  1205             self.hunk = []
       
  1206             self.headers = []
       
  1207 
       
  1208         def addrange(self, limits):
       
  1209             fromstart, fromend, tostart, toend, proc = limits
       
  1210             self.fromline = int(fromstart)
       
  1211             self.toline = int(tostart)
       
  1212             self.proc = proc
       
  1213 
       
  1214         def addcontext(self, context):
       
  1215             if self.hunk:
       
  1216                 h = recordhunk(self.header, self.fromline, self.toline,
       
  1217                         self.proc, self.before, self.hunk, context)
       
  1218                 self.header.hunks.append(h)
       
  1219                 self.fromline += len(self.before) + h.removed
       
  1220                 self.toline += len(self.before) + h.added
       
  1221                 self.before = []
       
  1222                 self.hunk = []
       
  1223                 self.proc = ''
       
  1224             self.context = context
       
  1225 
       
  1226         def addhunk(self, hunk):
       
  1227             if self.context:
       
  1228                 self.before = self.context
       
  1229                 self.context = []
       
  1230             self.hunk = hunk
       
  1231 
       
  1232         def newfile(self, hdr):
       
  1233             self.addcontext([])
       
  1234             h = header(hdr)
       
  1235             self.headers.append(h)
       
  1236             self.header = h
       
  1237 
       
  1238         def addother(self, line):
       
  1239             pass # 'other' lines are ignored
       
  1240 
       
  1241         def finished(self):
       
  1242             self.addcontext([])
       
  1243             return self.headers
       
  1244 
       
  1245         transitions = {
       
  1246             'file': {'context': addcontext,
       
  1247                      'file': newfile,
       
  1248                      'hunk': addhunk,
       
  1249                      'range': addrange},
       
  1250             'context': {'file': newfile,
       
  1251                         'hunk': addhunk,
       
  1252                         'range': addrange,
       
  1253                         'other': addother},
       
  1254             'hunk': {'context': addcontext,
       
  1255                      'file': newfile,
       
  1256                      'range': addrange},
       
  1257             'range': {'context': addcontext,
       
  1258                       'hunk': addhunk},
       
  1259             'other': {'other': addother},
       
  1260             }
       
  1261 
       
  1262     p = parser()
       
  1263 
       
  1264     state = 'context'
       
  1265     for newstate, data in scanpatch(fp):
       
  1266         try:
       
  1267             p.transitions[state][newstate](p, data)
       
  1268         except KeyError:
       
  1269             raise PatchError('unhandled transition: %s -> %s' %
       
  1270                                    (state, newstate))
       
  1271         state = newstate
       
  1272     return p.finished()
  1193 
  1273 
  1194 def pathtransform(path, strip, prefix):
  1274 def pathtransform(path, strip, prefix):
  1195     '''turn a path from a patch into a path suitable for the repository
  1275     '''turn a path from a patch into a path suitable for the repository
  1196 
  1276 
  1197     prefix, if not empty, is expected to be normalized with a / at the end.
  1277     prefix, if not empty, is expected to be normalized with a / at the end.