string_intrinsics.c [plain text]
#include <stdlib.h>
#include <string.h>
#include "libgfortran.h"
#define copy_string prefix(copy_string)
void copy_string (GFC_INTEGER_4, char *, GFC_INTEGER_4, const char *);
#define concat_string prefix(concat_string)
void concat_string (GFC_INTEGER_4, char *,
GFC_INTEGER_4, const char *,
GFC_INTEGER_4, const char *);
#define string_len_trim prefix(string_len_trim)
GFC_INTEGER_4 string_len_trim (GFC_INTEGER_4, const char *);
#define adjustl prefix(adjustl)
void adjustl (char *, GFC_INTEGER_4, const char *);
#define adjustr prefix(adjustr)
void adjustr (char *, GFC_INTEGER_4, const char *);
#define string_index prefix(string_index)
GFC_INTEGER_4 string_index (GFC_INTEGER_4, const char *, GFC_INTEGER_4,
const char *, GFC_LOGICAL_4);
#define string_scan prefix(string_scan)
GFC_INTEGER_4 string_scan (GFC_INTEGER_4, const char *, GFC_INTEGER_4,
const char *, GFC_LOGICAL_4);
#define string_verify prefix(string_verify)
GFC_INTEGER_4 string_verify (GFC_INTEGER_4, const char *, GFC_INTEGER_4,
const char *, GFC_LOGICAL_4);
#define string_trim prefix(string_trim)
void string_trim (GFC_INTEGER_4 *, void **, GFC_INTEGER_4, const char *);
#define string_repeat prefix(string_repeat)
void string_repeat (char *, GFC_INTEGER_4, const char *, GFC_INTEGER_4);
void
copy_string (GFC_INTEGER_4 destlen, char * dest,
GFC_INTEGER_4 srclen, const char * src)
{
if (srclen >= destlen)
{
memmove (dest, src, destlen);
}
else
{
memmove (dest, src, srclen);
memset (&dest[srclen], ' ', destlen - srclen);
}
}
GFC_INTEGER_4
compare_string (GFC_INTEGER_4 len1, const char * s1,
GFC_INTEGER_4 len2, const char * s2)
{
int res;
const char *s;
int len;
res = strncmp (s1, s2, (len1 < len2) ? len1 : len2);
if (res != 0)
return res;
if (len1 == len2)
return 0;
if (len1 < len2)
{
len = len2 - len1;
s = &s2[len1];
res = -1;
}
else
{
len = len1 - len2;
s = &s1[len2];
res = 1;
}
while (len--)
{
if (*s != ' ')
{
if (*s > ' ')
return res;
else
return -res;
}
s++;
}
return 0;
}
void
concat_string (GFC_INTEGER_4 destlen, char * dest,
GFC_INTEGER_4 len1, const char * s1,
GFC_INTEGER_4 len2, const char * s2)
{
if (len1 >= destlen)
{
memcpy (dest, s1, destlen);
return;
}
memcpy (dest, s1, len1);
dest += len1;
destlen -= len1;
if (len2 >= destlen)
{
memcpy (dest, s2, destlen);
return;
}
memcpy (dest, s2, len2);
memset (&dest[len2], ' ', destlen - len2);
}
void
string_trim (GFC_INTEGER_4 * len, void ** dest, GFC_INTEGER_4 slen, const char * src)
{
int i;
for (i = slen - 1; i >= 0; i--)
{
if (src[i] != ' ')
break;
}
*len = i + 1;
if (*len > 0)
{
*dest = internal_malloc (*len);
memmove (*dest, src, *len);
}
}
GFC_INTEGER_4
string_len_trim (GFC_INTEGER_4 len, const char * s)
{
int i;
for (i = len - 1; i >= 0; i--)
{
if (s[i] != ' ')
break;
}
return i + 1;
}
GFC_INTEGER_4
string_index (GFC_INTEGER_4 slen, const char * str, GFC_INTEGER_4 sslen,
const char * sstr, GFC_LOGICAL_4 back)
{
int start;
int last;
int i;
int delta;
if (sslen == 0)
return 1;
if (!back)
{
last = slen + 1 - sslen;
start = 0;
delta = 1;
}
else
{
last = -1;
start = slen - sslen;
delta = -1;
}
i = 0;
for (; start != last; start+= delta)
{
for (i = 0; i < sslen; i++)
{
if (str[start + i] != sstr[i])
break;
}
if (i == sslen)
return (start + 1);
}
return 0;
}
void
adjustl (char *dest, GFC_INTEGER_4 len, const char *src)
{
int i;
i = 0;
while (i<len && src[i] == ' ')
i++;
if (i < len)
memcpy (dest, &src[i], len - i);
if (i > 0)
memset (&dest[len - i], ' ', i);
}
void
adjustr (char *dest, GFC_INTEGER_4 len, const char *src)
{
int i;
i = len;
while (i > 0 && src[i - 1] == ' ')
i--;
if (i < len)
memset (dest, ' ', len - i);
memcpy (dest + (len - i), src, i );
}
GFC_INTEGER_4
string_scan (GFC_INTEGER_4 slen, const char * str, GFC_INTEGER_4 setlen,
const char * set, GFC_LOGICAL_4 back)
{
int start;
int last;
int i;
int delta;
if (slen == 0 || setlen == 0)
return 0;
if (back)
{
last = 0;
start = slen - 1;
delta = -1;
}
else
{
last = slen - 1;
start = 0;
delta = 1;
}
i = 0;
for (; start != last; start += delta)
{
for (i = 0; i < setlen; i++)
{
if (str[start] == set[i])
return (start + 1);
}
}
return 0;
}
GFC_INTEGER_4
string_verify (GFC_INTEGER_4 slen, const char * str, GFC_INTEGER_4 setlen,
const char * set, GFC_LOGICAL_4 back)
{
int start;
int last;
int i;
int delta;
if (slen == 0)
return 0;
if (back)
{
last = 0;
start = slen - 1;
delta = -1;
}
else
{
last = slen - 1;
start = 0;
delta = 1;
}
i = 0;
for (; start != last; start += delta)
{
for (i = 0; i < setlen; i++)
{
if (str[start] == set[i])
break;
}
if (i == setlen)
return (start + 1);
}
return 0;
}
void
string_repeat (char * dest, GFC_INTEGER_4 slen,
const char * src, GFC_INTEGER_4 ncopies)
{
int i;
if (ncopies < 0)
{
runtime_error ("Augument NCOPIES is negative.");
}
for (i = 0; i < ncopies; i++)
{
memmove (dest + (i * slen), src, slen);
}
}