]> git.mxchange.org Git - flightgear.git/blob - src/Scripting/NasalString.cxx
Clean up/prepare for porting NasalPositioned to cppbind
[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  *  Helper to convert size_t position/npos to Nasal conventions (-1 == npos)
64  */
65 naRef pos_to_nasal(size_t pos)
66 {
67   if( pos == nasal::String::npos )
68     return naNum(-1);
69   else
70     return naNum(pos);
71 }
72
73 /**
74  *  Find first occurrence of single character
75  *
76  *  find(c, pos = 0)
77  */
78 static naRef f_find(naContext c, naRef me, int argc, naRef* args)
79 {
80   nasal::CallContext ctx(c, argc, args);
81   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
82                 find = ctx.requireArg<nasal::String>(0);
83   size_t pos = ctx.getArg<int>(1, 0);
84
85   if( find.size() != 1 )
86     naRuntimeError(c, "string::find: single character expected");
87
88   return pos_to_nasal( str.find(*find.c_str(), pos) );
89 }
90
91 /**
92  * Find first character of a string occurring in this string
93  *
94  * find_first_of(search, pos = 0)
95  */
96 static naRef f_find_first_of(naContext c, naRef me, int argc, naRef* args)
97 {
98   nasal::CallContext ctx(c, argc, args);
99   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
100                 find = ctx.requireArg<nasal::String>(0);
101   size_t pos = ctx.getArg<int>(1, 0);
102
103   return pos_to_nasal( str.find_first_of(find, pos) );
104 }
105
106 /**
107  * Find first character of this string not occurring in the other string
108  *
109  * find_first_not_of(search, pos = 0)
110  */
111 static naRef f_find_first_not_of(naContext c, naRef me, int argc, naRef* args)
112 {
113   nasal::CallContext ctx(c, argc, args);
114   nasal::String str = nasal::from_nasal<nasal::String>(c, me),
115                 find = ctx.requireArg<nasal::String>(0);
116   size_t pos = ctx.getArg<int>(1, 0);
117
118   return pos_to_nasal( str.find_first_not_of(find, pos) );
119 }
120
121 //------------------------------------------------------------------------------
122 naRef initNasalString(naRef globals, naRef string, naContext c, naRef gcSave)
123 {
124   nasal::Hash string_module(string, c);
125
126   string_module.set("compare", f_compare);
127   string_module.set("starts_with", f_starts_with);
128   string_module.set("find", f_find);
129   string_module.set("find_first_of", f_find_first_of);
130   string_module.set("find_first_not_of", f_find_first_not_of);
131
132   return naNil();
133 }