@@ -383,6 +383,92 @@ func strIsDigit(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
383383 return True .ToObject (), nil
384384}
385385
386+ func strIsLower (f * Frame , args Args , kwargs KWArgs ) (* Object , * BaseException ) {
387+ if raised := checkMethodArgs (f , "islower" , args , StrType ); raised != nil {
388+ return nil , raised
389+ }
390+ s := toStrUnsafe (args [0 ]).Value ()
391+ if len (s ) == 0 {
392+ return False .ToObject (), nil
393+ }
394+ for i := range s {
395+ if ! isLower (s [i ]) {
396+ return False .ToObject (), nil
397+ }
398+ }
399+ return True .ToObject (), nil
400+ }
401+
402+ func strIsSpace (f * Frame , args Args , kwargs KWArgs ) (* Object , * BaseException ) {
403+ if raised := checkMethodArgs (f , "isspace" , args , StrType ); raised != nil {
404+ return nil , raised
405+ }
406+ s := toStrUnsafe (args [0 ]).Value ()
407+ if len (s ) == 0 {
408+ return False .ToObject (), nil
409+ }
410+ for i := range s {
411+ if ! isSpace (s [i ]) {
412+ return False .ToObject (), nil
413+ }
414+ }
415+ return True .ToObject (), nil
416+ }
417+
418+ func strIsTitle (f * Frame , args Args , kwargs KWArgs ) (* Object , * BaseException ) {
419+ if raised := checkMethodArgs (f , "istitle" , args , StrType ); raised != nil {
420+ return nil , raised
421+ }
422+
423+ s := toStrUnsafe (args [0 ]).Value ()
424+ if len (s ) == 0 {
425+ return False .ToObject (), nil
426+ }
427+
428+ if len (s ) == 1 {
429+ return GetBool (isUpper (s [0 ])).ToObject (), nil
430+ }
431+
432+ cased := false
433+ previousIsCased := false
434+
435+ for i := range s {
436+ if isUpper (s [i ]) {
437+ if previousIsCased {
438+ return False .ToObject (), nil
439+ }
440+ previousIsCased = true
441+ cased = true
442+ } else if isLower (s [i ]) {
443+ if ! previousIsCased {
444+ return False .ToObject (), nil
445+ }
446+ previousIsCased = true
447+ cased = true
448+ } else {
449+ previousIsCased = false
450+ }
451+ }
452+
453+ return GetBool (cased ).ToObject (), nil
454+ }
455+
456+ func strIsUpper (f * Frame , args Args , kwargs KWArgs ) (* Object , * BaseException ) {
457+ if raised := checkMethodArgs (f , "isupper" , args , StrType ); raised != nil {
458+ return nil , raised
459+ }
460+ s := toStrUnsafe (args [0 ]).Value ()
461+ if len (s ) == 0 {
462+ return False .ToObject (), nil
463+ }
464+ for i := range s {
465+ if ! isUpper (s [i ]) {
466+ return False .ToObject (), nil
467+ }
468+ }
469+ return True .ToObject (), nil
470+ }
471+
386472func strJoin (f * Frame , args Args , _ KWArgs ) (* Object , * BaseException ) {
387473 if raised := checkMethodArgs (f , "join" , args , StrType , ObjectType ); raised != nil {
388474 return nil , raised
@@ -807,9 +893,9 @@ func strSwapCase(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
807893 }
808894 b := make ([]byte , numBytes )
809895 for i := 0 ; i < numBytes ; i ++ {
810- if s [i ] >= 'a' && s [ i ] <= 'z' {
896+ if isLower ( s [i ]) {
811897 b [i ] = toUpper (s [i ])
812- } else if s [i ] >= 'A' && s [ i ] <= 'Z' {
898+ } else if isUpper ( s [i ]) {
813899 b [i ] = toLower (s [i ])
814900 } else {
815901 b [i ] = s [i ]
@@ -828,6 +914,10 @@ func initStrType(dict map[string]*Object) {
828914 dict ["isalnum" ] = newBuiltinFunction ("isalnum" , strIsAlNum ).ToObject ()
829915 dict ["isalpha" ] = newBuiltinFunction ("isalpha" , strIsAlpha ).ToObject ()
830916 dict ["isdigit" ] = newBuiltinFunction ("isdigit" , strIsDigit ).ToObject ()
917+ dict ["islower" ] = newBuiltinFunction ("islower" , strIsLower ).ToObject ()
918+ dict ["isspace" ] = newBuiltinFunction ("isspace" , strIsSpace ).ToObject ()
919+ dict ["istitle" ] = newBuiltinFunction ("istitle" , strIsTitle ).ToObject ()
920+ dict ["isupper" ] = newBuiltinFunction ("isupper" , strIsUpper ).ToObject ()
831921 dict ["join" ] = newBuiltinFunction ("join" , strJoin ).ToObject ()
832922 dict ["lower" ] = newBuiltinFunction ("lower" , strLower ).ToObject ()
833923 dict ["lstrip" ] = newBuiltinFunction ("lstrip" , strLStrip ).ToObject ()
@@ -1119,12 +1209,12 @@ func strTitle(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
11191209 for i := 0 ; i < numBytes ; i ++ {
11201210 c := s [i ]
11211211 switch {
1122- case s [ i ] >= 'a' && s [ i ] <= 'z' :
1212+ case isLower ( c ) :
11231213 if ! previousIsCased {
11241214 c = toUpper (c )
11251215 }
11261216 previousIsCased = true
1127- case s [ i ] >= 'A' && s [ i ] <= 'Z' :
1217+ case isUpper ( c ) :
11281218 if previousIsCased {
11291219 c = toLower (c )
11301220 }
@@ -1174,14 +1264,14 @@ func init() {
11741264}
11751265
11761266func toLower (b byte ) byte {
1177- if b >= 'A' && b <= 'Z' {
1267+ if isUpper ( b ) {
11781268 return b + caseOffset
11791269 }
11801270 return b
11811271}
11821272
11831273func toUpper (b byte ) byte {
1184- if b >= 'a' && b <= 'z' {
1274+ if isLower ( b ) {
11851275 return b - caseOffset
11861276 }
11871277 return b
@@ -1192,13 +1282,30 @@ func isAlNum(c byte) bool {
11921282}
11931283
11941284func isAlpha (c byte ) bool {
1195- return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
1285+ return isUpper ( c ) || isLower ( c )
11961286}
11971287
11981288func isDigit (c byte ) bool {
11991289 return '0' <= c && c <= '9'
12001290}
12011291
1292+ func isLower (c byte ) bool {
1293+ return 'a' <= c && c <= 'z'
1294+ }
1295+
1296+ func isSpace (c byte ) bool {
1297+ switch c {
1298+ case ' ' , '\n' , '\t' , '\v' , '\f' , '\r' :
1299+ return true
1300+ default :
1301+ return false
1302+ }
1303+ }
1304+
1305+ func isUpper (c byte ) bool {
1306+ return 'A' <= c && c <= 'Z'
1307+ }
1308+
12021309// strLeftPad returns s padded with fillchar so that its length is at least width.
12031310// Fillchar must be a single character. When fillchar is "0", s starting with a
12041311// sign are handled correctly.
0 commit comments