1#!/usr/bin/env python
2#
3# gen-py-errors.py: Generate a python module which maps error names to numbers.
4#                   (The purpose being easier writing of the python tests.)
5#
6# ====================================================================
7#    Licensed to the Apache Software Foundation (ASF) under one
8#    or more contributor license agreements.  See the NOTICE file
9#    distributed with this work for additional information
10#    regarding copyright ownership.  The ASF licenses this file
11#    to you under the Apache License, Version 2.0 (the
12#    "License"); you may not use this file except in compliance
13#    with the License.  You may obtain a copy of the License at
14#
15#      http://www.apache.org/licenses/LICENSE-2.0
16#
17#    Unless required by applicable law or agreed to in writing,
18#    software distributed under the License is distributed on an
19#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20#    KIND, either express or implied.  See the License for the
21#    specific language governing permissions and limitations
22#    under the License.
23# ====================================================================
24#
25#
26# Locates svn_error_codes.h based on its relative location to this script.
27#
28# Generates to STDOUT. Typically, redirect this into svntest/err.py
29#
30
31import sys
32import os
33import re
34
35HEADER = '''#!/usr/bin/env python
36### This file automatically generated by tools/dev/gen-py-errors.py,
37### which see for more information
38###
39### It is versioned for convenience.
40'''
41
42# Established by svn 1.0. May as well hard-code these.
43APR_OS_START_ERROR = 20000
44APR_OS_START_USERERR = APR_OS_START_ERROR + 50000 * 2
45SVN_ERR_CATEGORY_SIZE = 5000
46
47RE_CAT_NAME = re.compile(r'SVN_ERR_([A-Z_]+)_CATEG')
48RE_CAT_VALUE = re.compile(r'\d+')
49
50RE_DEF_NAME = re.compile(r'SVN_ERRDEF\(([A-Z0-9_]+)')
51RE_DEF_VALUE = re.compile(r'SVN_ERR_([A-Z_]+)_CATEG[^0-9]*([0-9]+)')
52
53
54def write_output(codes):
55  print(HEADER)
56
57  for name, value in codes:
58    # skip SVN_ERR_ on the name
59    print('%s = %d' % (name[8:], value))
60
61
62def main(codes_fname):
63  categ = { }
64  codes = [ ]
65
66  f = open(codes_fname)
67
68  # Parse all the category start values
69  while True:
70    line = f.next()
71    m = RE_CAT_NAME.search(line)
72    if m:
73      name = m.group(1)
74      m = RE_CAT_VALUE.search(f.next())
75      assert m
76      value = int(m.group(0))
77      categ[name] = APR_OS_START_USERERR + value * SVN_ERR_CATEGORY_SIZE
78
79    elif line.strip() == 'SVN_ERROR_START':
80      break
81
82  # Parse each of the error values
83  while True:
84    line = f.next()
85    m = RE_DEF_NAME.search(line)
86    if m:
87      name = m.group(1)
88      line = f.next()
89      m = RE_DEF_VALUE.search(line)
90      if not m:
91        # SVN_ERR_WC_NOT_DIRECTORY is defined as equal to NOT_WORKING_COPY
92        # rather than relative to SVN_ERR_WC_CATEGORY_START
93        #print 'SKIP:', line
94        continue
95      cat = m.group(1)
96      value = int(m.group(2))
97      codes.append((name, categ[cat] + value))
98
99    elif line.strip() == 'SVN_ERROR_END':
100      break
101
102  write_output(sorted(codes))
103
104
105if __name__ == '__main__':
106  this_dir = os.path.dirname(os.path.abspath(__file__))
107  codes_fname = os.path.join(this_dir, os.path.pardir, os.path.pardir,
108                             'subversion', 'include', 'svn_error_codes.h')
109  main(codes_fname)
110