Module : standard

<module title="Standard functions of Unibase"
        author="Jurjen Stellingwerff"
        revision="20010419"
        URL="www.unibase.org">
Include this module to get access to the standard types and functions of
unibase.
<sub title="Future developments">
More different type handling functions. Including display layout strings.
These should also cover the handling of date and time layout.
Also functions for find and replace within texts.
A seperate module 'math' should contain the mathematical functions and types.
<list heading="Known bugs">
<item name="Text handling functions">The text handling is not perfect. Especially
the functions on fields don't work as they should. A new text type should get a
copy of the text and not the same pointer.
</list>

<import module="stdtype"/>
<include file="system"/>
<include file="unistd"/>
<include file="time"/>
<include file="sys/time"/>
<import module="dbase"/>

<sub title="String handling functions">

<routine name="fromhex" use="Gets a hexedecimal value out of a string"
   type="number" use="the number or 0 when nothing was found"
   parameter="hex" type="constr" use="the string is totally scanned for numbers" system>
  long int n;
  int t;
  n=0;
  if (v_hex==0) return 0;
  for(t=0; t< strlen(v_hex); t++)
  { if (isdigit(v_hex[t])) n=n*16+v_hex[t]-'0';
    else n=n*16+v_hex[t]-'A'+10;
  }
  return n;
</routine>

<routine name="tohex" use="Creates a string with a hexedecimal value"
     type="string" use="the string or a null when too big or below zero"
     parameter="num" type="number" use="the none negative number"
     system>
  char *r=0;
  char ch[2];
  int t;
  ch[1]=0;
  if (v_num<0 || v_num>0xfffffff) return 0;
  for(t=0; t<7; t++)
  { long int n=v_num % 16;
    v_num = v_num/16;
    if (v_num==0 && n==0) break;
    if (n>9) ch[0]=n+'A'-10;
    else ch[0]=n+'0';
    r=sadd(scpy(ch), r);
  }
  return r;
</routine>

<routine name="ascii" use="Get the acsii value of the first character of the string"
     type="number" use="the found ascii value of -1 when string was null"  
     parameter="str" type="string" use="a string, only the first character is relevant"
     system>
  if (v_str==0) return -1;
  return v_str[0];
</routine>

<routine name="char" use="Creates a string with a single character"
     type="constr" use="the string"
     parameter="ascii" type="number" use="the ascii-number of the character"
     system>
  static char ch[2];
  ch[0]=v_ascii;
  ch[1]=0;
  return ch;
</routine>

<routine name="findstring" use="Find a substring within another string"
     type="number" use="the found position or 0 when nothing is found"
     parameter="haystack" type="constr" use="the string to search in"
     parameter="needle" type="constr" use="the string to search for"
     parameter="from" type="number" default="1" use="the starting position to search from"
     system>
  char *result;
  if (v_haystack==0 || v_needle==0) return -1;
  if (v_from<0) v_from=0;
  if (v_from>strlen(v_haystack)) v_from=strlen(v_haystack)+1;
  result=strstr(v_haystack+v_from-1, v_needle);
  if (result==0) return -1;
  return (((long int)result) - ((long int)v_haystack))+1;
</routine>

<routine name="pattern" type="constr"
   parameter="pattern" type="string"
   parameter="times" type="number" system>
  long int t;
  char *r=0;
  for (t=0; t < v_times; t++) r=scon(r, v_pattern);
  return r;
</routine>

<routine name="left" use="Get the leftmost part of a string"
     type="string" use="the return string or an empty string when length=0"
     parameter="string" type="constr" use="the source string"
     parameter="length" type="number" use="number of characters to get from the string"
     system>
  char *r;
  if (v_string==0) return 0;
  if (v_length>(long int)strlen(v_string)) v_length=strlen(v_string);
  if (v_length<1 || v_string==0)
  { r=scpy("");
  } else
  { r=malloc(v_length+1);
    strncpy(r, v_string, v_length);
    r[v_length]=0;
  }
  return r;
</routine>

<routine name="right" use="Get the rightmost part of a string"
     type="string" use="the return string or an empty string when length=0"
     parameter="string" type="constr" use="the source string"
     parameter="length" type="number" use="number of characters to get from the string"
     system>
  char *r;
  if (v_string==0) return 0;
  if (v_length>(long int)strlen(v_string)) v_length=strlen(v_string);
  if (v_length<0 || v_string==0) r=scpy("");
  else r=scpy(v_string+(strlen(v_string)-v_length));
  return r;
