Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Typedefs | Functions

mbprint.c File Reference

#include "postgres_fe.h"
#include "mbprint.h"
#include "settings.h"
Include dependency graph for mbprint.c:

Go to the source code of this file.

Defines

#define PG_UTF8   pg_get_utf8_id()

Typedefs

typedef unsigned int pg_wchar

Functions

static int pg_get_utf8_id (void)
static pg_wchar utf8_to_unicode (const unsigned char *c)
static int utf_charcheck (const unsigned char *c)
static void mb_utf_validate (unsigned char *pwcs)
int pg_wcswidth (const char *pwcs, size_t len, int encoding)
void pg_wcssize (const unsigned char *pwcs, size_t len, int encoding, int *result_width, int *result_height, int *result_format_size)
void pg_wcsformat (const unsigned char *pwcs, size_t len, int encoding, struct lineptr *lines, int count)
unsigned char * mbvalidate (unsigned char *pwcs, int encoding)

Define Documentation

#define PG_UTF8   pg_get_utf8_id()

Definition at line 42 of file mbprint.c.

Referenced by mbvalidate(), and pg_wcsformat().


Typedef Documentation

typedef unsigned int pg_wchar

Definition at line 30 of file mbprint.c.


Function Documentation

static void mb_utf_validate ( unsigned char *  pwcs  )  [static]

Definition at line 135 of file mbprint.c.

References i, and utf_charcheck().

Referenced by mbvalidate().

{
    unsigned char *p = pwcs;

    while (*pwcs)
    {
        int         len;

        if ((len = utf_charcheck(pwcs)) > 0)
        {
            if (p != pwcs)
            {
                int         i;

                for (i = 0; i < len; i++)
                    *p++ = *pwcs++;
            }
            else
            {
                pwcs += len;
                p += len;
            }
        }
        else
            /* we skip the char */
            pwcs++;
    }
    if (p != pwcs)
        *p = '\0';
}

unsigned char* mbvalidate ( unsigned char *  pwcs,
int  encoding 
)

Definition at line 385 of file mbprint.c.

References mb_utf_validate(), and PG_UTF8.

Referenced by printTableAddCell(), and printTableAddHeader().

{
    if (encoding == PG_UTF8)
        mb_utf_validate(pwcs);
    else
    {
        /*
         * other encodings needing validation should add their own routines
         * here
         */
    }

    return pwcs;
}

static int pg_get_utf8_id ( void   )  [static]

Definition at line 33 of file mbprint.c.

References pg_char_to_encoding().

{
    static int  utf8_id = -1;

    if (utf8_id < 0)
        utf8_id = pg_char_to_encoding("utf8");
    return utf8_id;
}

void pg_wcsformat ( const unsigned char *  pwcs,
size_t  len,
int  encoding,
struct lineptr lines,
int  count 
)

Definition at line 293 of file mbprint.c.

References i, NULL, PG_UTF8, PQdsplen(), PQmblen(), lineptr::ptr, utf8_to_unicode(), and lineptr::width.

Referenced by print_aligned_text(), and print_aligned_vertical().

{
    int         w,
                chlen = 0;
    int         linewidth = 0;
    unsigned char *ptr = lines->ptr;    /* Pointer to data area */

    for (; *pwcs && len > 0; pwcs += chlen)
    {
        chlen = PQmblen((const char *) pwcs, encoding);
        if (len < (size_t) chlen)
            break;
        w = PQdsplen((const char *) pwcs, encoding);

        if (chlen == 1)         /* single-byte char */
        {
            if (*pwcs == '\n')  /* Newline */
            {
                *ptr++ = '\0';
                lines->width = linewidth;
                linewidth = 0;
                lines++;
                count--;
                if (count <= 0)
                    exit(1);    /* Screwup */

                /* make next line point to remaining memory */
                lines->ptr = ptr;
            }
            else if (*pwcs == '\r')     /* Linefeed */
            {
                strcpy((char *) ptr, "\\r");
                linewidth += 2;
                ptr += 2;
            }
            else if (*pwcs == '\t')     /* Tab */
            {
                do
                {
                    *ptr++ = ' ';
                    linewidth++;
                } while (linewidth % 8 != 0);
            }
            else if (w < 0)     /* Other control char */
            {
                sprintf((char *) ptr, "\\x%02X", *pwcs);
                linewidth += 4;
                ptr += 4;
            }
            else    /* Output it as-is */
            {
                linewidth += w;
                *ptr++ = *pwcs;
            }
        }
        else if (w < 0)         /* Non-ascii control char */
        {
            if (encoding == PG_UTF8)
                sprintf((char *) ptr, "\\u%04X", utf8_to_unicode(pwcs));
            else
            {
                /*
                 * This case cannot happen in the current code because only
                 * UTF-8 signals multibyte control characters. But we may need
                 * to support it at some stage
                 */
                sprintf((char *) ptr, "\\u????");
            }
            ptr += 6;
            linewidth += 6;
        }
        else    /* All other chars */
        {
            int         i;

            for (i = 0; i < chlen; i++)
                *ptr++ = pwcs[i];
            linewidth += w;
        }
        len -= chlen;
    }
    lines->width = linewidth;
    *ptr++ = '\0';              /* Terminate formatted string */

    if (count <= 0)
        exit(1);                /* Screwup */

    (lines + 1)->ptr = NULL;    /* terminate line array */
}

void pg_wcssize ( const unsigned char *  pwcs,
size_t  len,
int  encoding,
int *  result_width,
int *  result_height,
int *  result_format_size 
)

