aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/getopt/small/last_getopt_opt.cpp
blob: 576b8f03d539ee0605f6ed84f687bc325a8ca922 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "last_getopt_opt.h"

#include <util/stream/format.h>
#include <util/string/escape.h>
#include <util/generic/ylimits.h>
#include <util/generic/utility.h>
#include <util/generic/algorithm.h>
#include <ctype.h>

namespace NLastGetopt {
    static const TStringBuf ExcludedShortNameChars = "= -\t\n";
    static const TStringBuf ExcludedLongNameChars = "= \t\n";

    bool TOpt::NameIs(const TString& name) const { 
        for (const auto& next : LongNames_) { 
            if (next == name) 
                return true; 
        } 
        return false; 
    } 

    bool TOpt::CharIs(char c) const { 
        for (auto next : Chars_) { 
            if (next == c) 
                return true; 
        } 
        return false; 
    } 

    char TOpt::GetChar() const { 
        ; 
        if (Chars_.empty()) 
            ythrow TConfException() << "no char for option " << this->ToShortString(); 
        return Chars_.at(0); 
    }

    char TOpt::GetCharOr0() const { 
        if (Chars_.empty()) 
            return 0; 
        return GetChar(); 
    }

    TString TOpt::GetName() const { 
        ; 
        if (LongNames_.empty()) 
            ythrow TConfException() << "no name for option " << this->ToShortString(); 
        return LongNames_.at(0); 
    } 

    bool TOpt::IsAllowedShortName(unsigned char c) { 
        return isprint(c) && TStringBuf::npos == ExcludedShortNameChars.find(c); 
    } 

    TOpt& TOpt::AddShortName(unsigned char c) { 
        ; 
        if (!IsAllowedShortName(c)) 
            throw TUsageException() << "option char '" << c << "' is not allowed";
        Chars_.push_back(c); 
        return *this; 
    } 

    bool TOpt::IsAllowedLongName(const TString& name, unsigned char* out) { 
        for (size_t i = 0; i != name.size(); ++i) { 
            const unsigned char c = name[i]; 
            if (!isprint(c) || TStringBuf::npos != ExcludedLongNameChars.find(c)) { 
                if (nullptr != out) 
                    *out = c; 
                return false; 
            } 
        }
        return true; 
    }

    TOpt& TOpt::AddLongName(const TString& name) { 
        ; 
        unsigned char c = 0; 
        if (!IsAllowedLongName(name, &c)) 
            throw TUsageException() << "option char '" << c
                                     << "' in long '" << name << "' is not allowed"; 
        LongNames_.push_back(name); 
        return *this; 
    } 

    namespace NPrivate { 
        TString OptToString(char c); 

        TString OptToString(const TString& longOption); 
    } 

    TString TOpt::ToShortString() const { 
        ; 
        if (!LongNames_.empty()) 
            return NPrivate::OptToString(LongNames_.front()); 
        if (!Chars_.empty()) 
            return NPrivate::OptToString(Chars_.front()); 
        return "?"; 
    } 

    void TOpt::FireHandlers(const TOptsParser* parser) const { 
        for (const auto& handler : Handlers_) { 
            handler->HandleOpt(parser); 
        } 
    }

    TOpt& TOpt::IfPresentDisableCompletionFor(const TOpt& opt) {
        if (opt.GetLongNames()) {
            IfPresentDisableCompletionFor(opt.GetName());
        } else {
            IfPresentDisableCompletionFor(opt.GetChar());
        }
        return *this;
    }
}