</routine>

<routine name="mid" use="Get a subsection from a string"
     type="string" use="the return string or and empty string when length=0"
     parameter="string" type="constr" use="the source string"
     parameter="position" type="number" use="the position to start getting characters from"
     parameter="length" type="number" default="99999" use="the maximum length of the return string"
     system>
  char *r;
  if (v_length<1 || v_position>(long int)strlen(v_string)) return 0;
  if (v_length+v_position>(long int)strlen(v_string)) v_length=1+strlen(v_string)-v_position;
  r=malloc(v_length+1);
  strncpy(r, v_string+(v_position-1), v_length);
  r[v_length]=0;
  return r;
</routine>

<routine name="trim" use="Trim the spaces from the start and the end of a string"
         type="string" use="return string or null when str doesn't exist"
         parameter="str" type="constr" use="the source string"
 system>
  int f;
  int t;
  if (v_str==0) return 0;
  f=1;
  while (v_str[f-1]==' ' || v_str[f-1]==10 || v_str[f-1]==13 || v_str[f-1]==9) f++;
  t=strlen(v_str);
  while (t>=f && (v_str[t-1]==' ' || v_str[t-1]==10 || v_str[t-1]==13 || v_str[t-1]==9)) t--;
  return rtn_mid(v_str, f, t-f+1);
</routine>

<routine name="lefttrim" use="Trim the leading spaces from a string"
         type="string" use="the resulting string or null when str doesn't exist"
         parameter="str" type="constr" use="the source string"
 system>
  int f;
  int t;
  f=1;
  if (v_str==0) return 0;
  while (v_str[f-1]==' ' || v_str[f-1]==10 || v_str[f-1]==13 || v_str[f-1]==9) f++;
  t=strlen(v_str);
  return rtn_mid(v_str, f, t-f+1);
</routine>

<routine name="righttrim" use="Trim the trailing spaces from a string"
         type="string" use="the resulting string or null when str doesn't exist"
         parameter="str" type="constr" use="the source string"
 system>
  int f;
  int t;
  if (v_str==0) return 0;
  f=1;
  t=strlen(v_str);
  while (t>1 && (v_str[t-1]==' ' || v_str[t-1]==10 || v_str[t-1]==13 || v_str[t-1]==9)) t--;
  return rtn_mid(v_str, f, t-f+1);
</routine>

<routine name="uppercase" use="Converts a string to only uppercase characters"
         type="string" use="the resulting string"
         parameter="str" type="constr" use="the source string"
 system>
  long int p;
  char *r;
  if (v_str==0) return 0;
  r=scpy(v_str);
  for(p=0; p< strlen(r); p++) r[p]=toupper(r[p]);
  return r;
</routine>

<routine name="lowercase" use="Converts a string to only lowercase characters"
         type="string" use="the resulting string"
         parameter="str" type="constr" use="the source string"
 system>
  long int p;
  char *r=scpy(v_str);
  for(p=0; p< strlen(r); p++) r[p]=tolower(r[p]);
  return r;
</routine>

<routine name="length" use="Get the length of a string"
     type="number" use="the length or 0 when it is null"
     parameter="string" type="constr" use="the source string"
     system>
  if (v_string==0) return 0;
  return strlen(v_string);
</routine>

<routine name="isalpha" use="Check if a string has only alphabetical characters"
   type="boolean"
   parameter="string" type="constr" system>
  int p=0;
  if (v_string==0 || strlen(v_string)==0) return (1==0);
  while (v_string[p]!=0)
  { if (!isalpha(v_string[p])) return (1==0);
    p++;
  }
  return (1==1);
</routine>

<routine name="isnumber" type="boolean"
   parameter="string" type="constr" system>
  int p=0;
  if (v_string==0 || strlen(v_string)==0) return (1==0);
  while (v_string[p]!=0)
  { if (!isdigit(v_string[p])) return (1==0);
    p++;
  }
  return (1==1);
</routine>

<sub title="File handling functions">