Definition at line 210 of file mbprint.c.

References PQdsplen(), and PQmblen().

Referenced by print_aligned_text(), and print_aligned_vertical().

{
    int         w,
                chlen = 0,
                linewidth = 0;
    int         width = 0;
    int         height = 1;
    int         format_size = 0;

    for (; *pwcs && len > 0; pwcs += chlen)
    {
        chlen = PQmblen((const char *) pwcs, encoding);
        if (len < (size_t) chlen)
            break;
        w = PQdsplen((const char *) pwcs, encoding);

        if (chlen == 1)         /* single-byte char */
        {
            if (*pwcs == '\n')  /* Newline */
            {
                if (linewidth > width)
                    width = linewidth;
                linewidth = 0;
                height += 1;
                format_size += 1;       /* For NUL char */
            }
            else if (*pwcs == '\r')     /* Linefeed */
            {
                linewidth += 2;
                format_size += 2;
            }
            else if (*pwcs == '\t')     /* Tab */
            {
                do
                {
                    linewidth++;
                    format_size++;
                } while (linewidth % 8 != 0);
            }
            else if (w < 0)     /* Other control char */
            {
                linewidth += 4;
                format_size += 4;
            }
            else    /* Output it as-is */
            {
                linewidth += w;
                format_size += 1;
            }
        }
        else if (w < 0)         /* Non-ascii control char */
        {
            linewidth += 6;     /* \u0000 */
            format_size += 6;
        }
        else    /* All other chars */
        {
            linewidth += w;
            format_size += chlen;
        }
        len -= chlen;
    }
    if (linewidth > width)
        width = linewidth;
    format_size += 1;           /* For NUL char */

    /* Set results */
    if (result_width)
        *result_width = width;
    if (result_height)
        *result_height = height;
    if (result_format_size)
        *result_format_size = format_size;
}

int pg_wcswidth ( const char *  pwcs,
size_t  len,
int  encoding 
)

Definition at line 176 of file mbprint.c.

References PQdsplen(), and PQmblen().

Referenced by describeOneTableDetails().

{
    int         width = 0;

    while (len > 0)
    {
        int         chlen,
                    chwidth;

        chlen = PQmblen(pwcs, encoding);
        if (len < (size_t) chlen)
            break;              /* Invalid string */

        chwidth = PQdsplen(pwcs, encoding);
        if (chwidth > 0)
            width += chwidth;

        pwcs += chlen;
        len -= chlen;
    }
    return width;
}

static pg_wchar utf8_to_unicode ( const unsigned char *  c  )  [static]

Definition at line 52 of file mbprint.c.

{
    if ((*c & 0x80) == 0)
        return (pg_wchar) c[0];
    else if ((*c & 0xe0) == 0xc0)
        return (pg_wchar) (((c[0] & 0x1f) << 6) |
                           (c[1] & 0x3f));
    else if ((*c & 0xf0) == 0xe0)
        return (pg_wchar) (((c[0] & 0x0f) << 12) |
                           ((c[1] & 0x3f) << 6) |
                           (c[2] & 0x3f));
    else if ((*c & 0xf8) == 0xf0)
        return (pg_wchar) (((c[0] & 0x07) << 18) |
                           ((c[1] & 0x3f) << 12) |
                           ((c[2] & 0x3f) << 6) |
                           (c[3] & 0x3f));
    else
        /* that is an invalid code on purpose */
        return 0xffffffff;
}

static int utf_charcheck ( const unsigned char *  c  )  [static]

Definition at line 81 of file mbprint.c.

Referenced by mb_utf_validate().

{
    if ((*c & 0x80) == 0)
        return 1;
    else if ((*c & 0xe0) == 0xc0)
    {
        /* two-byte char */
        if (((c[1] & 0xc0) == 0x80) && ((c[0] & 0x1f) > 0x01))
            return 2;
        return -1;
    }
    else if ((*c & 0xf0) == 0xe0)
    {
        /* three-byte char */
        if (((c[1] & 0xc0) == 0x80) &&
            (((c[0] & 0x0f) != 0x00) || ((c[1] & 0x20) == 0x20)) &&
            ((c[2] & 0xc0) == 0x80))
        {
            int         z = c[0] & 0x0f;
            int         yx = ((c[1] & 0x3f) << 6) | (c[0] & 0x3f);
            int         lx = yx & 0x7f;

            /* check 0xfffe/0xffff, 0xfdd0..0xfedf range, surrogates */
            if (((z == 0x0f) &&
                 (((yx & 0xffe) == 0xffe) ||
               (((yx & 0xf80) == 0xd80) && (lx >= 0x30) && (lx <= 0x4f)))) ||
                ((z == 0x0d) && ((yx & 0xb00) == 0x800)))
                return -1;
            return 3;
        }
        return -1;
    }
    else if ((*c & 0xf8) == 0xf0)
    {
        int         u = ((c[0] & 0x07) << 2) | ((c[1] & 0x30) >> 4);

        /* four-byte char */
        if (((c[1] & 0xc0) == 0x80) &&
            (u > 0x00) && (u <= 0x10) &&
            ((c[2] & 0xc0) == 0x80) && ((c[3] & 0xc0) == 0x80))
        {
            /* test for 0xzzzzfffe/0xzzzzfffff */
            if (((c[1] & 0x0f) == 0x0f) && ((c[2] & 0x3f) == 0x3f) &&
                ((c[3] & 0x3e) == 0x3e))
                return -1;
            return 4;
        }
        return -1;
    }
    return -1;
}