-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add FileIO library (read, write to file) #374
Conversation
As far as I can see, I will never want to have a a
|
while (f.isOpen()) { | ||
print("{}",f.readline()); | ||
}; | ||
f.fclose(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks a bit weird. "While f
is open, read lines from f
. When f
is no longer open, close f
". If f.isOpen()
returns false
, I would expect that I do not need to close it. Maybe f.eof()
is a better name?
Minor comment, I think |
Just noting that you should create branches in your own copy of the repository and not in this copy ( Obviously, don't change anything for now. But for the next pull request. |
----------------------------------- | ||
-- Write to file. | ||
----------------------------------- | ||
def write(fout:String, fmode:String, content:String) : void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do I need to pass the out-file and mode to this method? Don't I already have this information in the corresponding fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@supercooldave : Oh, I am sorry for my bad. I used git push
without specifying my repository's name.
At some point we could consider separating input streams from output streams to avoid having to guess if a |
@pengstrom might look into doing some nicer IO based on Iteratees sometime in the future. |
@EliasC : I agree with you, the names is quite misleading. I think in general the name can be |
----------------------------------- | ||
-- Write to file. | ||
----------------------------------- | ||
def write(fout:String, content:String) : void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fout
argument is never used (it is passed to writeChar
, which binds it to a variable that is never used). It should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(third time's the charm)
This argument is never used and should be removed.
I strongly disagree. We cannot force our users to use a good naming convention, but we can design our libraries in a way that helps the user. Since an instream and an outstream present different interfaces, they shouldn't be the same type. If I open a file with mode With this said, I think that this could be fixed later. |
(also, you will probably want to squash your commits for the final push) |
The squash can be done on github via merge button. FYI. |
|
||
def eof() : bool { | ||
let f = this.file; | ||
embed bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you use embed bool feof(#{f}); end
instead? (only asking since you need another commit to remove the fout
argument from write
and writeChar
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems the embed bool feof(#{f}); end
does not work correctly. It prints nothing.
While using previous implementation, it prints the file's content.
def eof() : bool {
let f = this.file;
embed bool
bool res = true;
if (ungetc(fgetc(#{f}),#{f})==EOF) res = false;
else res = true;
res;
end;
}
Don't forget to fix the last tiny things so that we can get this merged :) |
Thanks @EliasC . I have pushed the revised version. |
What about async I/O? I worry about adding a file abstraction that will kill performance … because we have a tendency of letting that file become the file, plus breaking legacy code. |
@TobiasWrigstad: There is no legacy code. |
@TobiasWrigstad: I don't think that merging this is a big problem. There are other refactorings we should do here anyway, so it won't stay the file. |
I think this is good enough! Better to have a synchronous version than nothing at all. |
@TobiasWrigstad : I think the asyn I/O would be better. The sync version is used when I review the RequestHttp PL, I think a FileIO module is necessary to write out the result. I also have another asyn I/O version. Should I push it here? |
What does this mean?
Do you have an async file abstraction? |
There is still segmentation fault with this async version. class File {
....
}
class Main
def main () : void {
let file = "IOTest.out";
let f = new File(file,"w");
let msg = "Hello World!\n";
-- Test write file
f.open(file,"a");
f.write(file,msg);
f.close();
-- Test read file
f.open(file,"r");
while (not (get f.eof())) {
print("{}", get f.readline());
};
f.close();
print "Finished!"
} |
OK. I'm going with @kikofernandez's recommendation. Let's support what works now and add async I/O later. |
def writeChar(fout:String, content:embed char* end) : void { | ||
let | ||
fout1 = fout.data | ||
mode = this.mode.data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two variables also aren't used.
@PhucVH888: Please remove the unused variables from |
@EliasC : I have fixed it. Tack! |
I think has uncovered a bug! Your implementation of
The conditional of this loop should be |
You are right. The very first name of the function is |
def readlineChar() : embed char* end { | ||
let f = this.file; | ||
embed (embed char* end) | ||
char* line = encore_alloc(_ctx,255); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@albertnetymk: Does this code run a risk of an outdated context? Consider if readline
is called in a loop that also does get
.
(@PhucVH888: this is related to a bug discovered by Albert yesterday, you shouldn't worry about having introduced it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@EliasC : Does it solve the outdated context if the _ctx
is refreshed before passing to encore_alloc()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, @albertnetymk's solution to these problems is calling encore_ctx()
instead of using the (possibly stale) _ctx
variable. I'm working on a PR to make sure that all embedded uses of encore_alloc
refresh the context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then to be safe, let's change _ctx
for a call to encore_ctx()
, and then I think this is ready to be merged!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does encore_ctx()
return _ctx
?
Should I change like this char* line = encore_alloc(encore_ctx(),255);
or this encore_ctx(); char* line = encore_alloc(_ctx,255);
?
Because it works in both ways.
I would do the following (since the evaluation of function arguments in C is not defined):
|
I don't think the evaluation order matters here. Actually, the one-liner looks more compact. Subjective, sure. |
I read somewhere in stackoverflow that in C99, |
@kikofernandez That's very surprising. How can a function call be evaluated before it's arguments ... except in Haskell. |
I am only aware that arguments evaluation order is undefined in C, but that the evaluation could happen after the function call is beyond me. Reference? |
@kikofernandez: I think only the order of evaluation is unspecified, so if you have EDIT: What @albertnetymk said... |
Ok, maybe this is not the most reliable source but I understand something different from here: http://www.geeksforgeeks.org/g-fact-20/ |
|
Here is a good text on the subject: http://stackoverflow.com/a/4176333 |
For record purpose, I think inlining |
Let's try with inlining |
I think this is ready to be merged! Merging in 30 min unless there are objections (I will try to auto-squash to see how it works :) ) |
I have added the basic File IO library to Encore prototype along with the test.
The library has basic functions as the following: