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

« back to all changes in this revision

Viewing changes to valkyrie/options/vk_popt.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
 
 * Implementation of Popt functions                          vk_popt.cpp
3
 
 * This is a seriously hacked version of the popt libraries.
4
 
 * No credit to me, all thanks and many apologies to the Red Hat team
5
 
 * ---------------------------------------------------------------------
6
 
 * popt is Copyright (c) 1998 Red Hat Software and distributed under
7
 
 * an X11-style license, which is in turn compatible the GNU GPL v.2.
8
 
 * See the file COPYING for the full license details.
9
 
*/
10
 
 
11
 
#include "vk_popt.h"
12
 
#include "vk_option.h"           /* namespace VkOPTION */
13
 
#include "vk_utils.h"
14
 
 
15
 
 
16
 
/* return a vkPoptOption initialised to null */
17
 
vkPoptOption nullOpt()
18
 
{
19
 
   vkPoptOption _nullOpt = TABLE_END;
20
 
   return _nullOpt;
21
 
}
22
 
 
23
 
const char * vkPoptPeekArg( vkPoptContext con )
24
 
{
25
 
   const char * ret = NULL;
26
 
   if ( con && con->leftovers != NULL && 
27
 
        con->nextLeftover < con->numLeftovers )
28
 
      ret = con->leftovers[con->nextLeftover];
29
 
   return ret;
30
 
}
31
 
 
32
 
 
33
 
const char * vkPoptGetArg( vkPoptContext con )
34
 
{
35
 
   const char * ret = NULL;
36
 
   if ( con && con->leftovers != NULL && 
37
 
        con->nextLeftover < con->numLeftovers ) {
38
 
      ret = con->leftovers[con->nextLeftover++];
39
 
   }
40
 
   return ret;
41
 
}
42
 
 
43
 
 
44
 
const char ** vkPoptGetArgs( vkPoptContext con )
45
 
{
46
 
   if ( con == NULL || con->leftovers == NULL || 
47
 
        con->numLeftovers == con->nextLeftover )
48
 
      return NULL;
49
 
 
50
 
   /* some apps like [like RPM ;-) ] need this NULL terminated */
51
 
   con->leftovers[con->numLeftovers] = NULL;
52
 
   return (con->leftovers + con->nextLeftover);
53
 
}
54
 
 
55
 
 
56
 
vkPoptContext vkPoptGetContext( int argc, const char ** argv,
57
 
                                const vkPoptOption * options )
58
 
{
59
 
   vkPoptContext con = (vkPoptContext)malloc( sizeof(*con) );
60
 
 
61
 
   if ( con == NULL ) {
62
 
      return NULL;
63
 
   }
64
 
 
65
 
   memset( con, 0, sizeof(*con) );
66
 
 
67
 
   con->os = con->optionStack;
68
 
   con->os->argc  = argc;
69
 
   con->os->argv  = argv;
70
 
   con->os->next  = 1;      /* skip argv[0] */
71
 
   con->leftovers = (const char**)calloc( (argc + 1), sizeof(*con->leftovers) );
72
 
   con->options   = options;
73
 
   con->flags     = PCONTEXT_POSIXMEHARDER;
74
 
   con->finalArgvAlloced = argc * 2;
75
 
   con->finalArgv = (const char**)calloc( con->finalArgvAlloced, 
76
 
                                          sizeof(*con->finalArgv) );
77
 
 
78
 
   return con;
79
 
}
80
 
 
81
 
 
82
 
static void vkCleanOSE( struct optionStackEntry *os )
83
 
{
84
 
   os->nextArg = (const char*)_free( os->nextArg );
85
 
   os->argv    = (const char**)_free( os->argv );
86
 
}
87
 
 
88
 
 
89
 
const vkPoptOption * vkFindOption( const vkPoptOption * opt, 
90
 
                                   const char * longFlag,  
91
 
                                   char shortFlag, 
92
 
                                   int singleDash )
93
 
