grange.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
  2. # Copyright (C) 2012-2017 Nominum, Inc.
  3. #
  4. # Permission to use, copy, modify, and distribute this software and its
  5. # documentation for any purpose with or without fee is hereby granted,
  6. # provided that the above copyright notice and this permission notice
  7. # appear in all copies.
  8. #
  9. # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
  10. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
  12. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  15. # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. """DNS GENERATE range conversion."""
  17. from typing import Tuple
  18. import dns
  19. def from_text(text: str) -> Tuple[int, int, int]:
  20. """Convert the text form of a range in a ``$GENERATE`` statement to an
  21. integer.
  22. *text*, a ``str``, the textual range in ``$GENERATE`` form.
  23. Returns a tuple of three ``int`` values ``(start, stop, step)``.
  24. """
  25. start = -1
  26. stop = -1
  27. step = 1
  28. cur = ""
  29. state = 0
  30. # state 0 1 2
  31. # x - y / z
  32. if text and text[0] == "-":
  33. raise dns.exception.SyntaxError("Start cannot be a negative number")
  34. for c in text:
  35. if c == "-" and state == 0:
  36. start = int(cur)
  37. cur = ""
  38. state = 1
  39. elif c == "/":
  40. stop = int(cur)
  41. cur = ""
  42. state = 2
  43. elif c.isdigit():
  44. cur += c
  45. else:
  46. raise dns.exception.SyntaxError(f"Could not parse {c}")
  47. if state == 0:
  48. raise dns.exception.SyntaxError("no stop value specified")
  49. elif state == 1:
  50. stop = int(cur)
  51. else:
  52. assert state == 2
  53. step = int(cur)
  54. assert step >= 1
  55. assert start >= 0
  56. if start > stop:
  57. raise dns.exception.SyntaxError("start must be <= stop")
  58. return (start, stop, step)