~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to third_party/lzma.js/lzip/arg_parser.cc

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-06-11 15:45:24 UTC
  • mfrom: (1.2.1) (2.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130611154524-rppb3w6tixlegv4n
Tags: 1.4.7~20130611~a1eb425-1
* New snapshot release
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  Arg_parser - POSIX/GNU command line argument parser. (C++ version)
 
2
    Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
 
3
    Antonio Diaz Diaz.
 
4
 
 
5
    This library is free software: you can redistribute it and/or modify
 
6
    it under the terms of the GNU General Public License as published by
 
7
    the Free Software Foundation, either version 3 of the License, or
 
8
    (at your option) any later version.
 
9
 
 
10
    This library is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
    GNU General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU General Public License
 
16
    along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
17
 
 
18
    As a special exception, you may use this file as part of a free
 
19
    software library without restriction.  Specifically, if other files
 
20
    instantiate templates or use macros or inline functions from this
 
21
    file, or you compile this file and link it with other files to
 
22
    produce an executable, this file does not by itself cause the
 
23
    resulting executable to be covered by the GNU General Public
 
24
    License.  This exception does not however invalidate any other
 
25
    reasons why the executable file might be covered by the GNU General
 
26
    Public License.
 
27
*/
 
28
 
 
29
#include <cstring>
 
30
#include <string>
 
31
#include <vector>
 
32
 
 
33
#include "arg_parser.h"
 
34
 
 
35
 
 
36
bool Arg_parser::parse_long_option( const char * const opt, const char * const arg,
 
37
                                    const Option options[], int & argind )
 
38
  {
 
39
  unsigned len;
 
40
  int index = -1;
 
41
  bool exact = false, ambig = false;
 
42
 
 
43
  for( len = 0; opt[len+2] && opt[len+2] != '='; ++len ) ;
 
44
 
 
45
  // Test all long options for either exact match or abbreviated matches.
 
46
  for( int i = 0; options[i].code != 0; ++i )
 
47
    if( options[i].name && std::strncmp( options[i].name, &opt[2], len ) == 0 )
 
48
      {
 
49
      if( std::strlen( options[i].name ) == len )       // Exact match found
 
50
        { index = i; exact = true; break; }
 
51
      else if( index < 0 ) index = i;           // First nonexact match found
 
52
      else if( options[index].code != options[i].code ||
 
53
               options[index].has_arg != options[i].has_arg )
 
54
        ambig = true;                   // Second or later nonexact match found
 
55
      }
 
56
 
 
57
  if( ambig && !exact )
 
58
    {
 
59
    error_ = "option '"; error_ += opt; error_ += "' is ambiguous";
 
60
    return false;
 
61
    }
 
62
 
 
63
  if( index < 0 )               // nothing found
 
64
    {
 
65
    error_ = "unrecognized option '"; error_ += opt; error_ += '\'';
 
66
    return false;
 
67
    }
 
68
 
 
69
  ++argind;
 
70
  data.push_back( Record( options[index].code ) );
 
71
 
 
72
  if( opt[len+2] )              // '--<long_option>=<argument>' syntax
 
73
    {
 
74
    if( options[index].has_arg == no )
 
75
      {
 
76
      error_ = "option '--"; error_ += options[index].name;
 
77
      error_ += "' doesn't allow an argument";
 
78
      return false;
 
79
      }
 
80
    if( options[index].has_arg == yes && !opt[len+3] )
 
81
      {
 
82
      error_ = "option '--"; error_ += options[index].name;
 
83
      error_ += "' requires an argument";
 
84
      return false;
 
85
      }
 
86
    data.back().argument = &opt[len+3];
 
87
    return true;
 
88
    }
 
89
 
 
90
  if( options[index].has_arg == yes )
 
91
    {
 
92
    if( !arg || !arg[0] )
 
93
      {
 
94
      error_ = "option '--"; error_ += options[index].name;
 
95
      error_ += "' requires an argument";
 
96
      return false;
 
97
      }
 
98
    ++argind; data.back().argument = arg;
 
99
    return true;
 
100
    }
 
101
 
 
102
  return true;
 
103
  }
 
104
 
 
105
 
 
106
bool Arg_parser::parse_short_option( const char * const opt, const char * const arg,
 
107
                                     const Option options[], int & argind )
 
108
  {
 
109
  int cind = 1;                 // character index in opt
 
110
 
 
111
  while( cind > 0 )
 
112
    {
 
113
    int index = -1;
 
114
    const unsigned char c = opt[cind];
 
115
 
 
116
    if( c != 0 )
 
117
      for( int i = 0; options[i].code; ++i )
 
118
        if( c == options[i].code )
 
119
          { index = i; break; }
 
120
 
 
121
    if( index < 0 )
 
122
      {
 
123
      error_ = "invalid option -- "; error_ += c;
 
124
      return false;
 
125
      }
 
126
 
 
127
    data.push_back( Record( c ) );
 
128
    if( opt[++cind] == 0 ) { ++argind; cind = 0; }      // opt finished
 
129
 
 
130
    if( options[index].has_arg != no && cind > 0 && opt[cind] )
 
131
      {
 
132
      data.back().argument = &opt[cind]; ++argind; cind = 0;
 
133
      }
 
134
    else if( options[index].has_arg == yes )
 
135
      {
 
136
      if( !arg || !arg[0] )
 
137
        {
 
138
        error_ = "option requires an argument -- "; error_ += c;
 
139
        return false;
 
140
        }
 
141
      data.back().argument = arg; ++argind; cind = 0;
 
142
      }
 
143
    }
 
144
  return true;
 
145
  }
 
146
 
 
147
 
 
148
Arg_parser::Arg_parser( const int argc, const char * const argv[],
 
149
                        const Option options[], const bool in_order )
 
150
  {
 
151
  if( argc < 2 || !argv || !options ) return;
 
152
 
 
153
  std::vector< std::string > non_options;       // skipped non-options
 
154
  int argind = 1;                               // index in argv
 
155
 
 
156
  while( argind < argc )
 
157
    {
 
158
    const unsigned char ch1 = argv[argind][0];
 
159
    const unsigned char ch2 = ( ch1 ? argv[argind][1] : 0 );
 
160
 
 
161
    if( ch1 == '-' && ch2 )             // we found an option
 
162
      {
 
163
      const char * const opt = argv[argind];
 
164
      const char * const arg = (argind + 1 < argc) ? argv[argind+1] : 0;
 
165
      if( ch2 == '-' )
 
166
        {
 
167
        if( !argv[argind][2] ) { ++argind; break; }     // we found "--"
 
168
        else if( !parse_long_option( opt, arg, options, argind ) ) break;
 
169
        }
 
170
      else if( !parse_short_option( opt, arg, options, argind ) ) break;
 
171
      }
 
172
    else
 
173
      {
 
174
      if( !in_order ) non_options.push_back( argv[argind++] );
 
175
      else { data.push_back( Record() ); data.back().argument = argv[argind++]; }
 
176
      }
 
177
    }
 
178
  if( error_.size() ) data.clear();
 
179
  else
 
180
    {
 
181
    for( unsigned i = 0; i < non_options.size(); ++i )
 
182
      { data.push_back( Record() ); data.back().argument.swap( non_options[i] ); }
 
183
    while( argind < argc )
 
184
      { data.push_back( Record() ); data.back().argument = argv[argind++]; }
 
185
    }
 
186
  }
 
187
 
 
188
 
 
189
Arg_parser::Arg_parser( const char * const opt, const char * const arg,
 
190
                        const Option options[] )
 
191
  {
 
192
  if( !opt || !opt[0] || !options ) return;
 
193
 
 
194
  if( opt[0] == '-' && opt[1] )         // we found an option
 
195
    {
 
196
    int argind = 1;                     // dummy
 
197
    if( opt[1] == '-' )
 
198
      { if( opt[2] ) parse_long_option( opt, arg, options, argind ); }
 
199
    else
 
200
      parse_short_option( opt, arg, options, argind );
 
201
    if( error_.size() ) data.clear();
 
202
    }
 
203
  else { data.push_back( Record() ); data.back().argument = opt; }
 
204
  }