Wrap thoughts

N

name

Well, I've reached a milestone: Here I have an adequately functional
application I can't use without some preliminary stuff. If I'm going to
assign dynamic memory, I need to know the file length, or undergo some sort
of guess routine. And other things as well. It's now immediately evident
that some non-portable code must be written to make this useful.

What to do?

At the moment, I'm inclined to wrap the 'wrap' code (heh...) in a shell
script which can supply all the parameters handily. Such a script can be
written for any operating system, of course, and that would leave the code
portable in its own right. Another approach would be to do the same with a
GUI routine (I like GTK+), and put all the non-portable code in at that level.

The last choice would be to lard the code with system calls to supply the
added functionality, or so I think.

I guess the point is to keep the portable code separate and intact. It's
easy to provide all the necessary arguments at command line for the script
to address, and that way, the app itself could be used manually if the
required information were at hand. Also, any added functionality to the
code itself could be handled the same way, as CL arguments, and the wrapper
script modified accordingly.

I guess my question here is: What *do* you guys do about this, and given
options, what order of preference thereof is most common?

Thanks for reading!
 
M

Malcolm

name said:
Well, I've reached a milestone: Here I have an adequately functional
application I can't use without some preliminary stuff. If I'm going to
assign dynamic memory, I need to know the file length, or undergo some sort
of guess routine. And other things as well. It's now immediately evident
that some non-portable code must be written to make this useful.

What to do?
Normally you can use "portable enough" code. If you want to know the length
of a file, open it, fseek() to the end, ftell() the location, and add a few
hundred bytes for luck. In strict ANSI terms this can fail, but practically
it is unlikely that your code will ever have to run on a pathological
platform.
 
N

name

Normally you can use "portable enough" code. If you want to know the length
of a file, open it, fseek() to the end, ftell() the location, and add a few
hundred bytes for luck. In strict ANSI terms this can fail, but practically
it is unlikely that your code will ever have to run on a pathological
platform.

Aha. I had gathered elsewhere that this actually didn't work, but can't now
remember exactly why. I do recall it wasn't considered portably (I
think...), but you raise an interesting and apparently practical approach.
There is excellent theoretical justification for the general "good enough"
approach, of course; the problem might be in identifying what that turns out
to be in any particular case. Seems to me the real issue is the skill and
knowledge of the programmer. But is it not always thus!

Normally, I wouldn't even raise this issue, and probably would not have
posted here in the first place. I can generally get something to work with
a bit of effort, but that's not what this particular project is about. I
want to understand what I can about programming in general, as seen from the
C programmer's point of view. And so these issues thus become relevant.

So I'll take your recommendation and see what I can make of it. I'll also
be interested in the general range of opinions regarding the "good enough"
approach.

Thanks for your response!
 
A

Arthur J. O'Dwyer

Normally you can use "portable enough" code. If you want to know the length
of a file, open it, fseek() to the end, ftell() the location, and add a few
hundred bytes for luck. In strict ANSI terms this can fail, but practically
it is unlikely that your code will ever have to run on a pathological
platform.

True enough---sometimes you do really need to write non-portable
or "portable enough" code. But lest the OP get the wrong idea:
His program does /not/ require implementation-defined behavior.
Unless he's changed the specs again, it requires O(k) memory where
k is the number entered at the command line. And that's something
you can get without knowing anything about file lengths.

I'll write the program tonight, and maybe post some more thoughts
then. In the meantime, I encourage the OP to examine 'usenetify',
'usenetify2', and Leor Zolman's 'pf', links to all of which can be
found in the Google Groups archive; search for "usenetify wrapping",
I would think. All three programs were written with portability
in mind, and they all do basically the same thing the OP is trying
to do, albeit with more bells and whistles.

-Arthur
 
N

name

On Sat, 28 Aug 2004, Malcolm wrote:


True enough---sometimes you do really need to write non-portable
or "portable enough" code. But lest the OP get the wrong idea:
His program does /not/ require implementation-defined behavior.
Unless he's changed the specs again, it requires O(k) memory where
k is the number entered at the command line. And that's something
you can get without knowing anything about file lengths.

I don't understand the '0(k)' concept. Would that not simply make any
number entered a zero? Clearly, I'm missing something (probably a lot!) here.
I'll write the program tonight, and maybe post some more thoughts
then. In the meantime, I encourage the OP to examine 'usenetify',
'usenetify2', and Leor Zolman's 'pf', links to all of which can be
found in the Google Groups archive; search for "usenetify wrapping",
I would think. All three programs were written with portability
in mind, and they all do basically the same thing the OP is trying
to do, albeit with more bells and whistles.

-Arthur

Wow!!

These, I gather, are what would be required to write the application in
"full generality"? It's immediately obvious that I'm very far behind the
curve here. I had figured that I could keep it really simple and still make
this code useful. I'm not surprised that I was wrong, though. There's
always a lot more that is required from an app than is initially envisioned,
I suspect.

