From: Owner on
Anyone knows how ed 's buffer is represented?
Is it linked list in memory or a scratch file?
What library function call used to create buffer?
Any extra information wouldbe appreciated.
From: Owner on
On Tue, 22 Jun 2010 23:08:15 +0000, Tim Harig wrote:

> ftp://ftp.math.utah.edu/pub/mirrors/minnie.tuhs.org/PDP-11/Trees/2.11BSD/usr/src/bin/ed.c

Thank you. I was looking for something like this.
From: Jens Thoms Toerring on
Owner <Owner(a)owner-pc.com> wrote:
> On Tue, 22 Jun 2010 23:08:15 +0000, Tim Harig wrote:

> I still not quite sure what they're using for buf from the
> source file

> I'm looking at putfile routine guessing it read one line
> by one line and saves to buf file

> putfile()
> {
> int *a1, n;
> register char *fp, *lp;
> register nib;

> nib = 512;
> fp = genbuf;
> a1 = addr1;
> do {
> lp = getline(*a1++);
> for (;;) {
> if (--nib < 0) {
> n = fp-genbuf;
> if(write(io, genbuf, n) != n) {
> puts(WRERR);
> error(Q);
> }
> nib = 511;
> fp = genbuf;
> }
> count++;
> if ((*fp++ = *lp++) == 0) {
> fp[-1] = '\n';
> break;
> }
> }
> } while (a1 <= addr2);
> n = fp-genbuf;
> if(write(io, genbuf, n) != n) {
> puts(WRERR);
> error(Q);
> }
> }

You can't tell from that bit of code. It simply seems to
copy stuff from one buffer to another, replacing '\0'
chars by '\n' in the process, and writing out the result.
The getline() function seems to take some kind of index
as it's argument and then seems to return a pointer to
a string, probably a line. The buffer used for output
seems to be limited to 512 chars. Having a closer look
at the getline() function may tell you a it more about
the way the lines are stored internally.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt(a)toerring.de
\__________________________ http://toerring.de
From: Tim Harig on
On 2010-06-23, Jens Thoms Toerring <jt(a)toerring.de> wrote:
> Owner <Owner(a)owner-pc.com> wrote:
>> On Tue, 22 Jun 2010 23:08:15 +0000, Tim Harig wrote:
>
>> I still not quite sure what they're using for buf from the
>> source file
>
>> I'm looking at putfile routine guessing it read one line
>> by one line and saves to buf file

Owner:
This is what, top posting with the atribution on top? If you insist on
top posting, the attribution should at least be with the quoted text to
make it clear what is being attributed.

> You can't tell from that bit of code. It simply seems to
> copy stuff from one buffer to another, replacing '\0'
> chars by '\n' in the process, and writing out the result.
> The getline() function seems to take some kind of index
> as it's argument and then seems to return a pointer to
> a string, probably a line. The buffer used for output

Owner should have looked at the GNU version which is somewhat cleaner.
Massive use of global variables, three letter variable names, and a total
lack of comments make this a questionable coding example.

> seems to be limited to 512 chars. Having a closer look
> at the getline() function may tell you a it more about
> the way the lines are stored internally.

Have a look at append() and gettty() which is where the bulk of the buffer
processing takes place. append() usually takes a function pointer to
gettty() to actually get the user line input.
From: Pascal J. Bourguignon on
Owner <Owner(a)Owner-PC.com> writes:

> Can any guess what std functions used to manipulate file
> based buffer?

You didn't learn anything from this thread?

Same answer!

Go read the sources, or imagine how you would do it yourself!!!



> That's one question I couln't guess at all.

Then go read the sources.


> Only function I see to move around inside text buffer is
> fseek. And I'm guessing everytime file is being saved,
> seperate new buffer is needed to copy everything including
> new modifications to original buffer. so everything is
> re-copied to new buffer everytime change is made to original
> buffer. Am I guessing little right about how file based
> buffer works?


Again, ed works line by line.

So one thing you need to implement the commands of ed, is a data
structure that let's you find a line from its line number, to insert
or delete a line. Whether the lines themselves are loaded into RAM or
kept in the file is irrelevant for this data structure. Whether this
data structure is implemented as a linked list, a hash-table, a
vector, or anything is also irrelevant. What matters is that you have
this abstract data type signature:

(make-buffer) --> buffer
(line-at buffer number) --> line
(line-count buffer) --> integer
(insert-line buffer integer line) --> buffer
(delete-line buffer integer) --> buffer

With only this, you can implement already half the commands of ed.


Now to load a file without loading the lines, you will need to build
an index of the original lines. This is done easily by reading the
file, and noting the position of each newline character. You can then
have a subclass of line representing cached-lines, and another
representing in-memory-lines.

line = (or cached-line in-memory-line)

(make-cached-line position length) --> cached-line
(load-line cached-line) --> in-memory-line
(cached-line-position cached-line) --> integer
(cached-line-length cached-line) --> integer

(make-in-memory-line) --> in-memory-line
(line-length in-memory-line) --> integer
(insert-character in-memory-line integer character) --> in-memory-line
(delete-character in-memory-line integer) --> in-memory-line


And as you noted, you can use fseek to position back to the beginning
of the line, so that you can implement load-line as:

(defun read-line (file in-memory-line remaining-length)
(if (zerop remaining-length)
in-memory-line
(read-line file
(insert-character in-memory-line (line-length in-memory-line) (read-char file))
(- remaining-length 1))))


(defun load-line (cached-line)
(fseek *file* (cached-line-position cached-line))
(read-line *file* (make-in-memory-line) (cached-line-length cached-line)))


--
__Pascal Bourguignon__ http://www.informatimago.com/