{
94
 
   /* this happens when a single - is given */
95
 
   if ( singleDash && !shortFlag && (longFlag && *longFlag == '\0') )
96
 
      shortFlag = '-';
97
 
 
98
 
   for (; opt->longFlag || opt->shortFlag || opt->arg; opt++) {
99
 
 
100
 
      if ( opt->arg != NULL ) {     /* is-a table */
101
 
         /* recurse on included sub-tables. */
102
 
         const vkPoptOption* opt2 = vkFindOption( opt->arg, longFlag, shortFlag, singleDash );
103
 
         if ( opt2 == NULL )
104
 
            continue;     /* no match in sub-table */
105
 
         /* found match: return option */
106
 
         return opt2;
107
 
      }
108
 
      else {                        /* is-a leaf */
109
 
         if ( longFlag && opt->longFlag && !singleDash &&
110
 
              !strcmp( longFlag, opt->longFlag ) )
111
 
            break; /* longFlag match */
112
 
         if (shortFlag && shortFlag == opt->shortFlag)
113
 
            break; /* shortFlag match */
114
 
      }
115
 
   }
116
 
 
117
 
   if ( !opt->longFlag && !opt->shortFlag )
118
 
      return NULL;    /* end of optArr: no match found */
119
 
 
120
 
   /* found match */
121
 
   return opt;
122
 
}
123
 
 
124
 
 
125
 
static const char * vkExpandNextArg( const char * s )
126
 
{
127
 
   char *t, *te;
128
 
   size_t tn = strlen(s) + 1;
129
 
   char c;
130
 
 
131
 
   te = t = (char*)malloc(tn);;
132
 
   if ( t == NULL ) 
133
 
      return NULL;
134
 
   while ((c = *s++) != '\0') {
135
 
      *te++ = c;
136
 
   }
137
 
 
138
 
   *te = '\0';
139
 
   /* memory leak, hard to plug */
140
 
   t = (char*)realloc(t, strlen(t) + 1);
141
 
   return t;
142
 
}
143
 
 
144
 
 
145
 
/* get next option opt_ret
146
 
   returns 0 on success, 1 on last item, PERROR_* on error */
147
 
int vkPoptGetNextOpt( vkPoptContext con,
148
 
                      char *arg_val/*OUT*/,
149
 
                      const vkPoptOption** opt_ret/*OUT*/ )
150
 
