mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Updated examples and grammar for big error change.
This commit is contained in:
@@ -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?
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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]))
|
||||
|
||||
@@ -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
390
resources/lib/system/io.c3
Normal 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_ */
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user