source: trunk/test/commandline.cc @ 2703

Last change on this file since 2703 was 2703, checked in by Peter, 11 years ago

merge release 0.8.1 into trunk

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 18.7 KB
Line 
1// $Id: commandline.cc 2703 2012-03-12 06:43:10Z peter $
2
3/*
4  Copyright (C) 2007, 2008, 2009 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2010, 2011, 2012 Peter Johansson
6
7  This file is part of the yat library, http://dev.thep.lu.se/yat
8
9  The yat library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 3 of the
12  License, or (at your option) any later version.
13
14  The yat library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with yat. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "Suite.h"
24
25#include "yat/utility/CommandLine.h"
26#include "yat/utility/FileUtil.h"
27#include "yat/utility/OptionArg.h"
28#include "yat/utility/OptionFile.h"
29#include "yat/utility/OptionHelp.h"
30#include "yat/utility/OptionSwitch.h"
31
32#include <cassert>
33#include <cstdlib>
34#include <fstream>
35#include <stdexcept>
36#include <string>
37
38#include <string.h>
39
40using namespace theplu;
41using namespace yat::utility;
42bool cmd_help(yat::test::Suite& error);
43char** stradup(const char* str[], int size);
44void strafree(char** str, int size);
45bool test_switch(yat::test::Suite& error);
46bool test_arg(yat::test::Suite& error);
47void test_exception_msg(yat::test::Suite& error);
48bool test_file(yat::test::Suite& error);
49bool test_file2(yat::test::Suite& error);
50bool test_file3(yat::test::Suite& error);
51bool test_file3_(yat::test::Suite& error, const std::string&);
52bool test_file4(yat::test::Suite& error);
53bool test_file4_(yat::test::Suite& error, const std::string&);
54bool test_failures(yat::test::Suite& error);
55bool test_option_name_clash(yat::test::Suite& suite);
56bool test_free_arg(yat::test::Suite& suite);
57
58int main(int argc, char* argv[])
59{ 
60  yat::test::Suite suite(argc, argv);
61
62  suite.err() << "testing commandline" << std::endl;
63
64  // Peter, creation of this directory should perhaps be in a more central place
65  FileUtil dir("testSubDir");
66  if (!dir.exists())
67    if (mkdir(dir.path().c_str(), 0755)) {
68      suite.err() << "mkdir " << dir.path() << " failed\n";
69      return 1;
70    }
71  FileUtil subdir("testSubDir/commandline_test.dir");
72  if (!subdir.exists()) {
73    if (mkdir(subdir.path().c_str(), 0755)) {
74      suite.err() << "mkdir " << subdir.path() << " failed\n";
75      return 1;
76    }
77  }
78  if (subdir.permissions("w")) {
79    chmod(subdir.path().c_str(), S_IREAD | S_IWRITE | S_IEXEC);
80  }
81
82  try {
83    suite.add(cmd_help(suite));
84    suite.add(test_switch(suite));
85    suite.add(test_arg(suite));
86    suite.add(test_file(suite));
87    suite.add(test_file2(suite));
88    suite.add(test_file3(suite));
89    suite.add(test_file4(suite));
90    suite.add(test_failures(suite));
91    suite.add(test_option_name_clash(suite));
92    suite.add(test_free_arg(suite));
93    test_exception_msg(suite);
94  }
95  catch (std::runtime_error& e) {
96    suite.err() << "Error: unexpected exception thrown\n" << e.what() 
97                << std::endl;
98    suite.add(false);
99  }
100
101  CommandLine cmd;
102  OptionFile file(cmd, "f,file", "description");
103
104  return suite.return_value();
105}
106
107
108bool cmd_help(yat::test::Suite& suite)
109{
110  using namespace theplu::yat::utility;
111  CommandLine cmd;
112  OptionArg<std::string> dir(cmd, "d,dir", "output directory");
113  OptionHelp help(cmd);
114  OptionArg<std::string> target(cmd, "T,target", "treat DEST as a normal file", 
115                                true);
116  target.print_arg("=TARGET");
117  OptionSwitch verbose(cmd, "v,verbose", "explain what is being done");
118  OptionSwitch version(cmd, "version", "output version and exit");
119
120  suite.err() << cmd;
121  return true;
122}
123
124
125char** stradup(const char** str, int size)
126{
127  char** res = new char*[size];
128  for (int i = 0; i<size; ++i) {
129    res[i] = strdup(str[i]);
130    assert(res[i]);
131  }
132  return res;
133}
134
135
136void strafree(char** str, int size)
137{
138  for (int i = 0; i<size; ++i) {
139    free(str[i]);
140  }
141}
142
143
144void test_exception_msg(yat::test::Suite& suite)
145{
146  // test for ticket 508
147  using namespace theplu::yat::utility;
148  CommandLine cmd;
149  OptionHelp help(cmd, "h,help", "");
150  OptionFile indata(cmd, "i,in", "input file", true, true,"r");
151  OptionSwitch cmd_memory(cmd, "m", "transpose in a memory cheap manner");
152  OptionArg<size_t> cmd_n(cmd, "n", "number of rows to print in each iteration");
153  OptionSwitch cmd_numeric(cmd, "numeric", 
154                                         "input is a numeric matrix");
155  OptionFile outdata(cmd, "o,out", "output file",true, false,"w");
156  OptionSwitch verbose(cmd, "v,verbose", "display progress");
157  int ac = 2;
158  const char* cav[] = { "test_prog", "--haha" };
159  char** av = stradup(cav, ac);
160  try {
161    cmd.parse(ac,av);
162  }
163  catch (std::runtime_error& e) {
164    std::string msg(e.what());
165    if (msg.size()<15) {
166      suite.xadd(false);
167      suite.err() << "Error: short exception message\n" 
168                  << "  exception message is: `" << msg
169                  << "' that is " << msg.size() << " characters long.\n" 
170                  << "  expected at least 15 characters\n";
171    }
172  }
173  strafree(av, ac);
174}
175
176
177bool test_switch(yat::test::Suite& suite)
178{
179  bool ok=true;
180  CommandLine cmd;
181  OptionSwitch target(cmd, "T,target", "treat DEST as a normal file", true);
182  OptionSwitch verbose(cmd, "v,verbose", "explain what is being done", true);
183
184  suite.err() << "Testing OptionSwitch -T...";
185  {
186    int ac = 2;
187    const char* cav[] = { "test_prog", "-T" };
188    char** av = stradup(cav, ac);
189    cmd.parse(ac,av);
190    if (target.present() && !verbose.present())
191      suite.err() << "ok\n";
192    else {
193      suite.err() << "failed\n";
194      ok =false;
195    }
196    strafree(av, ac);
197  }
198
199
200  suite.err() << "Testing OptionSwitch --target...";
201  {
202    int ac = 2;
203    const char* cav[] = { "test_prog", "--target" };
204    char** av = stradup(cav, ac);
205    cmd.parse(ac,av);
206    if (target.present() && target.value() && !verbose.present())
207      suite.err() << "ok\n";
208    else {
209      suite.err() << "failed\n";
210      ok =false;
211    }
212    strafree(av, ac);
213  }
214
215  suite.err() << "Testing OptionSwitch -T -v...";
216  {
217    int ac = 3;
218    const char* cav[] = { "test_prog", "-T" , "-v"};
219    char** av = stradup(cav, ac);
220    cmd.parse(ac,av);
221    if (target.present() && verbose.present())
222      suite.err() << "ok\n";
223    else {
224      suite.err() << "failed\n";
225      ok =false;
226    }
227    strafree(av, ac);
228  }
229
230  suite.err() << "Testing OptionSwitch -vT...";
231  {
232    int ac = 2;
233    const char* cav[] = { "test_prog", "-vT"};
234    char** av = stradup(cav, ac);
235    cmd.parse(ac,av);
236    if (target.present() && verbose.present())
237      suite.err() << "ok\n";
238    else {
239      suite.err() << "failed\n";
240      ok =false;
241    }
242    strafree(av, ac);
243  }
244
245  suite.err() << "Testing OptionSwitch --no-target...";
246  {
247    int ac = 2;
248    const char* cav[] = { "test_prog", "--no-target" };
249    char** av = stradup(cav, ac);
250    cmd.parse(ac,av);
251    if (target.present() && !target.value())
252      suite.err() << "ok\n";
253    else {
254      suite.err() << "failed\n";
255      if (!target.present())
256        suite.err() << "target.present() returned false\n";
257      if (target.value())
258        suite.err() << "target.value() returned true\n";
259      ok =false;
260    }
261    strafree(av, ac);
262  }
263  return ok;
264}
265
266
267bool test_arg(yat::test::Suite& suite)
268{
269  bool ok=true;
270  CommandLine cmd;
271  OptionArg<std::string> input(cmd, "i,input", "input file");
272  OptionArg<unsigned int> n(cmd, "n", "number of lines");
273  OptionArg<double> x(cmd, "x,extra", "a float number");
274
275  suite.err() << "Testing OptionArg existence -i file...";
276  {
277    int ac = 3;
278    const char* cav[] = { "test_prog", "-i", "file" };
279    char** av = stradup(cav, ac);
280    cmd.parse(ac,av);
281    if (input.present())
282      suite.err() << "ok\n";
283    else {
284      suite.err() << "failed\n";
285      ok =false;
286    }
287    strafree(av, ac);
288  }
289
290  suite.err() << "Testing OptionArg value -i file...";
291  {
292    int ac = 3;
293    const char* cav[] = { "test_prog", "-i", "file" };
294    char** av = stradup(cav, ac);
295    cmd.parse(ac,av);
296    if (input.value()=="file")
297      suite.err() << "ok\n";
298    else {
299      suite.err() << "failed\n";
300      ok =false;
301    }
302    strafree(av, ac);
303  }
304
305  suite.err() << "Testing OptionArg existence --input file...";
306  {
307    int ac = 3;
308    const char* cav[] = { "test_prog", "--input", "file" };
309    char** av = stradup(cav, ac);
310    cmd.parse(ac,av);
311    if (input.present())
312      suite.err() << "ok\n";
313    else {
314      suite.err() << "failed\n";
315      ok =false;
316    }
317    strafree(av, ac);
318  }
319
320  suite.err() << "Testing OptionArg value --input=file...";
321  {
322    int ac = 2;
323    const char* cav[] = { "test_prog", "--input=file" };
324    char** av = stradup(cav, ac);
325    cmd.parse(ac,av);
326    if (input.value()=="file")
327      suite.err() << "ok\n";
328    else {
329      suite.err() << "failed\n";
330      ok =false;
331    }
332    strafree(av, ac);
333  }
334
335  suite.err() << "Testing OptionArg value --input=\"file called something\"...";
336  {
337    int ac = 2;
338    const char* cav[] = { "test_prog", "--input=\"file called something\"" };
339    char** av = stradup(cav, ac);
340    cmd.parse(ac,av);
341    if (input.value()=="file called something")
342      suite.err() << "ok\n";
343    else {
344      suite.err() << "failed\n";
345      suite.err() << "value is `" << input.value() << "'\n"
346            << "expected `file called something'\n";
347      ok =false;
348    }
349    strafree(av, ac);
350  }
351
352  suite.err() << "Testing OptionArg unsigned int value -n 3...";
353  {
354    int ac = 3;
355    const char* cav[] = { "test_prog", "-n", "3" };
356    char** av = stradup(cav, ac);
357    cmd.parse(ac,av);
358    if (n.value()==3)
359      suite.err() << "ok\n";
360    else {
361      suite.err() << "failed\n";
362      ok =false;
363    }
364    strafree(av, ac);
365  }
366
367
368  suite.err() << "Testing OptionArg 2 value --input file -n 3...";
369  {
370    int ac = 5;
371    const char* cav[] = { "test_prog", "--input", "file", "-n", "3" };
372    char** av = stradup(cav, ac);
373    cmd.parse(ac,av);
374    if (input.value()=="file")
375      suite.err() << "ok\n";
376    else {
377      suite.err() << "failed\n";
378      ok =false;
379    }
380    strafree(av, ac);
381  }
382
383  suite.err() << "Testing OptionArg double value -x -6...";
384  try {
385    int ac = 3;
386    const char* cav[] = { "test_prog", "-x", "-6" };
387    char** av = stradup(cav, ac);
388    cmd.parse(ac,av);
389    if (x.value()==-6)
390      suite.err() << "ok\n";
391    else {
392      suite.err() << "failed\n";
393      ok =false;
394    }
395    strafree(av, ac);
396  }
397  catch (std::runtime_error& e) {
398    ok = false;
399    suite.err() << "failed\nexception thrown with what(): " << e.what() << "\n";
400  }
401
402  suite.err() << "Testing OptionArg double value --extra -6...";
403  try {
404    int ac = 3;
405    const char* cav[] = { "test_prog", "--extra", "-6" };
406    char** av = stradup(cav, ac);
407    cmd.parse(ac,av);
408    if (x.value()==-6)
409      suite.err() << "ok\n";
410    else {
411      suite.err() << "failed\n";
412      ok =false;
413    }
414    strafree(av, ac);
415  }
416  catch (std::runtime_error& e) {
417    ok=false;
418    suite.err() << "failed\nexception thrown with what(): " << e.what() << "\n";
419  }
420
421  suite.err() << "Testing OptionArg::value(T) ... ";
422  try {
423    int ac = 1;
424    const char* cav[] = { "test_prog"};
425    char** av = stradup(cav, ac);
426    cmd.parse(ac,av);
427    n.value(5);
428    if (n.present()==false && n.value()==5)
429      suite.err() << "ok\n";
430    else {
431      suite.err() << "failed\n";
432      ok = false;
433    }
434    strafree(av, ac);
435  }
436  catch (std::runtime_error& e) {
437    suite.err() << "failed\n";
438    ok = false;
439  }
440
441  // test for ticket 645
442  suite.err() << "Testing error message with -n STRING\n";
443  try {
444    int ac = 3;
445    const char* cav[] = { "test_prog", "-n", "STRING"};
446    char** av = stradup(cav, ac);
447    try {
448      cmd.parse(ac,av);
449      strafree(av, ac);
450      ok=false;
451      suite.err() << "error: expected parse to throw\n"; 
452    }
453    catch (std::runtime_error& e) {
454      strafree(av, ac);
455      suite.err() << "expected exception: what(): " << e.what() << "\n";
456    }
457  }
458  catch (std::runtime_error& e) {
459    suite.err() << "failed: " << e.what() << "\n";
460    ok=false;
461  }
462  return ok;
463}
464
465bool test_failures(yat::test::Suite& suite)
466{
467  bool ok=true;
468  CommandLine cmd;
469  OptionSwitch verbose(cmd, "v,verbose", "explain what is being done");
470  OptionArg<std::string> input(cmd, "i,input", "input file");
471  OptionArg<unsigned int> n(cmd, "n", "number of lines");
472
473  suite.err() << "Testing unknown option --peter...";
474  {
475    int ac = 2;
476    const char* cav[] = { "test_prog", "--peter"};
477    char** av = stradup(cav, ac);
478    try{
479      cmd.parse(ac,av);
480      suite.err() << "failed\n";
481      ok =false;
482    }
483    catch (...) {
484      suite.err() << "ok\n";
485    }
486    strafree(av, ac);
487  }
488
489  suite.err() << "Testing unknown option -jvjhsgad...";
490  {
491    int ac = 2;
492    const char* cav[] = { "test_prog", "-vjhsgad"};
493    char** av = stradup(cav, ac);
494    try{
495      cmd.parse(ac,av);
496      suite.err() << "failed\n";
497      ok =false;
498    }
499    catch (...) {
500      suite.err() << "ok\n";
501    }
502    strafree(av, ac);
503  }
504
505
506  suite.err() << "Testing invalid option -nv 3...";
507  {
508    int ac = 3;
509    const char* cav[] = { "test_prog", "-nv", "3"};
510    char** av = stradup(cav, ac);
511    try{
512      cmd.parse(ac,av);
513      suite.err() << "failed\n";
514      ok =false;
515    }
516    catch (...) {
517      suite.err() << "ok\n";
518    }
519    strafree(av, ac);
520  }
521
522
523  suite.err() << "Testing 23.12 is not unsigned int...";
524  {
525    int ac = 3;
526    const char* cav[] = { "test_prog", "-n", "23.12"};
527    char** av = stradup(cav, ac);
528    try{
529      cmd.parse(ac,av);
530      suite.err() << "failed\n";
531      ok =false;
532    }
533    catch (std::runtime_error& e) {
534      suite.err() << "ok\n";
535    }
536    strafree(av, ac);
537  }
538
539  suite.err() << "Testing -1 is not unsigned int...";
540  {
541    int ac = 3;
542    const char* cav[] = { "test_prog", "-n", "-1"};
543    char** av = stradup(cav, ac);
544    try{
545      cmd.parse(ac,av);
546      suite.err() << "failed\n";
547      ok =false;
548    }
549    catch (...) {
550      suite.err() << "ok\n";
551    }
552    strafree(av, ac);
553  }
554
555
556  suite.err() << "Testing invalid: test_prog peter...";
557  {
558    int ac = 2;
559    const char* cav[] = { "test_prog", "peter" };
560    char** av = stradup(cav, ac);
561    try{
562      cmd.parse(ac,av);
563      suite.err() << "failed\n";
564      ok =false;
565    }
566    catch (...) {
567      suite.err() << "ok\n";
568    }
569    strafree(av, ac);
570  }
571
572  suite.err() << "Testing OptionArg required ...";
573  {
574    OptionArg<std::string> required(cmd, "required", "required", true); 
575    int ac = 1;
576    const char* cav[] = { "test_prog" };
577    char** av = stradup(cav, ac);
578    try{
579      cmd.parse(ac,av);
580      suite.err() << "failed\n";
581      ok =false;
582    }
583    catch (...) {
584      suite.err() << "ok\n";
585    }
586    strafree(av, ac);
587  }
588
589
590  return ok;
591}
592
593
594bool test_file(yat::test::Suite& suite)
595{
596  bool ok=true;
597  CommandLine cmd;
598  OptionFile inclones(cmd, "clones", "file containing clones");
599  OptionFile indata(cmd, "data", "data to merge");
600  OptionFile out(cmd, "o,out", "data to merge", true, false, "w");
601  OptionSwitch help(cmd, "h,help", "display this help and exit");
602
603  suite.err() << "Testing OptionFile... ";
604  {
605    int ac = 7;
606    const char* cav[] = { "test_prog", "--clones", "commandline_test.cc", 
607                          "--data", "commandline_test.cc", "-o", 
608                          "commandline_test.cc"};
609    char** av = stradup(cav, ac);
610    cmd.parse(ac,av);
611    suite.err() << "ok\n";
612    strafree(av, ac);
613  }
614  return ok;
615}
616
617
618bool test_file2(yat::test::Suite& suite)
619{
620  suite.err() << "Testing OptionFile in write-protected directory... ";
621
622  if (yat::test::run_as_root()) {
623    suite.err() << "skipped because user is root\n";
624    // skipping means test should still be successful
625    return true;
626  }
627
628  FileUtil subdir("testSubDir/commandline_test.dir/write-protected");
629  if (!subdir.exists()) {
630    if (mkdir(subdir.path().c_str(), 0555)) {
631      suite.err() << "mkdir " << subdir.path() << " failed\n";
632      return false;
633    }
634  }
635  else
636    if (!subdir.permissions("w")) {
637      suite.err() << subdir.path() << " already exists\n";
638      return false;
639    }
640
641  FileUtil file("testSubDir/commandline_test.dir/write-protected/out.txt");
642  if (file.exists()) {
643    suite.err() << "FileUtil::exists returns true unexpectedly\n";
644    return false;
645  }
646  if (file.permissions("w")==0) {
647    suite.err() << "FileUtil::permission(\"w\") returns 0 while "
648                << "-1 was expected\n";
649    return false;
650  }
651
652  bool ok=true;
653  CommandLine cmd;
654  OptionFile out(cmd, "o,out", "output to file", false, false, "w");
655  OptionSwitch help(cmd, "h,help", "display this help and exit");
656
657  {
658    int ac = 3;
659    const char* cav[] = { "test_prog", "--out", 
660                    "testSubDir/commandline_test.dir/write-protected/out.txt"};
661    char** av = stradup(cav, ac);
662    try {
663      cmd.parse(ac,av);
664      ok =false;
665      suite.err() << "failed\n";
666    }
667    catch (cmd_error& e) {
668      suite.err() << "ok\n";
669      suite.err() << "catch expected error: " << e.what() << "\n";
670    }
671    strafree(av, ac);
672  }
673  return ok;
674}
675
676
677bool test_file3(yat::test::Suite& suite)
678{
679  suite.err() << "Testing OptionFile in non-existing tree\n";
680  // testing error message from OptionFile when tree is not existing
681  bool ok=true;
682  ok &= test_file3_(suite, "r");
683  ok &= test_file3_(suite, "w");
684  ok &= test_file3_(suite, "x");
685  ok &= test_file3_(suite, "d");
686  return ok;
687}
688
689
690bool test_file3_(yat::test::Suite& suite, const std::string& perm)
691{
692  CommandLine cmd;
693  OptionFile file(cmd, "file", "", true, false, perm);
694
695  suite.err() << "Testing OptionFile '" << perm << "' ... "; 
696  int ac = 3;
697  const char* cav[] = { "test_prog", "--file", "sjhgaw/jmegb/tmp.tmpx"};
698  char** av = stradup(cav, ac);
699  try {
700    cmd.parse(ac,av);
701    suite.err() << "no\n";
702    strafree(av, ac);
703    return false;
704  }
705  catch (cmd_error& e) {
706    suite.err() << "ok\n";
707    suite.err() << "catch expected error: " << e.what() << "\n";
708  }
709  strafree(av, ac);
710  return true;
711}
712
713
714bool test_file4(yat::test::Suite& suite)
715{
716  FileUtil file("testSubDir/commandline_test.dir/test_file4.txt");
717  if (!file.exists()) {
718    std::ofstream os(file.path().c_str());
719  } 
720  chmod(file.path().c_str(), 0);
721
722  suite.err() << "Testing OptionFile with no permssions\n";
723  bool ok=true;
724  ok &= test_file4_(suite, "r");
725  ok &= test_file4_(suite, "w");
726  ok &= test_file4_(suite, "x");
727  ok &= test_file4_(suite, "d");
728  return ok;
729}
730
731
732bool test_file4_(yat::test::Suite& suite, const std::string& perm)
733{
734  CommandLine cmd;
735  OptionFile file(cmd, "file", "", true, false, perm);
736
737  suite.err() << "Testing OptionFile '" << perm << "' ... "; 
738  if (yat::test::run_as_root()) {
739    suite.err() << "skipped because user is root\n";
740    return true;
741  }
742  try {
743    int ac = 3;
744    const char* cav[] = { "test_prog", "--file", 
745                          "testSubDir/commandline_test.dir/test_file4.txt"};
746    char** av = stradup(cav, ac);
747    cmd.parse(ac,av);
748    suite.err() << "no\n";
749    strafree(av, ac);
750    return false;
751  }
752  catch (cmd_error& e) {
753    suite.err() << "ok\n";
754    suite.err() << "catch expected error: " << e.what() << "\n";
755  }
756  return true;
757}
758
759
760bool test_option_name_clash(yat::test::Suite& suite)
761{
762  bool ok=true;
763  suite.err() << "Testing long option name clash ...";
764  try {
765    CommandLine cmd;
766    OptionSwitch op1(cmd, "opt", "bla bla");
767    OptionSwitch op2(cmd, "o,opt", "other bla");
768    ok=false;
769    suite.err() << "failed\n";
770  }
771  catch (std::runtime_error& e) {
772    suite.err() << "ok\n";
773  }
774  suite.err() << "Testing short option name clash ...";
775  try {
776    CommandLine cmd;
777    OptionSwitch op1(cmd, "o", "bla bla");
778    OptionSwitch op2(cmd, "o,opt", "other bla");
779    ok=false;
780    suite.err() << "failed\n";
781  }
782  catch (std::runtime_error& e) {
783    suite.err() << "ok\n";
784  }
785
786  return ok;
787}
788
789
790bool test_free_arg(yat::test::Suite& suite)
791{
792  bool ok=true;
793  suite.err() << "Testing free arguments ...";
794
795  CommandLine cmd;
796  cmd.allow_free_args(2);
797  OptionHelp help(cmd);
798  int ac = 3;
799  const char* cav[] = { "test_prog", "file", "kl"};
800  char** av = stradup(cav, ac);
801  cmd.parse(ac, av);
802  suite.err() << "ok\n";
803  strafree(av, ac);
804  return ok;
805}
Note: See TracBrowser for help on using the repository browser.