1 /*
2  *  cArgContainer.cc
3  *  Avida
4  *
5  *  Created by David Bryson on 9/12/06.
6  *  Copyright 1999-2011 Michigan State University. All rights reserved.
7  *
8  *
9  *  This file is part of Avida.
10  *
11  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
12  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
13  *
14  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
18  *  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #include "cArgContainer.h"
23 
24 #include "avida/core/Feedback.h"
25 
26 #include "cArgSchema.h"
27 
28 using namespace Avida;
29 
30 
Load(cString args,const cArgSchema & schema,Feedback & feedback)31 cArgContainer* cArgContainer::Load(cString args, const cArgSchema& schema, Feedback& feedback)
32 {
33   tArray<bool> set_ints;
34   tArray<bool> set_doubles;
35   tArray<bool> set_strings;
36 
37   cArgContainer* ret = new cArgContainer();
38 
39   set_ints.Resize(schema.GetNumIntArgs(), false);
40   ret->m_ints.Resize(schema.GetNumIntArgs());
41   set_doubles.Resize(schema.GetNumDoubleArgs(), false);
42   ret->m_doubles.Resize(schema.GetNumDoubleArgs());
43   set_strings.Resize(schema.GetNumStringArgs(), false);
44   ret->m_strings.Resize(schema.GetNumStringArgs());
45 
46   cString arg_ent;
47   cString arg_name;
48   bool success = true;
49 
50   arg_ent = args.Pop(schema.GetEntrySeparator());
51   while (arg_ent.GetSize() > 0) {
52     arg_name = arg_ent.Pop(schema.GetValueSeparator());
53     schema.AdjustArgName(arg_name);
54 
55     cArgSchema::tType type;
56     int index;
57     if (schema.FindEntry(arg_name, type, index)) {
58       switch (type) {
59         case cArgSchema::SCHEMA_INT:
60           set_ints[index] = true;
61           ret->m_ints[index] = arg_ent.AsInt();
62           if (!schema.ValidateInt(index, ret->m_ints[index])) {
63             cString name;
64             if (schema.GetIntName(index, name)) {
65               feedback.Error("value of '%s' exceeds its defined range", static_cast<const char*>(name));
66             } else {
67               feedback.Error("invalid int schema entry at index %d", index);
68             }
69           }
70           break;
71         case cArgSchema::SCHEMA_DOUBLE:
72           set_doubles[index] = true;
73           ret->m_doubles[index] = arg_ent.AsDouble();
74           if (!schema.ValidateDouble(index, ret->m_doubles[index])) {
75             cString name;
76             if (schema.GetDoubleName(index, name)) {
77               feedback.Error("value of '%s' exceeds its defined range", static_cast<const char*>(name));
78             } else {
79               feedback.Error("invalid double schema entry at index %d", index);
80             }
81           }
82           break;
83         case cArgSchema::SCHEMA_STRING:
84           set_strings[index] = true;
85           arg_ent.Trim();
86           ret->m_strings[index] = arg_ent;
87           break;
88         default:
89           success = false;
90           feedback.Error("invalid schema argument type!");
91       }
92     } else {
93       success = false;
94       feedback.Error("unrecognized argument: '%s'", static_cast<const char*>(arg_name));
95     }
96     arg_ent = args.Pop(schema.GetEntrySeparator());
97   }
98 
99   for (int i = 0; i < set_ints.GetSize(); i++) {
100     if (set_ints[i]) continue;
101     if (schema.IsOptionalInt(i)) schema.SetDefaultInt(i, ret->m_ints[i]);
102     else {
103       success = false; // doc err here
104       cString name;
105       if (schema.GetIntName(i, name)) {
106         feedback.Error("required argument '%s' was not found", static_cast<const char*>(name));
107       } else {
108         feedback.Error("invalid int schema entry at index %d", i);
109       }
110     }
111   }
112   for (int i = 0; i < set_doubles.GetSize(); i++) {
113     if (set_doubles[i]) continue;
114     if (schema.IsOptionalDouble(i)) schema.SetDefaultDouble(i, ret->m_doubles[i]);
115     else {
116       success = false; // doc err here
117       cString name;
118       if (schema.GetDoubleName(i, name)) {
119         feedback.Error("required argument '%s' was not found", static_cast<const char*>(name));
120       } else {
121         feedback.Error("invalid double schema entry at index %d", i);
122       }
123     }
124   }
125   for (int i = 0; i < set_strings.GetSize(); i++) {
126     if (set_strings[i]) continue;
127     if (schema.IsOptionalString(i)) schema.SetDefaultString(i, ret->m_strings[i]);
128     else {
129       success = false; // doc err here
130       cString name;
131       if (schema.GetStringName(i, name)) {
132         feedback.Error("required argument '%s' was not found", static_cast<const char*>(name));
133       } else {
134         feedback.Error("invalid string schema entry at index %d", i);
135       }
136     }
137   }
138 
139   if (!success) {
140     delete ret;
141     ret = NULL;
142   }
143 
144   return ret;
145 }
146