{
151
 
   const vkPoptOption * opt = NULL;
152
 
   int done = 0;
153
 
 
154
 
   if ( con == NULL ) {
155
 
      return 1;
156
 
   }
157
 
 
158
 
   while ( !done ) {
159
 
      const char * origOptString = NULL;
160
 
      const char * longArg = NULL;
161
 
      int shorty = 0;
162
 
 
163
 
      while ( !con->os->nextCharArg && 
164
 
              con->os->next == con->os->argc && 
165
 
              con->os > con->optionStack ) {
166
 
         vkCleanOSE( con->os-- );
167
 
      }
168
 
 
169
 
      if ( !con->os->nextCharArg && 
170
 
           con->os->next == con->os->argc ) {
171
 
         return 1;
172
 
      }
173
 
 
174
 
      /* process next long option */
175
 
      if ( !con->os->nextCharArg ) {
176
 
         char * localOptString, * optString;
177
 
         int thisopt;
178
 
         thisopt = con->os->next;
179
 
         if ( con->os->argv != NULL )
180
 
            origOptString = con->os->argv[con->os->next++];
181
 
 
182
 
         if ( origOptString == NULL ) {
183
 
            return PERROR_BADOPT;
184
 
         }
185
 
         if ( strcmp(origOptString, "--") == 0 ) {
186
 
            return PERROR_BADQUOTE;
187
 
         }
188
 
 
189
 
         if ( con->restLeftover || *origOptString != '-' ) {
190
 
            if ( con->flags & PCONTEXT_POSIXMEHARDER )
191
 
               con->restLeftover = 1;
192
 
            if ( con->leftovers != NULL )
193
 
               con->leftovers[con->numLeftovers++] = origOptString;
194
 
            continue;
195
 
         }
196
 
 
197
 
         /* make a copy we can hack at */
198
 
         localOptString = optString = 
199
 
            strcpy((char*)alloca(strlen(origOptString) + 1), origOptString);
200
 
 
201
 
         if ( optString[0] == '\0' )
202
 
            return PERROR_BADOPT;
203
 
 
204
 
         if ( optString[1] == '-' && !optString[2] ) {
205
 
            con->restLeftover = 1;
206
 
            continue;
207
 
         } else {
208
 
            char *oe;
209
 
            int singleDash;
210
 
            optString++;
211
 
            if ( *optString == '-' )
212
 
               singleDash = 0, optString++;
213
 
            else
214
 
               singleDash = 1;
215
 
 
216
 
            /* Check for "--long=arg" option. */
217
 
            for ( oe = optString; *oe && *oe != '='; oe++ )
218
 
               { };
219
 
            if ( *oe == '=' ) {
220
 
               /* FIX: don't use '=' for shortopts */
221
 
               if ( singleDash )
222
 
                  return PERROR_NODASH;
223
 
               *oe++ = '\0';
224
 
               /* longArg is mapped back to persistent storage. */
225
 
               longArg = origOptString + (oe - localOptString);
226
 
               /* FIX: catch cases where --longarg=<no-arg> */
227
 
               if ( strlen(longArg) == 0 ) {
228
 
                  //printf("1: returning PERROR_NOARG\n");
229
 
                  return PERROR_NOARG;
230
 
               }
231
 
            } 
232
 
#if 0
233
 
            else if ( singleDash == 0 ) {
234
 
               /* FIX: catch cases where we didn't find an '=', 
235
 
                  and this is a --longarg option */
236
 
               //printf("2: returning PERROR_NOARG\n");
237
 
               return PERROR_NOARG;
238
 
            } 
239
 
#endif
240
 
 
241
 
            opt = vkFindOption( con->options, optString, 
242
 
                                '\0', singleDash );
243
 
            if ( !opt && !singleDash ) {
244
 
               //printf("returning PERROR_BADOPT\n");
245
 
               return PERROR_BADOPT;
246
 
            }
247
 
         }
248
 
 
249
 
         if ( !opt ) {
250
 
            con->os->nextCharArg = origOptString + 1;
251
 
         } else {
252
 
            shorty = 0;
253
 
         }
254
 
      }
255
 
 
256
 
      /* process next short option */
257
 
      if ( con->os->nextCharArg ) {
258
 
         origOptString = con->os->nextCharArg;
259
 
         con->os->nextCharArg = NULL;
260
 
 
261
 
         opt = vkFindOption( con->options, NULL, *origOptString, 0 );
262
 
         if ( !opt ) {
263
 
            return PERROR_BADOPT;
264
 
         }
265
 
         shorty = 1;
266
 
      
267
 
         origOptString++;
268
 
         if ( *origOptString != '\0' )
269
 
            con->os->nextCharArg = origOptString;
270
 
      }
271
 
 
272
 
      if ( opt == NULL ) 
273
 
         return PERROR_BADOPT;
274
 
 
275
 
      if ( opt->argType != VkOPTION::ARG_NONE ) {
276
 
         con->os->nextArg = (const char*)_free(con->os->nextArg);
277
 
         if ( longArg ) {
278
 
            longArg = vkExpandNextArg( longArg );
279
 
            con->os->nextArg = longArg;
280
 
         } else if ( con->os->nextCharArg ) {
281
 
            longArg = vkExpandNextArg( con->os->nextCharArg);
282
 
            con->os->nextArg = longArg;
283
 
            con->os->nextCharArg = NULL;
284
 
         } else {
285
 
            while ( con->os->next == con->os->argc &&
286
 
                    con->os > con->optionStack ) {
287
 
               vkCleanOSE( con->os-- );
288
 
            }
289
 
            if ( con->os->next == con->os->argc ) {
290
 
               /* FIX: con->os->argv not defined */
291
 
               return PERROR_NOARG;
292
 
               con->os->nextArg = NULL;
293
 
            } else {
294
 
               if ( con->os->argv != NULL ) {
295
 
                  /* watch out: subtle side-effects live here. */
296
 
                  longArg = con->os->argv[con->os->next++];
297
 
                  longArg = vkExpandNextArg( longArg );
298
 
                  con->os->nextArg = longArg;
299
 
               }
300
 
            }
301
 
         }
302
 
         longArg = NULL;
303
 
 
304
 
         /* store the argument value for checking */
305
 
         if ( con->os->nextArg ) {
306
 
            sprintf( arg_val, "%s", con->os->nextArg );
307
 
         }
308
 
      }     /* end if ! VkOPTION::ARG_NONE */
309
 
 
310
 
      if ( opt->optKey >= 0 ) {  /* is-a leaf */
311
 
         done = 1;
312
 
      }
313
 
 
314
 
      if ( (con->finalArgvCount + 2) >= (con->finalArgvAlloced) ) {
315
 
         con->finalArgvAlloced += 10;
316
 
         con->finalArgv = (const char**)realloc(con->finalArgv,
317
 
                                                sizeof(*con->finalArgv) * con->finalArgvAlloced);
318
 
      }
319
 
 
320
 
      if ( con->finalArgv != NULL ) {
321
 
         char *s = (char*)malloc((opt->longFlag ? strlen(opt->longFlag) : 0) + 3);
322
 
         if ( s != NULL ) {
323
 
            if ( opt->longFlag ) {
324
 
               sprintf(s, "--%s", opt->longFlag);
325
 
            } else {
326
 
               sprintf(s, "-%c", opt->shortFlag);
327
 
            }
328
 
            con->finalArgv[con->finalArgvCount++] = s;
329
 
         } else
330
 
            con->finalArgv[con->finalArgvCount++] = NULL;
331
 
      }
332
 
 
333
 
      if ((opt->arg == NULL/* leaf */) &&
334
 
          (opt->argType != VkOPTION::ARG_NONE)) {
335
 
         if (con->finalArgv != NULL && con->os->nextArg) {
336
 
            char* s = (char*)malloc( strlen(con->os->nextArg)+1 );
337
 
            if (s == NULL) {
338
 
               vkPrintErr("virtual memory exhausted.");
339
 
               exit(EXIT_FAILURE);
340
 
            } else {
341
 
               con->finalArgv[con->finalArgvCount++] =
342
 
                  strcpy( s, con->os->nextArg );
343
 
            }
344
 
         }
345
 
      }
346
 
   }  /* end while ( !done ) */
347
 
 
348
 
   //  vk_assert( opt != NULL );
349
 
   *opt_ret = opt;
350
 
   return PARSED_OK;
351
 
}
352
 
 
353
 
 
354
 
