mirror of
https://github.com/open-simh/simtools.git
synced 2026-02-10 18:21:20 +00:00
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.
184 lines
4.5 KiB
C
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;
|
|
}
|