1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 # Copyright 2006-2008 Floréal Morandat <morandat@lirmm.fr>
6 # This file is free software, which comes along with NIT. This software is
7 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
9 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
10 # is kept unaltered, and a notification of the changes is added.
11 # You are allowed to redistribute it and sell it, alone or is a part of
14 # This module is about character strings.
19 ###############################################################################
21 ###############################################################################
23 # Strings are arrays of characters.
25 special AbstractArray[Char]
29 redef type OTHER: String
31 redef meth
[](index
) do return _items
[index
]
33 redef meth
[]=(index
, item
)
35 if index
== length
then
39 assert index
>= 0 and index
< length
45 if _capacity
<= length
then enlarge
(length
+ 5)
50 redef meth enlarge
(cap
)
53 if cap
<= c
then return
54 while c
<= cap
do c
= c
* 2 + 2
55 var a
= calloc_string
(c
)
56 _items
.copy_to
(a
, length
, 0, 0)
65 if _capacity
< length
+ sl
then enlarge
(length
+ sl
)
66 s
.items
.copy_to
(_items
, sl
, 0, length
)
73 # The concatenation of `self' with `r'
74 meth
+(s
: String): String
76 var r
= new String.with_capacity
(length
+ s
.length
)
82 # i repetitions of self
83 meth
*(i
: Int): String
86 var r
= new String.with_capacity
(length
* i
)
95 redef meth to_s
: String do return new String.from
(self)
97 # If `self' contains only digits, return the corresponding integer
101 return to_cstring
.atoi
104 # If `self' contains only digits and alpha <= 'f', return the corresponding integer.
105 meth to_hex
: Int do return a_to
(16)
107 # If `self' contains only digits and letters, return the corresponding integer in a given base
108 meth a_to
(base
: Int) : Int
135 # Return a null terminated char *
136 meth to_cstring
: NativeString
143 # Create a substring.
145 # "abcd".substring(1, 2) # --> "bc"
146 # "abcd".substring(-1, 2) # --> "a"
147 # "abcd".substring(1, 0) # --> ""
148 # "abcd".substring(2, 5) # --> "cd"
149 meth substring
(from
: Int, count
: Int): String
153 if from
< 0 then from
= 0
154 if count
> length
then count
= length
156 var r
= new String.with_capacity
(count
- from
)
157 while from
< count
do
167 # Create a substring with the string beginning at the 'from' position
169 # "abcd".substring(1) # --> "bcd"
170 # "abcd".substring(-1) # --> "abcd"
171 # "abcd".substring(2) # --> "cd"
172 meth substring_from
(from
: Int): String
175 return substring
(from
, length
- from
)
178 # is this string a substring of the 'of' string from pos 'pos'
180 # "bc".is_substring("abcd",1) # --> true
181 # "bc".is_substring("abcd",2) # --> false
182 meth has_substring
(str
: String, pos
: Int): Bool
184 var itsindex
= str
.length
- 1
185 var myindex
= pos
+ itsindex
187 var itsitems
= str
._items
188 if myindex
> length
or itsindex
> myindex
then return false
189 while itsindex
> 0 do
190 if myitems
[myindex
] != itsitems
[itsindex
] then return false
197 # Is this string prefixed by 'prefix'
199 # "abc".is_prefix("abcd") # --> true
200 # "bc".is_prefix("abcd") # --> false
201 meth has_prefix
(prefix
: String): Bool do return has_substring
(prefix
,0)
203 # Is this string suffixed by 'suffix'
205 # "abcd".has_suffix("abc") # --> false
206 # "abcd".has_suffix("bcd") # --> true
207 meth has_suffix
(suffix
: String): Bool do return has_substring
(suffix
, length
- suffix
.length
)
214 while i
< l1
and i
< l2
do
215 var c1
= self[i
].ascii
231 # Create a new empty string.
239 _capacity
= s
.length
+ 1
241 _items
= calloc_string
(_capacity
)
242 s
.items
.copy_to
(_items
, _length
, 0, 0)
245 # Create a new empty string with a given capacity.
246 init with_capacity
(cap
: Int)
249 # _items = new NativeString.calloc(cap)
250 _items
= calloc_string
(cap
)
255 # Create a new string from a given char *.
256 init with_native
(nat
: NativeString, size
: Int)
264 # Create a new string from a null terminated char *.
265 init from_cstring
(str
: NativeString)
267 var size
= str
.cstring_length
269 _capacity
= size
+ 1 # Since there is a trailing \n
273 # Create a string of `count' chararter `c'
274 init filled_with
(c
: Char, count
: Int)
296 if not o
isa String or o
is null then return false
299 if o
.length
!= l
then return false
304 if it
[i
] != oit
[i
] then return false
310 # String to upper case
311 meth to_upper
: String
313 var s
= new String.with_capacity
(length
)
314 for i
in self do s
.add
(i
.to_upper
)
318 # String to lower case
319 meth to_lower
: String
321 var s
= new String.with_capacity
(length
)
322 for i
in self do s
.add
(i
.to_lower
)
326 readable private attr _items
: NativeString
327 readable private attr _capacity
: Int
330 ###############################################################################
332 ###############################################################################
335 # meth class_name: String is extern intern # The name of the class
337 # User redeable representation of `self'.
338 meth to_s
: String do return inspect
340 # Developper readable representation of `self'.
341 # Usualy, it uses the form "<CLASSNAME:#OBJECTID bla bla bla>"
349 # Return "<CLASSNAME:#OBJECTID".
350 # This fuction is mainly used with the redefinition of the inspect(0) method
351 protected meth inspect_head
: String
353 return "<{object_id.to_hex}"
356 protected meth args
: IndexedCollection[String]
374 meth fill_string
(s
: String, base
: Int, signed
: Bool)
375 # Fill `s' with the digits in base 'base' of `self' (and with the '-' sign if 'signed' and negative).
376 # assume < to_c max const of char
383 else if self == 0 then
390 var pos
= digit_count
(base
) - 1
391 while pos
>= 0 and n
> 0 do
392 s
[pos
] = (n
% base
).to_c
398 # return displayable int in base 10 and signed
399 redef meth to_s
do return to_base
(10,true)
401 # return displayable int in hexadecimal (unsigned (not now))
402 meth to_hex
: String do return to_base
(16,false)
404 # return displayable int in base base and signed
405 meth to_base
(base
: Int, signed
: Bool): String
407 var l
= digit_count
(base
)
408 var s
= new String.filled_with
(' ', l
)
409 fill_string
(s
, base
, signed
)
415 redef meth to_s
do return to_precision
(6)
417 # `self' representation with `nb' digits after the '.'.
418 meth to_precision
(nb
: Int): String
420 if nb
== 0 then return to_i
.to_s
428 var d
= ((self-i
.to_f
)*dec
).to_i
436 var s
= new String.with_capacity
(1)
442 redef class Collection[E
]
443 # Concatenate elements.
447 for e
in self do if e
!= null then s
.append
(e
.to_s
)
451 # Concatenate and separate each elements with `sep'.
452 meth join
(sep
: String): String
454 if is_empty
then return ""
456 var s
= new String # Result
461 if e
!= null then s
.append
(e
.to_s
)
468 if e
!= null then s
.append
(e
.to_s
)
476 # Concatenate couple of 'key value' separate by 'couple_sep' and separate each couple with `sep'.
477 meth map_join
(sep
: String, couple_sep
: String): String
479 if is_empty
then return ""
481 var s
= new String # Result
487 if e
!= null then s
.append
("{k}{couple_sep}{e}")
495 if e
!= null then s
.append
("{k}{couple_sep}{e}")
502 ###############################################################################
504 ###############################################################################
506 # Native strings are simple C char *
508 meth
[](index
: Int): Char is intern
509 meth
[]=(index
: Int, item
: Char) is intern
510 meth copy_to
(dest
: NativeString, length
: Int, from
: Int, to
: Int) is intern
512 # Position of the first nul character.
513 meth cstring_length
: Int
516 while self[l
] != '\0' do l
+= 1
519 meth atoi
: Int is intern
522 # StringCapable objects can create native strings
524 protected meth calloc_string
(size
: Int): NativeString is intern
528 attr _args_cache
: IndexedCollection[String]
530 redef meth args
: IndexedCollection[String]
532 if _args_cache
== null then init_args
536 # The name of the program as given by the OS
537 meth program_name
: String
539 return new String.from_cstring
(native_argv
(0))
542 # Initialize `args' with the contents of `native_argc' and `native_argv'.
543 private meth init_args
545 var argc
= native_argc
546 var args
= new Array[String].with_capacity
(0)
549 args
[i-1
] = new String.from_cstring
(native_argv
(i
))
555 private meth native_argc
: Int is extern "kernel_Sys_Sys_native_argc_0" # First argument of the main C function.
557 private meth native_argv
(i
: Int): NativeString is extern "kernel_Sys_Sys_native_argv_1" # Second argument of the main C function.