vkPoptContext vkPoptFreeContext( vkPoptContext con )
355
 
{
356
 
   if ( con == NULL ) 
357
 
      return con;
358
 
 
359
 
   /* poptResetContext( con ); */
360
 
   int i;
361
 
   while ( con->os > con->optionStack ) {
362
 
      vkCleanOSE(con->os--);
363
 
   }
364
 
   con->os->nextCharArg = NULL;
365
 
   con->os->nextArg  = NULL;
366
 
   con->os->next     = 1;      /* skip argv[0] */
367
 
   con->numLeftovers = 0;
368
 
   con->nextLeftover = 0;
369
 
   con->restLeftover = 0;
370
 
 
371
 
   if ( con->finalArgv != NULL )
372
 
      for (i = 0; i < con->finalArgvCount; i++)
373
 
         con->finalArgv[i] = (const char*)_free(con->finalArgv[i]);
374
 
   con->finalArgvCount = 0;
375
 
 
376
 
   con->leftovers = (const char**)_free( con->leftovers );
377
 
   con->finalArgv = (const char**)_free( con->finalArgv );
378
 
 
379
 
   con = (vkPoptContext)_free( con );
380
 
   return con;
381
 
}
382
 
 
383
 
 
384
 
const char * vkPoptBadOption( vkPoptContext con )
385
 
{
386
 
   struct optionStackEntry * os = NULL;
387
 
 
388
 
   if ( con != NULL )
389
 
      os = con->optionStack;
390
 
 
391
 
   return ( os && os->argv ? os->argv[os->next - 1] : NULL );
392
 
}
393
 
 
394
 
 
395
 
 
396
 
/*------ help printing stuff --------------------------------*/
397
 
