Browse Source

header-only issues in gcc, separated implementation

master
surkeh 5 years ago
parent
commit
ba6418ea33
  1. 2
      Makefile
  2. 114
      include/Borland.h
  3. 52
      include/FileAttributes.h
  4. 169
      src/Borland.c
  5. 108
      src/FileAttributes.c

2
Makefile

@ -6,7 +6,7 @@ TESTDIR=test @@ -6,7 +6,7 @@ TESTDIR=test
CFLAGS=-std=c++11 -I"$(INC)"
tester: $(TESTDIR)/test.cpp
$(CC) $^ $(CFLAGS) -o $(TESTEX) -lboost_unit_test_framework
$(CC) $^ src/FileAttributes.c src/Borland.c $(CFLAGS) -o $(TESTEX) -lboost_unit_test_framework
cp $(TESTEX) .git/hooks/pre-commit

114
include/Borland.h

@ -61,104 +61,11 @@ @@ -61,104 +61,11 @@
* Argument: char *, Returns extension component, if not NULL and dir was found
* =====================================================================================
*/
inline int fnsplit(const char *path,
int fnsplit(const char *path,
char *drive,
char *dir,
char *name,
char *ext)
{
int i = 0; // for loop iterator set after drive letter, if needed
int flags = 0;
if (path != NULL) {
// Code using fnsplit suggests first char of all return args is set to NULL
// (Undocumented behavior, could be sample code misusing fnsplit)
if (drive != NULL)
drive[0] = '\0';
if (dir != NULL)
dir[0] = '\0';
if (name != NULL)
name[0] = '\0';
if (ext != NULL)
ext[0] = '\0';
// Check for character denoting drive letter
if (path[1] == ':') {
flags |= DRIVE;
if (drive != NULL) {
strncat (drive, path, 2);
drive[2] = '\0';
}
i = 2;
}
// path not necessarily terminated by \0
// parse char by char
char token[MAXPATH];
int iToken = 0;
for ( ; i < MAXPATH; i++) {
// if delimiter, act accordingly
// token is part of the directory
if (path[i] == '/' || path[i] == '\\') {
token[iToken++] = path[i];
token[iToken++] = '\0';
flags |= DIRECTORY;
if (dir != NULL)
strcat (dir, token);
iToken = 0;
continue;
}
// token is name
else if (path[i] == '.') {
token[iToken] = '\0';
if (flags & FILENAME) {
flags |= EXTENSION;
if (ext != NULL)
strcat (ext, token);
}
else {
flags |= FILENAME;
if (name != NULL)
strcpy (name, token);
}
token[0] = '.';
iToken = 1;
continue;
}
// token is name or extension
else if (path[i] == '\0'
|| i >= MAXPATH - 1 ) {
//|| extCount >= MAXEXT - 1) {
if (flags & FILENAME) {
// is extension
token[iToken] = '\0';
flags |= EXTENSION;
if (ext != NULL)
strcat (ext, token);
// all parts gathered, exit function
break;
}
else {
// is name
token[iToken] = '\0';
flags |= FILENAME;
if (name != NULL)
strcpy (name, token);
// all parts gathered, exit
break;
}
}
else {
//if not delimiter, build string
token[iToken++] = path[i];
}
}
}
return flags;
}
char *ext);
/*
@ -177,22 +84,7 @@ inline void fnmerge (char *path, @@ -177,22 +84,7 @@ inline void fnmerge (char *path,
const char *drive,
const char *dir,
const char *name,
const char *ext)
{
if (path == NULL)
return;
path[0] = '\0';
if (drive != NULL)
strcat (path, drive);
if (dir != NULL)
strcat (path, dir);
if (name != NULL)
strcat (path, name);
if (ext != NULL)
strcat (path, ext);
}
const char *ext);
#endif //PORTLIBC_BORLAND_H

52
include/FileAttributes.h

@ -78,15 +78,7 @@ typedef struct FileTimePortable { @@ -78,15 +78,7 @@ typedef struct FileTimePortable {
* Returns: int, 0 if success, negative value if failed
* =====================================================================================
*/
inline int isPosixTime(time_t t)
{
time_t now;
time(&now);
if(t > UNIX_EPOCH && t <= now)
return 0;
else
return -1;
}
int isPosixTime(time_t t);
/*
* === FUNCTION ======================================================================
@ -95,14 +87,7 @@ inline int isPosixTime(time_t t) @@ -95,14 +87,7 @@ inline int isPosixTime(time_t t)
* Returns: time_t, translated FileTimePortable to equivalent time_t
* =====================================================================================
*/
inline time_t convertToPosixTime (FileTimePortable windowsTime)
{
uint64_t ticks = windowsTime.dwHighDateTime;
ticks = ticks << 32;
ticks |= windowsTime.dwLowDateTime;
return (time_t)( ticks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH );
}
time_t convertToPosixTime (FileTimePortable windowsTime);
/*
* === FUNCTION ======================================================================
@ -111,15 +96,7 @@ inline time_t convertToPosixTime (FileTimePortable windowsTime) @@ -111,15 +96,7 @@ inline time_t convertToPosixTime (FileTimePortable windowsTime)
* Returns: FileTimePortable, struct of same size and structure as FILETIME
* =====================================================================================
*/
inline FileTimePortable convertToFileTime (time_t posixTime)
{
uint64_t winTime = WINDOWS_TICK * (uint64_t)(posixTime + SEC_TO_UNIX_EPOCH);
FileTimePortable fileTime;
uint32_t highBytes = winTime >> 32;
fileTime.dwHighDateTime = highBytes;
fileTime.dwLowDateTime = winTime; // just 32 lower bits
return fileTime;
}
FileTimePortable convertToFileTime (time_t posixTime);
/*
* === FUNCTION ======================================================================
@ -128,20 +105,7 @@ inline FileTimePortable convertToFileTime (time_t posixTime) @@ -128,20 +105,7 @@ inline FileTimePortable convertToFileTime (time_t posixTime)
* Returns: uint32_t, Windows attributes bitvector
* =====================================================================================
*/
inline uint32_t convertToWindowsAttributes(uint32_t posixMode)
{
uint32_t readAccess =
posixMode & ( POSIX_RUSR | POSIX_RGRP | POSIX_ROTH );
uint32_t writeAccess =
posixMode & ( POSIX_WUSR | POSIX_WGRP | POSIX_WOTH );
uint32_t executeAccess =
posixMode & ( POSIX_XUSR | POSIX_XGRP | POSIX_XOTH );
if (readAccess != 0 && writeAccess == 0 && executeAccess == 0)
return FILE_ATTRIBUTE_READONLY;
else
return FILE_ATTRIBUTE_NORMAL;
}
uint32_t convertToWindowsAttributes(uint32_t posixMode);
/*
* === FUNCTION ======================================================================
@ -150,13 +114,7 @@ inline uint32_t convertToWindowsAttributes(uint32_t posixMode) @@ -150,13 +114,7 @@ inline uint32_t convertToWindowsAttributes(uint32_t posixMode)
* Returns: uint32_t, mode_t bitvector
* =====================================================================================
*/
inline uint32_t convertToPosixAttributes(uint32_t windowsAttributes)
{
if (windowsAttributes & FILE_ATTRIBUTE_READONLY)
return POSIX_READONLY;
else
return POSIX_NORMAL;
}
uint32_t convertToPosixAttributes(uint32_t windowsAttributes);

