/*
 * gf.c
 *
 * Read directories in a buffered way
 *
 *  1998 Straylight/Edgeware
 */

/*----- Licensing note ----------------------------------------------------*
 *
 * This file is part of Straylight's core utilities (coreutils).
 *
 * Coreutils 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, or (at your option)
 * any later version.
 *
 * Coreutils 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 coreutils.  If not, write to the Free Software Foundation,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

/*----- Header files ------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "swis.h"
#include "swiv.h"

#include "gf.h"

/*----- Main code ---------------------------------------------------------*/

/* --- @gf_init@ --- *
 *
 * Arguments:	@gf_ctx *g@ = pointer to a context buffer for me
 *		@const char *pat@ = pointer to a (RISC OS) pattern string
 *		@cost char *dir@ = pointer to name of parent directory
 *
 * Returns:	---
 *
 * Use:		Initialise a wildcard match context ready for scanning.
 */

void gf_init(gf_ctx *g, const char *pat, const char *dir)
{
  g->ctx = 0;
  g->pat = pat;
  g->dir = dir;
  g->nleft = 0;
}

/* --- @gf_next@ --- *
 *
 * Arguments:	@gf_ctx *g@ = pointer to my context
 *
 * Returns:	Pointer to a filename, or zero for end
 *
 * Use:		Returns the next matching file from the block.
 */

char *gf_next(gf_ctx *g)
{
  /* --- See if the buffer is empty --- */

  while (!g->nleft) {

    /* --- Check for end of the list --- */

    if (g->ctx == -1)
      return (0);

    /* --- Fetch some more items from the list --- */

    g->p = g->buf;
    if (_swix(OS_GBPB, _inr(0, 6) | _out(3) | _out(4),
              9, g->dir, g->buf, 1024, g->ctx, sizeof(g->buf), g->pat,
              &g->nleft, &g->ctx))
      return (0);
  }

  /* --- Dole out the next item from the list --- */

  {
    char *p = g->p;

    while (*g->p)
      g->p++;
    g->p++;
    g->nleft--;
    return (p);
  }
}

/*----- That's all, folks -------------------------------------------------*/