/* set in poptPrintHelp */
398
 
static int leftColWidth = -1;
399
 
 
400
 
static const char * vkGetHelpDesc( const vkPoptOption * opt )
401
 
{
402
 
   /* if ARG_NONE: no arguments to describe */
403
 
   if ( opt->argType == VkOPTION::ARG_NONE )
404
 
      return NULL;
405
 
 
406
 
   if ( opt->helpdesc )
407
 
      return opt->helpdesc;
408
 
 
409
 
   return NULL;
410
 
}
411
 
 
412
 
 
413
 
/* called from vkTableHelp() for leaf table */
414
 
static void vkSingleOptionHelp( FILE * fp, 
415
 
                                const vkPoptOption * opt )
416
 
{
417
 
   int indentLength  = leftColWidth + 2;
418
 
   int lineLength    = 80 - indentLength;
419
 
   const char * help = opt->helptxt;
420
 
   const char * helpdesc = vkGetHelpDesc( opt );
421
 
   int helpLength;
422
 
   char * defs = NULL;
423
 
   char * left;
424
 
   int nb = leftColWidth + 1;
425
 
 
426
 
   /* make sure there's more than enough room in target buffer. */
427
 
   if ( opt->longFlag )  
428
 
      nb += strlen( opt->longFlag );
429
 
   if ( helpdesc )  
430
 
      nb += strlen( helpdesc );
431
 
 
432
 
   left = (char*)malloc( nb );
433
 
   if ( left == NULL ) 
434
 
      return;
435
 
   left[0] = '\0';
436
 
   left[leftColWidth] = '\0';
437
 
 
438
 
   if ( opt->longFlag && opt->shortFlag ) {
439
 
      sprintf( left, "-%c, --%s", opt->shortFlag, opt->longFlag);
440
 
   } else if (opt->shortFlag != '\0') {
441
 
      sprintf( left, "-%c", opt->shortFlag);
442
 
   } else if (opt->longFlag) {
443
 
      sprintf( left, "--%s", opt->longFlag );
444
 
   }
445
 
 
446
 
   if ( !*left ) {
447
 
      goto out;
448
 
   }
449
 
 
450
 
   if ( helpdesc ) {
451
 
      char * le = left + strlen( left );
452
 
      *le++ = ' ';
453
 
      strcpy( le, helpdesc );
454
 
      le += strlen(le);
455
 
      *le = '\0';
456
 
   }
457
 
 
458
 
   if ( help ) {
459
 
      fprintf( fp,"  %-*s", leftColWidth, left );
460
 
   } else {
461
 
      fprintf( fp,"  %s\n", left ); 
462
 
      goto out;
463
 
   }
464
 
 
465
 
   left = (char*)_free(left);
466
 
   if ( defs ) {
467
 
      help = defs;
468
 
      defs = NULL;
469
 
   }
470
 
  
471
 
   helpLength = strlen( help );
472
 
   while ( helpLength > lineLength ) {
473
 
      const char * ch;
474
 
      char format[100];
475
 
 
476
 
      ch = help + lineLength - 1;
477
 
      while ( ch > help && !isspace(*ch) ) 
478
 
         ch--;
479
 
      if ( ch == help ) 
480
 
         break;    /* give up */
481
 
      while ( ch > (help + 1) && isspace(*ch) )
482
 
         ch--;
483
 
      ch++;
484
 
    
485
 
      sprintf( format, "%%.%ds\n%%%ds", 
486
 
               (int) (ch - help), indentLength );
487
 
      fprintf( fp, format, help, " " );
488
 
      help = ch;
489
 
      while ( isspace(*help) && *help ) 
490
 
         help++;
491
 
      helpLength = strlen( help );
492
 
   }
493
 
 
494
 
   if ( helpLength ) 
495
 
      fprintf( fp, "%s\n", help );
496
 
 
497
 
 out:
498
 
   defs = (char*)_free(defs);
499
 
   left = (char*)_free(left);
500
 
}
501
 
 
502
 
 
503
 
static int vkMaxArgWidth( const vkPoptOption * opt )
504
 