<routine name="open" use="Open a file for reading"
     type="stream" use="a stream or null when in error"
     parameter="file" type="constr" use="the name of the file to open"
     system>
  FILE *n=fopen(v_file, "r+");
  return n;
</routine>

<routine name="close" use="Closes a stream"
     parameter="stream" type="stream" use="the stream to close"
     system>
  if (v_stream>0) fclose(v_stream);
</routine>

<routine name="write" use="Write data to a stream"
  parameter="data" type="number" use="the data to write"
  parameter="stream" type="stream" use="the stream to write to"
  system>
  if (v_stream==0) return;
  fwrite(&v_data, 4, 1, v_stream);
</routine>

<routine name="write" use="Write data to a stream"
  parameter="data" type="text" use="the data to write"
  parameter="stream" type="stream" use="the stream to write to"
  system>
  if (v_stream==0) return;
  fwrite(&v_data.len, 4, 1, v_stream);
  fwrite(v_data.ptr, v_data.len, 1, v_stream);
</routine>

<routine name="read" use="Read data from a stream"
  type="number" use="the found number of null if nothing is found"
  parameter="stream" type="stream" use="the stream to read"
  system>
  long int r=0;
  if (v_stream==0 || feof(v_stream)) return null;
  fread(&r, 4, 1, v_stream);
  return r;
</routine>

<routine name="readtext" use="Read text from a stream"
  type="text" use="the found text or null if nothing is found"
  parameter="stream" type="stream" use="the stream to read"
  system>
  struct text t;
  if (v_stream==0 || feof(v_stream)) {t.len=0; t.ptr=0; return t;}
  fread(&t.len, 4, 1, v_stream);
  if (t.len>0 && !feof(v_stream)) 
  { t.ptr=malloc(t.len+1); 
    fread(&t.ptr, t.len, 1, v_stream);
    t.ptr[t.len]=0;
  } else
  { t.len=0;
    t.ptr=0;
  }
  return t;
</routine>

<routine name="get" use="Gets a single character from a stream"
     type="constr" use="a string or a null when nothing found"
     parameter="stream" type="stream" use="the stream to read"
     system>
  int i=-1;
  static char ch[2];
  if (((long int)v_stream)==null) return 0;
  if (v_stream>0) i=fgetc(v_stream);
  if (v_stream==0 || i<0) return 0;
  ch[0]=i;
  ch[1]=0;
  return ch;
</routine>

<routine name="input" use="Read a line of text from a stream"
     type="string" use="The read string or null if the end of the file is reached"
     parameter="from" type="stream" default="stdin" use="the stream to read"
     system>
  int ch;
  char s[2];
  char *r=0;
  if (v_from==0) v_from=stdin;
  ch=fgetc(v_from);
  s[1]=0;
  while (ch!=10 && ch!=-1)
  { s[0]=ch;
    r=scon(r, s);
    ch=fgetc(v_from);
  }
  return r;
</routine>

<routine name="eof" use="Determin the end of the stream"
   type="boolean" use="True is end of file found"
   parameter="str" type="stream" use="the current stream" system>
  return (v_str==0)?(1==1):(feof(v_str)!=0);
</routine>

<routine name="append" use="Open a stream to write to the end of it"
     type="stream" use="the stream or null when in error"
     parameter="file" type="constr" use="the name of the file"
     system>
  FILE *n=fopen(v_file, "a+");
  return n;
</routine>

<routine name="create" use="Creates a new file with a stream to write to"
     type="stream" use="the stream or null when in error"
     parameter="file" type="constr" use="the name of the file"
     system>
  FILE *n=fopen(v_file, "w");
  return n;
</routine>

<routine name="seek" use="Place the filepointer to a specific position"
   parameter="str" type="stream" use="the stream to change"
   parameter="pos" type="number" use="the position to move to"
   system>
  fseek(v_str, v_pos, SEEK_SET);
</routine>

<routine name="flush" use="Flush the buffers used with this stream"
   parameter="str" type="stream" default="stdout" use="the stream to flush"
   system>
  if (v_str==0) v_str=stdout;
  fflush(v_str);
</routine>

<sub title="System functions">

<routine name="shell"  use="Issue a command to the current shell"
     type="[OK Error]" use="return value of the statement"
     parameter="command" type="constr" use="the command to perform"
     system>
  char *argv[4];
  argv[0]="sh";
  argv[1]="-c";
  argv[2]=v_command;
  argv[3]=0;
  if (execvp("/bin/sh", argv)==-1) return 2;
  return 1;
