added qse_stradup() and related functions

coded qse_dir_change() for win32
This commit is contained in:
hyung-hwan 2011-10-15 23:18:55 +00:00
parent 23ee1f7f51
commit 38500b97d6
8 changed files with 331 additions and 87 deletions

View File

@ -22,12 +22,17 @@
#define _QSE_CMN_PATH_H_ #define _QSE_CMN_PATH_H_
/** @file /** @file
* This file provides functions for simple path name manipulation. * This file provides functions for path name manipulation.
*/ */
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
/**
* The qse_basename() macro returns the pointer to the file name
* segment in a path name. It maps to qse_mbsbasename() if #QSE_CHAR_IS_MCHAR
* is defined; it maps to qse_wcsbasename() if #QSE_CHAR_IS_WCHAR is defined.
*/
#ifdef QSE_CHAR_IS_MCHAR #ifdef QSE_CHAR_IS_MCHAR
# define qse_basename(path) qse_mbsbasename(path) # define qse_basename(path) qse_mbsbasename(path)
#else #else
@ -38,26 +43,45 @@
extern "C" { extern "C" {
#endif #endif
/**
* The qse_mbsbasename() function returns the pointer to the file name
* segment in a multibyte path name.
*/
const qse_mchar_t* qse_mbsbasename ( const qse_mchar_t* qse_mbsbasename (
const qse_mchar_t* path const qse_mchar_t* path
); );
/**
* The qse_wcsbasename() function returns the pointer to the file name
* segment in a wide-character path name.
*/
const qse_wchar_t* qse_wcsbasename ( const qse_wchar_t* qse_wcsbasename (
const qse_wchar_t* path const qse_wchar_t* path
); );
/* /**
* The qse_canonpath() function deletes unnecessary path segments * The qse_canonpath() function canonicalizes a path name @a path by deleting
* from a path name 'path' and stores it to a memory buffer pointed * unnecessary path segments from it and stores the result to a memory buffer
* to by 'canon'. It null-terminates the canonical path in 'canon' and * pointed to by @a canon. Canonicalization is purely performed on the path
* returns the number of characters excluding the terminating null. * name without refering to actual file systems. It null-terminates the
* The caller must ensure that it is large enough before calling this * canonical path in @a canon and returns the number of characters excluding
* because this function does not check the size of the memory buffer. * the terminating null.
* Since the canonical path cannot be larger than the original path,
* you can simply ensure this by providing a memory buffer as long as
* the number of characters and a terminating null in the original path.
* *
* @return the number of characters in the resulting canonical path. * @code
* qse_char_t buf[64];
* qse_canonpath ("/usr/local/../bin/sh", buf);
* qse_printf (QSE_T("%s\n")); // prints /usr/bin/sh
* @endcode
*
* The caller must ensure that it is large enough to hold the resulting
* canonical path before calling because this function does not check the
* size of the memory buffer. Since the canonical path cannot be larger
* than the original path, you can simply ensure this by providing a memory
* buffer as long as the number of characters and a terminating null in
* the original path.
*
* @return number of characters in the resulting canonical path excluding
* the terminating null.
*/ */
qse_size_t qse_canonpath ( qse_size_t qse_canonpath (
const qse_char_t* path, const qse_char_t* path,

View File

@ -961,6 +961,11 @@ qse_mchar_t* qse_mbsxdup2 (
qse_mmgr_t* mmgr qse_mmgr_t* mmgr
); );
qse_mchar_t* qse_mbsadup (
const qse_mchar_t* str[],
qse_mmgr_t* mmgr
);
qse_wchar_t* qse_wcsdup ( qse_wchar_t* qse_wcsdup (
const qse_wchar_t* str, const qse_wchar_t* str,
qse_mmgr_t* mmgr qse_mmgr_t* mmgr
@ -986,16 +991,23 @@ qse_wchar_t* qse_wcsxdup2 (
qse_mmgr_t* mmgr qse_mmgr_t* mmgr
); );
qse_wchar_t* qse_wcsadup (
const qse_wchar_t* str[],
qse_mmgr_t* mmgr
);
#ifdef QSE_CHAR_IS_MCHAR #ifdef QSE_CHAR_IS_MCHAR
# define qse_strdup(s,mmgr) qse_mbsdup(s,mmgr) # define qse_strdup(s,mmgr) qse_mbsdup(s,mmgr)
# define qse_strdup2(s1,s2,mmgr) qse_mbsdup2(s1,s2,mmgr) # define qse_strdup2(s1,s2,mmgr) qse_mbsdup2(s1,s2,mmgr)
# define qse_strxdup(s,l,mmgr) qse_mbsxdup(s,l,mmgr) # define qse_strxdup(s,l,mmgr) qse_mbsxdup(s,l,mmgr)
# define qse_strxdup2(s1,l1,s2,l2,mmgr) qse_mbsxdup(s1,l1,s2,l2,mmgr) # define qse_strxdup2(s1,l1,s2,l2,mmgr) qse_mbsxdup(s1,l1,s2,l2,mmgr)
# define qse_stradup(sa,mmgr) qse_mbsadup(sa,mmgr)
#else #else
# define qse_strdup(s,mmgr) qse_wcsdup(s,mmgr) # define qse_strdup(s,mmgr) qse_wcsdup(s,mmgr)
# define qse_strdup2(s1,s2,mmgr) qse_wcsdup2(s1,s2,mmgr) # define qse_strdup2(s1,s2,mmgr) qse_wcsdup2(s1,s2,mmgr)
# define qse_strxdup(s,l,mmgr) qse_wcsxdup(s,l,mmgr) # define qse_strxdup(s,l,mmgr) qse_wcsxdup(s,l,mmgr)
# define qse_strxdup2(s1,l1,s2,l2,mmgr) qse_wcsxdup(s1,l1,s2,l2,mmgr) # define qse_strxdup2(s1,l1,s2,l2,mmgr) qse_wcsxdup(s1,l1,s2,l2,mmgr)
# define qse_stradup(sa,mmgr) qse_wcsadup(sa,mmgr)
#endif #endif
/** /**

View File

@ -24,8 +24,6 @@
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
typedef struct qse_dir_ent_t qse_dir_ent_t;
struct qse_dir_ent_t struct qse_dir_ent_t
{ {
enum enum
@ -38,8 +36,18 @@ struct qse_dir_ent_t
QSE_DIR_ENT_BLOCK, QSE_DIR_ENT_BLOCK,
QSE_DIR_ENT_LINK QSE_DIR_ENT_LINK
} type; } type;
qse_foff_t size; qse_foff_t size;
const qse_char_t* name; qse_char_t* name;
};
typedef struct qse_dir_ent_t qse_dir_ent_t;
struct qse_dir_t
{
QSE_DEFINE_COMMON_FIELDS (dir)
qse_dir_ent_t ent;
qse_char_t* curdir;
void* info;
}; };
typedef struct qse_dir_t qse_dir_t; typedef struct qse_dir_t qse_dir_t;
@ -52,14 +60,22 @@ QSE_DEFINE_COMMON_FUNCTIONS (dir)
qse_dir_t* qse_dir_open ( qse_dir_t* qse_dir_open (
qse_mmgr_t* mmgr, qse_mmgr_t* mmgr,
qse_size_t xtnsize, qse_size_t xtnsize
const qse_char_t* name
); );
void qse_dir_close ( void qse_dir_close (
qse_dir_t* dir qse_dir_t* dir
); );
int qse_dir_init (
qse_dir_t* dir,
qse_mmgr_t* mmgr
);
void qse_dir_fini (
qse_dir_t* dir
);
qse_dir_ent_t* qse_dir_read ( qse_dir_ent_t* qse_dir_read (
qse_dir_t* dir qse_dir_t* dir
); );

View File

@ -21,16 +21,21 @@
#include <qse/cmn/path.h> #include <qse/cmn/path.h>
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
# define ISMSEP(c) ((c) == QSE_MT('/') || (c) == QSE_MT('\\'))
# define ISWSEP(c) ((c) == QSE_WT('/') || (c) == QSE_WT('\\'))
#else
# define ISMSEP(c) ((c) == QSE_MT('/'))
# define ISWSEP(c) ((c) == QSE_WT('/'))
#endif
const qse_mchar_t* qse_mbsbasename (const qse_mchar_t* path) const qse_mchar_t* qse_mbsbasename (const qse_mchar_t* path)
{ {
const qse_mchar_t* p, * last = QSE_NULL; const qse_mchar_t* p, * last = QSE_NULL;
for (p = path; *p != QSE_MT('\0'); p++) for (p = path; *p != QSE_MT('\0'); p++)
{ {
if (*p == QSE_MT('/')) last = p; if (ISMSEP(*p)) last = p;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
else if (*p == QSE_MT('\\')) last = p;
#endif
} }
return (last == QSE_NULL)? path: (last + 1); return (last == QSE_NULL)? path: (last + 1);
@ -42,10 +47,7 @@ const qse_wchar_t* qse_wcsbasename (const qse_wchar_t* path)
for (p = path; *p != QSE_WT('\0'); p++) for (p = path; *p != QSE_WT('\0'); p++)
{ {
if (*p == QSE_WT('/')) last = p; if (ISWSEP(*p)) last = p;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
else if (*p == QSE_WT('\\')) last = p;
#endif
} }
return (last == QSE_NULL)? path: (last + 1); return (last == QSE_NULL)? path: (last + 1);

View File

@ -72,6 +72,27 @@ qse_mchar_t* qse_mbsxdup2 (
return tmp; return tmp;
} }
qse_mchar_t* qse_mbsadup (const qse_mchar_t* str[], qse_mmgr_t* mmgr)
{
qse_mchar_t* buf, * ptr;
qse_size_t i;
qse_size_t capa = 0;
QSE_ASSERT (mmgr != QSE_NULL);
for (i = 0; str[i]; i++) capa += qse_mbslen(str[i]);
buf = (qse_mchar_t*) QSE_MMGR_ALLOC (mmgr, (capa+1)*QSE_SIZEOF(*buf));
if (buf == QSE_NULL) return QSE_NULL;
ptr = buf;
for (i = 0; str[i]; i++) ptr += qse_mbscpy (ptr, str[i]);
return buf;
}
/* --------------------------------------------------------------- */
qse_wchar_t* qse_wcsdup (const qse_wchar_t* str, qse_mmgr_t* mmgr) qse_wchar_t* qse_wcsdup (const qse_wchar_t* str, qse_mmgr_t* mmgr)
{ {
qse_wchar_t* tmp; qse_wchar_t* tmp;
@ -124,3 +145,23 @@ qse_wchar_t* qse_wcsxdup2 (
qse_wcsncpy (tmp + len1, str2, len2); qse_wcsncpy (tmp + len1, str2, len2);
return tmp; return tmp;
} }
qse_wchar_t* qse_wcsadup (const qse_wchar_t* str[], qse_mmgr_t* mmgr)
{
qse_wchar_t* buf, * ptr;
qse_size_t i;
qse_size_t capa = 0;
QSE_ASSERT (mmgr != QSE_NULL);
for (i = 0; str[i]; i++) capa += qse_wcslen(str[i]);
buf = (qse_wchar_t*) QSE_MMGR_ALLOC (mmgr, (capa+1)*QSE_SIZEOF(*buf));
if (buf == QSE_NULL) return QSE_NULL;
ptr = buf;
for (i = 0; str[i]; i++) ptr += qse_wcscpy (ptr, str[i]);
return buf;
}

View File

@ -19,35 +19,36 @@
*/ */
#include <qse/fs/dir.h> #include <qse/fs/dir.h>
#include "../cmn/mem.h"
#include <qse/cmn/str.h> #include <qse/cmn/str.h>
#include <qse/cmn/path.h>
#include "../cmn/mem.h"
#if defined(_WIN32) #if defined(_WIN32)
# include <windows.h> # include <windows.h>
#elif defined(__OS2__)
# error NOT IMPLEMENTED
#elif defined(__DOS__)
# error NOT IMPLEMENTED
#else
# include <sys/types.h>
# include <dirent.h>
#endif #endif
struct qse_dir_t typedef struct info_t info_t;
struct info_t
{ {
QSE_DEFINE_COMMON_FIELDS (dir) qse_xstr_t name;
qse_dir_ent_t ent;
#if defined(_WIN32) #if defined(_WIN32)
HANDLE handle; HANDLE handle;
WIN32_FIND_DATA wfd; WIN32_FIND_DATA wfd;
int no_more_files; int no_more_files;
#else
#endif #endif
}; };
QSE_IMPLEMENT_COMMON_FUNCTIONS (dir) QSE_IMPLEMENT_COMMON_FUNCTIONS (dir)
int qse_dir_init (qse_dir_t* dir, qse_mmgr_t* mmgr, const qse_char_t* name); qse_dir_t* qse_dir_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
void qse_dir_fini (qse_dir_t* dir);
qse_dir_t* qse_dir_open (
qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_char_t* name)
{ {
qse_dir_t* dir; qse_dir_t* dir;
@ -61,10 +62,10 @@ qse_dir_t* qse_dir_open (
if (mmgr == QSE_NULL) return QSE_NULL; if (mmgr == QSE_NULL) return QSE_NULL;
} }
dir = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*dir)); dir = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*dir) + xtnsize);
if (dir == QSE_NULL) return QSE_NULL; if (dir == QSE_NULL) return QSE_NULL;
if (qse_dir_init (dir, mmgr, name) <= -1) if (qse_dir_init (dir, mmgr) <= -1)
{ {
QSE_MMGR_FREE (mmgr, dir); QSE_MMGR_FREE (mmgr, dir);
return QSE_NULL; return QSE_NULL;
@ -79,49 +80,184 @@ void qse_dir_close (qse_dir_t* dir)
QSE_MMGR_FREE (dir->mmgr, dir); QSE_MMGR_FREE (dir->mmgr, dir);
} }
int qse_dir_init (qse_dir_t* dir, qse_mmgr_t* mmgr, const qse_char_t* name) int qse_dir_init (qse_dir_t* dir, qse_mmgr_t* mmgr)
{ {
#if defined(_WIN32)
qse_char_t* dirname;
#endif
QSE_MEMSET (dir, 0, QSE_SIZEOF(*dir)); QSE_MEMSET (dir, 0, QSE_SIZEOF(*dir));
dir->mmgr = mmgr; dir->mmgr = mmgr;
return 0;
}
void qse_dir_fini (qse_dir_t* dir)
{
info_t* info = dir->info;
if (info)
{
if (info->name.ptr)
{
QSE_ASSERT (info->name.len > 0);
QSE_MMGR_FREE (dir->mmgr, info->name.ptr);
info->name.ptr = QSE_NULL;
info->name.len = 0;
}
#if defined(_WIN32) #if defined(_WIN32)
dirname = qse_strdup2 (name, QSE_T("\\*"), dir->mmgr); if (info->handle != INVALID_HANDLE_VALUE)
{
FindClose (info->handle);
info->handle = INVALID_HANDLE_VALUE;
}
#endif
QSE_MMGR_FREE (dir->mmgr, info);
dir->info = QSE_NULL;
}
if (dir->curdir)
{
QSE_MMGR_FREE (dir->mmgr, dir->curdir);
dir->curdir = QSE_NULL;
}
}
static int is_absolute (const qse_char_t* name)
{
if (name[0] == QSE_T('/')) return 1;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
if (name[0] == QSE_T('\\')) return 1;
if (((name[0] >= QSE_T('A') && name[0] <= QSE_T('Z')) ||
(name[0] >= QSE_T('a') && name[0] <= QSE_T('a'))) &&
name[1] == QSE_T(':')) return 1;
#endif
return 0;
}
int qse_dir_change (qse_dir_t* dir, const qse_char_t* name)
{
info_t* info = dir->info;
#if defined(_WIN32)
qse_char_t* dirname;
HANDLE handle;
WIN32_FIND_DATA wfd;
const qse_char_t* tmp_name[4];
qse_size_t idx;
#endif
if (name[0] == QSE_T('\0'))
{
/* dir->errnum = QSE_DIR_EINVAL; */
return -1;
}
/* TODO: if name is a relative path??? combine it with the current path
and canonicalize it to get the actual path */
if (info == QSE_NULL)
{
info = QSE_MMGR_ALLOC (dir->mmgr, QSE_SIZEOF(*info));
if (info == QSE_NULL) return -1;
QSE_MEMSET (info, 0, QSE_SIZEOF(*info));
#if defined(_WIN32)
info->handle = INVALID_HANDLE_VALUE;
#endif
dir->info = info;
}
#if defined(_WIN32)
idx = 0;
if (!is_absolute(name) && dir->curdir)
tmp_name[idx++] = dir->curdir;
tmp_name[idx++] = name;
tmp_name[idx++] = QSE_T("\\ ");
tmp_name[idx] = QSE_NULL;
dirname = qse_stradup (tmp_name, dir->mmgr);
if (dirname == QSE_NULL) if (dirname == QSE_NULL)
{ {
/* dir->errnum = QSE_DIR_ENOMEM; */ /* dir->errnum = QSE_DIR_ENOMEM; */
return -1; return -1;
} }
dir->handle = FindFirstFile (dirname, &dir->wfd);
QSE_MMGR_FREE (dir->mmgr, dirname);
if (dir->handle == INVALID_HANDLE_VALUE) idx = qse_canonpath (dirname, dirname);
/* Put the asterisk after canonicalization to prevent side-effects.
* otherwise, .\* would be transformed to * by qse_canonpath() */
dirname[idx-1] = QSE_T('*');
handle = FindFirstFile (dirname, &wfd);
if (handle == INVALID_HANDLE_VALUE)
{ {
/* dir->errnum = QSE_DIR_ESYSTEM; */
QSE_MMGR_FREE (dir->mmgr, dirname);
return -1; return -1;
} }
if (info->handle != INVALID_HANDLE_VALUE)
FindClose (info->handle);
QSE_MEMSET (info, 0, QSE_SIZEOF(*info));
info->handle = handle;
info->wfd = wfd;
if (dir->curdir) QSE_MMGR_FREE (dir->mmgr, dir->curdir);
dirname[idx-1] = QSE_T('\0'); /* drop the asterisk */
dir->curdir = dirname;
return 0; return 0;
#else #else
return -1; return -1;
#endif #endif
} }
void qse_dir_fini (qse_dir_t* dir) static int set_entry_name (qse_dir_t* dir, const qse_char_t* name)
{ {
#if defined(_WIN32) info_t* info = dir->info;
FindClose (dir->handle); qse_size_t len;
#endif
QSE_ASSERT (info != QSE_NULL);
len = qse_strlen (name);
if (len > info->name.len)
{
qse_char_t* tmp;
/* TOOD: round up len to the nearlest multiples of something (32, 64, ??)*/
tmp = QSE_MMGR_REALLOC (
dir->mmgr,
info->name.ptr,
(len + 1) * QSE_SIZEOF(*tmp)
);
if (tmp == QSE_NULL)
{
/* dir->errnum = QSE_DIR_ENOMEM; */
return -1;
}
info->name.len = len;
info->name.ptr = tmp;
}
qse_strcpy (info->name.ptr, name);
dir->ent.name = info->name.ptr;
return 0;
} }
qse_dir_ent_t* qse_dir_read (qse_dir_t* dir) qse_dir_ent_t* qse_dir_read (qse_dir_t* dir)
{ {
#if defined(_WIN32) info_t* info = dir->info;
if (dir->no_more_files) return QSE_NULL; if (info == QSE_NULL) return QSE_NULL;
if (dir->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) #if defined(_WIN32)
if (info->no_more_files)
{
/*
dir->errnum = QSE_DIR_ENOENT;
*/
return QSE_NULL;
}
if (info->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{ {
dir->ent.size = 0; dir->ent.size = 0;
dir->ent.type = QSE_DIR_ENT_DIRECTORY; dir->ent.type = QSE_DIR_ENT_DIRECTORY;
@ -129,19 +265,18 @@ qse_dir_ent_t* qse_dir_read (qse_dir_t* dir)
else else
{ {
LARGE_INTEGER li; LARGE_INTEGER li;
li.LowPart = dir->wfd.nFileSizeLow; li.LowPart = info->wfd.nFileSizeLow;
li.HighPart = dir->wfd.nFileSizeHigh; li.HighPart = info->wfd.nFileSizeHigh;
dir->ent.size = li.QuadPart; dir->ent.size = li.QuadPart;
dir->ent.type = QSE_DIR_ENT_UNKNOWN; dir->ent.type = QSE_DIR_ENT_UNKNOWN;
} }
// TODO: proper management... if (set_entry_name (dir, info->wfd.cFileName) <= -1) return QSE_NULL;
dir->ent.name = qse_strdup (dir->wfd.cFileName, dir->mmgr);
if (FindNextFile (dir->handle, &dir->wfd) == FALSE) if (FindNextFile (info->handle, &info->wfd) == FALSE)
{ {
/*if (GetLastError() == ERROR_NO_MORE_FILES) */ /*if (GetLastError() == ERROR_NO_MORE_FILES) */
dir->no_more_files = 1; info->no_more_files = 1;
} }
#endif #endif
@ -153,13 +288,3 @@ int qse_dir_rewind (qse_dir_t* dir)
return 0; return 0;
} }
#if 0
int qse_dir_change (qse_dir_t* dir, const qse_char_t* name)
{
#if defined(_WIN32)
qse_strxdup (dir->current,
#else
return -1;
#endif
}
#endif

View File

@ -16,16 +16,22 @@ int path_main (int argc, qse_char_t* argv[])
return -1; return -1;
} }
/*
canon = QSE_MMGR_ALLOC (QSE_MMGR_GETDFL(), (qse_strlen(argv[1]) + 1) * QSE_SIZEOF(*canon)); canon = QSE_MMGR_ALLOC (QSE_MMGR_GETDFL(), (qse_strlen(argv[1]) + 1) * QSE_SIZEOF(*canon));
if (canon == QSE_NULL) if (canon == QSE_NULL)
{ {
qse_fprintf (QSE_STDERR, QSE_T("Error: out of memory\n")); qse_fprintf (QSE_STDERR, QSE_T("Error: out of memory\n"));
return -1; return -1;
} }
len = qse_canonpath (argv[1], canon); len = qse_canonpath (argv[1], canon);
qse_printf (QSE_T("[%s] => [%s] %d chars\n"), argv[1], canon, (int)len); qse_printf (QSE_T("[%s] => [%s] %d chars\n"), argv[1], canon, (int)len);
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), canon); QSE_MMGR_FREE (QSE_MMGR_GETDFL(), canon);
*/
qse_printf (QSE_T("[%s] => "), argv[1]);
len = qse_canonpath (argv[1], argv[1]);
qse_printf (QSE_T("[%s] %d chars\n"), argv[1], (int)len);
return 0; return 0;
} }

View File

@ -3,24 +3,19 @@
#include <qse/cmn/stdio.h> #include <qse/cmn/stdio.h>
#include <qse/cmn/main.h> #include <qse/cmn/main.h>
int dir_main (int argc, qse_char_t* argv[]) static void list (qse_dir_t* dir, const qse_char_t* name)
{ {
int n;
qse_dir_t* dir;
qse_dir_ent_t* ent; qse_dir_ent_t* ent;
if (argc != 2) if (qse_dir_change (dir, name) <= -1)
{ {
qse_fprintf (QSE_STDERR, QSE_T("Usage: %s <directory>\n"), argv[0]); qse_fprintf (QSE_STDERR, QSE_T("Error: Cannot change directory to %s\n"), name);
return -1; return;
} }
dir = qse_dir_open (QSE_NULL, 0, argv[1]); qse_printf (QSE_T("----------------------------------------------------------------\n"), dir->curdir);
if (dir == QSE_NULL) qse_printf (QSE_T("CURRENT DIRECTORY: [%s]\n"), dir->curdir);
{ qse_printf (QSE_T("----------------------------------------------------------------\n"), dir->curdir);
qse_fprintf (QSE_STDERR, QSE_T("Error: Cannot open directory\n"), argv[1]);
return -1;
}
do do
{ {
@ -34,6 +29,29 @@ int dir_main (int argc, qse_char_t* argv[])
} }
while (1); while (1);
}
int dir_main (int argc, qse_char_t* argv[])
{
int n;
qse_dir_t* dir;
if (argc != 2)
{
qse_fprintf (QSE_STDERR, QSE_T("Usage: %s <directory>\n"), argv[0]);
return -1;
}
dir = qse_dir_open (QSE_NULL, 0);
if (dir == QSE_NULL)
{
qse_fprintf (QSE_STDERR, QSE_T("Error: Cannot open directory\n"), argv[1]);
return -1;
}
list (dir, argv[1]);
list (dir, QSE_T(".."));
qse_dir_close (dir); qse_dir_close (dir);
return n; return n;
} }