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