/**
***  IPDial - Vsscanf.c
***
***  This file implements a function very similar to sscanf().
***
***
***  This program is free software; you can redistribute it and/or modify
***  it under the terms of the GNU General Public License as published by
***  the Free Software Foundation; either version 2 of the License, or
***  (at your option) any later version.
***
***  This program is distributed in the hope that it will be useful,
***  but WITHOUT ANY WARRANTY; without even the implied warranty of
***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
***  GNU General Public License for more details.
***
***  You should have received a copy of the GNU General Public License
***  along with this program; if not, write to the Free Software
***  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***
***  Authors: Jochen Wiedmann <wiedmann@neckar-alb.de>
***           Stefan Gybas <cab@studbox.uni-stuttgart.de>
**/




/**
***  Include files
**/
#ifndef IPDIAL_H
#include "IPDial.h"
#endif
#include <ctype.h>




/**
***  Scan the character buf for a string like %} and terminate it
***  with a '\0'. Return the pointer after %}
**/
STRPTR ReadWord(STRPTR buf, UBYTE c)

{ while(*buf)
  { if (*buf == '%')
    { char *ptr;

      if (buf[1] == c)
      { *buf = '\0';
        return(buf+2);
      }

      ptr = (char*) buf;
      while (ptr[1])
      { *ptr = ptr[1];
        ++ptr;
      }
      *ptr = '\0';
    }
    else
    { ++buf;
    }
  }
  return(buf);
}


/**
***  This is a function very similar to sscanf: A buffer is scanned
***  according to a format string.
***
***  The format string is interpreted as follows:
***
***     - The sequence %{WORD%} means any number of characters until the
***       word WORD is found. (Use %% to include the character '%'
***       into WORD itself.
***     - A blank means any number (including 0) and kind (blank, tab,
***       return, line feed, form feed) of white space characters.
***     - The sequence %[VAR%]%(SUFFIX%) means to store the following
***       white space separated word into the environment variable VAR.
***       The optional SUFFIX will be removed, if it is present.
***
***  Other characters are simply ignored.
***
***  The function returns the number of environment variables created.
**/
LONG Vsscanf(STRPTR buffer, STRPTR format, ULONG flags)

{ char *buf, *fmt;
  int result;

  /*  Copy strings, so that we can modify them. */
  if (!(buf = strdup((char*) buffer))  ||
      !(fmt = strdup((char*) format)))
  { PrintError(0, "not enough memory");
  }
  buffer = (STRPTR) buf;
  format = (STRPTR) fmt;

  result = 0;
  while (*fmt  &&  *buf)
  { if (isspace(*fmt))
    { while (isspace(*buf))
      { ++buf;
      }
      ++fmt;
    }
    else if (*fmt == '%')
    { ++fmt;
      if (*fmt == '{')
      { char *word;
        int len;

        /* Read word to match    */
        word = fmt+1;
        fmt = (char*) ReadWord((STRPTR) word, '}');
        len = strlen(word);

        /*  Word read, look into buffer  */
        if (!len)
        { continue;
        }

        while (*buf  &&  strncmp(buf, word, len) != 0)
        { ++buf;
        }
        if (*buf)
        { buf += len;
        }
      }
      else if (*fmt == '[')
      { char *var, *val, *suffix;

        /*  Read variable name.     */
        var = fmt+1;
        fmt = (char*) ReadWord((STRPTR) var, ']');

        /*  Read suffix             */
        if (strncmp(fmt, "%(", 2) == 0)
        { suffix = fmt+2;
          fmt = (char*) ReadWord((STRPTR) suffix, ')');
        }
        else
        { suffix = "";
        }

        /*  Read next word from buffer  */
        val = buf;
        while (*buf  &&  !isspace(*buf))
        { ++buf;
        }
        if (*buf)
        { *buf = '\0';
          ++buf;
        }

        /*  Check for suffix            */
        if (strlen(suffix) < strlen(val)  &&
            strcmp(val + strlen(val) - strlen(suffix), suffix) == 0)
        { val[strlen(val) - strlen(suffix)] = '\0';
        }

        /*  Set environment variable    */
        if (*var)
        { if (VerboseMode)
          { fprintf(stderr, "Setting environment variable %s to value %s.\n",
                    var, val);
          }
          if (!SetVar((STRPTR) var, (STRPTR) val, -1, LV_VAR | flags))
          { fprintf(stderr, "Error while setting environment variable %s to value %s.\n",
                    var, val);
          }
          ++result;
        }
      }
      else
      { /*  Ignore this character.    */
        ++fmt;
      }
    }
    else
    { ++fmt;     /*  Ignore this character   */
    } 
  }

  free(buffer);
  free(format);

  return(result);
}
