~ubuntu-branches/ubuntu/oneiric/valkyrie/oneiric

« back to all changes in this revision

Viewing changes to valkyrie/options/parse_cmd_args.cpp

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2011-09-02 22:08:34 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: package-import@ubuntu.com-20110902220834-kigsixteppj9epp5
Tags: 2.0.0-0ubuntu1
* New upstream release. (LP: #635129, LP: #832886, LP: #721298)
* Standards bumped to 3.9.2, no changes required.
* d/control, d/rules: cdbs removed, dh minimal rule instead.
* d/control: build system is qmake not autotools
* d/control: bump required qt to qt4
* d/valkyrie.install: installing html docs manually as make install
  no longer does so.
* d/patches/valkyrie-2.0.0-fix-doc.dir.patch: Fix doc path to match
  policy. Also corrects LP: #588074 since the documentation link now
  works.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* --------------------------------------------------------------------- 
2
 
 * Parse command-line options                         parse_cmd_args.cpp
3
 
 * Called from main()
4
 
 * ---------------------------------------------------------------------
5
 
 * This file is part of Valkyrie, a front-end for Valgrind
6
 
 * Copyright (C) 2000-2008, OpenWorks LLP <info@open-works.co.uk>
7
 
 * This program is released under the terms of the GNU GPL v.2
8
 
 * See the file COPYING for the full license details.
9
 
 */
10
 
 
11
 
#include "vk_objects.h"
12
 
#include "valkyrie_object.h"  /* for Valkyrie::enums */
13
 
 
14
 
#include "vk_utils.h"
15
 
#include "vk_popt.h"
16
 
#include "vk_option.h"       /* namespace VkOPTION */
17
 
#include "vk_config.h"
18
 
 
19
 
/* return values: error < 0, ok = 0(PARSED_OK), show-help-and-exit = 1 */
20
 
#define SHOW_HELP_EXIT 1
21
 
 
22
 
 
23
 
void showHelp( vkPoptContext con, char key, Valkyrie* vk )
24
 
{
25
 
   switch ( key ) {
26
 
   case 'v':
27
 
      printf("%s-%s\n", vkConfig->vkName(), vkConfig->vkVersion() );
28
 
      break;
29
 
 
30
 
   case 'h':
31
 
      vkPoptPrintHelp( con, stdout, vk->title().latin1() );
32
 
      printf( "\n%s is copyright %s %s\n"
33
 
              "and licensed under the GNU General Public License, version 2.\n"
34
 
              "Bug reports, feedback, praise, abuse, etc, to <%s>\n\n",
35
 
              vkConfig->vkName(), vkConfig->vkCopyright(), 
36
 
              vkConfig->vkAuthor(), vkConfig->vkEmail() );
37
 
      break;
38
 
 
39
 
   case 'V':
40
 
      vkPoptPrintHelp( con, stdout, NULL );
41
 
      printf("\n%s is copyright %s %s\n", 
42
 
             vkConfig->vkName(), 
43
 
             vkConfig->vkCopyright(), vkConfig->vkAuthor() );
44
 
      printf("Valgrind is copyright %s\n\n", vkConfig->vgCopyright() );
45
 
      break;
46
 
 
47
 
   default:
48
 
      vk_assert_never_reached();
49
 
   }
50
 
}
51
 
 
52
 
 
53
 
void parseError( vkPoptContext con, const int err )
54
 
{
55
 
   /* don't print anything; sender is dealing with msgs */
56
 
   if ( err != PERROR_DEFAULT ) {
57
 
      fprintf( stderr, "%s: Parse error [%s] : %s\n", 
58
 
               vkConfig->vkname(),
59
 
               vkPoptBadOption(con), parseErrString( err )  );
60
 
      fprintf( stderr, "%s: Use --help for more information.\n",
61
 
               vkConfig->vkname() );
62
 
   }
63
 
}           
64
 
 
65
 
 
66
 
/* determine the total no. of option structs required by counting the
67
 
   no. of entries in the optList.  Note: num_options = optList+1
68
 
   because we need a NULL option entry to terminate each option array. */
69
 
vkPoptOption* getObjOptions( /*IN */VkObject* obj,
70
 
                             /*OUT*/vkPoptOption* vkOpts )
71
 
{
72
 
   int idx = 0;
73
 
   Option *opt;
74
 
   OptionList optList;
75
 
   vk_assert( obj != NULL );
76
 
   vk_assert( vkOpts != NULL );
77
 
 
78
 
   optList = obj->optList();
79
 
   for ( opt = optList.first(); opt; opt = optList.next() ) {
80
 
      vk_assert( opt != NULL );
81
 
 
82
 
      /* ignore non-popt options */
83
 
      if ( opt->m_argType == VkOPTION::NOT_POPT )
84
 
         continue;
85
 
 
86
 
      vkPoptOption* vkopt = &vkOpts[idx++];
87
 
      vkopt->optKey    = opt->m_key;
88
 
      vkopt->argType   = opt->m_argType;
89
 
      vkopt->shortFlag = opt->m_shortFlag.latin1();
90
 
      vkopt->longFlag  = opt->m_longFlag.latin1();
91
 
      vkopt->arg       = 0;
92
 
      vkopt->helptxt   = opt->m_longHelp.latin1();
93
 
      vkopt->helpdesc  = opt->m_flagDescrip.latin1();
94
 
      /* to later call obj->checkOptArg() */
95
 
      vkopt->objectId  = obj->objId();
96
 
   }
97
 
   /* null entry terminator */
98
 
   vkOpts[idx] = nullOpt();
99
 
   return vkOpts;
100
 
}
101
 
 
102
 
 
103
 
void getAllOptions( /*IN */VkObjectList objList,
104
 
                    /*OUT*/vkPoptOption* allOpts )
105
 
{
106
 
   int nopts, idx = 0;
107
 
   size_t nbytes;
108
 
   vkPoptOption* vkOpts;
109
 
   vk_assert( allOpts != NULL );
110
 
 
111
 
   for ( VkObject* obj = objList.first(); obj; obj = objList.next() ) {
112
 
      /* allocate mem for this object's options */
113
 
      nopts  = obj->optList().count();
114
 
      nbytes = sizeof(vkPoptOption) * (nopts + 1/*null end*/);
115
 
      vkOpts = (vkPoptOption*)malloc( nbytes );
116
 
 
117
 
      vkPoptOption* tblOpt = &allOpts[idx++];
118
 
      *tblOpt = nullOpt();                             /* init null struct */
119
 
      tblOpt->arg     = getObjOptions( obj, vkOpts );  /* get this object's options */
120
 
      tblOpt->helptxt = obj->title().latin1();         /* for lookup later */
121
 
   }
122
 
   /* null entry terminator */
123
 
   allOpts[idx] = nullOpt();
124
 
}
125
 
 
126
 
 
127
 
void freeOptions( vkPoptOption* allOpts, int num_objs )
128
 
{
129
 
   for ( int idx=0; idx<num_objs; idx++) {
130
 
      /* free allocated optTable.arg */
131
 
      if (allOpts[idx].arg != NULL) {
132
 
         free( allOpts[idx].arg );
133
 
         allOpts[idx].arg = NULL;
134
 
      }
135
 
   }
136
 
}
137
 
 
138
 
 
139
 
 
140
 
int parseCmdArgs( int argc, char** argv, Valkyrie* vk )
141
 
{
142
 
   int rc;                 // check fn return value / err value
143
 
   char argVal[512];       // store argument values for checking
144
 
   Option* vk_opt = NULL;
145
 
   QString qs_argval;
146
 
 
147
 
   /* fetch all object options */
148
 
   VkObjectList objList = vk->vkObjList();
149
 
   int num_objs = objList.count();
150
 
   vkPoptOption allOpts[num_objs+1/*null end*/];
151
 
   getAllOptions( objList, allOpts );
152
 
 
153
 
   /* context for parsing cmd-line opts */
154
 
   vkPoptContext optCon =
155
 
      vkPoptGetContext( argc, (const char**)argv, allOpts ); 
156
 
 
157
 
   /* process the options */ 
158
 
   const vkPoptOption* opt = NULL;
159
 
   while ( (rc = vkPoptGetNextOpt( optCon, argVal, &opt )) == PARSED_OK ) {
160
 
      /* rc == 1 for the first non-valkyrie/valgrind option */
161
 
 
162
 
      vk_assert(opt);
163
 
 
164
 
      char vk_arg = opt->shortFlag;
165
 
      //    printf("vk_arg: '%c'\n", vk_arg);
166
 
      if ( vk_arg == 'h' || vk_arg == 'v' || vk_arg == 'V' ) {
167
 
         showHelp( optCon, vk_arg, vk );
168
 
         rc = SHOW_HELP_EXIT;
169
 
         goto done;
170
 
      }
171
 
    
172
 
      VkObject* obj = vk->vkObject( opt->objectId );
173
 
      vk_assert( obj != NULL );
174
 
      qs_argval = argVal;
175
 
      rc = obj->checkOptArg( opt->optKey, qs_argval );
176
 
 
177
 
      if ( rc != PARSED_OK ) {
178
 
         parseError( optCon, rc );
179
 
         goto done;
180
 
      }
181
 
 
182
 
      /* else ok: write option to config
183
 
         Note: not written to disk. The user can do this via option config */
184
 
      vk_opt = obj->findOption( opt->optKey );
185
 
      vk_assert(vk_opt != NULL);
186
 
 
187
 
      if ( opt->objectId == VkObject::ID_VALGRIND &&
188
 
           opt->optKey == Valgrind::SUPPS_SEL ) {
189
 
         /* exception: multiple suppressions are allowed */
190
 
         vkConfig->addEntry( qs_argval, vk_opt->cfgKey(), vk_opt->cfgGroup() );
191
 
      } else {
192
 
         vkConfig->wrEntry( qs_argval, vk_opt->cfgKey(), vk_opt->cfgGroup() );
193
 
      }
194
 
 
195
 
   }   /* end while ... */
196
 
 
197
 
   /* rc == 1 for the first non-valkyrie/valgrind option */
198
 
   if (rc == 1)
199
 
      rc = PARSED_OK; 
200
 
 
201
 
   /* an error occurred during option processing */ 
202
 
   if ( rc != PARSED_OK ) {
203
 
      parseError( optCon, rc );
204
 
      goto done;
205
 
   }
206
 
 
207
 
   /* get the leftovers: should only be 'myprog --myflags'.  check we
208
 
      really do have a valid prog-to-debug here.  if yes, then all
209
 
      flags that follow it on the cmd line are assumed to belong to it. */
210
 
   if ( vkPoptPeekArg(optCon) != NULL ) {
211
 
      qs_argval = vkPoptGetArg(optCon);
212
 
      rc = vk->checkOptArg( Valkyrie::BINARY, qs_argval );
213
 
      if ( rc != PARSED_OK ) {
214
 
         parseError( optCon, rc );
215
 
         goto done;
216
 
      }
217
 
 
218
 
      /* else ok: write option to config (but not to disk yet) */
219
 
      vk_opt = vk->findOption( Valkyrie::BINARY );
220
 
      vk_assert(vk_opt != NULL);
221
 
      vkConfig->wrEntry( qs_argval, vk_opt->cfgKey(), vk_opt->cfgGroup() );
222
 
 
223
 
      /* get client flags, if any */
224
 
      const char **args = vkPoptGetArgs( optCon );
225
 
      int i = 0;
226
 
      QStringList aList;
227
 
      while ( args && args[i] != NULL ) {
228
 
         aList << args[i];
229
 
         i++;
230
 
      }
231
 
      QString flags = aList.join( " " );
232
 
      qs_argval = !flags.isNull() ? flags : "";
233
 
      rc = vk->checkOptArg( Valkyrie::BIN_FLAGS, qs_argval );
234
 
 
235
 
      if ( rc != PARSED_OK ) {
236
 
         parseError( optCon, rc );
237
 
         goto done;
238
 
      }
239
 
 
240
 
      /* else ok: write option to config (but not to disk yet) */
241
 
      vk_opt = vk->findOption( Valkyrie::BIN_FLAGS );
242
 
      vk_assert(vk_opt != NULL);
243
 
      vkConfig->wrEntry( qs_argval, vk_opt->cfgKey(), vk_opt->cfgGroup() );
244
 
   }
245
 
 
246
 
 done:
247
 
   /* Cleanup */
248
 
   freeOptions( allOpts, num_objs );
249
 
   vkPoptFreeContext( optCon ); 
250
 
   return rc;
251
 
}