home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume27 / top-3.2 / part02 / utils.c < prev   
Encoding:
C/C++ Source or Header  |  1993-08-08  |  6.1 KB  |  307 lines

  1. /*
  2.  *  Top users/processes display for Unix
  3.  *  Version 3
  4.  *
  5.  *  This program may be freely redistributed,
  6.  *  but this entire comment MUST remain intact.
  7.  *
  8.  *  Copyright (c) 1984, 1989, William LeFebvre, Rice University
  9.  *  Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
  10.  */
  11.  
  12. /*
  13.  *  This file contains various handy utilities used by top.
  14.  */
  15.  
  16. #include "top.h"
  17.  
  18. int atoiwi(str)
  19.  
  20. char *str;
  21.  
  22. {
  23.     register int len;
  24.  
  25.     len = strlen(str);
  26.     if (len != 0)
  27.     {
  28.     if (strncmp(str, "infinity", len) == 0 ||
  29.         strncmp(str, "all",      len) == 0 ||
  30.         strncmp(str, "maximum",  len) == 0)
  31.     {
  32.         return(Infinity);
  33.     }
  34.     else if (str[0] == '-')
  35.     {
  36.         return(Invalid);
  37.     }
  38.     else
  39.     {
  40.         return(atoi(str));
  41.     }
  42.     }
  43.     return(0);
  44. }
  45.  
  46. /*
  47.  *  itoa - convert integer (decimal) to ascii string for positive numbers
  48.  *         only (we don't bother with negative numbers since we know we
  49.  *       don't use them).
  50.  */
  51.  
  52. static char buffer[16];        /* shared by the next two routines */
  53.                 /*
  54.                  * How do we know that 16 will suffice?
  55.                  * Because the biggest number that we will
  56.                  * ever convert will be 2^32-1, which is 10
  57.                  * digits.
  58.                  */
  59.  
  60. char *itoa(val)
  61.  
  62. register int val;
  63.  
  64. {
  65.     register char *ptr;
  66.  
  67.     ptr = buffer + sizeof(buffer);
  68.     *--ptr = '\0';
  69.     if (val == 0)
  70.     {
  71.     *--ptr = '0';
  72.     }
  73.     else while (val != 0)
  74.     {
  75.     *--ptr = (val % 10) + '0';
  76.     val /= 10;
  77.     }
  78.     return(ptr);
  79. }
  80.  
  81. /*
  82.  *  itoa7(val) - like itoa, except the number is right justified in a 7
  83.  *    character field.  This code is a duplication of itoa instead of
  84.  *    a front end to a more general routine for efficiency.
  85.  */
  86.  
  87. char *itoa7(val)
  88.  
  89. register int val;
  90.  
  91. {
  92.     register char *ptr;
  93.  
  94.     ptr = buffer + sizeof(buffer);
  95.     *--ptr = '\0';
  96.     if (val == 0)
  97.     {
  98.     *--ptr = '0';
  99.     }
  100.     else while (val != 0)
  101.     {
  102.     *--ptr = (val % 10) + '0';
  103.     val /= 10;
  104.     }
  105.     while (ptr > buffer + sizeof(buffer) - 7)
  106.     {
  107.     *--ptr = ' ';
  108.     }
  109.     return(ptr);
  110. }
  111.  
  112. /*
  113.  *  digits(val) - return number of decimal digits in val.  Only works for
  114.  *    positive numbers.  If val <= 0 then digits(val) == 0.
  115.  */
  116.  
  117. int digits(val)
  118.  
  119. int val;
  120.  
  121. {
  122.     register int cnt = 0;
  123.  
  124.     while (val > 0)
  125.     {
  126.     cnt++;
  127.     val /= 10;
  128.     }
  129.     return(cnt);
  130. }
  131.  
  132. /*
  133.  *  strecpy(to, from) - copy string "from" into "to" and return a pointer
  134.  *    to the END of the string "to".
  135.  */
  136.  
  137. char *strecpy(to, from)
  138.  
  139. register char *to;
  140. register char *from;
  141.  
  142. {
  143.     while ((*to++ = *from++) != '\0');
  144.     return(--to);
  145. }
  146.  
  147. /*
  148.  * argparse(line, cntp) - parse arguments in string "line", separating them
  149.  *    put into an argv-like array, and setting *cntp to the number of
  150.  *    arguments encountered.  This is a simple parser that doesn't understand
  151.  *    squat about quotes.
  152.  */
  153.  
  154. char **argparse(line, cntp)
  155.  
  156. char *line;
  157. int *cntp;
  158.  
  159. {
  160.     register char *from;
  161.     register char *to;
  162.     register int cnt;
  163.     register int ch;
  164.     int length;
  165.     int lastch;
  166.     register char **argv;
  167.     char **argarray;
  168.     char *args;
  169.  
  170.     /* unfortunately, the only real way to do this is to go thru the
  171.        input string twice. */
  172.  
  173.     /* step thru the string counting the white space sections */
  174.     from = line;
  175.     lastch = cnt = length = 0;
  176.     while ((ch = *from++) != '\0')
  177.     {
  178.     length++;
  179.     if (ch == ' ' && lastch != ' ')
  180.     {
  181.         cnt++;
  182.     }
  183.     lastch = ch;
  184.     }
  185.  
  186.     /* add three to the count:  one for the initial "dummy" argument,
  187.        one for the last argument and one for NULL */
  188.     cnt += 3;
  189.  
  190.     /* allocate a char * array to hold the pointers */
  191.     argarray = (char **)malloc(cnt * sizeof(char *));
  192.  
  193.     /* allocate another array to hold the strings themselves */
  194.     args = (char *)malloc(length+2);
  195.  
  196.     /* initialization for main loop */
  197.     from = line;
  198.     to = args;
  199.     argv = argarray;
  200.     lastch = '\0';
  201.  
  202.     /* create a dummy argument to keep getopt happy */
  203.     *argv++ = to;
  204.     *to++ = '\0';
  205.     cnt = 2;
  206.  
  207.     /* now build argv while copying characters */
  208.     *argv++ = to;
  209.     while ((ch = *from++) != '\0')
  210.     {
  211.     if (ch != ' ')
  212.     {
  213.         if (lastch == ' ')
  214.         {
  215.         *to++ = '\0';
  216.         *argv++ = to;
  217.         cnt++;
  218.         }
  219.         *to++ = ch;
  220.     }
  221.     lastch = ch;
  222.     }
  223.  
  224.     /* set cntp and return the allocated array */
  225.     *cntp = cnt;
  226.     return(argarray);
  227. }
  228.  
  229. /*
  230.  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
  231.  *    between array "old" and "new", putting the percentages i "out".
  232.  *    "cnt" is size of each array and "diffs" is used for scratch space.
  233.  *    The array "old" is updated on each call.
  234.  *    The routine assumes modulo arithmetic.  This function is especially
  235.  *    useful on BSD mchines for calculating cpu state percentages.
  236.  */
  237.  
  238. long percentages(cnt, out, new, old, diffs)
  239.  
  240. int cnt;
  241. int *out;
  242. register long *new;
  243. register long *old;
  244. long *diffs;
  245.  
  246. {
  247.     register int i;
  248.     register long change;
  249.     register long total_change;
  250.     register long *dp;
  251.     long half_total;
  252.  
  253.     /* initialization */
  254.     total_change = 0;
  255.     dp = diffs;
  256.  
  257.     /* calculate changes for each state and the overall change */
  258.     for (i = 0; i < cnt; i++)
  259.     {
  260.     if ((change = *new - *old) < 0)
  261.     {
  262.         /* this only happens when the counter wraps */
  263.         change = (int)
  264.         ((unsigned long)*new-(unsigned long)*old);
  265.     }
  266.     total_change += (*dp++ = change);
  267.     *old++ = *new++;
  268.     }
  269.  
  270.     /* calculate percentages based on overall change, rounding up */
  271.     half_total = total_change / 2l;
  272.     for (i = 0; i < cnt; i++)
  273.     {
  274.     *out++ = (int)((*diffs++ * 1000 + half_total) / total_change);
  275.     }
  276.  
  277.     /* return the total in case the caller wants to use it */
  278.     return(total_change);
  279. }
  280.  
  281. /*
  282.  * errmsg(errnum) - return an error message string appropriate to the
  283.  *           error number "errnum".  This is a substitute for the System V
  284.  *           function "strerror" with one important difference:  the string
  285.  *           returned by this function does NOT end in a newline!
  286.  *           N.B.:  there appears to be no reliable way to determine if
  287.  *           "strerror" exists at compile time, so I make do by providing
  288.  *           something of similar functionality.
  289.  */
  290.  
  291. /* externs referenced by errmsg */
  292.  
  293. extern char *sys_errlist[];
  294. extern int sys_nerr;
  295.  
  296. char *errmsg(errnum)
  297.  
  298. int errnum;
  299.  
  300. {
  301.     if (errnum > 0 && errnum < sys_nerr)
  302.     {
  303.     return(sys_errlist[errnum]);
  304.     }
  305.     return("No error");
  306. }
  307.