]> git.mxchange.org Git - flightgear.git/blob - src/Scripting/NasalString.cxx
Reset: do re-init Ghost bindings.
[flightgear.git] / src / Scripting / NasalString.cxx
1 // Add (std::string) like methods to Nasal strings
2 //
3 // Copyright (C) 2013  Thomas Geymayer <tomgey@gmail.com>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // 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, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
19 #ifdef HAVE_CONFIG_H
20 #  include "config.h"
21 #endif
22
23 #include "NasalString.hxx"
24
25 #include <simgear/nasal/cppbind/from_nasal.hxx>
26 #include <simgear/nasal/cppbind/Ghost.hxx>
27 #include <simgear/nasal/cppbind/NasalHash.hxx>
28 #include <simgear/nasal/cppbind/NasalString.hxx>
29
30 /**
31  *  Compare (sub)string with other string
32  *
33  *  compare(s)
34  *  compare(pos, len, s)
35  */
36 static naRef f_compare(naContext c, naRef me, int argc, naRef* args)
37 {
38   nasal::CallContext ctx(c, argc, args);
39   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
40                 rhs = ctx.requireArg<nasal::String>(argc > 1 ? 2 : 0);
41   size_t pos = argc > 1 ? ctx.requireArg<int>(1) : 0;
42   size_t len = argc > 1 ? ctx.requireArg<int>(2) : 0;
43
44   if( len == 0 )
45     len = nasal::String::npos;
46
47   return naNum( str.compare(pos, len, rhs) );
48 }
49
50 /**
51  *  Check whether string starts with other string
52  */
53 static naRef f_starts_with(naContext c, naRef me, int argc, naRef* args)
54 {
55   nasal::CallContext ctx(c, argc, args);
56   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
57                 rhs = ctx.requireArg<nasal::String>(0);
58
59   return naNum( str.starts_with(rhs) );
60 }
61
62 /**
63  *  Check whether string ends with other string
64  */
65 static naRef f_ends_with(naContext c, naRef me, int argc, naRef* args)
66 {
67   nasal::CallContext ctx(c, argc, args);
68   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
69                 rhs = ctx.requireArg<nasal::String>(0);
70
71   return naNum( str.ends_with(rhs) );
72 }
73
74 /**
75  *  Helper to convert size_t position/npos to Nasal conventions (-1 == npos)
76  */
77 naRef pos_to_nasal(size_t pos)
78 {
79   if( pos == nasal::String::npos )
80     return naNum(-1);
81   else
82     return naNum(pos);
83 }
84
85 /**
86  *  Find first occurrence of single character
87  *
88  *  find(c, pos = 0)
89  */
90 static naRef f_find(naContext c, naRef me, int argc, naRef* args)
91 {
92   nasal::CallContext ctx(c, argc, args);
93   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
94                 find = ctx.requireArg<nasal::String>(0);
95   size_t pos = ctx.getArg<int>(1, 0);
96
97   if( find.size() != 1 )
98     naRuntimeError(c, "string::find: single character expected");
99
100   return pos_to_nasal( str.find(*find.c_str(), pos) );
101 }
102
103 /**
104  * Find first character of a string occurring in this string
105  *
106  * find_first_of(search, pos = 0)
107  */
108 static naRef f_find_first_of(naContext c, naRef me, int argc, naRef* args)
109 {
110   nasal::CallContext ctx(c, argc, args);
111   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
112                 find = ctx.requireArg<nasal::String>(0);
113   size_t pos = ctx.getArg<int>(1, 0);
114
115   return pos_to_nasal( str.find_first_of(find, pos) );
116 }
117
118 /**
119  * Find first character of this string not occurring in the other string
120  *
121  * find_first_not_of(search, pos = 0)
122  */
123 static naRef f_find_first_not_of(naContext c, naRef me, int argc, naRef* args)
124 {
125   nasal::CallContext ctx(c, argc, args);
126   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
127                 find = ctx.requireArg<nasal::String>(0);
128   size_t pos = ctx.getArg<int>(1, 0);
129
130   return pos_to_nasal( str.find_first_not_of(find, pos) );
131 }
132
133 //------------------------------------------------------------------------------
134 naRef initNasalString(naRef globals, naRef string, naContext c)
135 {
136   nasal::Hash string_module(string, c);
137
138   string_module.set("compare", f_compare);
139   string_module.set("starts_with", f_starts_with);
140   string_module.set("ends_with", f_ends_with);
141   string_module.set("find", f_find);
142   string_module.set("find_first_of", f_find_first_of);
143   string_module.set("find_first_not_of", f_find_first_not_of);
144
145   return naNil();
146 }