diff options
author | Mad Camel <madcamel@gmail.com> | 2024-02-18 16:49:33 +0000 |
---|---|---|
committer | Mad Camel <madcamel@gmail.com> | 2024-02-18 16:49:33 +0000 |
commit | 8edebcaf5ecdb7bcc731142921e16390436fc7a3 (patch) | |
tree | eba669dc30a217af0d8a958b324dcaf9772f6c54 /attoconf/types.py | |
parent | 208f846464b96721d93436006365705fde3b6b2c (diff) | |
parent | f1a54c378b7b51b36103ad8111d66aef63e7f041 (diff) | |
download | attobuild-master.tar.gz attobuild-master.tar.bz2 attobuild-master.tar.xz attobuild-master.zip |
Import from specing's attoconf branch
See merge request legacy/attobuild!1
Diffstat (limited to 'attoconf/types.py')
-rw-r--r-- | attoconf/types.py | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/attoconf/types.py b/attoconf/types.py new file mode 100644 index 0000000..e1af528 --- /dev/null +++ b/attoconf/types.py @@ -0,0 +1,129 @@ +# Copyright 2013-2014 Ben Longbons <b.r.longbons@gmail.com> +# +# This file is part of attoconf. +# +# attoconf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# attoconf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with attoconf. If not, see <http://www.gnu.org/licenses/>. + + + +import os +from pipes import quote as shell_quote +from shlex import split as shell_split + +from .core import trim_trailing_slashes + + +class IntRange(object): + def __init__(self, min, max): + self.min = min + self.max = max + + def __call__(self, s): + i = int(s) + if self.min <= i <= self.max: + return i + raise ValueError('%d is out of range' % i) + +sint = IntRange(float('-inf'), float('inf')) +uint = IntRange(0, float('inf')) + + +class enum(object): + __slots__ = ('args',) + + def __init__(self, *args): + self.args = args + + def __call__(self, s): + if s in self.args: + return s + raise ValueError('%r not in {%s}' % (s, ', '.join(self.args))) + + +class maybe(object): + __slots__ = ('inferior') + + def __init__(self, inferior): + self.inferior = inferior + + def __call__(self, s): + if not s: + return s + return (self.inferior)(s) + + +class ShellList(object): + ''' An argument type representing a sequence of 0 or more arguments + ''' + __slots__ = ('list',) + def __init__(self, arg): + if isinstance(arg, str): + self.list = shell_split(arg) + elif isinstance(arg, list): + self.list = arg[:] + elif isinstance(arg, ShellList): + self.list = arg.list[:] + else: + raise TypeError('arg is an instance of %s' % type(arg).__name__) + + def __str__(self): + return ' '.join(shell_quote(a) for a in self.list) + + def __add__(self, other): + if isinstance(other, str): + other = shell_split(other) + elif isinstance(other, ShellList): + other = other.list + elif not isinstance(other, list): + raise TypeError('arg is an instance of %s' % type(arg).__name__) + return ShellList(self.list + other) + + +def shell_word(s): + if s != shell_quote(s): + raise ValueError('not a word: %r' % s) + return s + + +def shell_partial_word(s): + if s == '': + return s + return shell_word(s) + + +def quoted_string(s): + return shell_quote(s) + + +def filepath(s): + s = trim_trailing_slashes(s) + # must be absolute *and* canonical, except joinable + a = os.path.abspath(s) + if a == '/': + # filepaths often directly cat a subpath + # @me@/whatever is invalid if @me@ == / + a = '/.' + if s != a: + raise ValueError('Not an absolute, canonical (except joinable) pathname: %r != %r' % (s, a)) + return s + + +def triple(s): + # Triples do not, in fact, follow a regular pattern. + # Some have only two segments, some appear to have four ... + # Also, sometimes a wrong thing is used as a triple. + # All we *really* care about is generating the tool names. + if s.startswith('-') or s.endswith('-') or '-' not in s[1:-1]: + raise ValueError('Probably not a triple') + return s |