Files
open-simh.simtools/extracters/ods2/winfile.c
Timothe Litt 66e00b9900 Backlog of work since 2016
Too much to list all, but includes (in no particular order):
 - Cleanup for 64-bit builds, MSVC warnings.
 - Structured help
 - Help file compiler.
 - Supports volsets, writes/create work.
 - Support for I18n in messages, help.
 - Makefiles.
 - Initialize volume/volset
 - Command line editing/history

Builds and works on Linux and Windows (VS).
Not recently built or tested on other platforms, but
not intentinonally broken.
2022-10-10 11:00:20 -04:00

184 lines
4.5 KiB
C

/* This is part of ODS2 written by Paul Nankervis,
* email address: Paulnank@au1.ibm.com
* ODS2 is distributed freely for all members of the
* VMS community to use. However all derived works
* must maintain comments in their source to acknowledge
* the contributions of the original author and
* subsequent contributors. This is free software; no
* warranty is offered, and while we believe it to be useful,
* you use it at your own risk.
*/
/* Copyright (C) 2016 Timothe Litt, litt at acm dot org.
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <windows.h>
#include "winfile.h"
typedef struct globlist_ {
struct globlist_ *next;
char path[1];
} globlist_;
/******************************************************************* addfile() */
static int addfile( int flags, glob_t *pglob, const char *path ) {
size_t n, ofs;
char ** nl;
globlist_ *fp;
ofs = pglob->gl_pathc;
if( flags & GLOB_DOOFFS )
ofs += pglob->gl_offs;
if( (nl = (char **)realloc( pglob->gl_pathv,
(ofs + 2) * sizeof( char **) )) == NULL ) {
return GLOB_NOSPACE;
}
pglob->gl_pathv = nl;
n = offsetof( globlist_, path ) + strlen( path ) + 1;
if( (fp = malloc( n )) == NULL )
return GLOB_NOSPACE;
memcpy( fp->path, path, n - offsetof( globlist_, path ) );
pglob->gl_pathv[ofs++] = fp->path;
pglob->gl_pathv[ofs] = NULL;
++pglob->gl_pathc;
fp->next = pglob->list_;
pglob->list_ = fp;
return 0;
}
/******************************************************************* globfree() */
void globfree( glob_t *pglob ) {
globlist_ *fp;
while( (fp = pglob->list_) != NULL ) {
pglob->list_ = fp->next;
free( fp );
}
free( pglob->gl_pathv );
pglob->gl_pathv = NULL;
pglob->gl_pathc = 0;
}
/******************************************************************* cmpglb() */
static int cmpglb( const void *p1, const void *p2 ) {
return _stricmp( *((const char *const *)p1),
*((const char *const *)p2) );
}
/******************************************************************* glob() */
int glob( const char *pattern, int flags,
int (*errfunc)( const char *epath, int eerrno ),
glob_t *pglob ) {
HANDLE hfindfile;
WIN32_FIND_DATAA finddata;
int err;
size_t found;
if( errfunc != NULL )
abort();
found =
err = 0;
if( !(flags & GLOB_APPEND) ) {
pglob->gl_pathc = 0;
pglob->list_ = NULL;
pglob->gl_pathv = NULL;
}
hfindfile = FindFirstFileA( pattern, &finddata );
if( hfindfile == INVALID_HANDLE_VALUE ) {
if( flags & GLOB_NOCHECK ) {
err = addfile( flags, pglob, pattern );
found ++;
}
} else {
do {
err = addfile( flags, pglob, finddata.cFileName );
found++;
} while( !err && FindNextFile( hfindfile, &finddata ) );
FindClose( hfindfile );
}
if( !found )
err = GLOB_NOMATCH;
if( err ) {
globfree( pglob );
errno = err;
} else {
if( !(flags & GLOB_NOSORT) ) {
qsort( pglob->gl_pathv, pglob->gl_pathc,
sizeof( char **), cmpglb );
}
}
return err;
}
/******************************************************************* strlcpy() */
static size_t strlcpy( char *dst, const char *src, size_t size ) {
size_t srclen;
size--;
srclen = strlen( src );
if( srclen > size )
srclen = size;
memcpy( dst, src, srclen );
dst[srclen] = '\0';
return (srclen);
}
/******************************************************************* winbasename() */
char *winbasename( char *path ) {
static char buf[MAX_PATH + 1];
char *p, *d;
if( path == NULL || !*path )
return ".";
strlcpy( buf, path, sizeof( buf ) );
for( d = buf; *d && *d != ':' && *d != '\\'; d++ )
;
if( !*d )
return buf;
if( *d == ':' ) {
d++;
if( !strcmp( d, "." ) )
return buf;
}
for( p = d + strlen( d ) - 1; p > d; p-- )
if( *p == '\\' )
*p = '\0';
else
break;
if( p <= d ) {
if( !*++d )
return "\\";
return d;
}
if( (p = strrchr( d, '\\' )) == NULL ) {
return d;
}
return ++p;
}