Commit Graph

212 Commits

Author SHA1 Message Date
Stephen Heumann
2bb5361c24 Add a new file for 64-bit integer routines, initially with an unsigned multiply.
This file will be expanded with more support routines as needed.

The unsigned multiply routine uses the core multiplication loop from the 64-bit signed multiply routine in SysLib, with new entry/exit code for the unsigned version.
2021-02-04 23:58:54 -06:00
Stephen Heumann
80dbf0c34c printf/scanf: Add 'P' conversion specifier as a synonym for 'b'.
The 'b' conversion specifier is an ORCA extension to support p-strings, but lower case letters are reserved for use in future C standards, and in fact C23 is likely to use 'b' for integers in binary notation. For the time being, 'b' is still supported with its existing meaning, but it is considered deprecated. It may be removed in the future if we want to support the C23 behavior. Upper-case letters are available to use for extensions, so 'P' should remain available for our use.
2021-01-30 19:53:50 -06:00
Stephen Heumann
bd1e822a43 printf: In d/i/o/u/x/X conversions with a precision specified, the 0 flag should be ignored.
For example, the output of the following should have only two leading zeros (and the rest of the field width padded with spaces):

#include <stdio.h>

int main(void) {
        printf("%016.5i\n", 123);
}
2021-01-30 17:51:55 -06:00
Stephen Heumann
7c4141f03d printf: properly handle negative field width or precision arguments.
If the field width is given by an argument (when * is used in the format specification) and the value given is negative, it should be treated like a positive field width with the - flag. If a negative argument is given for the precision, it should be treated as if the precision was not specified.

The following is an example of code that behaved incorrectly:

#include <stdio.h>
int main(void) {
        printf("%*iXX\n", -50, 123);
}
2021-01-30 16:55:27 -06:00
Stephen Heumann
71a25f0fef printf: %#x or %#X conversions should not print the 0x/0X prefix if the value is 0.
This is the behavior specified in all versions of the C standards.
2021-01-30 16:04:18 -06:00
Stephen Heumann
37c38a7077 Add partial support for 64-bit 'long long' types in printf.
Currently, it works as follows:
*The 'll' length modifier is recognized. 'j' (for intmax_t) is also now treated as denoting a 64-bit type.
*The 'x', 'X', and 'o' format specifiers have full support for 64-bit types.
*The 'n' format specifier can write a 64-bit integer, but only actually supports values up to 64k.
*The 'd', 'i', and 'u' format specifiers can consume a 64-bit value, but they only print it correctly if it is within the range of 32-bit long/unsigned long.
2021-01-30 14:41:07 -06:00
Stephen Heumann
7566fffb6c Add readme describing GNO version of ORCALib. 2020-02-19 12:49:29 -06:00
Stephen Heumann
f906cac5f9 Update the version in the resource fork.
This is now an ORCA/C version number, rather than a GNO version number.
2020-02-19 12:47:16 -06:00
Stephen Heumann
3145f4b023 Merge branch 'master' into gno-version.
The includes all the changes through the version in ORCA/C 2.2.0 B4, plus a small POSIX conformance tweak in strtol/strtoul.

# Conflicts:
#	assert.asm
#	cc.asm
#	ctype.asm
#	string.asm
#	vars.asm
2020-02-19 12:43:57 -06:00
Stephen Heumann
97c3ecad73 ORCALib changes for GNO.
This is a reconstruction of the ORCALib source changes for the version of ORCALib distributed with GNO 2.0.6. The library built with this code should be identical to the original GNO one, apart from insignificant junk bytes at the ends of segments and the build date in the resource fork.
2020-02-19 12:19:41 -06:00
Stephen Heumann
e9de42d6c4 fopen: do not require read access when opening a file for append only.
This can cause an error if the file's permissions deny read access.
2020-02-17 19:49:18 -06:00
Stephen Heumann
717cf99071 Detect invalid base values in strtol and strtoul.
They will now return 0 and set errno to EINVAL if an invalid base value (anything other than 0 or 2..36) is detected.

This behavior is required by POSIX. It's not required by the C standards (which leave the behavior in this case undefined), but it seems reasonable to do.
2020-02-17 17:39:36 -06:00
Stephen Heumann
e5360c9605 Spellcheck comments. 2020-02-16 13:29:53 -06:00
Stephen Heumann
573bc6efa9 Use consistent indentation within files.
Tabs have been expanded to spaces in several files that use mainly spaces for indentation.

The files ctype.asm, stdio.asm, and string.asm consistently use tabs for indentation. The tabs in these files have been left alone, except that a few tabs between sentences in comments were changed to spaces.  One space-indented line in stdio.asm was changed to use a tab.
2020-02-16 13:28:18 -06:00
Stephen Heumann
44dfc1d1d6 Prevent localtime() from potentially giving incorrect tm_isdst values.
This could happen when it was called for a time other than the present, because it set tm_isdst based on the current value of the DST flag in BRAM, which is valid only for the current time.

Now it works as follows: If localtime() is passed the time_t value that was produced by the most recent call to time(), it gives the DST setting in effect at the time of that call.  Otherwise, it sets tm_isdst to -1, indicating that the correct value is unknown.

This is about the best we can do without having a full timezone library/database. It should give the right tm_isdst value in probably the most common case, and avoids giving an incorrect value in any case (assuming the system's DST flag is right).

This fixes #18.
2020-02-02 12:52:42 -06:00
Stephen Heumann
9af1c093cb Ensure tmpfile() doesn't access a file created by someone else.
This could happen due to a race condition, which shouldn't generally be an issue on the GS but is at least theoretically possible under GNO or Golden Gate.
2020-01-31 12:47:34 -06:00
Stephen Heumann
c439f2e3ea Make tmpnam() return the pointer passed to it, if non-null.
This is what the standards call for. It was previously always returning a pointer to its internal buffer.
2020-01-31 12:45:02 -06:00
Stephen Heumann
27a32d82bd Allow 'b' to come before '+' in freopen modes (e.g. "wb+").
Previously, only forms like "w+b" worked.
2020-01-30 21:16:48 -06:00
Stephen Heumann
c77c5927d9 Support "x" in fopen()/freopen() mode strings (C11).
If the mode string ends in "x", opening a file for writing will fail if the file already exists.
2020-01-30 20:15:45 -06:00
Stephen Heumann
bd6d517854 Note that ~RemoveWord is used by scanf, not printf. 2020-01-30 18:51:59 -06:00
Stephen Heumann
8490da9d85 Allow -2147483648 (LONG_MIN) as valid input to strtol(), not setting errno.
This is what other implementations do and seems to be the intent of the standards, although the wording isn't entirely clear.
2020-01-24 12:25:01 -06:00
Stephen Heumann
14554fcdc7 Make strtol() and strtoul() set the right end pointer in error cases.
Previously, they often did not do this. Now they do, as follows:

If there was a sequence of the expected numeric form, then they fully parse that sequence and give a pointer past the end of it, even if the number was out of range.  If there was not a sequence of the expected form, they give the starting pointer that they were passed in.
2020-01-23 23:47:55 -06:00
Stephen Heumann
ebbb5b73ed Allow strtoul to take numbers with a minus sign.
The effect of this is to negate the number in the unsigned long type before returning it.
2020-01-23 21:50:11 -06:00
Stephen Heumann
599c1e3c7b Fix problem where strtol would accept invalid strings like "- +53".
This stemmed from its calling strtoul internally, causing it to accept extra while space and/or + signs. The fix is to have an alternate entry point for strtoul that skips that processing.
2020-01-23 20:42:25 -06:00
Stephen Heumann
ee1b7e606d Implement quick_exit() and at_quick_exit() from C11.
Also, make all the exit functions quit via RTL if #pragma rtl was used. This fixes #19.
2020-01-23 18:43:20 -06:00
Stephen Heumann
07011e5b05 Fix issue causing potential stack corruption in scanf().
This could happen if a scan error occurred and certain conversion specifiers containing the % character in a scanset (e.g. %4[%]) appeared as subsequent elements in the format string. The fix is to more thoroughly parse the format string when cleaning up after a scan error.

This fixes #26.
2020-01-22 07:40:40 -06:00
Stephen Heumann
d89096236e Ensure that strtok returns NULL after reaching the end of the string.
It had been doing a null pointer dereference and effectively treating memory locations starting from 0 as the continuation of the string, potentially producing inappropriate results depending on what they contained.
2020-01-21 17:12:54 -06:00
Stephen Heumann
887d66d537 Implement aligned_alloc function (C11).
This allocates memory with a specified alignment. Currently, the only allowed alignment value is 1.
2020-01-12 18:54:07 -06:00
Stephen Heumann
571c601b66 strtoul: return 0 when given an empty string, as required by the C standards.
The issue was introduced in commit 6e9790667.

errno is now set to EINVAL in this case. (This is not required by the C standards, but is consistent with various other implementations.)

This fixes the cases in #23 related to strtol() and strtoul().
2019-06-16 20:26:13 -05:00
Stephen Heumann
7a20f5f71d strtoul: don't try to parse initial '0x' as hex prefix unless base is 0 or 16.
In other bases, the 'x' either ends parsing of the number string or (in base 34 and larger) is a digit.

Also, ensure only ASCII characters (with high bit clear) are accepted in all situations.
2018-09-13 18:28:02 -05:00
Stephen Heumann
27fc6836cc Fix div() and ldiv() to return properly-signed remainders.
They could previously give the wrong sign on the remainder in certain cases where one or both of the arguments were negative, because they were using the wrong condition to decide whether to negate it.
2018-09-10 17:09:28 -05:00
Stephen Heumann
efab82784d Add _Exit() function from C99.
This exits the programs without calling atexit functions and possibly without doing other clean-up operations. In ORCA/C, it is functionally identical to _exit().
2018-09-09 23:23:19 -05:00
Stephen Heumann
24ec2ae9bc Fix perror() issues.
perror() should write only a single new-line. Also, it should not write the prefix string, colon and space if the prefix string pointer is NULL or if it points to an empty string.
2018-09-09 21:43:14 -05:00
Stephen Heumann
2be73c4e5d Make strerror() return a valid error string for unknown errno values.
This is required by C99 and later.
2018-09-09 21:26:21 -05:00
Stephen Heumann
2d20af84fd Fix support for 'h' length modifier in scanf.
This got broken when adding support for 'hh'.
2018-09-09 20:55:23 -05:00
MikeW50
57e8a686f8
Merge pull request #29 from ksherlock/assert_ph2
assert - use updated ph2/ph4 macros that support pei dp vs lda dp / pha.
2018-06-29 08:08:15 -06:00
Kelvin Sherlock
d600cd0b61 assert - use updated ph2/ph4 macros that support pei dp vs lda dp / pha.
also expand a couple tabs -> spaces.
2018-06-27 23:36:02 -04:00
Stephen Heumann
a11660f597 Implement support for 'hh' length modifier in *scanf.
Also support '%ln', although the length that can be reported is still limited to 64k.
2018-03-22 22:10:56 -05:00
Stephen Heumann
5ee6e87f44 Implement support for 'hh' length modifier in *printf.
This corresponds to signed char or unsigned char (although arguments of those types will have been promoted to int).
2018-03-22 21:13:09 -05:00
Kelvin Sherlock
6a2e3c1abd fix typos and misleading commentary. 2018-03-21 23:05:46 -04:00
Stephen Heumann
6e97906678 Make strtol/strtoul return LONG_MIN/LONG_MAX/ULONG_MAX for out-of-range values.
This fixes #10.

There are still issues with the end pointer value generated in error cases.
2018-03-13 22:11:40 -05:00
Stephen Heumann
7abdfc9beb Make system(NULL) detect whether a command processor is available.
Previously, it just ran an Execute shell call with NULL as the command-line pointer.

The fix is to still call Execute, but with an empty string as the command line, and then check if the call gave an error. If running under plain GS/OS, this gives an error for an unknown system call, whereas both ORCA/APW and GNO shells will return with no error in this case. (Golden Gate doesn't implement the Execute shell call, so it also gives an error and will report no command processor available.)

This fixes issue #25.
2018-03-13 17:49:49 -05:00
Stephen Heumann
21d34a30ce mktime: tm_yday should be indexed from 0 for January 1st, not 1.
This fixes the libca07.c test case.
2018-03-09 17:38:55 -06:00
Stephen Heumann
a77e44d7b5 Fix asctime() to properly print years 1000 through 9999.
Also, use a leading space rather than a leading 0 in days 1 through 9.

This fixes the libca11.c test case.
2018-03-09 13:10:53 -06:00
Stephen Heumann
73f04eaab4 Add snprintf() and vsnprintf() functions (C99). 2018-03-05 18:52:43 -06:00
Stephen Heumann
8562842f66 sprintf/vsprintf should write a terminating null character even if the string produced is empty.
They were just not writing anything in this case.
2018-03-05 18:02:36 -06:00
Kelvin Sherlock
6006cefc70 add the c99 isblank() function 2018-03-04 22:31:11 -05:00
Stephen Heumann
8533ea221c When argc==0, argv should be a valid pointer and argv[0] should be NULL.
This is normal for S16 programs or inits, and can happen with shell executables in certain cases like when being run from Prizm.
2018-02-28 00:17:35 -06:00
Stephen Heumann
33ab148cea Merge commit 'd95f9f29d27d02d8c57bd23620f41afbf7607ac5' 2018-02-27 23:01:51 -06:00
Stephen Heumann
62f6b712e7 Add support for 'F', 'a', and 'A' conversion specifiers for scanf (C99).
These all behave identically to 'f'. Note that none of these accept the hexadecimal floating-point representation as input, which they should under C99.
2018-02-27 21:39:49 -06:00