</routine>

<routine name="getstring" use="Get a specific string from a array of strings"
  type="constr" use="the found string not defined for too high values of 'pos'"
  parameter="sarray" type="strings" use="an array of strings like the parameters of a program"
  parameter="pos" type="number" use="the number of the string to get"
  system>
  if (v_pos<1) return 0;
  return v_sarray[v_pos-1];
</routine>

<routine name="getenv" use="Get the value of a spefic environment variable"
  type="constr" use="Returns the found variable or null when not found"
  parameter="variable" type="constr" use="the variable to find" system>
  char *s=getenv(v_variable);
  return s;
</routine>

<routine name="random" use="Get a random number"
  type="number" use="The found number" system>
  return random();
</routine>

<routine name="initiate" use="Feed a random seed" system>
  struct timeval tv;
  struct timezone tz;
  gettimeofday(&tv, &tz);
  srandom((int)(tv.tv_usec/100));
</routine>

<routine name="curtime" use="Get the current time of day"
  type="time" use="the time of day in hundreth of seconds" system>
  return time(0);
</routine>

<routine name="showtime" use="Show the time"
  type="string" use="the time in readable form"
  parameter="time" type="time" system>
 return rtn_trim(ctime(&v_time));
</routine>

<routine name="check" use="Check the contence of two variables"
   type="byte" use="If first parameter is lower: -1, when equal 0: higher: 1"
   parameter="num1" type="number" use="first parameter"
   parameter="num2" type="number" use="second parameter"
   system>
  if (v_num1==v_num2) return 0;
  if (v_num1==null) return -1;
  if (v_num2==null) return 1;
  return (v_num1<v_num2)?-1:(v_num1>v_num2);
</routine>

<routine name="check" use="Same routine but now for comparation of strings"
   type="byte"
   parameter="str1" type="constr"
   parameter="str2" type="constr" system>
 if (v_str1==v_str2) return 0;
 if (v_str1==0) return -1;
 if (v_str2==0) return 1;
 return strcmp(v_str1, v_str2);
</routine>

<routine name="check" use="Same routine but now for comparation of pointers"
  type="byte"
  parameter="ptr1" type="pointer"
  parameter="ptr2" type="pointer" system>
 long int i1=v_ptr1.branch*4000+v_ptr1.leaf;
 long int i2=v_ptr2.branch*4000+v_ptr2.leaf;
 if (i1==i2) return 0;
 if (v_ptr1.branch==-1) return -1;
 if (v_ptr2.branch==-1) return 1;
 return (i1<i2)?-1:(i1>i2);
</routine>

<routine name="abs" use="Get the absolute value of a number"
   type="number"
   parameter="num" type="number" system>
 return (v_num<-1)?(-v_num):v_num;
</routine>

<routine name="newtext" use="Create a new text value"
  type="text" use="the text value"
  parameter="str" type="string" use="the once string" system>
  struct text t;
  if (v_str==0) {t.len=0; t.ptr=0; return t;}
  t.len=rtn_length(v_str);
  t.ptr=v_str;
  return t;
</routine>

<routine name="gettext" use="Get the string from a text"
  type="string" use="the string"
  parameter="text" type="text" use="the text" system>
  return v_text.ptr;
</routine>

<routine name="addtext" use="Adds texts together"
  type="text" use="the resulting text"
  parameter="first" type="text" use="the first text"
  parameter="second" type="text" use="the second text" system>
  struct text t;
  if (v_first.ptr==0) return v_second;
  if (v_second.ptr==0) return v_first;
  t.len=v_first.len+v_second.len;
  t.ptr=realloc(v_first.ptr, t.len+1);
  memcpy(t.ptr+v_first.len, v_second.ptr, v_second.len+1);
  free(v_second.ptr);
  return t;
</routine>

<routine name="nullpointer" use="Get a null pointer value"
  type="pointer" system>
  struct pointer res;
  res.branch=-1;
  res.leaf=-1;
  res.rec=-1;
  return res;
</routine>

<routine name="pause" use="Pauses the system till the next signal" system>
  pause();
</routine>
Copyright (C) 2001   Jurjen J. Stellingwerff