169
src/Borland.c

@ -0,0 +1,169 @@ @@ -0,0 +1,169 @@
/*
* =====================================================================================
*
* Filename: Borland.c
*
* Description: Various Borland function replacements
*
* Version: 1.0
* Created: 08/24/2017 10:00:40 PM
* Revision: none
* Compiler: gcc
*
* Author: surkeh@protonmail.com
*
* =====================================================================================
*/
#include "Borland.h"
/*
* === FUNCTION ======================================================================
* Name: fnsplit
* Description: Separates a path into components
* NOTE: Does not handle wildcard * due to shell handling this in Linux
* Return: int, bitflags of what components were found in path, NULL args included
* Argument: const char *, Valid Windows/Posix path
* Argument: char *, Returns drive component, if not NULL and drive was found
* Argument: char *, Returns directory component, if not NULL and dir was found
* Argument: char *, Returns file name component, if not NULL and dir was found
* Argument: char *, Returns extension component, if not NULL and dir was found
* =====================================================================================
*/
int fnsplit(const char *path,
char *drive,
char *dir,
char *name,
char *ext)
{
int i = 0; // for loop iterator set after drive letter, if needed
int flags = 0;
if (path != NULL) {
// Code using fnsplit suggests first char of all return args is set to NULL
// (Undocumented behavior, could be sample code misusing fnsplit)
if (drive != NULL)
drive[0] = '\0';
if (dir != NULL)
dir[0] = '\0';
if (name != NULL)
name[0] = '\0';
if (ext != NULL)
ext[0] = '\0';
// Check for character denoting drive letter
if (path[1] == ':') {
flags |= DRIVE;
if (drive != NULL) {
strncat (drive, path, 2);
drive[2] = '\0';
}
i = 2;
}
// path not necessarily terminated by \0
// parse char by char
char token[MAXPATH];
int iToken = 0;
for ( ; i < MAXPATH; i++) {
// if delimiter, act accordingly
// token is part of the directory
if (path[i] == '/' || path[i] == '\\') {
token[iToken++] = path[i];
token[iToken++] = '\0';
flags |= DIRECTORY;
if (dir != NULL)
strcat (dir, token);
iToken = 0;
continue;
}
// token is name
else if (path[i] == '.') {
token[iToken] = '\0';
if (flags & FILENAME) {
flags |= EXTENSION;
if (ext != NULL)
strcat (ext, token);
}
else {
flags |= FILENAME;
if (name != NULL)
strcpy (name, token);
}
token[0] = '.';
iToken = 1;
continue;
}
// token is name or extension
else if (path[i] == '\0'
|| i >= MAXPATH - 1 ) {
//|| extCount >= MAXEXT - 1) {
if (flags & FILENAME) {
// is extension
token[iToken] = '\0';
flags |= EXTENSION;
if (ext != NULL)
strcat (ext, token);
// all parts gathered, exit function
break;
}
else {
// is name
token[iToken] = '\0';
flags |= FILENAME;
if (name != NULL)
strcpy (name, token);
// all parts gathered, exit
break;
}
}
else {
//if not delimiter, build string
token[iToken++] = path[i];
}
}
}
return flags;
}
/*
* === FUNCTION ======================================================================
* Name: fnmerge
* Description: Combines components into a path
* NOTE: Does not handle wildcard * due to shell handling this in Linux
* Argument: char *, Returns assembled path
* Argument: const char *, Drive component
* Argument: const char *, Directory component
* Argument: const char *, File name component
* Argument: const char *, Extension component
* =====================================================================================
*/
void fnmerge (char *path,
const char *drive,
const char *dir,
const char *name,
const char *ext)
{
if (path == NULL)
return;
path[0] = '\0';
if (drive != NULL)
strcat (path, drive);
if (dir != NULL)
strcat (path, dir);
if (name != NULL)
strcat (path, name);
if (ext != NULL)
strcat (path, ext);
}

