home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d9xx / d902 / less.lha / Less / Source / source.lha / prompt.c < prev    next >
C/C++ Source or Header  |  1993-01-21  |  7KB  |  305 lines

  1. /*
  2.  * Prompting and other messages.
  3.  * There are three flavors of prompts, SHORT, MEDIUM and LONG,
  4.  * selected by the -m/-M options.
  5.  * A prompt is either a colon or a message composed of various
  6.  * pieces, such as the name of the file being viewed, the percentage
  7.  * into the file, etc.
  8.  */
  9.  
  10. #include "less.h"
  11.  
  12. #include "position.h"
  13.  
  14. extern int pr_type;
  15. extern int ispipe;
  16. extern int hit_eof;
  17. extern int new_file;
  18. extern int sc_width;
  19. extern char current_file[];
  20. extern int ac;
  21. extern char **av;
  22. extern int curr_ac;
  23.  
  24. /* Prototypes for functions defined in prompt.c */
  25.  
  26. static void setmp __PROTO((void));
  27. static void ap_filename __PROTO((void));
  28. static void ap_of __PROTO((void));
  29. static void ap_byte __PROTO((void));
  30. static void ap_percent __PROTO((int must_print));
  31. static void ap_eof __PROTO((void));
  32. static char *pr_expand __PROTO((char *proto,
  33.                                 int maxwidth));
  34.  
  35.  
  36. /*
  37.  * Prototypes for the three flavors of prompts.
  38.  * These strings are expanded by pr_expand().
  39.  */
  40. char *prproto[] = {
  41.         "fo",           /* PR_SHORT */
  42.         "foP",          /* PR_MEDIUM */
  43.         "Fobp"          /* PR_LONG */
  44. };
  45.  
  46. static char message[200];
  47. static char *mp;
  48.  
  49. #ifdef __STDC__
  50. static void setmp (void)
  51. #else
  52.         static void
  53. setmp()
  54. #endif
  55. {
  56.         mp = message + strlen(message);
  57. }
  58.  
  59. /*
  60.  * Append the name of the current file (to the message buffer).
  61.  */
  62. #ifdef __STDC__
  63. static void ap_filename (void)
  64. #else
  65.         static void
  66. ap_filename()
  67. #endif
  68. {
  69.         if (ispipe)
  70.                 return;
  71.         strtcpy(mp, current_file, &message[sizeof(message)] - mp);
  72.         setmp();
  73. }
  74.  
  75. /*
  76.  * Append the "file N of M" message.
  77.  */
  78. #ifdef __STDC__
  79. static void ap_of (void)
  80. #else
  81.         static void
  82. ap_of()
  83. #endif
  84. {
  85.         if (ac <= 1)
  86.                 return;
  87.         sprintf(mp, " (file %ld of %ld)", curr_ac+1, ac);
  88.         setmp();
  89. }
  90.  
  91. /*
  92.  * Append the byte offset into the current file.
  93.  */
  94. #ifdef __STDC__
  95. static void ap_byte (void)
  96. #else
  97.         static void
  98. ap_byte()
  99. #endif
  100. {
  101.         POSITION pos, len;
  102.  
  103.         pos = position(BOTTOM_PLUS_ONE);
  104.         if (pos == NULL_POSITION)
  105.                 pos = ch_length();
  106.         if (pos != NULL_POSITION)
  107.         {
  108.                 sprintf(mp, " byte %ld", (long)pos);
  109.                 setmp();
  110.                 len = ch_length();
  111.                 if (len > 0)
  112.                 {
  113.                         sprintf(mp, "/%ld", (long)len);
  114.                         setmp();
  115.                 }
  116.         }
  117. }
  118.  
  119. /*
  120.  * Append the percentage into the current file.
  121.  * If we cannot find the percentage and must_print is true,
  122.  * use the byte offset.
  123.  */
  124. #ifdef __STDC__
  125. static void ap_percent (int must_print)
  126. #else
  127.         static void
  128. ap_percent(must_print)
  129. #endif
  130. {
  131.         POSITION pos,len;
  132.  
  133.         pos = position(BOTTOM_PLUS_ONE);
  134.         len = ch_length();
  135.         if (len > 0 && pos != NULL_POSITION)
  136.         {
  137.                 sprintf(mp, " (%ld%%)", (100 * (long)pos) / len);
  138.                 setmp();
  139.         } else if (must_print)
  140.                 ap_byte();
  141. }
  142.  
  143. /*
  144.  * Append the end-of-file message.
  145.  */
  146. #ifdef __STDC__
  147. static void ap_eof (void)
  148. #else
  149.         static void
  150. ap_eof()
  151. #endif
  152. {
  153.         strcpy(mp, " (END)");
  154.         setmp();
  155.         if (curr_ac + 1 < ac)
  156.         {
  157.                 sprintf(mp, " - Next: %s", av[curr_ac+1]);
  158.                 setmp();
  159.         }
  160. }
  161.  
  162. /*
  163.  * Construct a message based on a prototype string.
  164.  */
  165. #ifdef __STDC__
  166. static char *pr_expand (char *proto, int maxwidth)
  167. #else
  168.         static char *
  169. pr_expand(proto, maxwidth)
  170.         char *proto;
  171.         int maxwidth;
  172. #endif
  173. {
  174.         register char *p;
  175.  
  176.         mp = message;
  177.  
  178.         for (p = proto;  *p != '\0';  p++)
  179.         {
  180.                 if (maxwidth > 0 && mp >= message + maxwidth)
  181.                 {
  182.                         /*
  183.                          * Truncate to the screen width.
  184.                          * {{ This isn't very nice. }}
  185.                          */
  186. #ifndef AMIGA
  187.                         mp = message + maxwidth;
  188. #endif
  189.                         break;
  190.                 }
  191.                 switch (*p)
  192.                 {
  193.                 case 'f':
  194.                         if (new_file)
  195.                                 ap_filename();
  196.                         break;
  197.                 case 'F':
  198.                         ap_filename();
  199.                         break;
  200.                 case 'o':
  201.                         if (new_file)
  202.                                 ap_of();
  203.                         break;
  204.                 case 'O':
  205.                         ap_of();
  206.                         break;
  207.                 case 'b':
  208.                         ap_byte();
  209.                         break;
  210.                 case 'p':
  211.                         if (!hit_eof)
  212.                                 ap_percent(0);
  213.                         break;
  214.                 case 'P':
  215.                         if (!hit_eof)
  216.                                 ap_percent(1);
  217.                         break;
  218.                 case '<':
  219.                         while (*++p != '>')
  220.                         {
  221.                                 if (*p == '\0')
  222.                                 {
  223.                                         p--;
  224.                                         break;
  225.                                 }
  226.                                 *mp++ = *p;
  227.                         }
  228.                         break;
  229.                 default:
  230.                         *mp++ = *p;
  231.                         break;
  232.                 }
  233.         }
  234.         if (hit_eof)
  235.                 ap_eof();
  236.  
  237. #ifndef AMIGA
  238.         new_file = 0;
  239. #endif
  240.         if (mp == message)
  241.                 return (NULL);
  242.         *mp = '\0';
  243.         return (message);
  244. }
  245.  
  246. /*
  247.  * Return a message suitable for printing by the "=" command.
  248.  */
  249. #ifdef __STDC__
  250. char *eq_message (void)
  251. #else
  252.         public char *
  253. eq_message()
  254. #endif
  255. {
  256.         return (pr_expand("FObp", 0));
  257. }
  258.  
  259. /*
  260.  * Return a prompt.
  261.  * This depends on the prompt type (SHORT, MEDIUM, LONG), etc.
  262.  * If we can't come up with an appropriate prompt, return NULL
  263.  * and the caller will prompt with a colon.
  264.  */
  265. #ifdef __STDC__
  266. char *pr_string (void)
  267. #else
  268.         public char *
  269. pr_string()
  270. #endif
  271. {
  272.  
  273. #ifdef AMIGA
  274.         char *result, *bestresult;
  275.         int i, len, bestlen;
  276.  
  277.         /* Try to make the prompt fit the window */
  278.  
  279.         bestlen = -1;
  280.         for ( i = 0; i<3; i++ )
  281.         {
  282.             result = pr_expand(prproto[i], sc_width - 2);
  283.             len = (result? strlen(result): 0);
  284.             if ( i == pr_type && len < sc_width - 2 )
  285.             {
  286.                 bestresult = result;
  287.                 bestlen = len;
  288.                 break;
  289.             }
  290.             if ( len < sc_width - 2 && len > bestlen )
  291.             {
  292.                 bestresult = result;
  293.                 bestlen = len;
  294.             }
  295.         }
  296.         new_file = 0;
  297.         if ( bestlen >= 0 )
  298.             return bestresult;
  299.         else
  300.             return NULL;
  301. #else
  302.         return (pr_expand(prproto[pr_type], sc_width-2));
  303. #endif
  304. }
  305.