Fix for coverity #29409 - Use char 0 instead of NULL
[supertux.git] / src / addon / addon.cpp
1 //  SuperTux - Add-on
2 //  Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
3 //                2014 Ingo Ruhnke <grumbel@gmail.com>
4 //
5 //  This program 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 program 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 program.  If not, see <http://www.gnu.org/licenses/>.
17
18 #include "addon/addon.hpp"
19
20 #include <physfs.h>
21 #include <stdexcept>
22 #include <sstream>
23
24 #include "lisp/parser.hpp"
25 #include "util/reader.hpp"
26 #include "util/writer.hpp"
27 #include "util/log.hpp"
28
29 namespace {
30
31 static const char* s_allowed_characters = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
32
33 Addon::Type addon_type_from_string(const std::string& type)
34 {
35   if (type == "world")
36   {
37     return Addon::WORLD;
38   }
39   else if (type == "worldmap")
40   {
41     return Addon::WORLDMAP;
42   }
43   else if (type == "levelset")
44   {
45     return Addon::LEVELSET;
46   }
47   else
48   {
49     throw std::runtime_error("not a valid Addon::Type: " + type);
50   }
51 }
52
53 } // namespace
54
55 std::unique_ptr<Addon>
56 Addon::parse(const Reader& lisp)
57 {
58   std::unique_ptr<Addon> addon(new Addon);
59
60   try
61   {
62     if (!lisp.get("id", addon->m_id))
63     {
64       throw std::runtime_error("(id ...) field missing from addon description");
65     }
66
67     if (addon->m_id.empty())
68     {
69       throw std::runtime_error("addon id is empty");
70     }
71
72     if (addon->m_id.find_first_not_of(s_allowed_characters) != std::string::npos)
73     {
74       throw std::runtime_error("addon id contains illegal characters: " + addon->m_id);
75     }
76
77     lisp.get("version", addon->m_version);
78
79     std::string type;
80     lisp.get("type", type);
81     addon->m_type = addon_type_from_string(type);
82
83     lisp.get("title", addon->m_title);
84     lisp.get("author", addon->m_author);
85     lisp.get("license", addon->m_license);
86     lisp.get("url", addon->m_url);
87     lisp.get("md5", addon->m_md5);
88
89     return addon;
90   }
91   catch(const std::exception& err)
92   {
93     std::stringstream msg;
94     msg << "Problem when parsing addoninfo: " << err.what();
95     throw std::runtime_error(msg.str());
96   }
97 }
98
99 std::unique_ptr<Addon>
100 Addon::parse(const std::string& fname)
101 {
102   try
103   {
104     lisp::Parser parser;
105     const lisp::Lisp* root = parser.parse(fname);
106     const lisp::Lisp* addon = root->get_lisp("supertux-addoninfo");
107     if(!addon)
108     {
109       throw std::runtime_error("file is not a supertux-addoninfo file.");
110     }
111     else
112     {
113       return parse(*addon);
114     }
115   }
116   catch(const std::exception& err)
117   {
118     std::stringstream msg;
119     msg << "Problem when reading addoninfo '" << fname << "': " << err.what();
120     throw std::runtime_error(msg.str());
121   }
122 }
123
124 Addon::Addon() :
125   m_id(),
126   m_version(0),
127   m_type(),
128   m_title(),
129   m_author(),
130   m_license(),
131   m_url(),
132   m_md5(),
133   m_install_filename(),
134   m_enabled(false)
135 {}
136
137 std::string
138 Addon::get_filename() const
139 {
140   return get_id() + ".zip";
141 }
142
143 std::string
144 Addon::get_install_filename() const
145 {
146   return m_install_filename;
147 }
148
149 bool
150 Addon::is_installed() const
151 {
152   return !m_install_filename.empty();
153 }
154
155 bool
156 Addon::is_enabled() const
157 {
158   return m_enabled;
159 }
160
161 void
162 Addon::set_install_filename(const std::string& absolute_filename, const std::string& md5)
163 {
164   m_install_filename = absolute_filename;
165   m_md5 = md5;
166 }
167
168 void
169 Addon::set_enabled(bool v)
170 {
171   m_enabled = v;
172 }
173
174
175 /* EOF */