home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / xp / xp_wrap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  22.4 KB  |  805 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /* *
  20.  * 
  21.  *
  22.  * xp_wrap.c --- Word wrapping.
  23.  *
  24.  * Created: Jamie Zawinski <jwz@netscape.com>, 24-Jan-95.
  25.  */
  26.  
  27. #include "xp.h"
  28. #include "libi18n.h"
  29. #include <ctype.h>
  30.  
  31. #ifndef NOT_NULL
  32. #define NOT_NULL(x)x
  33. #endif
  34.  
  35.  
  36. #define XP_WORD_WRAP_NEW_CODE 1
  37. #ifdef  XP_WORD_WRAP_NEW_CODE
  38.  
  39.  
  40. #undef OUTPUT
  41. #define OUTPUT(b) \
  42. do \
  43. { \
  44.     if (out - ret >= size) \
  45.     { \
  46.         unsigned char *old; \
  47.         size *= 2; \
  48.         old = ret; \
  49.         ret = XP_REALLOC(old, size); \
  50.         if (!ret) \
  51.         { \
  52.             XP_FREE(old); \
  53.             return NULL; \
  54.         } \
  55.         out = ret + (size / 2); \
  56.     } \
  57.     *out++ = b; \
  58. } while (0)
  59.  
  60.  
  61. #undef OUTPUT_MACHINE_NEW_LINE
  62. #if defined(XP_WIN) || defined(XP_OS2)
  63. #define OUTPUT_MACHINE_NEW_LINE() \
  64. do \
  65. { \
  66.     OUTPUT(CR); \
  67.     OUTPUT(LF); \
  68. } while (0)
  69. #else
  70. #ifdef XP_MAC
  71. #define OUTPUT_MACHINE_NEW_LINE() OUTPUT(CR)
  72. #else
  73. #define OUTPUT_MACHINE_NEW_LINE() OUTPUT(LF)
  74. #endif
  75. #endif
  76.  
  77.  
  78. #undef OUTPUT_NEW_LINE
  79. #define OUTPUT_NEW_LINE() \
  80. do \
  81. { \
  82.     OUTPUT_MACHINE_NEW_LINE(); \
  83.     beginningOfLine = in; \
  84.     currentColumn = 0; \
  85.     lastBreakablePos = NULL; \
  86. } while (0)
  87.  
  88.  
  89. #undef NEW_LINE
  90. #define NEW_LINE() \
  91. do \
  92. { \
  93.     if ((*in == CR) && (*(in + 1) == LF)) \
  94.     { \
  95.         in += 2; \
  96.     } \
  97.     else \
  98.     { \
  99.         in++; \
  100.     } \
  101.     OUTPUT_NEW_LINE(); \
  102. } while (0)
  103.  
  104.  
  105. unsigned char *
  106. XP_WordWrap(int charset, unsigned char *str, int maxColumn, int checkQuoting)
  107. {
  108.     unsigned char    *beginningOfLine;
  109.     int        byteWidth;
  110.     int        columnWidth;
  111.     int        currentColumn;
  112.     unsigned char    *end;
  113.     unsigned char    *in;
  114.     unsigned char    *lastBreakablePos;
  115.     unsigned char    *out;
  116.     unsigned char    *p;
  117.     unsigned char    *ret;
  118.     int32        size;
  119.  
  120.     if (!str)
  121.     {
  122.         return NULL;
  123.     }
  124.  
  125.     size = 1;
  126.     ret = XP_ALLOC(size);
  127.     if (!ret)
  128.     {
  129.         return NULL;
  130.     }
  131.  
  132.     in = str;
  133.     out = ret;
  134.  
  135.     beginningOfLine = str;
  136.     currentColumn = 0;
  137.     lastBreakablePos = NULL;
  138.  
  139.     while (*in)
  140.     {
  141.         if (checkQuoting && (in == beginningOfLine) && (*in == '>'))
  142.         {
  143.             while (*in && (*in != CR) && (*in != LF))
  144.             {
  145.                 OUTPUT(*in++);
  146.             }
  147.             if (*in)
  148.             {
  149.                 NEW_LINE();
  150.             }
  151.             else
  152.             {
  153.                 /*
  154.                  * to prevent writing out line again after
  155.                  * the main while loop
  156.                  */
  157.                 beginningOfLine = in;
  158.             }
  159.         }
  160.         else
  161.         {
  162.             if ((*in == CR) || (*in == LF))
  163.             {
  164.                 if (in != beginningOfLine)
  165.                 {
  166.                     p = beginningOfLine;
  167.                     while (p < in)
  168.                     {
  169.                         OUTPUT(*p++);
  170.                     }
  171.                 }
  172.                 NEW_LINE();
  173.                 continue;
  174.             }
  175.             byteWidth = INTL_CharLen(charset, in);
  176.             columnWidth = INTL_ColumnWidth(charset, in);
  177.             if (currentColumn + columnWidth > (maxColumn +
  178.                 (((*in == ' ') || (*in == '\t')) ? 1 : 0)))
  179.             {
  180.                 if (lastBreakablePos)
  181.                 {
  182.                     p = beginningOfLine;
  183.                     end = lastBreakablePos - 1;
  184.                     if ((*end != ' ') && (*end != '\t'))
  185.                     {
  186.                         end++;
  187.                     }
  188.                     while (p < end)
  189.                     {
  190.                         OUTPUT(*p++);
  191.                     }
  192.                     in = lastBreakablePos;
  193.                     OUTPUT_NEW_LINE();
  194.                     continue;
  195.                 }
  196.             }
  197.             if
  198.             (
  199.               (
  200.                 ((in[0] == ' ') || (in[0] == '\t')) &&
  201.                 ((in[1] != ' ') && (in[1] != '\t'))
  202.               ) ||
  203.               (
  204.                 (INTL_CharSetType(charset) == MULTIBYTE) &&
  205.                 (
  206.                   ((!(in[0] & 0x80)) && (in[1] & 0x80)) ||
  207.                   (
  208.                 (in[0] & 0x80) &&
  209.                 (INTL_KinsokuClass(charset, in) !=
  210.                     PROHIBIT_END_OF_LINE) &&
  211.                 (!(in[byteWidth] & 0x80))
  212.                   ) ||
  213.                   (
  214.                 (in[0] & 0x80) &&
  215.                 (INTL_KinsokuClass(charset, in) !=
  216.                     PROHIBIT_END_OF_LINE) &&
  217.                 (in[byteWidth] & 0x80) &&
  218.                 (INTL_KinsokuClass(charset, &in[byteWidth]) !=
  219.                     PROHIBIT_BEGIN_OF_LINE)
  220.                   )
  221.                 )
  222.               )
  223.             )
  224.             {
  225.                 lastBreakablePos = in + byteWidth;
  226.             }
  227.             in += byteWidth;
  228.             currentColumn += columnWidth;
  229.         }
  230.     }
  231.  
  232.     if (in != beginningOfLine)
  233.     {
  234.         p = beginningOfLine;
  235.         while (*p)
  236.         {
  237.             OUTPUT(*p++);
  238.         }
  239.     }
  240.  
  241.     OUTPUT(0);
  242.  
  243.     return ret;
  244. }
  245.  
  246.  
  247. #else /* XP_WORD_WRAP_NEW_CODE */
  248.  
  249.  
  250. /* There are any number of approaches one can take to wrapping long lines
  251.    in a body of text, and this code can be configured to do several of them,
  252.    mainly as a legacy to the experimentation I did while writing it.  The
  253.    states are as follows:
  254.  
  255.    NEWLINES_ARE_SIGNIFICANT
  256.         If this is defined, then all line breaks in the input cause line
  257.         breaks in the output as well.  If it is not defined, then single
  258.         newlines in the input are considered to be simple whitespace, and
  259.         a blank line (that is, two consecutive line breaks) is needed to
  260.         break a paragraph.
  261.  
  262.    HACK_PREFIX
  263.         If this is defined, then lines beginning with ">" will be treated
  264.         specially.
  265.  
  266.    NEWLINES_ARE_SIGNIFICANT && !HACK_PREFIX
  267.         In this state, all lines which are longer than the fill column will
  268.         be wrapped, and all other lines will be left alone.
  269.  
  270.    NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX
  271.         In this state, all lines which are longer than the fill column will
  272.         be wrapped unless they begin with ">" in the first column.  Lines which
  273.         are shorter than the fill column, or lines which begin with ">", will
  274.         be left alone.
  275.  
  276.    !NEWLINES_ARE_SIGNIFICANT && !HACK_PREFIX
  277.         In this state, all paragraphs will be re-wrapped to the fill column,
  278.         regardless of where the line breaks were in the input.  A blank line
  279.         delimits a paragraph.
  280.  
  281.    !NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX
  282.         In this state, all paragraphs will be re-wrapped to the fill column,
  283.         regardless of where the line breaks were in the input.  A blank line
  284.         delimits a paragraph.
  285.  
  286.         Fill prefixes on paragraphs are recognised, if they begin with ">"
  287.         followed by any number of >'s or whitespace, and the paragraphs will
  288.         be re-filled using that prefix.
  289.  
  290.         Paragraphs are delimited by blank lines, or by changes in the prefix
  291.         sequence.
  292.  
  293.         NOTE: The code for this state is not yet fully debugged.
  294.  
  295.   The current plan is that, when the user generates a mail or news message, we
  296.   will use a text editor which does display-time wrapping of lines; and then,
  297.   when the time comes to send the message, we will wrap it to a fill column
  298.   equal to the width of the user's window.  In this way, we will (hopefully)
  299.   insert newlines in the text in the same places where the text editor had
  300.   wrapped them for display: what the user saw on the screen is what the person
  301.   at the other end will see as well.
  302.  
  303.   However, this has the drawback that no line will ever be longer than the
  304.   fill column, even when that would be better.  A common situation is this:
  305.  
  306.   = The user cites a message; this causes the message to be inserted in their
  307.     editor with a "> " prefix on each line.
  308.  
  309.   = If a line was 79 columns in the original text, it will now be 81 columns.
  310.  
  311.   = That means that the text editor will wrap the line: it will look something
  312.     like this:
  313.  
  314.             > This is a body of text that was just shorter than
  315.             the
  316.             > fill column, and is now just longer than it.  Which
  317.             causes
  318.             > the text to be displayed with alternating long and
  319.             short
  320.             > lines, which is extremely unpleasant.
  321.  
  322.     Now, if the user resized their window to be 81 columns wide instead of 80,
  323.     that text would look "normal" again; but there are two problems with this,
  324.     the first and most obvious being that most people aren't going to do that,
  325.     and the second being that that would cause the user's new text to be
  326.     filled to 81 columns as well, which would be a bad thing.
  327.  
  328.   = So, a good approach to solving this problem would be to re-fill the cited
  329.     text before inserting it in the text area, to ensure that no line is longer
  330.     than 79 columns after the prefix has been added; and then, when the user
  331.     sends the message, to wrap the lines as display did.
  332.  
  333.     This would mean applying (!NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX) to the
  334.     cited text, and then applying (NEWLINES_ARE_SIGNIFICANT && !HACK_PREFIX)
  335.     to the outgoing text.
  336.  
  337.   = However, I couldn't get the (!NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX) 
  338.     state to work well enough.  Which is the reason for the existance of the
  339.     (NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX) state.  the current plan is this:
  340.  
  341.     = The user cites a message; this causes the message to be inserted in their
  342.       editor with a "> " prefix on each line.
  343.  
  344.     = Some lines may be wider than the window, causing the display to wrap
  345.       them unattractively.
  346.  
  347.     = When the user sends the message, we insert newlines in the text at the
  348.       same places where the display would have wrapped the lines, *except* 
  349.       that we don't touch lines which begin with ">".  So, our line wrapping
  350.       is WYSIWYG for new text, but not for cited text, which is passed through
  351.       unaltered.
  352.  
  353.     I think this should do the right thing most of the time.  Problems:
  354.  
  355.     = This will mess up on lines/paragraphs which just happen to begin with ">"
  356.       as their first character.  That could cause us to send extremely long
  357.       lines.  This should be pretty rare, howeveer.
  358.  
  359.     = It is possible that the user might edit a message which *looked* like it
  360.       had a paragraph with ">" at the beginning of each line, but that really
  361.       didn't contain any newlines at all; the implicit line wrapping done by
  362.       display might be all that there is.  This also seems pretty unlikely.
  363.  
  364.     = It's fairly important that the algorithm implemented by this code be the
  365.       same as the algorithm used in redisplay by the various text editors.
  366.  
  367.   This code is pretty tough to read because of all the ifdefs; once we're
  368.   really sure how it all should work, we should rip out the unused states,
  369.   or live with duplicated code.
  370.  */
  371.  
  372. #define NEWLINES_ARE_SIGNIFICANT
  373. #define HACK_PREFIX
  374.  
  375. #undef DEBUG_WRAP
  376.  
  377. /* Oops, what was I thinking.  I wrote this thing to alter the string in
  378.    place, forgetting that on the PC, the transformation "A B" -> "A\nB"
  379.    actually increases the length of the string ("A\r\nB").
  380.  
  381.    So...  On Unix and Mac, this produces usable strings, but on the PC,
  382.    lone \015 characters will need to be expanded to \015\012.
  383.  */
  384.  
  385. #undef LINEBREAK
  386.  
  387. #if defined(XP_MAC)
  388. # define LINEBREAK "\015"
  389. #elif defined(XP_WIN)
  390. # define LINEBREAK "\015"
  391. #elif defined(XP_OS2)
  392. # define LINEBREAK "\015"
  393. #elif defined(XP_UNIX)
  394. # define LINEBREAK "\012"
  395. #endif
  396.  
  397. void
  398. XP_WordWrap (char *string, int fill_column)
  399. {
  400.   char *s;
  401.   char *input = string;
  402.   char *output = string;
  403.   char *word_start = input;        /* beginning of last word seen */
  404.   char *word_end = input;        /* end of last word seen */
  405.   int column = 0;                /* current column */
  406.   Bool in_word = FALSE;
  407.   Bool done = FALSE;
  408. #ifdef NEWLINES_ARE_SIGNIFICANT
  409. # ifdef HACK_PREFIX
  410.   Bool cited_line_p = (*string == '>');
  411. # endif /* !HACK_PREFIX */
  412. #else  /* !NEWLINES_ARE_SIGNIFICANT */
  413.   Bool white_has_newline = FALSE;
  414. # ifdef HACK_PREFIX
  415.   char last_prefix [20];
  416.   char new_prefix [20];
  417. # endif /* !HACK_PREFIX */
  418. #endif /* !NEWLINES_ARE_SIGNIFICANT */
  419.  
  420. #ifdef DEBUG_WRAP
  421.   int L = strlen (input) + 1;
  422.   char *I = input;
  423.   char *O = (char *) calloc (sizeof (char), L);
  424.   output = O;
  425. #endif /* DEBUG_WRAP */
  426.  
  427.   if (!string || !*string)
  428.     return;
  429.  
  430. #if !defined(NEWLINES_ARE_SIGNIFICANT) && defined(HACK_PREFIX)
  431. # define FIND_PREFIX() \
  432.   do { \
  433.     char *si = input; \
  434.     char *so = new_prefix; \
  435.     while (so < new_prefix + sizeof (new_prefix) && \
  436.            (*si == ' ' || *si == '\t' || *si == '>')) \
  437.       *so++ = *si++; \
  438.     so--; \
  439.     while (so > new_prefix && isspace (*so)) \
  440.       so--; \
  441.     so++; \
  442.     *so++ = 0; \
  443.     if (*so) \
  444.       input = si; \
  445.   } while (0)
  446. #endif /* !NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX */
  447.  
  448. #if !defined(NEWLINES_ARE_SIGNIFICANT) && defined(HACK_PREFIX)
  449.   FIND_PREFIX ();
  450.   XP_STRCPY (last_prefix, new_prefix);
  451.  
  452.   for (s = new_prefix; *s; s++)
  453.     {
  454.       *output++ = *s;
  455.       column++;
  456.     }
  457. #endif /* !NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX */
  458.  
  459.   word_start = input;
  460.   word_end = input;
  461.  
  462.   while (!done)
  463.     {
  464.       if (in_word && (XP_IS_SPACE (*input) || !*input))
  465.         /* If we are in a word and have reached whitespace, remember
  466.            this position in `input' as the end of the word. */
  467.         {
  468. #ifdef DEBUG_WRAP
  469.           printf ("WHITE: \"");
  470.           for (s = word_end; s < word_start; s++)
  471.             printf ("%c", *s);
  472.           printf ("\"\n");
  473.  
  474.           printf ("WORD: \"");
  475.           for (s = word_start; s < input; s++)
  476.             printf ("%c", *s);
  477.           printf ("\"\n");
  478. #endif /* DEBUG_WRAP */
  479.  
  480.           if (
  481. #if defined(NEWLINES_ARE_SIGNIFICANT) && defined(HACK_PREFIX)
  482.               !cited_line_p &&
  483. #endif /* NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX */
  484.               (column
  485.                + (
  486. #ifndef NEWLINES_ARE_SIGNIFICANT
  487.                   white_has_newline ? (input - word_start + 1) :
  488. #endif /* !NEWLINES_ARE_SIGNIFICANT */
  489.                   (input - word_end))
  490.                > fill_column)
  491.  
  492.  
  493.               /* If the word is itself longer than a line is allowed to
  494.                  be, then don't wrap - same behavior as if this is a
  495.                  cited line. */
  496.               && ((input - word_end) < fill_column)
  497.               )
  498.             {
  499.               for (s = LINEBREAK; *s; s++)
  500.                 *output++ = *s;
  501.               column = 0;
  502. #if !defined(NEWLINES_ARE_SIGNIFICANT) && defined(HACK_PREFIX)
  503.               for (s = new_prefix; *s; s++)
  504.                 *output++ = *s, column++;
  505. #endif /* NEWLINES_ARE_SIGNIFICANT && HACK_PREFIX */
  506. #ifdef DEBUG_WRAP
  507.               printf ("NEWLINE\n");
  508. #endif /* DEBUG_WRAP */
  509.             }
  510.           else
  511.             {
  512. #ifndef NEWLINES_ARE_SIGNIFICANT
  513.               if (white_has_newline)
  514.                 {
  515.                   *output++ = ' ';
  516.                   column++;
  517.                 }
  518.               else
  519. #endif /* !NEWLINES_ARE_SIGNIFICANT */
  520.                 {
  521.                   while (word_end < word_start)
  522.                     {
  523.                       *output++ = *word_end++;
  524.                       column++;
  525.                     }
  526.                 }
  527.             }
  528.  
  529.           while (word_start < input)
  530.             {
  531.               *output++ = *word_start++;
  532.               column++;
  533.             }
  534.  
  535.           word_end = input;
  536.           in_word = FALSE;
  537.  
  538. #ifdef NEWLINES_ARE_SIGNIFICANT
  539.           if (*input == CR || *input == LF)
  540.             goto HARD_BREAK;
  541.  
  542. #else  /* !NEWLINES_ARE_SIGNIFICANT */
  543.  
  544.           white_has_newline = (*input == CR || *input == LF);
  545.  
  546.           /* Treat CRLF as CR */
  547.           if (white_has_newline && *input == CR && input[1] == LF)
  548.             input++;
  549.  
  550.           if (white_has_newline)
  551.             {
  552.               input++;
  553. # ifdef HACK_PREFIX
  554.               FIND_PREFIX ();
  555.               /* If the prefixes differ, treat this as a paragraph break. */
  556.               if (XP_STRCMP (new_prefix, last_prefix))
  557.                 goto PARA_BREAK;
  558.               XP_STRCPY (last_prefix, new_prefix);
  559. # endif /* HACK_PREFIX */
  560.               continue;
  561.             }
  562. #endif /* !NEWLINES_ARE_SIGNIFICANT */
  563.  
  564.           if (!*input)
  565.             done = TRUE;
  566.         }
  567.       else if (!in_word && !*input)
  568.         {
  569.           break;
  570.         }
  571.       else if (!in_word && (!XP_IS_SPACE (*input)))
  572.         /* If we are between words and have reached non-whitespace,
  573.            remember this position in `input' as the beginning of the
  574.            word.
  575.          */
  576.         {
  577.           in_word = TRUE;
  578.           word_start = input;
  579.         }
  580.       else if (!in_word)
  581.         {
  582.           if (*input == CR || *input == LF)
  583.             {
  584. #ifdef NEWLINES_ARE_SIGNIFICANT
  585.       HARD_BREAK:
  586. # ifdef DEBUG_WRAP
  587.           printf ("HARD BREAK\n");
  588. # endif /* DEBUG_WRAP */
  589.           in_word = FALSE;
  590.           column = 0;
  591.           while (word_end < input)    /* whitespace at eol */
  592.             *output++ = *word_end++;
  593.           *output++ = *input++;
  594.           word_end = input;
  595.           word_start = input;
  596.  
  597. # ifdef HACK_PREFIX
  598.           s = input;
  599.           /* while (isspace (s)) s++; */
  600.           cited_line_p = (*s == '>');
  601. # endif /* !HACK_PREFIX */
  602.  
  603.           continue;
  604.  
  605. #else  /* !NEWLINES_ARE_SIGNIFICANT */
  606.  
  607.               /* Treat CRLF as CR */
  608.               if (*input == CR && input[1] == LF)
  609.                 input++;
  610.  
  611. # ifdef HACK_PREFIX
  612.               input++;
  613.               FIND_PREFIX ();
  614.               input--;
  615.  
  616.               /* If the prefixes differ, treat this as a paragraph break. */
  617.               if (XP_STRCMP (new_prefix, last_prefix))
  618.                 white_has_newline = TRUE;
  619.  
  620.           PARA_BREAK:
  621.               XP_STRCPY (last_prefix, new_prefix);
  622. # endif /* HACK_PREFIX */
  623.  
  624.               if (white_has_newline)
  625.                 {
  626.                   /* This is the second newline - paragraph break. */
  627.  
  628.                   column = 0;
  629.                   for (s = LINEBREAK; *s; s++)
  630.                     *output++ = *s;
  631. # ifdef HACK_PREFIX
  632.                   for (s = new_prefix; *s; s++)
  633.                     *output++ = *s;
  634. # endif /* !HACK_PREFIX */
  635.                   for (s = LINEBREAK; *s; s++)
  636.                     *output++ = *s;
  637. # ifdef HACK_PREFIX
  638.                   for (s = new_prefix; *s; s++)
  639.                     *output++ = *s,
  640.                     column++;
  641. # endif /* !HACK_PREFIX */
  642.                   while (isspace (*input))
  643.                     input++;
  644.                   white_has_newline = FALSE;
  645.                   in_word = TRUE;
  646.                   word_end = input;
  647.                   word_start = input;
  648.                   continue;
  649.                 }
  650.               else
  651.                 {
  652.                   white_has_newline = TRUE;
  653.                 }
  654. #endif /* !NEWLINES_ARE_SIGNIFICANT */
  655.             }
  656.         }
  657.  
  658.       input++;
  659.     }
  660.   *output = 0;
  661. #undef FIND_PREFIX
  662.  
  663. #ifdef DEBUG_WRAP
  664.   memcpy (I, O, L);
  665. #endif
  666. }
  667.  
  668. #endif /* XP_WORD_WRAP_NEW_CODE */
  669.  
  670.  
  671. #if 0
  672.  
  673. #include <stdio.h>
  674.  
  675. int
  676. INTL_CharLen(int charsetid, unsigned char *str)
  677. {
  678.     return 1;
  679. }
  680.  
  681. int
  682. INTL_ColumnWidth(int charsetid, unsigned char *str)
  683. {
  684.     return 1;
  685. }
  686.  
  687. void
  688. main ()
  689. {
  690.   char *s;
  691.  
  692. #ifdef XP_WORD_WRAP_NEW_CODE
  693. # define TEST(STR) \
  694.   s = strdup (STR); \
  695.   printf ("----------\n"); \
  696.   printf ("%s\n", s); \
  697.   printf ("----------\n"); \
  698.   printf ("%s\n", XP_WordWrap(CS_LATIN1, s, 79, 1)); \
  699.   printf ("----------\n"); \
  700.   free (s)
  701. #else
  702. # define TEST(STR) \
  703.   s = strdup (STR); \
  704.   printf ("----------\n"); \
  705.   printf ("%s\n", s); \
  706.   XP_WordWrap (s, 79); \
  707.   printf ("----------\n"); \
  708.   printf ("%s\n", s); \
  709.   printf ("----------\n"); \
  710.   free (s)
  711. #endif
  712.  
  713. #if 1
  714.   TEST ("This is a test of the new wrapping code.  This test does not "
  715.         "have any newlines in it, but it does have a number of long words "
  716.         "like unfathomably and nevertheless and perspicacious.  Let's see "
  717.         "how this works.  Let's try making it a bit longer.");
  718.  
  719.   TEST ("This is a test of the new wrapping code.  This test does not "
  720.         "have any    newlines in it, but it does have a number of long words "
  721.         "like unfathomably and nevertheless and perspicacious.  Let's see "
  722.         "how this works.  Let's try making it a bit longer.       ");
  723.  
  724.   TEST ("This is a test of the new wrapping code.  This test does not "
  725.         "have any    newlines in it, but it does have a number of long words "
  726.         "like unfathomably and nevertheless and perspicacious.  Let's see "
  727.         "how this works.  Let's try making it a bit longer.       "
  728.         "                                      "
  729.         );
  730.  
  731.   TEST ("This is a test of the new wrapping code.  This test does not "
  732.         "have any    newlines in it, but it does have a number of long words "
  733.         "like unfathomably and nevertheless and perspicacious.  Let's see "
  734.         "how this works.  Let's try making it a bit longer.       "
  735.         "                                                                  "
  736.         );
  737.  
  738.   TEST ("This is a test of the new wrapping code.  This test DOES contain\n"
  739.         "newlines, so let's see   \n"
  740.         "how we deal with that.  And (for good measure) we'll throw in\n"
  741.         "the afforementioned long words: unfathomably, nevertheless, and\n"
  742.         " perspicacious.  Oh, and now `afforementioned.'");
  743.  
  744.   TEST ("This is a test of the new wrapping code.  This test DOES contain\n"
  745.         "newlines, so let's see   \n"
  746.         "how we deal with that.  And (for good measure) we'll throw in\n"
  747.         "the afforementioned long words: unfathomably, nevertheless, and\n"
  748.         " perspicacious.  Oh, and now `afforementioned.'\n"
  749.         "\n"
  750.         "And now we'll try multiple paragraphs.  This text should not\n"
  751.         "be wrapped in with the preceeding text.  Blah blah blah.\n"
  752.         "\n"
  753.         "And now we'll try multiple paragraphs.  This text should not\n"
  754.         "be wrapped in with the preceeding text.  Blah blah blah.\n"
  755.         "   \n   \n   \n   \n   "
  756.         "And now we'll try multiple paragraphs.  This text should not "
  757.         "be wrapped in with the preceeding text.  Blah blah blah."
  758.         );
  759. #endif
  760.  
  761.   TEST (">> This is a test of the new wrapping code.  This test DOES contain\n"
  762.         ">> newlines, so let's see   \n"
  763.         ">> how we deal with that.  And (for good measure) we'll throw in\n"
  764.         ">> the afforementioned long words: unfathomably, nevertheless, and\n"
  765.         ">>   perspicacious.  Oh, and now `afforementioned.'\n"
  766.         "\n"
  767.         "And now we'll try multiple paragraphs.  This text should not\n"
  768.         "be wrapped in with the preceeding text.  Blah blah blah.\n"
  769.         "Blab blab blab.  Blab blab blab.  Blab blab blab.  Blab blab.\n"
  770.         "\n"
  771.         ">  And now we'll try multiple paragraphs.  This text should not\n"
  772.         ">    be wrapped in with the preceeding text.  Blah blah blah.\n"
  773.         ">  Blab blab blab.  Blab blab blab.  Blab blab blab.  Blab blab.\n"
  774.         "   \n   \n   \n   \n   "
  775.         "And now we'll try multiple paragraphs.  This text should not "
  776.         "be wrapped in with the preceeding text.  Blah blah blah."
  777.         "Blab blab blab.  Blab blab blab.  Blab blab blab.  Blab blab.\n"
  778.         "\n"
  779.         "> And here's a line that begins with > in column 0 which is longer"
  780.         " than the fill column.  This line should be left alone.\n"
  781.         "> This is the second such line: it's short.\n"
  782.         ">> This is the third such line, but much like the first line, it"
  783.         " is long.  Run and hide.  Run and hide.  Run and hide.\n"
  784.         "> You can hide.  All your life.  Run and hide.  Run and hide.  "
  785.         "but I'll have.  Your hide.  Run and hide.  Run and hide.\n"
  786.         "\n"
  787.         "This line doesn't begin with > and is long and thus should be"
  788.         " wrapped (like a good line should.)  But this next line:\n"
  789.         ">does begin with that hateful > character, and should be left"
  790.         " alone no matter how it rambles on.  No escape.  run and hide.\n"
  791.         "And now we're back in wrappable line land.  On.  And on and on.  "
  792.         "And on and on.  And on.\n"
  793.         "\n"
  794.         "And now a test of a word that is longer than the line: "
  795.         "12345689-12345689-12345689-12345689-12345689-12345689-12345689-"
  796.         "12345689-12345689-12345689-12345689-12345689-12345689-12345689.  "
  797.         "12345689-12345689-12345689-12345689-12345689-12345689-12345689-"
  798.         "12345689-12345689-12345689-12345689-12345689-12345689-12345689."
  799.         );
  800.  
  801. # undef TEST
  802. }
  803.  
  804. #endif /* 0 */
  805.