108
src/FileAttributes.c

@ -0,0 +1,108 @@ @@ -0,0 +1,108 @@
/*
* =====================================================================================
*
* Filename: FileAttributes.h
*
* Description:
*
* Version: 3.0
* Created: 08/23/2017 02:36:05 PM
* Revision: none
* Compiler: gcc
*
* Author: surkeh@protonmail.com
*
* =====================================================================================
*/
#include "FileAttributes.h"
/*
* === FUNCTION ======================================================================
* Name: isPosixTime
* Description: Check if a 64-bit value is in a range of possible time_t values
* Returns: int, 0 if success, negative value if failed
* =====================================================================================
*/
int isPosixTime(time_t t)
{
time_t now;
time(&now);
if(t > UNIX_EPOCH && t <= now)
return 0;
else
return -1;
}
/*
* === FUNCTION ======================================================================
* Name: convertToPosixTime
* Description: Convert FILETIME to time_t
* Returns: time_t, translated FileTimePortable to equivalent time_t
* =====================================================================================
*/
time_t convertToPosixTime (FileTimePortable windowsTime)
{
uint64_t ticks = windowsTime.dwHighDateTime;
ticks = ticks << 32;
ticks |= windowsTime.dwLowDateTime;
return (time_t)( ticks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH );
}
/*
* === FUNCTION ======================================================================
* Name: convertToFileTime
* Description: Convert time_t to FILETIME
* Returns: FileTimePortable, struct of same size and structure as FILETIME
* =====================================================================================
*/
FileTimePortable convertToFileTime (time_t posixTime)
{
uint64_t winTime = WINDOWS_TICK * (uint64_t)(posixTime + SEC_TO_UNIX_EPOCH);
FileTimePortable fileTime;
uint32_t highBytes = winTime >> 32;
fileTime.dwHighDateTime = highBytes;
fileTime.dwLowDateTime = winTime; // just 32 lower bits
return fileTime;
}
/*
* === FUNCTION ======================================================================
* Name: convertToWindowsAttributes
* Description: Convert mode_t into Windows attributes type
* Returns: uint32_t, Windows attributes bitvector
* =====================================================================================
*/
uint32_t convertToWindowsAttributes(uint32_t posixMode)
{
uint32_t readAccess =
posixMode & ( POSIX_RUSR | POSIX_RGRP | POSIX_ROTH );
uint32_t writeAccess =
posixMode & ( POSIX_WUSR | POSIX_WGRP | POSIX_WOTH );
uint32_t executeAccess =
posixMode & ( POSIX_XUSR | POSIX_XGRP | POSIX_XOTH );
if (readAccess != 0 && writeAccess == 0 && executeAccess == 0)
return FILE_ATTRIBUTE_READONLY;
else
return FILE_ATTRIBUTE_NORMAL;
}
/*
* === FUNCTION ======================================================================
* Name: convertToPosixAttributes
* Description: Converts Windows attributes type into mode_t
* Returns: uint32_t, mode_t bitvector
* =====================================================================================
*/
uint32_t convertToPosixAttributes(uint32_t windowsAttributes)
{
if (windowsAttributes & FILE_ATTRIBUTE_READONLY)
return POSIX_READONLY;
else
return POSIX_NORMAL;
}
Loading…
Cancel
Save