[go: up one dir, main page]

Skip to content

Commit

Permalink
Readd accidentally deleted files.
Browse files Browse the repository at this point in the history
  • Loading branch information
BlastBrothers authored Jul 8, 2024
1 parent 91900fc commit a451337
Show file tree
Hide file tree
Showing 7 changed files with 975 additions and 2,102 deletions.
200 changes: 200 additions & 0 deletions src/libc/arg_processing.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/* Complex argument processing for program invocation
Called from within crt0.src - see extract below
; Process the command line into argc & argv[]
; -------------------------------------------
;
; Parse the parameter string into a C array
; Parameters
; - HL: Address of parameter string (seems to be set by MOS at start of programme)
; - IX: Address for array pointer storage
; Returns:
; - C: Number of parameters parsed
;
; Only include conditionally if ___main_argc_argv is present
section .init.args
ifextern ___main_argc_argv
private _parse_params
_parse_params:
if HAS_ARG_PROCESSING ; if want to do complex arg processing
extern ___arg_processing
ld bc, _exec_name ; first value in argv is program name
ld (ix+0), bc
push ix
push hl
call ___arg_processing ; call a C function to do this
pop hl
pop hl
lb bc, 0 ; clear out top part of UBC
ld c, a
ret
*/

/*
Processes up to argv_ptrs_max values from zero terminated param_str
and stores the results in argv[]
Will need to allocated its own storage, at least in some instances, as can do wild card
expansion (TBD)
*/

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#define ARGV_PTRS_MAX 16 // this should align with the value defined in crt0.src

int __parse_args( char *param_str, char *argv[] );
int __check_redirect( int in_cnt, char *argv[] );
char *__get_redir_fname( char *s, char *t );
void __close_redir_files( void );

uint8_t __arg_processing( char *param_str, char *argv[] )
{
int cnt;

// puts( "Parameter processing including redirection." );
// puts( param_str );
cnt = __parse_args( param_str, argv );
cnt = __check_redirect( cnt, argv );
return (uint8_t)cnt;
}

// Parse the arguments from the command string, separating out
// - space separated and
// - quoted strings
// the strings are left in place with their locations in argv
// and zero terminated over the delimiter

int __parse_args( char *param_str, char *argv[] )
{
int cnt = 1;
char *s = param_str;
char delim = ' ';

// skip the leading spaces

while ( cnt < ARGV_PTRS_MAX ) {
while ( *s != '\0' && *s == delim ) s++;
if ( *s == '\0' ) return cnt;
if ( *s == '"' ) {
delim = '"';
s++;
}
argv[cnt++] = s;

// skip over the letters

while ( *s != '\0' && *s != delim ) s++;
if ( *s == '\0' ) return cnt;
if ( *s == '"' ) delim = ' ';
*s++ = '\0'; // terminate the string in place
}
return cnt;
}

// Check for input / ouput redirection
// > redirect stdout (creates new file)
// >> redirects stdout (appends)
// Not implemented yet
// 2> and 2>> as above for stderr
// p>&q merges output from stream p with stream q (stdin=0, stdout=1, stderr=2)
// < redirect stdin
//
// file follows the redirection operator, with or without spaces
// removes redirection operators and associated file names from argv
// by changing the pointer to NULL
// uses freopen to redirect

int __check_redirect( int in_cnt, char *argv[] )
{
char *s, *t;
char *fname;
char *mode;
FILE *fp;
bool redirect = false;

for ( int i = 1; i < in_cnt; i++ ) {
s = argv[i];
fname = NULL;

if ( i+1 < in_cnt) t = argv[i+1];
else t = NULL;

if ( *s == '<' ) {
fname = __get_redir_fname( s+1, t );
fp = stdin;
mode = "r";
} else if ( *s == '>' ) {
if ( *(++s) == '>' ) {
fname = __get_redir_fname( s+1, t );
fp = stdout;
mode = "a";
} else {
fname = __get_redir_fname( s, t );
fp = stdout;
mode = "w";
}
/*
} else if ( *s == '&' ) {
} else if ( *s == '2' ) {
*/
}
if ( fname ) {
argv[i] = NULL;
if ( fname == t ) argv[++i] = NULL;
// puts( fname );
// puts( mode );
// getchar();
if ( !freopen( fname, mode, fp ) ) exit( EXIT_FAILURE );
redirect = true;
}
}

// Register atexit() function to close the filehandles

if ( redirect ) atexit( __close_redir_files );

// Re-pack argv to remove any redirection operators and file names

int cnt = 1;

for ( int i = 1; i < in_cnt; i++ )
if ( argv[i] ) argv[cnt++] = argv[i];

return cnt;
}

// Get redirection filename from argv list
// - can either be in the in current parameter (s) or next parameter (t)
// - the current parameter is passed with the redirection operators skipped over
// - if t is NULL will always return s even if there is no file name

char *__get_redir_fname( char *s, char *t )
{
if ( !t ) return s; // if t is NULL then s
if ( *s != '\0' ) return s; // not at the end of the string then s
return t; // otherwise t
}

// Called at exit to close any files that are targets of redirection
// - registered via atexit()
// - the check is deliberately <FH_STDIN - i.e. a regular file
// - if STDIN has been redirected to STDERR, won't call fclose

void __close_redir_files( void )
{
// fputs( "Closing redirect files.", stderr );
if ( stdin->fhandle < FH_STDIN ) fclose( stdin );
if ( stdout->fhandle < FH_STDIN ) fclose( stdout );
if ( stderr->fhandle < FH_STDIN ) fclose( stderr );
}
42 changes: 42 additions & 0 deletions src/libc/time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* time_t time(time_t *t)
----------------------
Description
time() returns the current time as the number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
If t is non-NULL, the return value is also stored in the memory pointed to by t.
Return Value
On success, the value of time in seconds since the Epoch is returned. On error, ((time_t) -1) is
returned, and errno is set appropriately.
*/

#include <time.h>
#include <stdint.h>
#include <mos_api.h>

time_t time(time_t *timer)
{
volatile RTC_DATA *rtc = getsysvar_rtc();

static char rtc_buffer[33];
mos_getrtc( rtc_buffer ); // Seems that need to call mos_getrtc() to update sysvar_rtc

struct tm tm2;
time_t res;

tm2.tm_sec = rtc->second;
tm2.tm_min = rtc->minute;
tm2.tm_hour = rtc->hour;
tm2.tm_mday = rtc->day;
tm2.tm_mon = rtc->month;
tm2.tm_year = (unsigned int)rtc->year + 1980 - 1900;

res = mktime(&tm2);

if (timer != NULL)
{
*timer = res;
}

return res;
}
65 changes: 0 additions & 65 deletions src/libc/time.c.src

This file was deleted.

29 changes: 29 additions & 0 deletions src/libc/ungetc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* ungetc
------
The C library function int ungetc(int char, FILE *stream) pushes the character char (an unsigned
char) onto the specified stream so that the this is available for the next read operation.
Declaration: Following is the declaration for ungetc() function.
int ungetc(int char, FILE *stream)
Parameters
char − This is the character to be put back. This is passed as its int promotion.
stream − This is the pointer to a FILE object that identifies the stream where the character
is to be written.
Return Value
If successful, it returns the character that was pushed back
otherwise, EOF is returned and the stream remains unchanged.
*/

#include <stdio.h>

int ungetc(int c, FILE *stream)
{
if (stream == NULL || stream == stdout || stream == stderr) return EOF;
if (stream->unget_char) return EOF;

stream->unget_char = c;
return c;
}
Loading

0 comments on commit a451337

Please sign in to comment.