/* -*- Mode: C; c-file-style:"gnu"; indent-tabs-mode:nil -*-
   scandir.c -- if scandir() is missing, make a replacement
   Created: Petter Reinholdtsen <pere@td.org.uit.no>, 1998-03-24
*/
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1998, 1999 The Hungry Programmers

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "nspr.h"
#include "plstr.h"
#include "compat.h"

/*
 * XXX This is a simple hack version which doesn't sort the data, and
 * just passes all unsorted.
 */

int
Scandir(const char *dir, PRDirEntry ***namelist,
        int (*select)(const PRDirEntry*),
        int (*compar)(const void *, const void *))
{
  PRDir *d = PR_OpenDir(dir);
  PRDirEntry *current;
  PRDirEntry **names;
  int count = 0;
  int pos = 0;
  int error = 0;

  if (NULL == d)
    return -1;

  while (NULL != PR_ReadDir(d, PR_SKIP_NONE)) count++;

  names = PR_MALLOC(sizeof(PRDirEntry) * count);

  PR_CloseDir(d);
  d = PR_OpenDir(dir);
  if (NULL == d)
    return -1;

  while (NULL != (current = PR_ReadDir(d, PR_SKIP_NONE))) {
    if ( NULL == select || select(current) ) {
      PRDirEntry *copyentry = PR_MALLOC(sizeof(PRDirEntry));
      if (copyentry == NULL) {
        error = -1;
        break;
      }
      copyentry->name = PL_strdup(current->name);
      if (copyentry->name == NULL) {
        error = -1;
        break;
      }

      names[pos] = copyentry;
      pos++;
    }
  }
  PR_CloseDir(d);
  if (error) {
    PR_DELETE(names);
    return -1;
  }

  if (pos != count)
    names = PR_REALLOC(names, sizeof(struct dirent *)*pos);

  *namelist = names;

  return pos;
}
