Append a record to the end of a text file: Difference between revisions

(Added solution for Action!)
Line 1,410:
|-
| FB Type || CSV text file || FB Standard Library || ☑ || ☑ || ☑ (Hopefully!)
|}
 
=={{header|Free Pascal}}==
''See also [[#Pascal|Pascal]]''
{{works with|Linux}}
<lang delphi>{$mode objFPC}
{$longStrings on}
{$modeSwitch classicProcVars+}
 
uses
cTypes,
// for system call wrappers
unix;
 
const
passwdPath = '/tmp/passwd';
 
resourceString
advisoryLockFailed = 'Error: could not obtain advisory lock';
 
type
GECOS = object
fullname: string;
office: string;
extension: string;
homephone: string;
email: string;
function asString: string;
end;
entry = object
account: string;
password: string;
UID: cUInt;
GID: cUInt;
comment: GECOS;
directory: string;
shell: string;
function asString: string;
end;
 
function GECOS.asString: string;
const
separator = ',';
begin
with self do
begin
writeStr(result, fullname, separator, office, separator, extension,
separator, homephone, separator, email);
end;
end;
 
function entry.asString: string;
const
separator = ':';
begin
with self do
begin
writeStr(result, account, separator, password, separator, UID:1,
separator, GID:1, separator, comment.asString, separator, directory,
separator, shell);
end;
end;
procedure writeEntry(var f: text; const value: entry);
begin
writeLn(f, value.asString);
end;
 
procedure appendEntry(var f: text; const value: entry);
begin
// (re-)open for writing and immediately seek to EOF
append(f);
writeEntry(f, value);
end;
 
 
// === MAIN ==============================================================
var
passwd: text;
 
procedure releaseLock;
begin
// equivalent to `exitCode := exitCode + …`
inc(exitCode, fpFLock(passwd, lock_un));
end;
 
var
user: entry;
line: string;
 
begin
assign(passwd, passwdPath);
// open for reading
reset(passwd);
if fpFLock(passwd, lock_ex or lock_NB) <> 0 then
begin
writeLn(stdErr, advisoryLockFailed);
halt(1);
end;
addExitProc(releaseLock);
// reopen for _over_writing: immediately sets file size to 0
rewrite(passwd);
user.account := 'jsmith';
user.password := 'x';
user.UID := 1001;
user.GID := 1000;
user.comment.fullname := 'Joe Smith';
user.comment.office := 'Room 1007';
user.comment.extension := '(234)555-8917';
user.comment.homephone := '(234)555-0077';
user.comment.email := 'jsmith@rosettacode.org';
user.directory := '/home/jsmith';
user.shell := '/bin/bash';
appendEntry(passwd, user);
with user do
begin
account := 'jdoe';
password := 'x';
UID := 1002;
GID := 1000;
with comment do
begin
fullname := 'Jane Doe';
office := 'Room 1004';
extension := '(234)555-8914';
homephone := '(234)555-0044';
email := 'jdoe@rosettacode.org';
end;
directory := '/home/jdoe';
shell := '/bin/bash';
end;
appendEntry(passwd, user);
// Close the file, ...
close(passwd);
with user, user.comment do
begin
account := 'xyz';
UID := 1003;
fullname := 'X Yz';
office := 'Room 1003';
extension := '(234)555-8913';
homephone := '(234)555-0033';
email := 'xyz@rosettacode.org';
directory := '/home/xyz';
end;
// ... then reopen the file for append.
appendEntry(passwd, user);
// open the file and demonstrate the new record has indeed written to the end
reset(passwd);
while not EOF(passwd) do
begin
readLn(passwd, line);
writeLn(line);
end;
end.</lang>
{{out}}
<pre>jsmith:x:1001:1000:Joe Smith,Room 1007,(234)555-8917,(234)555-0077,jsmith@rosettacode.org:/home/jsmith:/bin/bash
jdoe:x:1002:1000:Jane Doe,Room 1004,(234)555-8914,(234)555-0044,jdoe@rosettacode.org:/home/jdoe:/bin/bash
xyz:x:1003:1000:X Yz,Room 1003,(234)555-8913,(234)555-0033,xyz@rosettacode.org:/home/xyz:/bin/bash</pre>
 
{| class="wikitable" style="text-align: center; margin: 1em auto;"
|+ Append Capabilities.
|-
! colspan="2" | Data Representation
! rowspan="2" | IO<br/>Library
! rowspan="2" | Append<br/>Possible
! rowspan="2" | Automatic<br/>Append
! rowspan="2" | Multi-tasking<br/>Safe
|-
! In core || On disk
|-
| <tt>record</tt> || ASCII text || default <abbr title="run-time library">RTL</abbr> || ☑ || ☐ || ☐
|}
 
Line 2,463 ⟶ 2,643:
|-
| Object/Tuple || Text file || Nim Io || ☑ || ☑ || Window: yes<br/>Posix: Advisory lock
|}
 
=={{header|Pascal}}==
''See also: [[#Free Pascal|Free Pascal]]''
{{works with|Extended Pascal}}
<lang pascal>program appendARecordToTheEndOfATextFile;
 
var
passwd: bindable text;
FD: bindingType;
 
begin
{ initialize FD }
FD := binding(passwd);
FD.name := '/tmp/passwd';
{ attempt opening file [e.g. effective user has proper privileges?] }
bind(passwd, FD);
{ query binding state of `passwd` }
FD := binding(passwd);
if not FD.bound then
begin
writeLn('Error: could not open ', FD.name);
halt;
end;
{ open for overwriting }
rewrite(passwd);
writeLn(passwd, 'jsmith:x:1001:1000:Joe Smith,Room 1007,(234)555-8917,(234)555-0077,jsmith@rosettacode.org:/home/jsmith:/bin/bash');
writeLn(passwd, 'jdoe:x:1002:1000:Jane Doe,Room 1004,(234)555-8914,(234)555-0044,jdoe@rosettacode.org:/home/jdoe:/bin/bash');
{ close }
unbind(passwd);
{ rebind }
bind(passwd, FD);
FD := binding(passwd);
if not FD.bound then
begin
writeLn('Error: could not reopen ', FD.name);
halt;
end;
{ open in append/writable mode }
extend(passwd);
{ write another record to file }
writeLn(passwd, 'xyz:x:1003:1000:X Yz,Room 1003,(234)555-8913,(234)555-0033,xyz@rosettacode.org:/home/xyz:/bin/bash');
end.</lang>
 
{| class="wikitable" style="text-align: center; margin: 1em auto;"
|+ Append Capabilities.
|-
! colspan="2" | Data Representation
! rowspan="2" | IO<br/>Library
! rowspan="2" | Append<br/>Possible
! rowspan="2" | Automatic<br/>Append
! rowspan="2" | Multi-tasking<br/>Safe
|-
! In core || On disk
|-
| string literal || ASCII text || language core || ☑ || ☐ || ☐
|}
 
149

edits