Updated examples and grammar for big error change.

This commit is contained in:
Christoffer Lerno
2020-06-17 18:19:00 +02:00
parent 42a222e353
commit a6a4136685
11 changed files with 613 additions and 95 deletions

View File

@@ -49,6 +49,7 @@ There are some small work being done on the parser here, but most of the structu
- Improved integration with C.
- Generic macros.
- Update of error system
#### What's working?

View File

@@ -8,15 +8,12 @@ module acorn::arr;
* See Copyright Notice in avm.h
*/
error SearchError
{
NOT_FOUND
}
/* Return a new Array, allocating len slots for Values. */
func Value new(Value th, Value *dest, Value type, AuintIdx len)
{
// Create an array object
ArrInfo* val = @cast(mem::new(th, ArrEnc, sizeof(ArrInfo), ArrInfo*);
ArrInfo* val = cast(mem::new(th, ArrEnc, sizeof(ArrInfo), ArrInfo*);
val.flags1 = 0; // Initialize Flags1 flags
val.type = type;
val.avail = len;
@@ -30,7 +27,7 @@ func Value new(Value th, Value *dest, Value type, AuintIdx len)
func Value newClosure(Value *th, Value *dest, Value type, AuintIdx len)
{
// Create an array object
ArrInfo* val = @cast(mem::new(th, ArrEnc, sizeof(ArrInfo), ArrInfo*);
ArrInfo* val = cast(mem::new(th, ArrEnc, sizeof(ArrInfo), ArrInfo*);
val.flags1 = TypeClo; // Initialize Flags1 flags
val.type = type;
val.avail = len;

View File

@@ -14,18 +14,16 @@ module acorn::mem;
* It returns the location of the new block or NULL (if freed). */
func void* gcrealloc(Value th, void *block, Auint osize, Auint nsize)
{
Value newblock;
// Check consistency of block and osize (both must be null or specified)
Auint realosize = block ? osize : 0;
assert((realosize == 0) == (block == nil));
// Allocate/free/resize the memory block
newblock = @cast(frealloc(block, nsize), Value);
Value newblock = cast(frealloc(block, nsize), Value);
$if (defined(MEMORYLOG))
{
if (nsize==0)
if (nsize == 0)
{
vmLog("Freeing %p size %d", block, osize);
}
@@ -40,7 +38,7 @@ func void* gcrealloc(Value th, void *block, Auint osize, Auint nsize)
{
// realloc cannot fail when shrinking a block
gcfull(th, 1); // try to free some memory...
newblock = @cast(frealloc(block, nsize), Value); // try again
newblock = cast(frealloc(block, nsize), Value); // try again
if (newblock == nil)
{
logSevere("Out of memory trying allocate or grow a memory block.");
@@ -57,7 +55,7 @@ func void* gcreallocv(Value th, void* block, Auint osize, Auint nsize, Auint esi
{
// Ensure we are not asking for more memory than available in address space
// If we do not do this, calculating the needed memory will overflow
if (nsize+1 > ~((Auint)0) / esize)
if (nsize + 1 > ~(cast(0, Auint)) / esize)
{
logSevere("Out of memory trying to ask for more memory than address space has.");
}
@@ -72,20 +70,17 @@ func void* gcreallocv(Value th, void* block, Auint osize, Auint nsize, Auint esi
**/
func void* frealloc(void* block, Auint size)
{
if (size == 0)
if (!size)
{
free(block);
return NULL;
}
else
{
return realloc(block, size);
}
return realloc(block, size);
}
macro type($type) @amalloc($type)
{
return @cast(mem_frealloc(NULL, sizeof($type)), $type);
return cast(mem_frealloc(NULL, sizeof($type)), $type);
}
@@ -103,7 +98,7 @@ MemInfo* new(Value th, int enc, Auint sz)
gccheck(th); // Incremental GC before memory allocation events
}
vm(th).gcnbrnew++;
MemInfo* o = (MemInfo*) (char *) gcrealloc(th, nil, 0, sz);
MemInfo* o = cast(gcrealloc(th, nil, 0, sz), MemInfo *);
o.marked = vm(th).currentwhite & WHITEBITS;
o.enctyp = enc;
@@ -132,7 +127,7 @@ func MemInfo* newnolink(Value th, int enc, Auint sz)
}
vm(th)->gcnbrnew++;
// Allocate and initialize
MemInfo *o = (MemInfo*) (char *) gcrealloc(th, NULL, 0, sz);
MemInfo *o = cast(gcrealloc(th, NULL, 0, sz), MemInfo*);
o.marked = vm(th)->currentwhite & WHITEBITS;
o.enctyp = enc;
return o;
@@ -142,7 +137,7 @@ func MemInfo* newnolink(Value th, int enc, Auint sz)
func void growaux_(Value th, void *block, AuintIdx *size, AuintIdx size_elems, AuintIdx limit)
{
void* newblock;
AuintIdx newsize;
AuintIdx newsize = void;
// cannot double it?
if (*size >= limit / 2)
{

View File

@@ -82,7 +82,13 @@ public func void encode(byte[] in, string *out)
}
}
public func int decode(string in, byte[] out) throws Base64Error
error InvalidCharacter
{
int index;
char c;
}
public func int! decode(string in, byte[] out)
{
int j = 0;
@@ -92,9 +98,9 @@ public func int decode(string in, byte[] out) throws Base64Error
if (value == PAD) return j;
if (value < FIRST || in[i] > LAST) throw INVALID_CHARACTER;
if (value < FIRST || in[i] > LAST) return! InvalidCharacter(i, value);
byte c = LUT_DEC[in[i] - FIRST);
if (c == ERR) throw INVALID_CHARACTER;
if (c == ERR) return! InvalidCharacter(i, value);
switch (i % 4)
{

View File

@@ -4,9 +4,7 @@ func int main(void)
{
Curl curl;
try curl.init();
catch (error e)
catch (e = curl.init())
{
printf("Failed to create new curl: %s\n", e.message);
exit(FAILURE);
@@ -15,9 +13,7 @@ func int main(void)
curl.setopt(URL, "http://www.rosettacode.org/");
curl.setopt(FOLLOWLOCATION, 1);
try curl.perform();
catch (CurlError e)
catch (e = curl.perform())
{
printf("Error making request: %s\n", e.message);
exit(FAILURE);

View File

@@ -7,7 +7,7 @@ func void main()
string story = "";
while (1)
{
try string line = stdin.readln().strip();
string line = stdin.readln().strip() else "";
if (!line.size) break;
story += line + "\n";
}
@@ -21,14 +21,14 @@ func void main()
{
string s = match.string;
printf("Enter a value for '%s': ", s.slice(1, s.size - 2));
try string word = strin.readln().strip();
string! word = strin.readln().strip();
catch (word)
{
// Exit on error.
return;
}
story = story.replace(s, word);
}
println("\nThe story becomes:\n%s\n", story);
catch (error e)
{
// Ignore any error
}
}

View File

@@ -18,7 +18,7 @@ const uint MaxDepth = 8;
$if (DEBUG_NODES):
func void Blocks.dump(const Blocks* b)
func void Blocks.dump(Blocks* b)
{
printf("Nodes (%u/%u) (%u bytes)\n", b.nodeCount, b.maxNodes, b.nodeCount * sizeof(Node));
for (uint i = 0; i < b.nodeCount; i++)
@@ -170,7 +170,7 @@ func uint addType(uint raw, ValueType t) @(inline)
return raw | (t << ValueTypeOffset);
}
func void Parser.parseKeyValue(Parser* p) throws ParseError
func void! Parser.parseKeyValue(Parser* p)
{
//printf("parseKeyValue()\n");
char[MaxText] key;
@@ -193,7 +193,7 @@ func void Parser.parseKeyValue(Parser* p) throws ParseError
p.lastChild[p.numParents] = node;
}
func void Parser.parseTable(Parser* p) throws ParseError
func void! Parser.parseTable(Parser* p)
{
//printf("parseTable()\n");
try p.consumeToken();
@@ -348,13 +348,10 @@ func u32 Parser.addTable(Parser* p, const char* name, u32 depth, bool isTop, Nod
return 0;
}
func Location Parser.consumeToken(Parser* p) {
func Location! Parser.consumeToken(Parser* p)
{
Location prev = p.tok.loc;
p.tokenizer.lex(&p.tok);
if (p.tok.is(TokenKind.Error)) {
strcpy(p.errorMsg, p.tok.text);
longjmp(p.jump_err, 1);
}
try p.tokenizer.lex(&p.tok);
return prev;
}
@@ -362,16 +359,19 @@ func Token* Parser.nextToken(Parser* p) {
return p.tokenizer.lookahead();
}
func void Parser.expectAndConsume(Parser* p, TokenKind k) {
if (p.tok.isNot(k)) {
func void! Parser.expectAndConsume(Parser* p, TokenKind k) {
if (p.tok.isNot(k))
{
sprintf(p.errorMsg, "expected '%s' at %s", token2str(k), p.tok.loc.str());
longjmp(p.jump_err, 1);
}
p.consumeToken();
try p.consumeToken();
}
func void Parser.expect(Parser* p, TokenKind k) {
if (p.tok.isNot(k)) {
func void Parser.expect(Parser* p, TokenKind k)
{
if (p.tok.isNot(k))
{
sprintf(p.errorMsg, "expected '%s' at %s", token2str(k), p.tok.loc.str());
longjmp(p.jump_err, 1);
}
@@ -385,7 +385,7 @@ public struct TomlReader @opaque
Blocks* blocks;
}
public func TomlReader* TomlReader.create()
public func TomlReader* new_toml()
{
TomlReader* r = @malloc(TomlReader);
r.blocks = @malloc(Blocks);
@@ -405,7 +405,9 @@ public func const char* TomlReader.getMsg(const TomlReader* r)
return r.message;
}
public func void TomlReader.parse(TomlReader* r, string filename) throws ParseError, FileError
error EmptyFileError;
public func void! TomlReader.parse(TomlReader* r, string filename)
{
Reader file;
@@ -416,7 +418,7 @@ public func void TomlReader.parse(TomlReader* r, string filename) throws ParseEr
if (file.isEmpty())
{
printf("file %s is empty\n", filename);
throw ParseError.EMPTY_FILE;
raise EmptyFileError;
}
Parser parser;
@@ -431,7 +433,8 @@ $endif
// --------------------------------------------------------------
// Getters+iters
func const Node* Reader.findNode(const Reader* r, const char* key) {
func const Node* Reader.findNode(const Reader* r, const char* key)
{
char[MaxText] name;
const char* cp = key;
const char* start = cp;

View File

@@ -103,7 +103,13 @@ func void Tokenizer.init(Tokenizer* t, char* input)
t.text[0] = 0;
}
func void Tokenizer.lex(Tokenizer* t, Token* result)
error LexedEOF;
error LexError
{
string error_message;
}
func void! Tokenizer.lex(Tokenizer* t, Token* result)
{
if (t.haveNext)
{
@@ -118,16 +124,12 @@ func void Tokenizer.lex(Tokenizer* t, Token* result)
switch (t.current[0])
{
case 0:
result.loc = t.loc;
result.kind = TokenKind.EOF;
return;
return! LexedEOF();
case '#':
if (t.loc.column != 1)
{
sprintf(t.text, "unexpected '#' after line start at %s", t.loc.str());
result.kind = TokenKind.ERROR;
result.text = t.text;
return;
return! LexError(t.text);
}
t.parseComment();
case ' ':
@@ -214,18 +216,16 @@ func void Tokenizer.lex(Tokenizer* t, Token* result)
return;
}
sprintf(t.text, "unexpected char '%c' at %s", t.current[0], t.loc.str());
result.kind = ERROR;
result.text = t.text;
return;
return LexError(t.text);
}
}
}
func Token* Tokenizer.lookahead(Tokenizer* t)
func Token*! Tokenizer.lookahead(Tokenizer* t)
{
if (!t.haveNext)
{
t.lex(&t.nextToken);
try t.lex(&t.nextToken);
t.haveNext = true;
}
return &t.nextToken;
@@ -277,7 +277,7 @@ func void Tokenizer.parseText(Tokenizer* t, Token* result)
t.advance(1);
}
func void Tokenizer.parseMultiText(Tokenizer* t, Token* result)
func void! Tokenizer.parseMultiText(Tokenizer* t, Token* result)
{
t.advance(3);
if (t.current[0] == '\n')
@@ -293,9 +293,7 @@ func void Tokenizer.parseMultiText(Tokenizer* t, Token* result)
if (t.current[0] == 0)
{
sprintf(t.text, "missing end \"\"\" %s", t.loc.str());
result.kind = TokenKind.Error;
result.text = t.text;
return;
return! LexError(t.text);
}
if (t.current[0] == '\n')
{
@@ -310,7 +308,7 @@ func void Tokenizer.parseMultiText(Tokenizer* t, Token* result)
t.current++;
}
uint len = cast(uint, t.current - start);
uint len = uint(t.current - start);
// assert(len < MaxText);
memcpy(t.text, start, len);
t.text[len] = 0;
@@ -325,7 +323,7 @@ func void Tokenizer.parseNumber(Tokenizer* t, Token* result)
// handle hexadecimal/ocal/binary number
// handle '_', like 1_000_000
uint number = cast(atoi(t.current), uint);
uint number = uint(atoi(t.current));
result.kind = TokenKind.Number;
result.number = number;
while (t.current[0] && isdigit(t.current[0]))

View File

@@ -25,7 +25,7 @@ void yyerror(char *s);
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
%token FUNC ERROR MACRO GENERIC CTIF CTELIF CTENDIF CTELSE CTSWITCH CTCASE CTDEFAULT CTFOR
%token THROWS THROW TRY CATCH SCOPE PUBLIC DEFER ATTRIBUTE IN
%token TRY CATCH SCOPE PUBLIC DEFER ATTRIBUTE IN
%token FN_BLOCK_START FN_BLOCK_END
%token AUTO
@@ -150,8 +150,13 @@ conditional_expression
| logical_expression ELVIS conditional_expression
;
assignment_expression
error_expression
: conditional_expression
| conditional_expression '!'
;
assignment_expression
: error_expression
| unary_expression assignment_operator assignment_expression
| unary_expression '=' initializer_list
;
@@ -159,7 +164,7 @@ assignment_expression
expression
: assignment_expression
| TRY assignment_expression
| TRY assignment_expression ELSE assignment_expression
| assignment_expression ELSE assignment_expression
;
@@ -217,8 +222,8 @@ macro_argument_list
;
declaration
: type IDENT '=' initializer
| type IDENT
: failable_type IDENT '=' initializer
| failable_type IDENT
;
param_declaration
@@ -270,6 +275,11 @@ type
| type '[' '+' ']'
;
failable_type
: type
| type '!'
;
initializer
: expression
| initializer_list
@@ -318,8 +328,6 @@ ct_statement
| ct_for_stmt
;
throw_statement
: THROW expression ';'
statement
: compound_statement
@@ -334,7 +342,6 @@ statement
| try_statement
| defer_statement
| ct_statement
| throw_statement
;
defer_catch_body
@@ -351,8 +358,7 @@ defer_statement
;
catch_statement
: CATCH '(' type IDENT ')' defer_catch_body
| CATCH '(' ERROR IDENT ')' defer_catch_body
: CATCH '(' expression ')' defer_catch_body
;
try_statement
@@ -469,16 +475,6 @@ error_list
| error_list error_type
;
throw_declaration
: THROWS
| THROWS error_list
;
opt_throw_declaration
: throw_declaration
|
;
func_name
: path TYPE_IDENT '.' IDENT
| TYPE_IDENT '.' IDENT
@@ -486,7 +482,7 @@ func_name
;
func_declaration
: FUNC type func_name opt_parameter_type_list opt_attributes opt_throw_declaration
: FUNC failable_type func_name opt_parameter_type_list opt_attributes
;
func_definition
@@ -567,7 +563,7 @@ const_declaration
;
func_typedef
: FUNC type opt_parameter_type_list opt_throw_declaration
: FUNC failable_type opt_parameter_type_list
;
typedef_declaration

390
resources/lib/system/io.c3 Normal file
View File

@@ -0,0 +1,390 @@
module system::io;
typedef File as void;
extern File *stdin @cname(__stdinp);
extern File *stdout @cname(__stdoutp);
extern File *stderr @cname(__stderrp);
extern int fputc(int, aliased void*);
extern void clearerr(aliased void*);
extern int fclose(aliased void*);
extern int feof(aliased void*);
extern int ferror(aliased void*);
extern int fflush(aliased FILE *);
extern int fgetc(aliased FILE *);
extern int fgetpos(FILE *, fpos_t *);
extern int fseek(void*, long, int);
extern void* fopen(char *, char *);
struct File
{
void *file;
}
enum Seek
{
SET = 0,
CURSOR = 1,
END = 2
}
errorset FileError
{
}
local func FileError errorFromErrno()
{
}
public func void File.open(File *file, char *filename, char *mode) throws FileError
{
file.file = fopen(filename, mode);
if (!file.file) throw errorFromErrno();
}
public func void File.seek(File *file, long offset, Seek seekMode = Seek.SET) throws FileError
{
if (fseek(file->file, offset, cast(seekMode, int))) throw errorFromErrno();
}
public func void File.putChar(File *file, char c) throws FileError
{
if (fputc(c, file->file)) throw errorFromErrno();
}
pubic func void File.clearerr(File *file) @inline throws FileError
{
clearerr(file->file);
}
func void File.close(File *file) @inline
{
if (fclose(file->file)) throw errorFromErrno();
}
func void File.eof(File *file) @inline
{
int err = feof(file->file);
}
func void File.error(File *file) @inline
{
int err = ferror
}
#define __SLBF 0x0001 /* line buffered */
#define __SNBF 0x0002 /* unbuffered */
#define __SRD 0x0004 /* OK to read */
#define __SWR 0x0008 /* OK to write */
/* RD and WR are never simultaneously asserted */
#define __SRW 0x0010 /* open for reading & writing */
#define __SEOF 0x0020 /* found EOF */
#define __SERR 0x0040 /* found error */
#define __SMBF 0x0080 /* _buf is from malloc */
#define __SAPP 0x0100 /* fdopen()ed in append mode */
#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
#define __SOPT 0x0400 /* do fseek() optimisation */
#define __SNPT 0x0800 /* do not do fseek() optimisation */
#define __SOFF 0x1000 /* set iff _offset is in fact correct */
#define __SMOD 0x2000 /* true => fgetln modified _p text */
#define __SALC 0x4000 /* allocate string space dynamically */
#define __SIGN 0x8000 /* ignore this file in _fwalk */
/*
* The following three definitions are for ANSI C, which took them
* from System V, which brilliantly took internal interface macros and
* made them official arguments to setvbuf(), without renaming them.
* Hence, these ugly _IOxxx names are *supposed* to appear in user code.
*
* Although numbered as their counterparts above, the implementation
* does not rely on this.
*/
#define _IOFBF 0 /* setvbuf should set fully buffered */
#define _IOLBF 1 /* setvbuf should set line buffered */
#define _IONBF 2 /* setvbuf should set unbuffered */
#define BUFSIZ 1024 /* size of buffer used by setbuf */
#define EOF (-1)
/* must be == _POSIX_STREAM_MAX <limits.h> */
#define FOPEN_MAX 20 /* must be <= OPEN_MAX <sys/syslimits.h> */
#define FILENAME_MAX 1024 /* must be <= PATH_MAX <sys/syslimits.h> */
/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */
#ifndef _ANSI_SOURCE
#define P_tmpdir "/var/tmp/"
#endif
#define L_tmpnam 1024 /* XXX must be == PATH_MAX */
#define TMP_MAX 308915776
#define stdin __stdinp
#define stdout __stdoutp
#define stderr __stderrp
/* ANSI-C */
__BEGIN_DECLS
char *fgets(char * __restrict, int, FILE *);
#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE)
#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */
FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */
int fprintf(FILE * __restrict, const char * __restrict, ...) __printflike(2, 3);
int fputs(const char * __restrict, FILE * __restrict) __DARWIN_ALIAS(fputs);
size_t fread(void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream);
FILE *freopen(const char * __restrict, const char * __restrict,
FILE * __restrict) __DARWIN_ALIAS(freopen);
int fscanf(FILE * __restrict, const char * __restrict, ...) __scanflike(2, 3);
int fsetpos(FILE *, const fpos_t *);
long ftell(FILE *);
size_t fwrite(const void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream) __DARWIN_ALIAS(fwrite);
int getc(FILE *);
int getchar(void);
char *gets(char *);
void perror(const char *) __cold;
int printf(const char * __restrict, ...) __printflike(1, 2);
int putc(int, FILE *);
int putchar(int);
int puts(const char *);
int remove(const char *);
int rename (const char *__old, const char *__new);
void rewind(FILE *);
int scanf(const char * __restrict, ...) __scanflike(1, 2);
void setbuf(FILE * __restrict, char * __restrict);
int setvbuf(FILE * __restrict, char * __restrict, int, size_t);
int sprintf(char * __restrict, const char * __restrict, ...) __printflike(2, 3) __swift_unavailable("Use snprintf instead.");
int sscanf(const char * __restrict, const char * __restrict, ...) __scanflike(2, 3);
FILE *tmpfile(void);
__swift_unavailable("Use mkstemp(3) instead.")
#if !defined(_POSIX_C_SOURCE)
__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3) instead.")
#endif
char *tmpnam(char *);
int ungetc(int, FILE *);
int vfprintf(FILE * __restrict, const char * __restrict, va_list) __printflike(2, 0);
int vprintf(const char * __restrict, va_list) __printflike(1, 0);
int vsprintf(char * __restrict, const char * __restrict, va_list) __printflike(2, 0) __swift_unavailable("Use vsnprintf instead.");
__END_DECLS
/* Additional functionality provided by:
* POSIX.1-1988
*/
#if __DARWIN_C_LEVEL >= 198808L
#define L_ctermid 1024 /* size for ctermid(); PATH_MAX */
__BEGIN_DECLS
#include <_ctermid.h>
#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE)
FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fdopen));
#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */
FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fdopen));
#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */
int fileno(FILE *);
__END_DECLS
#endif /* __DARWIN_C_LEVEL >= 198808L */
/* Additional functionality provided by:
* POSIX.2-1992 C Language Binding Option
*/
#if TARGET_OS_EMBEDDED
#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(ios_msg)
#else
#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(osx_msg)
#endif
#if __DARWIN_C_LEVEL >= 199209L
__BEGIN_DECLS
int pclose(FILE *) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable.");
#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE)
FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(popen)) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable.");
#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */
FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(popen)) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable.");
#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */
__END_DECLS
#endif /* __DARWIN_C_LEVEL >= 199209L */
#undef __swift_unavailable_on
/* Additional functionality provided by:
* POSIX.1c-1995,
* POSIX.1i-1995,
* and the omnibus ISO/IEC 9945-1: 1996
*/
#if __DARWIN_C_LEVEL >= 199506L
/* Functions internal to the implementation. */
__BEGIN_DECLS
int __srget(FILE *);
int __svfscanf(FILE *, const char *, va_list) __scanflike(2, 0);
int __swbuf(int, FILE *);
__END_DECLS
/*
* The __sfoo macros are here so that we can
* define function versions in the C library.
*/
#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
#if defined(__GNUC__) && defined(__STDC__)
__header_always_inline int __sputc(int _c, FILE *_p) {
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
return (*_p->_p++ = _c);
else
return (__swbuf(_c, _p));
}
#else
/*
* This has been tuned to generate reasonable code on the vax using pcc.
*/
#define __sputc(c, p) \
(--(p)->_w < 0 ? \
(p)->_w >= (p)->_lbfsize ? \
(*(p)->_p = (c)), *(p)->_p != '\n' ? \
(int)*(p)->_p++ : \
__swbuf('\n', p) : \
__swbuf((int)(c), p) : \
(*(p)->_p = (c), (int)*(p)->_p++))
#endif
#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
#define __sferror(p) (((p)->_flags & __SERR) != 0)
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
#define __sfileno(p) ((p)->_file)
__BEGIN_DECLS
void flockfile(FILE *);
int ftrylockfile(FILE *);
void funlockfile(FILE *);
int getc_unlocked(FILE *);
int getchar_unlocked(void);
int putc_unlocked(int, FILE *);
int putchar_unlocked(int);
/* Removed in Issue 6 */
#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L
int getw(FILE *);
int putw(int, FILE *);
#endif
__swift_unavailable("Use mkstemp(3) instead.")
#if !defined(_POSIX_C_SOURCE)
__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead.")
#endif
char *tempnam(const char *__dir, const char *__prefix) __DARWIN_ALIAS(tempnam);
__END_DECLS
#ifndef lint
#define getc_unlocked(fp) __sgetc(fp)
#define putc_unlocked(x, fp) __sputc(x, fp)
#endif /* lint */
#define getchar_unlocked() getc_unlocked(stdin)
#define putchar_unlocked(x) putc_unlocked(x, stdout)
#endif /* __DARWIN_C_LEVEL >= 199506L */
/* Additional functionality provided by:
* POSIX.1-2001
* ISO C99
*/
#if __DARWIN_C_LEVEL >= 200112L
#include <sys/_types/_off_t.h>
__BEGIN_DECLS
int fseeko(FILE * __stream, off_t __offset, int __whence);
off_t ftello(FILE * __stream);
__END_DECLS
#endif /* __DARWIN_C_LEVEL >= 200112L */
#if __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus)
__BEGIN_DECLS
int snprintf(char * __restrict __str, size_t __size, const char * __restrict __format, ...) __printflike(3, 4);
int vfscanf(FILE * __restrict __stream, const char * __restrict __format, va_list) __scanflike(2, 0);
int vscanf(const char * __restrict __format, va_list) __scanflike(1, 0);
int vsnprintf(char * __restrict __str, size_t __size, const char * __restrict __format, va_list) __printflike(3, 0);
int vsscanf(const char * __restrict __str, const char * __restrict __format, va_list) __scanflike(2, 0);
__END_DECLS
#endif /* __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) */
/* Additional functionality provided by:
* POSIX.1-2008
*/
#if __DARWIN_C_LEVEL >= 200809L
#include <sys/_types/_ssize_t.h>
__BEGIN_DECLS
int dprintf(int, const char * __restrict, ...) __printflike(2, 3) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
int vdprintf(int, const char * __restrict, va_list) __printflike(2, 0) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
ssize_t getdelim(char ** __restrict __linep, size_t * __restrict __linecapp, int __delimiter, FILE * __restrict __stream) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
ssize_t getline(char ** __restrict __linep, size_t * __restrict __linecapp, FILE * __restrict __stream) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
FILE *fmemopen(void * __restrict __buf, size_t __size, const char * __restrict __mode) __API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
FILE *open_memstream(char **__bufp, size_t *__sizep) __API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
__END_DECLS
#endif /* __DARWIN_C_LEVEL >= 200809L */
/* Darwin extensions */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
__BEGIN_DECLS
extern __const int sys_nerr; /* perror(3) external variables */
extern __const char *__const sys_errlist[];
int asprintf(char ** __restrict, const char * __restrict, ...) __printflike(2, 3);
char *ctermid_r(char *);
char *fgetln(FILE *, size_t *);
__const char *fmtcheck(const char *, const char *);
int fpurge(FILE *);
void setbuffer(FILE *, char *, int);
int setlinebuf(FILE *);
int vasprintf(char ** __restrict, const char * __restrict, va_list) __printflike(2, 0);
FILE *zopen(const char *, const char *, int);
/*
* Stdio function-access interface.
*/
FILE *funopen(const void *,
int (* _Nullable)(void *, char *, int),
int (* _Nullable)(void *, const char *, int),
fpos_t (* _Nullable)(void *, fpos_t, int),
int (* _Nullable)(void *));
__END_DECLS
#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
#define feof_unlocked(p) __sfeof(p)
#define ferror_unlocked(p) __sferror(p)
#define clearerr_unlocked(p) __sclearerr(p)
#define fileno_unlocked(p) __sfileno(p)
#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
#ifdef _USE_EXTENDED_LOCALES_
#include <xlocale/_stdio.h>
#endif /* _USE_EXTENDED_LOCALES_ */
#if defined (__GNUC__) && _FORTIFY_SOURCE > 0 && !defined (__cplusplus)
/* Security checking functions. */
#include <secure/_stdio.h>
#endif
#endif /* _STDIO_H_ */

View File

@@ -751,6 +751,44 @@ func int oekt() throws
return x;
}
func int! oekt2() throws
{
int z = testThrow(-1) else goto NEXT;
printf("Skipped.\n");
NEXT:
int! x = testThrow(-3);
catch (err = x)
{
printf("An error %p\n", usize(e));
return err!;
}
return x;
}
func int! oekt3()
{
int z = testThrow(-1) else goto NEXT;
printf("Skipped.\n");
NEXT:
int! x = testThrow(-3);
if (e = catch(x)) printf("An error %p\n", usize(e));
return x;
}
func int! oekt3()
{
int z = testThrow(-1) else goto NEXT;
printf("Skipped.\n");
NEXT:
int! x = testThrow(-3);
if (e = x!) printf("An error %p\n", usize(e));
return x;
}
errset Xan
{
EE,
@@ -783,6 +821,51 @@ func void testErrorBug()
}
printf("End\n");
}
func void testErrorBug2()
{
printf("Test error multi\n");
error e;
{
printf("Will call\n");
e = catch(oekt());
}
switch (e)
{
case TestErr1:
printf("Expected particular error.\n");
default:
error foo = Err.TEST_ERR1;
printf("Not expected %p != %p\n", usize(e), usize(foo));
printf("Unexpected any error error.\n");
}
printf("End\n");
}
func void testErrorMulti()
{
defer printf("End defer\n");
int! z;
printf("Test error multi\n");
{
defer printf("Defer\n");
printf("Will call\n");
z = oekt();
printf("Got here\n");
}
switch (e = z!)
{
case TestErr1:
printf("Expected particular error.\n");
default:
error foo = Err.TEST_ERR1;
printf("Not expected %p != %p\n", usize(e), usize(foo));
printf("Unexpected any error error.\n");
}
printf("End\n");
}
func void testErrorMulti()
{
defer printf("End defer\n");
@@ -883,6 +966,59 @@ func void testErrors()
printf("End of errors\n");
}
func void testErrors()
{
printf("Throws: %d\n", throwsDone.times);
int x = testThrow(20) else 1;
printf("Value was %d, expected 400.\n", x);
printf("Throws: %d\n", throwsDone.times);
x = testThrow(-1) else 20;
printf("Value was %d, expected 20.\n", x);
printf("Throws: %d\n", throwsDone.times);
printf("Begin\n");
int! y = testThrow(-1);
if (y)
{
printf("Value was %d, expected 9.\n", y);
printf("Didn't expect this one.\n");
}
else catch(y)
{
printf("Expected this catch.\n");
}
y = testThrow(-1);
catch (y)
{
printf("Particular error.\n");
}
testErrorMulti();
catch (throwAOrB(1))
{
case Err:
printf("A1\n");
case Err2:
printf("A2\n");
}
catch (throwAOrB(2))
{
case Err:
printf("B1\n");
case Err2:
printf("B2\n");
}
printf("Throws: %d\n", throwsDone.times);
printf("End of errors\n");
}
macro void arrayCallMacro($x)
{
printf("Array call: %d, %d\n", $x[0], $x[1]);