Top vs. bottom posting, solution proposal ;-)

Arthur Pemberton pemboa at gmail.com
Sun Oct 15 20:27:57 UTC 2006


On 10/15/06, Marko Vojinovic <vvmarko at panet.co.yu> wrote:
>
> Hi everybody, :-)
>
> Please, don't hate me for bringing up this topic yet again. I do not wish to
> start another flame, and have no preferences with respect to top/bottom
> posting.
>
> It's just that in several years on this list there were several long
> discussions about that, and I guess we could do without them. :-)
>
> So, I devoted a couple of hours of my time to write down some prototype of
> top/bottom post converter, creatively named top2bottom.c :-) . I didn't even
> bother to google-research for any already existing stuff of the kind, just
> started from scratch and c-ed until it started working... The code is below.
> (Sorry, I don't have a website to upload it and send you a link, it seems the
> easiest way was to post it...) Also, below are some notes about it, for those
> interested.
>
> Try it, and if you like it, send me some feedback to make it better. Or do it
> yourself. Consider this to be my $0.04 to the global benefit of the list.
> Just imagine the scenario: somebody top-posts; he gets a kind reply to not
> top-post; if he continues, top-post-annoyed people filter his messages
> through top2bottom transparently, and there is no discussion about it any
> more. There is peace on Earth, and good will among people... ;-)
>
> Best regards, :-)
> Marko
>
> Still here? Ok. Read on... :-)
>
> A couple of usage notes:
> * This is c code. :-) I prefer it to assembly language, and don't have enough
> skill to do it using bash.
> * Compile it via "gcc top2bottom.c -o top2bottom", should work with any
> version of gcc. Actually, I guess it is compiler/os/platform independent.
> * It reads from stdin and writes to stdout. Feed it with the body of the
> top-posted message to get it bottom-posted.
>
> A couple of features/bugs:
> * Top-posted messages become bottom-posted. By reversing the order of sorting,
> one can make bottom-posted messages get converted to top-posted.
> * "Interspersed" messages are not touched.
> * The "Yesterday Jim wrote:" titles of quotes get from the top of the quote to
> the bottom of it. This may make a message look a bit awkward or confusing,
> but there is no easy way out of it. OTOH, when there are several successive
> quotes, the titles are equally confusing being on the top, also (at least for
> me).
> * ">" is the sole quoting symbol recognized. If there is feedback that this
> thing is useful, i'll be happy to include other quoting symbols, implement a
> bunch of behaviour-changing options, clean up and optimize the code, etc.
>
> A couple of technical notes:
> * I am completely aware that this program is terribly inefficient,
> unoptimized, slow, has insane memory usage, etc..., and that I have broken
> virtually every programming rule that can apply in this case.
> * That said, have in mind that this is just a proof-of-concept code, put
> together in a couple of hours, and I don't want to do any real work on it
> unless I get some feedback that it is useful to the others.
> * That said, note that it works.
> * If it doesn't work, tell me about it. If it segfaults, you probably need to
> enlarge the 5000 characters-per-line limit and/or 5000 lines-per-message
> limit... I know, it's a hack, it's ugly, it's awful, it's crap...
> * If you need to know about licencing etc, consider this to be GNU GPL
> software, although I don't really care. Use it, modify it, whatever...
> * DO NOT learn how to program by looking at this. This is a VERY VERY BAD
> example of code. :-)
> * It's not that I am a bad programmer, I am just being lazy. Have other things
> to do in life, a thesis to work on, etc...
>
> YET STILL HERE??!! Ok, here goes the code. Note that it may look ugly due to
> line wrapping, but it should work nevertheless... :-)
>
> ======== Beginning of the file top2bottom.c ============
> #include <stdio.h>
>
> #define MaxLine 5000  /* Maximum number of characters per line  */
> #define MaxMesg 5000  /* Maximum number of lines per file */
> #define EOLN '\n'    /* End of line character */
>
> int interspersed;       /* indicator to say whether the message is
> interspersed or not */
> int NumberOfLines;      /* Counts the total number of lines in a message */
>
> struct MessageStruct {
>  int quoteorder;            /* The number of leading quote symbols in this
> line */
>  int linenumber;            /* The initial number of this line */
>  char data[MaxLine];        /* The line string */
> } line[MaxMesg];        /* An array of lines, ie. the whole message buffer */
>
> void ReadTheMessage()
> {
> char c;
> int n=0;                 /* Current line counter */
> int i=0;                 /* Current character counter */
> int endoffile=0;         /* End of file indicator */
>
>  NumberOfLines=0;           /* Message is empty at this point */
>  while((!endoffile)&&((c=getchar())!=EOF))        /* Read in the data from
> stdin */
>   {
>    line[n].quoteorder=0;       /* Initialize the quote order. It will be
> counted later... */
>    i=0;                        /* Reset the character counter */
>    while((c!=EOLN)&&(c!=EOF))  /* Read in the current line */
>     {
>      line[n].data[i] = c;         /* Feed the message buffer with the data */
>      i++;                         /* Move to the next character */
>      c=getchar();                 /* Read it, and repeat */
>     }
>    line[n].data[i] = EOLN;     /* Finish the string */
>    line[n].linenumber=n;       /* Set the line number */
>    n++;                        /* Move to the next line, and repeat */
>    if(c==EOF) endoffile=1;     /* Handle the premature end of file */
>   }
>  NumberOfLines=n;           /* Save the number of lines and finish */
> }
>
> void WriteTheMessage()
> {
> int n=0;                  /* Current line counter */
> int i=0;                  /* Current character counter */
>
>  while(n<NumberOfLines)         /* Write the data to stdout */
>   {
>    i=0;                            /* Reset the character counter */
>    while(line[n].data[i]!=EOLN)
>      putchar(line[n].data[i++]);   /* Write the current line */
>    putchar(EOLN);                  /* Write the end of line */
>    n++;                            /* Move to the next line, and repeat */
>   }
> }
>
> void AnalyzeTheMessage()
> {
> char c;
> int n=0;                  /* Current line counter */
> int i=0;                  /* Current character counter */
> int k=0;                  /* Current quote order counter */
> int orderlessthenk=0;     /* Indicator if there is a quoteorder less then k */
> int maxquoteorder=0;      /* Maximum value for the quoteorder */
>
> /*
> Ok. First we count the so called "quote order" of each line,
> which amounts to number of leading '>'s per line. In the process,
> we need to account for the famous "From" bug in sendmail, and
> decrement the quoteorder if the text starts with the word
> "From", in order to get it right.
> */
>  for(n=0;n<NumberOfLines;n++)      /* Go through the each line */
>   {
>    i=0;                                    /* Reset the character counter */
>    c=line[n].data[i];                      /* Set the initial data */
>    while( ((c=='>')||(c==' ')) &&(c!=EOLN) )  /* Count the leading '>'s, skip
> spaces */
>     {
>      if (c=='>') line[n].quoteorder++;        /* Increment quoteorder for each
> '>' */
>      i++;                                     /* Go to the next character */
>      c=line[n].data[i];                       /* Read it, and repeat */
>     }
>    if (  (c=='F')&&                        /* Check if the following string is
> "From" */
>          (line[n].data[i+1]=='r')&&        /* Now, this is very, very ugly...
> */
>          (line[n].data[i+2]=='o')&&
>          (line[n].data[i+3]=='m')  )
>     line[n].quoteorder--;                     /* If yes, decrease the
> quoteorder... */
>   }
> /*
> Now we need to check if the message is interspersed or not. This is tricky,
> as we need to find constructions of the form:
>
> > > >
> >
> > > >
>
> and similar, which amount to quoteorder being 3,1,3 and the like.
> Simoultaneously, we *don't* want to find constrctions of the form:
>
> >
> > > >
> >
>
> because this can happen even if the message is not interspersed.
> But that's life... ;-)
> */
>  for(n=0;n<NumberOfLines;n++)           /* First find the biggest quote order
> */
>   if (line[n].quoteorder>maxquoteorder) maxquoteorder=line[n].quoteorder;
>
>  interspersed=0;     /* Assume message is not interspersed */
>
>  for(k=1;k<maxquoteorder;k++)   /* We need to check the above construction for
> all nonzero quote orders */
>   {
>    n=0;               /* Start from the begining of the message */
>    while ((line[n].quoteorder!=k)&&(n<NumberOfLines)) n++;  /* Get to the
> block of lines of quoteorder k */
>    while ((line[n].quoteorder==k)&&(n<NumberOfLines)) n++;  /* Go through the
> block */
>         /* Now go down the rest ot the lines, and check if some line has
>            quoteorder less then k, and another line after it the quoteorder
>            equal to k again, which amounts to interspersed construction.
> */
>    orderlessthenk=0;     /* Assume there are no quotes of order less then k */
>    while (n<NumberOfLines)     /* For each of the remaining lines */
>     {
>      if (line[n].quoteorder<k) orderlessthenk = 1;  /* alert if there is a
> quote of lesser order */
>      if ((line[n].quoteorder==k)&&(orderlessthenk)) interspersed=1; /* We
> found the interspersed construction!! */
>      n++;                      /* Go check the next line */
>     }
>   }
> /*
> And that's it. If the message has interspersed structure on any level
> of quoteorder, we have the indicator on. Otherwise, it is off.
> */
> }
>
> void SwitchLines(int i, int j)
> {
> int n;
> int tempquoteorder;
> int templinenumber;
> char tempdata[MaxLine];
>
> /* This switches line i with line j, as needed for sorting (sigh)... */
>  n=0;                                    /* Copy line i to temp */
>  tempquoteorder=line[i].quoteorder;
>  templinenumber=line[i].linenumber;
>  while(line[i].data[n]!=EOLN)
>   tempdata[n]=line[i].data[n++];
>  tempdata[n]=EOLN;
>  n=0;                                    /* Copy line j to line i */
>  line[i].quoteorder=line[j].quoteorder;
>  line[i].linenumber=line[j].linenumber;
>  while(line[j].data[n]!=EOLN)
>   line[i].data[n]=line[j].data[n++];
>  line[i].data[n]=EOLN;
>  n=0;                                    /* Copy temp to line j */
>  line[j].quoteorder=tempquoteorder;
>  line[j].linenumber=templinenumber;
>  while(tempdata[n]!=EOLN)
>   line[j].data[n]=tempdata[n++];
>  line[j].data[n]=EOLN;
> }
>
> void SortTheMessage()
> {
> int i,j;
>
> /*
> In order to make the message bottom-posted, we simply need to sort the lines
> by quoteorder
> descending. Further, we need to preserve the order of lines of the same
> quoteorder,
> which amounts in sorting same-quoteorder lines by line number, ascending.
> N.B.: Maybe this can be done in a more clever way, but I am lazy to ponder
> over it... :-)
> */
>
> /* The algorithm is just a simple, stupid and slow bubble-sort, over
> quoteorder and
> linenumber simultaneously... */
>  for(i=0;i<NumberOfLines;i++)
>   for (j=0;j<=i;j++)
>    {
>     if(line[i].quoteorder>line[j].quoteorder) SwitchLines(i,j);
>
> if((line[i].quoteorder==line[j].quoteorder)&&(line[i].linenumber<line[j].linenumber))
> SwitchLines(i,j);
>    }
> }
>
> int main()                /* This is self-explanatory, I hope... :-) */
> {
>  ReadTheMessage();
>  AnalyzeTheMessage();
>  if (!interspersed) SortTheMessage();
>  WriteTheMessage();
> }
>
> ======== End of the file top2bottom.c ================
>

Not that this debate really matters to me, lthough I do see the
benifits of bottom posting, I am willing to host this on my site
www.pembo13.com for you if you'd like.

-- 
Fedora Core 5 and proud




More information about the users mailing list