/*
** string.h
*/
     
void /*@alt void* @*/ memcpy (/*@unique@*/ /*@returned@*/ /*@out@*/ void *s1, void *s2, size_t n) 
  /*@modifies *s1@*/
  /*@requires maxRead(s2) >= (n - 1) /\ maxSet(s1) >= (n - 1); @*/ ;

void /*@alt void* @*/ memmove (/*@returned@*/ /*@out@*/ void *s1, void *s2, size_t n)
  /*@modifies *s1@*/
  /*@requires maxRead(s2) >= (n - 1) /\ maxSet(s1) >= (n - 1); @*/ ;
  
void /*@alt char * @*/ strcpy (/*@unique@*/ /*@out@*/ /*@returned@*/ char *s1, char *s2) 
  /*@modifies *s1@*/ 
  /*@requires maxSet(s1) >= maxRead(s2) @*/
  /*@ensures maxRead(s1) == maxRead (s2) /\ maxRead(result) == maxRead(s2) /\ maxSet(result) == maxSet(s1); @*/;

void /*@alt char * @*/ strncpy (/*@unique@*/ /*@out@*/ /*@returned@*/ char *s1, char *s2, size_t n) 
  /*@modifies *s1@*/ 
  /*@requires maxSet(s1) >= (n - 1); @*/
  /*@ensures maxRead (s2) >= maxRead(s1) /\ maxRead (s1) <= n; @*/ ; 

void /*@alt char * @*/ strcat (/*@unique@*/ /*@returned@*/ char *s1, char *s2) 
  /*@modifies *s1@*/
  /*@requires maxSet(s1) >= (maxRead(s1) + maxRead(s2));@*/
  /*@ensures maxRead(result) == (maxRead(s1) + maxRead(s2) );@*/;

void /*@alt char * @*/ strncat (/*@unique@*/ /*@returned@*/ char *s1, char *s2, size_t n)
  /*@modifies *s1@*/ 
  /*@requires maxSet(s1) >= ( maxRead(s1) + n); @*/
  /*@ensures maxRead(s1) >= (maxRead(s1) + n); @*/;

int memcmp (void *s1, void *s2, size_t n) /*@*/ ;
int strcmp (char *s1, char *s2) /*@*/ ;
int strcoll (char *s1, char *s2) /*@*/ ;
int strncmp (char *s1, char *s2, size_t n) /*@*/ ;
size_t strxfrm (/*@out@*/ /*@null@*/ char *s1, char *s2, size_t n) 
  /*@modifies *s1@*/ ;  /* s1 may be null only if n == 0 */ 

/*@null@*/ void *memchr (void *s, int c, size_t n) /*@*/ ;

/*@exposed@*/ /*@null@*/
char * strchr (/*@returned@*/ char *s, int
# ifndef STRICT
    /*@alt char@*/
# endif
    c)
  /*@*/
  /*@ensures maxSet(result) >= 0 /\ maxSet(result) <= maxSet(s) /\
             maxRead (result) <= maxRead(s) /\ maxRead(result) >= 0 @*/ ;

size_t strcspn (char *s1, char *s2) /*@*/ ;
/*@null@*/ /*@exposed@*/ char *
  strpbrk (/*@returned@*/ char *s, char *t) /*@*/ ;

/*@null@*/ /*@exposed@*/
char * strrchr (/*@returned@*/ char *s, int
# ifndef STRICT
    /*@alt char@*/
# endif
    c)
  /*@*/
  /*@ensures maxSet(result) >= 0 /\ maxSet(result) <= maxSet(s) /\
             maxRead (result) <= maxRead(s) /\ maxRead(result) >= 0 @*/ ;

size_t strspn (char *s, char *t) /*@*/ ;

/*@null@*/ /*@exposed@*/
char * strstr (/*@returned@*/ const char *s, const char *t) /*@*/
  /*@ensures maxSet(result) >= 0 /\ maxSet(result) <= maxSet(s) /\
             maxRead (result) <= maxRead(s) /\ maxRead(result) >= 0 /\
             maxRead(result) >= maxRead(t) /\ maxSet(result) >= maxRead(t)@*/ ;

/*@null@*/ /*@exposed@*/
char * strtok (/*@returned@*/ /*@null@*/ char *s, char *t)
  /*@modifies *s, internalState, errno@*/ ;

void * memset (/*@out@*/ /*@returned@*/ void *s, int c, size_t n)
  /*@modifies *s@*/
  /*@requires maxSet(s) >= (n - 1) @*/
  /*@ensures maxRead(s) >= (n - 1) @*/ ;

/*@observer@*/
char *strerror (int errnum) /*@*/ ;

size_t strlen (char *s) /*@*/
  /*@ensures result == maxRead(s); @*/; 

# ifdef POSIX
/*@null@*/ /*@only@*/
char *strdup (const char *s) /*@*/ ;
# endif

# ifdef UNIX
int strerror_r (int errnum, /*@out@*/ char *strerrbuf, int buflen)
  /*@modifies strerrbuf@*/ ;

void /*@alt void * @*/ 
  memccpy (/*@returned@*/ /*@out@*/ void *s1, 
	   /*@unique@*/ void *s2, int c, size_t n) 
  /*@modifies *s1@*/ ;

/* stpcpy and stpncpy are found on linux but don't seem to be present on other
   unixes; this function is like strcpy but it returns a pointer to the null
   terminated character in dest instead of the beginning of dest */
char * stpcpy(/*@out@*/ /*@returned@*/ char * dest, const char * src)
  /*@modifies *dest @*/
  /*@requires maxSet(dest) >= maxRead(src) @*/
  /*@ensures MaxRead(dest) == MaxRead (src) /\ MaxRead(result) == 0 /\ MaxSet(result) == ( maxSet(dest) - MaxRead(src) ); @*/;

char * stpncpy(/*@out@*/ /*@returned@*/ char * dest,
  const char * src, size_t n)
  /*@modifies *dest @*/
  /*@requires MaxSet(dest) >= ( n - 1 ); @*/
  /*@ensures MaxRead (src) >= MaxRead(dest) /\ MaxRead (dest) <= n; @*/ ; 

# endif