{
505
 
   int max = 0;
506
 
   int len = 0;
507
 
   const char * s;
508
 
 
509
 
   if ( opt == NULL )
510
 
      return 0;
511
 
 
512
 
   for (; opt->longFlag || opt->shortFlag || opt->arg; opt++ ) {
513
 
 
514
 
      if ( opt->arg != NULL ) {     /* is-a table */
515
 
         /* recurse on included sub-tables. */
516
 
         len = vkMaxArgWidth( opt->arg );
517
 
         if ( len > max ) 
518
 
            max = len;
519
 
      }
520
 
      else {                        /* is-a leaf */
521
 
         len = sizeof("  ") - 1;
522
 
         if ( opt->shortFlag != '\0' )
523
 
            len += sizeof("-X")-1;
524
 
         if ( opt->shortFlag != '\0' && opt->longFlag ) 
525
 
            len += sizeof(", ")-1;
526
 
         if (opt->longFlag) {
527
 
            len += sizeof("--") - 1;
528
 
            len += strlen( opt->longFlag );
529
 
         }
530
 
 
531
 
         s = vkGetHelpDesc( opt );
532
 
         if ( s )
533
 
            len += sizeof("=") - 1 + strlen( s );
534
 
         if ( len > max ) 
535
 
            max = len;
536
 
      }
537
 
   }
538
 
   return max;
539
 
}
540
 
 
541
 
 
542
 
/* this version prints nested tables first. swap 'em over if this
543
 
   isn't the behaviour you want. */
544
 
static void vkTableHelp( FILE * fp, const vkPoptOption * opt )
545
 
{
546
 
   if ( opt == NULL )
547
 
      return;
548
 
 
549
 
   /* recurse over all tables */
550
 
   for (; opt->longFlag || opt->shortFlag || opt->arg; opt++) {
551
 
      if ( opt->arg != NULL ) {     /* is-a table */
552
 
         /* print table title */
553
 
         fprintf( fp, "\n%s options:\n", opt->helptxt );
554
 
         /* recurse on included sub-tables. */
555
 
         vkTableHelp( fp, opt->arg );
556
 
      }
557
 
      else {                        /* is-a leaf */
558
 
         /* print options */
559
 
         vkSingleOptionHelp( fp, opt );
560
 
      }
561
 
   }
562
 
}
563
 
 
564
 
 
565
 
/* if tableName == NULL, recurses over all tables;
566
 
   else just prints contents of the specified table. */
567
 
void vkPoptPrintHelp( vkPoptContext con, FILE * fp,
568
 
                      const char * tableName )
569
 
{
570
 
   const char * fn;
571
 
 
572
 
   fprintf( fp, "\nUsage:" );
573
 
   fn = con->optionStack->argv[0];
574
 
   if ( fn != NULL ) {
575
 
      if ( strchr(fn, '/') ) 
576
 
         fn = strrchr( fn, '/' ) + 1;
577
 
      fprintf( fp, " %s", fn );
578
 
   }
579
 
 
580
 
   fprintf( fp, " %s", 
581
 
            "[valkyrie-opts] [valgrind-opts] [prog-and-args]\n" );
582
 
 
583
 
   leftColWidth = vkMaxArgWidth( con->options );
584
 
 
585
 
   if ( tableName == NULL ) {
586
 
      /* print all tables */
587
 
      vkTableHelp( fp, con->options );
588
 
   } else {
589
 
      /* trawl through con->options till we find the right table */
590
 
      const vkPoptOption * opt;
591
 
      for ( opt = con->options; (opt != NULL) &&
592
 
               (opt->helptxt != NULL); opt++ ) {
593
 
         if ( strcmp( opt->helptxt, tableName ) == 0 ) {
594
 
            break;
595
 
         }
596
 
      }
597
 
      if ( (opt != NULL) && (opt->helptxt) != NULL ) {
598
 
         if ( opt->helptxt )
599
 
            fprintf( fp, "\n%s options:\n", opt->helptxt );
600
 
         else
601
 
            vkPrintErr("Error: vkPoptPrintHelp(): No match found for table '%s'.", tableName);
602
 
         vkTableHelp( fp, opt->arg );
603
 
      }
604
 
   }
605
 
 
606
 
}