1 /* Native functions for string operations. 2 3 Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk> 4 5 This program is free software; you can redistribute it and/or modify it under 6 the terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3 of the License, or (at your option) any later 8 version. 9 10 This program is distributed in the hope that it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 13 details. 14 15 You should have received a copy of the GNU General Public License along with 16 this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <string.h> /* strcmp, strncpy, strlen */ 20 #include "native/common.h" 21 #include "types.h" 22 #include "exceptions.h" 23 #include "ops.h" 24 #include "progconsts.h" 25 #include "progops.h" 26 #include "progtypes.h" 27 #include "main.h" 28 29 /* String operations. */ 30 31 __attr __fn_native_str_str_add(__attr __args[]) 32 { 33 __attr * const _data = &__args[1]; 34 __attr * const other = &__args[2]; 35 /* _data, other interpreted as string */ 36 char *s = _data->strvalue; 37 char *o = other->strvalue; 38 int n = strlen(s) + strlen(o) + 1; 39 char *r = (char *) __ALLOCATE(n, sizeof(char)); 40 41 strncpy(r, s, n); 42 strncpy(r + strlen(s), o, n - strlen(s)); /* should null terminate */ 43 44 /* Return a new string. */ 45 return __new_str(r); 46 } 47 48 __attr __fn_native_str_str_lt(__attr __args[]) 49 { 50 __attr * const _data = &__args[1]; 51 __attr * const other = &__args[2]; 52 /* _data, other interpreted as string */ 53 char *s = _data->strvalue; 54 char *o = other->strvalue; 55 56 /* NOTE: Using simple byte-level string operations. */ 57 return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False; 58 } 59 60 __attr __fn_native_str_str_gt(__attr __args[]) 61 { 62 __attr * const _data = &__args[1]; 63 __attr * const other = &__args[2]; 64 /* _data, other interpreted as string */ 65 char *s = _data->strvalue; 66 char *o = other->strvalue; 67 68 /* NOTE: Using simple byte-level string operations. */ 69 return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False; 70 } 71 72 __attr __fn_native_str_str_eq(__attr __args[]) 73 { 74 __attr * const _data = &__args[1]; 75 __attr * const other = &__args[2]; 76 /* _data, other interpreted as string */ 77 char *s = _data->strvalue; 78 char *o = other->strvalue; 79 80 /* NOTE: Using simple byte-level string operations. */ 81 return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False; 82 } 83 84 __attr __fn_native_str_str_len(__attr __args[]) 85 { 86 __attr * const _data = &__args[1]; 87 /* _data interpreted as string */ 88 char *s = _data->strvalue; 89 90 /* Return the new integer. */ 91 return __new_int(strlen(s)); 92 } 93 94 __attr __fn_native_str_str_nonempty(__attr __args[]) 95 { 96 __attr * const _data = &__args[1]; 97 /* _data interpreted as string */ 98 char *s = _data->strvalue; 99 100 return strlen(s) ? __builtins___boolean_True : __builtins___boolean_False; 101 } 102 103 __attr __fn_native_str_str_ord(__attr __args[]) 104 { 105 __attr * const _data = &__args[1]; 106 /* _data interpreted as string */ 107 char *s = _data->strvalue; 108 109 return __new_int((unsigned int) s[0]); 110 } 111 112 __attr __fn_native_str_str_substr(__attr __args[]) 113 { 114 __attr * const _data = &__args[1]; 115 __attr * const start = &__args[2]; 116 __attr * const size = &__args[3]; 117 /* _data interpreted as string */ 118 char *s = _data->strvalue, *sub; 119 /* start.__data__ interpreted as int */ 120 int i = __load_via_object(start->value, __pos___data__).intvalue; 121 /* size.__data__ interpreted as int */ 122 int l = __load_via_object(size->value, __pos___data__).intvalue; 123 124 /* Reserve space for a new string. */ 125 sub = (char *) __ALLOCATE(l + 1, sizeof(char)); 126 strncpy(sub, s + i, l); /* does not null terminate but final byte should be zero */ 127 return __new_str(sub); 128 } 129 130 /* Module initialisation. */ 131 132 void __main_native_str() 133 { 134 }