patch-2.2.19 linux/drivers/isdn/eicon/kprintf.c

Next file: linux/drivers/isdn/eicon/lincfg.c
Previous file: linux/drivers/isdn/eicon/idi.h
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.18/drivers/isdn/eicon/kprintf.c linux/drivers/isdn/eicon/kprintf.c
@@ -0,0 +1,535 @@
+
+/*
+ *
+ * Copyright (C) Eicon Technology Corporation, 2000.
+ *
+ * Eicon File Revision :    1.3  
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+/*
+ * Source file for kernel interface to kernel log facility
+ */
+
+
+#include "sys.h"
+#include <stdarg.h>
+#undef MAX
+#undef MIN
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include "divas.h"
+#include "divalog.h"
+#include "uxio.h"
+
+/*
+ * Implementation of printf and sprintf for kernel
+ */
+
+#define MAX_BUFF    (80)        /* limit size of temporary buffers */
+
+#define WRITE_CHAR(BUFFER, SIZE, C) \
+  if (--(SIZE) < 0) { (BUFFER)--; *(BUFFER) = '\0'; return; } *(BUFFER)++ = (C)
+
+
+/*
+ * convert a number to decimal ASCII
+ */
+
+static
+void    do_decimal( char            *temp,
+                    int             temp_len,
+                    unsigned int    value,
+                    char            *s)
+
+{
+    int     i;
+
+    temp[0] = '\0';
+
+    for (i = 1; i < temp_len; i++)
+    {
+        temp[i] = (char) ((value % 10) + (int) '0');
+        value /= 10;
+    }
+
+    for (i = (temp_len - 1); temp[i] == '0'; i--)
+    {
+        ;
+    }
+
+    if (i == 0)
+    {
+        i++;
+    }
+
+    while (i >= 0)
+    {
+        *s++ = temp[i--];
+    }
+
+    return;
+}
+
+/*
+ * convert a number to octal ASCII
+ */
+
+static
+void    do_octal(   char            *temp,
+                    unsigned int    value,
+                    char            *s)
+
+{
+    int     i;
+
+    temp[0] = '\0';
+
+    for (i = 1; i <= 11; i++)
+    {
+        temp[i] = (char) ((value & 07) + (int) '0');
+        value >>= 3;
+    }
+    temp[11] &= '3';
+
+    for (i = 11; temp[i] == '0'; i--)
+    {
+        ;
+    }
+
+    if (i == 0)
+    {
+        i++;
+    }
+
+    while (i >= 0)
+    {
+        *s++ = temp[i--];
+    }
+
+    return;
+}
+
+/*
+ * convert a number to hex ASCII
+ */
+
+static
+void    do_hex( char            *temp,
+                unsigned int    value,
+                char            *s)
+
+{
+    int     i;
+    static
+    char    *dec_to_hex = "0123456789abcdef";
+
+    temp[0] = '\0';
+
+    for (i = 1; i <= 8; i++)
+    {
+        temp[i] = dec_to_hex[value & 0x0f];
+        value >>= 4;
+    }
+
+    for (i = 8; temp[i] == '0'; i--)
+    {
+        ;
+    }
+
+    if (i == 0)
+    {
+        i++;
+    }
+
+    while (i >= 0)
+    {
+        *s++ = temp[i--];
+    }
+
+    return;
+}
+
+/*
+ * convert a buffer to ASCII HEX
+ */
+
+static
+void    do_buffer(  char    *buffer,
+                    int     length,
+                    char    *s)
+
+{
+    static
+    char    hex_char [] = "0123456789abcdef";
+    char    *b = buffer;
+    int     hex_byte;
+    int     nybble;
+
+    length = (length >= ((MAX_BUFF / 3) + 1)) ? (MAX_BUFF / 3) : length;
+
+    while (length)
+    {
+        hex_byte = (int) *b++;
+        nybble = (hex_byte >> 4) & 0xf;
+        *s++ = hex_char[nybble];
+        nybble = hex_byte & 0xf;
+        *s++ = hex_char[nybble];
+        *s++ = ' ';
+        length--;
+    }
+    *s = '\0';
+
+    return;
+}
+
+/*
+ * Body of sprintf function: behaves just like standard sprintf, except we
+ * have an extra argument (buffer size) which we use to ensure we don't
+ * overflow
+ */
+
+void    Divas_vsprintf(   char    *buffer,
+                    int     size,
+                    char    *fmt,
+                    va_list argptr)
+
+{
+    char        c;          /* single character buffer */
+    int         i;          /* handy scratch counter */
+    int         f;          /* format character (after %) */
+    char        *str;       /* pointer into string */
+    char        temp[20];   /* temp buffer used in printing numbers */
+    char        string[MAX_BUFF]; /* output from number conversion */
+    int         length;     /* length of string "str" */
+    char        fill;       /* fill character ' ' or '0' */
+    boolean_t   leftjust;   /* TRUE if left justified, else right justified */
+    int         fmax, fmin; /* field specifiers % MIN . MAX s */
+    int         leading;    /* number of leading/trailing fill characters */
+    char        sign;       /* set to '-' for negative decimals */
+    int         number;     /* numeric argument */
+
+    char        *buff_ptr;  /* pointer to user's buffer of hex data */
+    int         buff_len;   /* length of hex data */
+
+    /* make sure we have somthing to write into */
+
+    if ((!buffer) || (size <= 0))
+    {
+        return;
+    }
+
+    while (TRUE)
+    {
+        /* echo characters until end or '%' encountered */
+
+        while ((c = *fmt++) != '%')
+        {
+            if (!c)
+            {
+                *buffer = '\0';
+                return;
+            }
+            WRITE_CHAR(buffer, size, c);
+        }
+
+        /* echo %% as % */
+
+        if (*fmt == '%')
+        {
+            WRITE_CHAR(buffer, size, *fmt);
+            continue;
+        }
+
+        /* %- turns on left-justify */
+
+        if ((leftjust = (boolean_t) ((*fmt == '-') ? TRUE : FALSE)))
+        {
+            fmt++;
+        }
+
+        /* %0 turns on zero filling */
+
+        if (*fmt == '0')
+        {
+            fill = '0';
+        }
+        else
+        {
+            fill = ' ';
+        }
+
+        /* minium field width specifier for %d, u, x, c, s */
+
+        fmin = 0;
+
+        if (*fmt == '*')
+        {
+            fmin = va_arg(argptr, int);
+            fmt++;
+        }
+        else
+        {
+            while ('0' <= *fmt && *fmt <= '9')
+            {
+                fmin = (fmin * 10) + (*fmt++ - '0');
+            }
+        }
+
+        /* maximum string width specifier for %s */
+
+        fmax = 0;
+
+        if (*fmt == '.')
+        {
+            if (*(++fmt) == '*')
+            {
+                fmax = va_arg(argptr, int);
+                fmt++;
+            }
+            else
+            {
+                while ('0' <= *fmt && *fmt <= '9')
+                {
+                    fmax = (fmax * 10) + (*fmt++ - '0');
+                }
+            }
+        }
+
+        /* skip over 'l' option (ints are assumed same size as longs) */
+
+        if (*fmt == 'l')
+        {
+            fmt++;
+        }
+
+        /* get the format chacater */
+
+        if (!(f = *fmt++))
+        {
+            WRITE_CHAR(buffer, size, '%');
+            *buffer = '\0';
+            return;
+        }
+
+        sign = '\0';        /* sign == '-' for negative decimal */
+
+        str = string;
+
+        switch (f)
+        {
+        case 'c' :
+            string[0] = (char) va_arg(argptr, int);
+            string[1] = '\0';
+            fmax = 0;
+            fill = ' ';
+            break;
+
+        case 's' :
+            str = va_arg(argptr, char *);
+            fill = ' ';
+            break;
+
+        case 'D' :
+        case 'd' :
+            number = va_arg(argptr, int);
+            if (number < 0)
+            {
+                sign = '-';
+                number = -number;
+            }
+            do_decimal(temp, DIM(temp), (unsigned int) number, str);
+            fmax = 0;
+            break;
+
+        case 'U' :
+        case 'u' :
+            number = va_arg(argptr, int);
+            do_decimal(temp, DIM(temp), (unsigned int) number, str);
+            fmax = 0;
+            break;
+
+        case 'O' :
+        case 'o' :
+            number = va_arg(argptr, int);
+            do_octal(temp, (unsigned int) number, str);
+            fmax = 0;
+            break;
+
+        case 'X' :
+        case 'x' :
+            number = va_arg(argptr, int);
+            do_hex(temp, (unsigned int) number, str);
+            fmax = 0;
+            break;
+
+        case 'H' :
+        case 'h' :
+            buff_ptr = va_arg(argptr, char *);
+            buff_len = va_arg(argptr, int);
+            do_buffer(buff_ptr, buff_len, str);
+            fmax = 0;
+            break;
+
+        default :
+            WRITE_CHAR(buffer, size, ((char) f));
+            break;
+        }
+
+        /* get the length of the string */
+
+        length = 0;
+        while (str[length])
+        {
+            length++;
+        }
+
+        /* make sure we have fmax and fmin values that are O.K. */
+
+        if (fmin > DIM(string) || fmin < 0)
+        {
+            fmin = 0;
+        }
+
+        if (fmax > DIM(string) || fmax < 0)
+        {
+            fmax = 0;
+        }
+
+        /* figure out how many leading characters thare are */
+
+        leading = 0;
+
+        if (fmax || fmin)
+        {
+            if (fmax)
+            {
+                if (length > fmax)
+                {
+                    length = fmax;
+                }
+            }
+
+            if (fmin)
+            {
+                leading = fmin - length;
+            }
+
+            if (sign == '-')
+            {
+                leading--;
+            }
+        }
+
+        /* output sign now, if fill is numeric */
+
+        if (sign == '-' && fill == '0')
+        {
+            WRITE_CHAR(buffer, size, '-');
+        }
+
+        /* if right justified, output fill characters */
+
+        if (!leftjust)
+        {
+            for (i = 0; i < leading; i++)
+            {
+                WRITE_CHAR(buffer, size, fill);
+            }
+        }
+
+        /* output sign now, if fill is spaces */
+
+        if (sign == '-' && fill == ' ')
+        {
+            WRITE_CHAR(buffer, size, '-');
+        }
+
+        /* now the actual value */
+
+        for (i = 0; i < length; i++)
+        {
+            WRITE_CHAR(buffer, size, str[i]);
+        }
+
+        /* if left justified, fill out with the fill character */
+
+        if (leftjust)
+        {
+            for (i = 0; i < leading; i++)
+            {
+                WRITE_CHAR(buffer, size, fill);
+            }
+        }
+    }
+}
+
+/*
+ * sprintf for kernel
+ *
+ * call our vsprintf assuming user has a big buffer....
+ */
+
+void    DivasSprintf(char *buffer, char *fmt, ...)
+
+{
+    va_list     argptr;         /* pointer to additional args */
+
+    va_start(argptr, fmt);
+
+    Divas_vsprintf(buffer, 1024, fmt, argptr);
+
+    va_end(argptr);
+
+    return;
+}
+
+void    DivasPrintf(char  *fmt, ...)
+
+{
+    klog_t      log;            /* log entry buffer */
+
+    va_list     argptr;         /* pointer to additional args */
+
+    va_start(argptr, fmt);
+
+    /* clear log entry */
+
+    bzero((caddr_t) &log, sizeof(klog_t));
+
+    log.card = -1;
+    log.type = KLOG_TEXT_MSG;
+
+    /* time stamp the entry */
+
+    log.time_stamp = UxTimeGet();
+
+    /* call vsprintf to format the user's information */
+
+    Divas_vsprintf(log.buffer, DIM(log.buffer), fmt, argptr);
+
+    va_end(argptr);
+
+    /* send to the log streams driver and return */
+
+    DivasLogAdd(&log, sizeof(klog_t));
+
+    return;
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)