mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Fixes to broken docs parsing. Fixes #880.
This commit is contained in:
committed by
Christoffer Lerno
parent
d0c00b859b
commit
b74b62e242
@@ -182,7 +182,7 @@ macro bool os_is_posix()
|
||||
|
||||
|
||||
/**
|
||||
* @param [&in] name
|
||||
* @param [in] name
|
||||
* @require name.len > 0
|
||||
**/
|
||||
fn String! get_var(String name)
|
||||
@@ -200,8 +200,8 @@ fn String! get_var(String name)
|
||||
|
||||
|
||||
/**
|
||||
* @param [&in] name
|
||||
* @param [&in] value
|
||||
* @param [in] name
|
||||
* @param [in] value
|
||||
* @require name.len > 0
|
||||
**/
|
||||
fn void set_var(String name, String value, bool overwrite = true)
|
||||
@@ -218,7 +218,7 @@ fn void set_var(String name, String value, bool overwrite = true)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [&in] name
|
||||
* @param [in] name
|
||||
* @require name.len > 0
|
||||
**/
|
||||
fn void clear_var(String name)
|
||||
|
||||
@@ -53,19 +53,19 @@ fn void! File.memopen(File* file, char[] data, String mode)
|
||||
|
||||
|
||||
/**
|
||||
* @require file && file.file != null
|
||||
* @require self.file != null
|
||||
*/
|
||||
fn void! File.putc(File *file, char c)
|
||||
fn void! File.putc(self, char c)
|
||||
{
|
||||
if (!libc::fputc(c, file.file)) return IoError.EOF?;
|
||||
if (!libc::fputc(c, self.file)) return IoError.EOF?;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require file != null
|
||||
* @param [&inout] self
|
||||
*/
|
||||
fn void! File.close(File *file) @inline
|
||||
fn void! File.close(&self) @inline
|
||||
{
|
||||
if (file.file && libc::fclose(file.file))
|
||||
if (self.file && libc::fclose(self.file))
|
||||
{
|
||||
switch (libc::errno())
|
||||
{
|
||||
@@ -83,67 +83,63 @@ fn void! File.close(File *file) @inline
|
||||
default: return IoError.UNKNOWN_ERROR?;
|
||||
}
|
||||
}
|
||||
file.file = null;
|
||||
self.file = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require file && file.file
|
||||
* @require self.file
|
||||
*/
|
||||
fn bool File.eof(File* file) @inline
|
||||
fn bool File.eof(self) @inline
|
||||
{
|
||||
return libc::feof(file.file) != 0;
|
||||
return libc::feof(self.file) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [in] buffer
|
||||
*/
|
||||
fn usz! File.read(File* file, char[] buffer)
|
||||
fn usz! File.read(self, char[] buffer)
|
||||
{
|
||||
return os::native_fread(file.file, buffer);
|
||||
return os::native_fread(self.file, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [&in] file
|
||||
* @param [&out] buffer
|
||||
* @require file.file `File must be initialized`
|
||||
* @param [out] buffer
|
||||
* @require self.file `File must be initialized`
|
||||
*/
|
||||
fn usz! File.write(File file, char[] buffer)
|
||||
fn usz! File.write(self, char[] buffer)
|
||||
{
|
||||
return os::native_fwrite(file.file, buffer);
|
||||
return os::native_fwrite(self.file, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [&in] file
|
||||
* @require file.file `File must be initialized`
|
||||
* @require self.file `File must be initialized`
|
||||
*/
|
||||
fn usz! File.printn(File file, String string = "")
|
||||
fn usz! File.printn(self, String string = "")
|
||||
{
|
||||
usz len = file.print(string)!;
|
||||
if (!libc::putc('\n', file.file)) return IoError.UNKNOWN_ERROR?;
|
||||
usz len = self.print(string)!;
|
||||
if (!libc::putc('\n', self.file)) return IoError.UNKNOWN_ERROR?;
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [&in] file
|
||||
* @require file.file `File must be initialized`
|
||||
* @require self.file `File must be initialized`
|
||||
*/
|
||||
fn usz! File.print(File file, String string)
|
||||
fn usz! File.print(self, String string)
|
||||
{
|
||||
usz len = string.len;
|
||||
if (len != file.write((char[])string)!) return IoError.UNKNOWN_ERROR?;
|
||||
if (len != self.write((char[])string)!) return IoError.UNKNOWN_ERROR?;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [&in] file
|
||||
* @require file.file `File must be initialized`
|
||||
* @require self.file `File must be initialized`
|
||||
*/
|
||||
fn DString File.getline(File* file, Allocator* using = mem::heap())
|
||||
fn DString File.getline(self, Allocator* using = mem::heap())
|
||||
{
|
||||
DString s = dstring::new_with_capacity(120, using);
|
||||
while (!file.eof())
|
||||
while (!self.eof())
|
||||
{
|
||||
int c = libc::fgetc(file.file);
|
||||
int c = libc::fgetc(self.file);
|
||||
if (c == -1) break;
|
||||
if (c == '\n') break;
|
||||
s.append_char((char)c);
|
||||
@@ -152,27 +148,25 @@ fn DString File.getline(File* file, Allocator* using = mem::heap())
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [&in] file
|
||||
* @require file.file `File must be initialized`
|
||||
* @require self.file `File must be initialized`
|
||||
* @return "a zero terminated String (the pointer may be safely cast into a ZString)"
|
||||
*/
|
||||
fn String File.tgetline(File* file)
|
||||
fn String File.tgetline(self)
|
||||
{
|
||||
return file.getline(mem::temp()).zstr().as_str();
|
||||
return self.getline(mem::temp()).zstr().as_str();
|
||||
}
|
||||
|
||||
fn char! File.getc(File* file)
|
||||
fn char! File.getc(self)
|
||||
{
|
||||
int c = libc::fgetc(file.file);
|
||||
int c = libc::fgetc(self.file);
|
||||
if (c == -1) return IoError.EOF?;
|
||||
return (char)c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [&in] file
|
||||
* @require file.file `File must be initialized`
|
||||
* @require self.file `File must be initialized`
|
||||
*/
|
||||
fn void File.flush(File* file)
|
||||
fn void File.flush(self)
|
||||
{
|
||||
libc::fflush(file.file);
|
||||
libc::fflush(self.file);
|
||||
}
|
||||
|
||||
@@ -137,7 +137,6 @@ fn bool Path.equals(self, Path p2)
|
||||
/**
|
||||
* Append the string to the current path.
|
||||
*
|
||||
* @param [in] path
|
||||
* @param [in] filename
|
||||
* @ensure return.path_string.len >= self.path_string.len
|
||||
**/
|
||||
|
||||
@@ -2375,11 +2375,20 @@ static inline bool parse_import(ParseContext *c)
|
||||
}
|
||||
|
||||
|
||||
INLINE void append_docs(AstId **next, AstId *first, Ast *new_doc)
|
||||
{
|
||||
if (!*first)
|
||||
{
|
||||
*first = astid(new_doc);
|
||||
}
|
||||
**next = astid(new_doc);
|
||||
*next = &new_doc->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* contract ::= expression_list (':'? STRING)?
|
||||
*/
|
||||
static inline bool parse_doc_contract(ParseContext *c, AstId **docs_ref, ContractKind kind)
|
||||
static inline bool parse_doc_contract(ParseContext *c, AstId *docs, AstId **docs_next, ContractKind kind)
|
||||
{
|
||||
Ast *ast = ast_new_curr(c, AST_CONTRACT);
|
||||
ast->contract.kind = kind;
|
||||
@@ -2426,8 +2435,7 @@ static inline bool parse_doc_contract(ParseContext *c, AstId **docs_ref, Contrac
|
||||
scratch_buffer_append(".");
|
||||
ast->contract.contract.expr_string = scratch_buffer_copy();
|
||||
}
|
||||
**docs_ref = astid(ast);
|
||||
*docs_ref = &ast->next;
|
||||
append_docs(docs_next, docs, ast);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2435,7 +2443,7 @@ static inline bool parse_doc_contract(ParseContext *c, AstId **docs_ref, Contrac
|
||||
* param_contract ::= '@param' inout_attribute? any_identifier ( (':' STRING) | STRING )?
|
||||
* inout_attribute ::= '[' '&'? ('in' | 'inout' | 'out') ']'
|
||||
*/
|
||||
static inline bool parse_contract_param(ParseContext *c, AstId **docs_ref)
|
||||
static inline bool parse_contract_param(ParseContext *c, AstId *docs, AstId **docs_next)
|
||||
{
|
||||
Ast *ast = ast_new_curr(c, AST_CONTRACT);
|
||||
ast->contract.kind = CONTRACT_PARAM;
|
||||
@@ -2497,12 +2505,11 @@ static inline bool parse_contract_param(ParseContext *c, AstId **docs_ref)
|
||||
{
|
||||
try_consume(c, TOKEN_STRING);
|
||||
}
|
||||
**docs_ref = astid(ast);
|
||||
*docs_ref = &ast->next;
|
||||
append_docs(docs_next, docs, ast);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool parse_doc_optreturn(ParseContext *c, AstId **docs_ref)
|
||||
static inline bool parse_doc_optreturn(ParseContext *c, AstId *docs, AstId **docs_next)
|
||||
{
|
||||
Ast **returns = NULL;
|
||||
Ast *ast = ast_new_curr(c, AST_CONTRACT);
|
||||
@@ -2531,8 +2538,7 @@ static inline bool parse_doc_optreturn(ParseContext *c, AstId **docs_ref)
|
||||
// Just ignore our potential string:
|
||||
(void)try_consume(c, TOKEN_STRING);
|
||||
ast->contract.faults = returns;
|
||||
**docs_ref = astid(ast);
|
||||
*docs_ref = &ast->next;
|
||||
append_docs(docs_next, docs, ast);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2542,7 +2548,7 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref)
|
||||
*contracts_ref = 0;
|
||||
if (!try_consume(c, TOKEN_DOCS_START)) return true;
|
||||
|
||||
AstId *last = contracts_ref;
|
||||
AstId **next = &contracts_ref;
|
||||
uint32_t row_last_row = c->span.row;
|
||||
while (1)
|
||||
{
|
||||
@@ -2555,7 +2561,7 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref)
|
||||
const char *name = symstr(c);
|
||||
if (name == kw_at_param)
|
||||
{
|
||||
if (!parse_contract_param(c, &last)) return false;
|
||||
if (!parse_contract_param(c, contracts_ref, next)) return false;
|
||||
break;
|
||||
}
|
||||
else if (name == kw_at_return)
|
||||
@@ -2563,7 +2569,7 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref)
|
||||
advance(c);
|
||||
if (tok_is(c, TOKEN_BANG))
|
||||
{
|
||||
if (!parse_doc_optreturn(c, &contracts_ref)) return false;
|
||||
if (!parse_doc_optreturn(c, contracts_ref, next)) return false;
|
||||
break;
|
||||
}
|
||||
if (!consume(c, TOKEN_STRING, "Expected a string description.")) return false;
|
||||
@@ -2578,25 +2584,24 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref)
|
||||
}
|
||||
else if (name == kw_at_require)
|
||||
{
|
||||
if (!parse_doc_contract(c, &contracts_ref, CONTRACT_REQUIRE)) return false;
|
||||
if (!parse_doc_contract(c, contracts_ref, next, CONTRACT_REQUIRE)) return false;
|
||||
break;
|
||||
}
|
||||
else if (name == kw_at_checked)
|
||||
{
|
||||
if (!parse_doc_contract(c, &contracts_ref, CONTRACT_CHECKED)) return false;
|
||||
if (!parse_doc_contract(c, contracts_ref, next, CONTRACT_CHECKED)) return false;
|
||||
break;
|
||||
}
|
||||
else if (name == kw_at_ensure)
|
||||
{
|
||||
if (!parse_doc_contract(c, &contracts_ref, CONTRACT_ENSURE)) return false;
|
||||
if (!parse_doc_contract(c, contracts_ref, next, CONTRACT_ENSURE)) return false;
|
||||
break;
|
||||
}
|
||||
else if (name == kw_at_pure)
|
||||
{
|
||||
Ast *ast = ast_new_curr(c, AST_CONTRACT);
|
||||
ast->contract.kind = CONTRACT_PURE;
|
||||
*contracts_ref = astid(ast);
|
||||
contracts_ref = &ast->next;
|
||||
append_docs(next, contracts_ref, ast);
|
||||
advance(c);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.580"
|
||||
#define COMPILER_VERSION "0.4.581"
|
||||
Reference in New Issue
Block a user