And I'm not surprised that what I trying to do has already been done with a
good deal more... well, a good deal of most everything, I guess! So what I
think I'll do is study these three programs and learn from them. At this
point, I'm not sure that continuing to work on 'wrap' has any merit, except
as a platform for experimentation.

Thanks a lot for sharing, and I appreciate the help, Arthur!
 
A

Arthur J. O'Dwyer

I don't understand the '0(k)' concept. Would that not simply make any
number entered a zero? Clearly, I'm missing something (probably a lot!)
here.

Yup; for one thing, you're missing a computer font that lets you
tell the difference between '0' and 'O'. I suggest Courier, although
ISTR there was a thread in comp.programming a month ago with some
"alternative" fixed-width font suggestions. :)
Google "Big-O notation", and ask comp.programming or comp.theory
if you still don't get it.

Wow!!

These, I gather, are what would be required to write the application in
"full generality"? It's immediately obvious that I'm very far behind the
curve here.

Well, no. It depends what you're trying to do. Those three programs
are all specifically targeted at correctly wrapping /C code/ (and/or
C++ code) to Usenet standards, which requires not only detabbing (which
I suggest you try) but also preserving the semantics of C code (which I
suggest you don't try yet). Consider wrapping the line

puts ("places on the table")

For your purposes, it suffices to wrap the line at word breaks, as

puts ("places on
the table")

But Leor and I were trying to preserve the C semantics of the wrapped
text---so it would wrap as one of

puts ("places on\
the table")

puts ("places on"
" the table")

So those programs aren't doing exactly the same thing that you're
trying to do; but they /are/ doing something similar (if more
complicated.) Looking at their basic structure and I/O routines may
help you get a better perspective on your own task.
And I'm not surprised that what I trying to do has already been done with a
good deal more... well, a good deal of most everything, I guess! So what I
think I'll do is study these three programs and learn from them. At this
point, I'm not sure that continuing to work on 'wrap' has any merit, except
as a platform for experimentation.

Well, wasn't that always the case? ;)

-Arthur
hasn't gotten back to coding yet, but will try later tonight
 
N

name

Yup; for one thing, you're missing a computer font that lets you
tell the difference between '0' and 'O'. I suggest Courier, although
ISTR there was a thread in comp.programming a month ago with some
"alternative" fixed-width font suggestions. :)
Google "Big-O notation", and ask comp.programming or comp.theory
if you still don't get it.

OMG! I clearly got that one completely wrong! Yes, I can see the
difference with the font I use (Courier of some brand or other), and this is
another example of seeing what one expects instead of what is actually there!

Big O notation, eh. Asymptotics and infinites and infinitesmals and such.
And yeah I do remember that it can be useful for assessing algorithms. I'll
have to go back and look at all this; I do remember being fascinated by the
behavior of asymptotes but that was a very long time ago, and one quickly
loses what one does not use.
Well, no. It depends what you're trying to do. Those three programs
are all specifically targeted at correctly wrapping /C code/ (and/or
C++ code) to Usenet standards, which requires not only detabbing (which
I suggest you try) but also preserving the semantics of C code (which I
suggest you don't try yet). Consider wrapping the line

puts ("places on the table")

For your purposes, it suffices to wrap the line at word breaks, as

puts ("places on
the table")

But Leor and I were trying to preserve the C semantics of the wrapped
text---so it would wrap as one of

puts ("places on\
the table")

puts ("places on"
" the table")

So those programs aren't doing exactly the same thing that you're
trying to do; but they /are/ doing something similar (if more
complicated.) Looking at their basic structure and I/O routines may
help you get a better perspective on your own task.

Aha. Yes, I did get that after a closer look. And yes, this is very much
more complex, of course.

But the basic problem remains: I've not got a clear idea of what this code
should and should not be expected to do, which is a matter of not having
made some design decisions at the beginning. As it stands, the code does
pretty much what I expect it to do with a minimum of fuss. But if I want it
to do large files, there will undoubtedly be other (more) format
considerations that it will need to handle. Etc.

Fact is, I can declare it done as it is, but that's no fun... <grin> So I
guess I should stop and think about these design decisions, and then work
toward implementing them; I fancy that is what professional programmers do,
indeed, what they have to do!

In any case, looking at the code you guys wrote makes it very clear that
having an original purpose that's well defined is a Good Thing, and that in
itself informs my view of your code; it's intended to do specific things
with specific parameters provided. Absent those, one really can't tell
whether the code is appropriate and effective: What, exactly, is it
supposed to DO?!?
Well, wasn't that always the case? ;)

Well, I thought I'd like to see what it would take to create a finished
product. Problem is, as I said, I have to be able to recognize when it
is one, and that takes deciding just what that should be. OTOH, changing
the intent to experimentation is worth considering.
-Arthur
hasn't gotten back to coding yet, but will try later tonight

Okay, I'll keep watch, and thanks again!
 
J

Joona I Palaste

OMG! I clearly got that one completely wrong! Yes, I can see the
difference with the font I use (Courier of some brand or other), and this is
another example of seeing what one expects instead of what is actually there!
Big O notation, eh. Asymptotics and infinites and infinitesmals and such.
And yeah I do remember that it can be useful for assessing algorithms. I'll
have to go back and look at all this; I do remember being fascinated by the
behavior of asymptotes but that was a very long time ago, and one quickly
loses what one does not use.

Kids these days think "Big O" is a Japanese cartoon series. It felt odd
going to a cartoon collectors' shop and seeing a series with a name I
had seen before but in a different context.
 
A

Arthur J. O'Dwyer

But the basic problem remains: I've not got a clear idea of what this code
should and should not be expected to do, which is a matter of not having
made some design decisions at the beginning. [...]
In any case, looking at the code you guys wrote makes it very clear that
having an original purpose that's well defined is a Good Thing, and that in
itself informs my view of your code; it's intended to do specific things
with specific parameters provided. Absent those, one really can't tell
whether the code is appropriate and effective: What, exactly, is it
supposed to DO?!?

Exactly. Of course, sometimes you can fail to anticipate all of the
corner cases that will come up. And sometimes, especially with tasks
like this line-wrapping project, you have to make decisions that are
based less on "what is right" and more on "what looks right." I found
a couple of those cases and documented them in my 'wrap.c' program
(see below). Consider, for example, wrapping the line

[23456789-123456789-1]
abc def

at a line length of 10 characters. The simplest thing to do is
replace spaces by newlines at positions 11 and 19, which yields
a result that looks like this on the screen:

abc

def

There's a blank line between the two parts of the input line. Is
that really "what looks right" in this case? Or should we try to
insert some ad-hoc code to deal with this special case?: say, don't
print any line if it's composed entirely of blanks.

Unfortunately, no textbook is going to give you the answers to
questions like that. You've just got to figure out what approach
will give you the "nicest-looking" results, and then code it.
Where "nicest-looking" is pretty much subjective, unless you have
the luxury of a whole bunch of beta-testers. :)


Anyway, I did finally code a simple 'wrap' program. It was harder
than I thought at first---lots of opportunities for off-by-one
errors! The finished product is on the web at
http://www.contrib.andrew.cmu.edu/~ajo/disseminate/wrap.c

HTH,
-Arthur
 
N

name

But the basic problem remains: I've not got a clear idea of what this code
should and should not be expected to do, which is a matter of not having
made some design decisions at the beginning. [...]
In any case, looking at the code you guys wrote makes it very clear that
having an original purpose that's well defined is a Good Thing, and that in
itself informs my view of your code; it's intended to do specific things
with specific parameters provided. Absent those, one really can't tell
whether the code is appropriate and effective: What, exactly, is it
supposed to DO?!?

Exactly. Of course, sometimes you can fail to anticipate all of the
corner cases that will come up. And sometimes, especially with tasks
like this line-wrapping project, you have to make decisions that are
based less on "what is right" and more on "what looks right." I found
a couple of those cases and documented them in my 'wrap.c' program
(see below). Consider, for example, wrapping the line

[23456789-123456789-1]
abc def

at a line length of 10 characters. The simplest thing to do is
replace spaces by newlines at positions 11 and 19, which yields
a result that looks like this on the screen:

abc

def

There's a blank line between the two parts of the input line. Is
that really "what looks right" in this case? Or should we try to
insert some ad-hoc code to deal with this special case?: say, don't
print any line if it's composed entirely of blanks.

I guess what I get from this is that one really has to be creative in one's
search for the oddball cases. That's probably a matter of experience as
much as anything else. I would not have thought of most of these, and would
have had to figure out what to do with them when I ran across them.

But then, you've already written a program like this, and so you've already
seen many of these exceptions. I shall be satisfied if I can address them
successful when I do run across them... said:
Unfortunately, no textbook is going to give you the answers to
questions like that. You've just got to figure out what approach
will give you the "nicest-looking" results, and then code it.
Where "nicest-looking" is pretty much subjective, unless you have
the luxury of a whole bunch of beta-testers. :)

As I suggested to someone else who emphasized the planning as necessary,
sometimes one simply has to tinker a while to discover what it is that one
really does want the app to do. This follows the "Be prepared to throw the
first one away" dicta. Nevertheless, at some point one really does have to
firm up the specifications and simply work to fill them, otherwise it can
never be judged as finished.
Anyway, I did finally code a simple 'wrap' program. It was harder
than I thought at first---lots of opportunities for off-by-one
errors!

Indeed! lol!!!

Ah yes. Got it and will study it as well. Wow, I've gotten a lot of code
to study from several people now! I expect this will take a while now, but
I'll be back... <grin>

And thanks to all others as well as Arthur!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top