[BACK]Return to alloc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/alloc.c, Revision 1.1

1.1     ! downsj      1: /* $OpenBSD$   */
        !             2: /* vi:set ts=4 sw=4:
        !             3:  *
        !             4:  * VIM - Vi IMproved       by Bram Moolenaar
        !             5:  *
        !             6:  * Do ":help uganda"  in Vim to read copying and usage conditions.
        !             7:  * Do ":help credits" in Vim to see a list of people who contributed.
        !             8:  */
        !             9:
        !            10: /*
        !            11:  * alloc.c
        !            12:  *
        !            13:  * This file contains various routines dealing with allocation and
        !            14:  * deallocation of memory. And some funcions for copying text.
        !            15:  */
        !            16:
        !            17: #include "vim.h"
        !            18: #include "globals.h"
        !            19: #include "proto.h"
        !            20:
        !            21: /*
        !            22:  * Some memory is reserved for error messages and for being able to
        !            23:  * call mf_release_all(), which needs some memory for mf_trans_add().
        !            24:  */
        !            25: #define KEEP_ROOM 8192L
        !            26:
        !            27: /*
        !            28:  * Note: if unsinged is 16 bits we can only allocate up to 64K with alloc().
        !            29:  * Use lalloc for larger blocks.
        !            30:  */
        !            31:    char_u *
        !            32: alloc(size)
        !            33:    unsigned        size;
        !            34: {
        !            35:    return (lalloc((long_u)size, TRUE));
        !            36: }
        !            37:
        !            38: /*
        !            39:  * alloc() with check for maximum line length
        !            40:  */
        !            41:    char_u *
        !            42: alloc_check(size)
        !            43:    unsigned        size;
        !            44: {
        !            45: #if !defined(UNIX) && !defined(__EMX__)
        !            46:    if (sizeof(int) == 2 && size > 0x7fff)
        !            47:    {
        !            48:        EMSG("Line is becoming too long");
        !            49:        return NULL;
        !            50:    }
        !            51: #endif
        !            52:    return (lalloc((long_u)size, TRUE));
        !            53: }
        !            54:
        !            55:    char_u *
        !            56: lalloc(size, message)
        !            57:    long_u          size;
        !            58:    int             message;
        !            59: {
        !            60:    register char_u   *p;           /* pointer to new storage space */
        !            61:    static int  releasing = FALSE;  /* don't do mf_release_all() recursive */
        !            62:    int         try_again;
        !            63:
        !            64:    if (size <= 0)
        !            65:    {
        !            66:        EMSGN("Internal error: lalloc(%ld, )", size);
        !            67:        return NULL;
        !            68:    }
        !            69: #if defined(MSDOS) && !defined(DJGPP)
        !            70:    if (size >= 0xfff0)         /* in MSDOS we can't deal with >64K blocks */
        !            71:        p = NULL;
        !            72:    else
        !            73: #endif
        !            74:
        !            75:    /*
        !            76:     * If out of memory, try to release some memfile blocks.
        !            77:     * If some blocks are released call malloc again.
        !            78:     */
        !            79:    for (;;)
        !            80:    {
        !            81:        if ((p = (char_u *)malloc(size)) != NULL)
        !            82:        {
        !            83:            if (mch_avail_mem(TRUE) < KEEP_ROOM && !releasing)
        !            84:            {                               /* System is low... no go! */
        !            85:                    vim_free((char *)p);
        !            86:                    p = NULL;
        !            87:            }
        !            88:        }
        !            89:    /*
        !            90:     * Remember that mf_release_all() is being called to avoid an endless loop,
        !            91:     * because mf_release_all() may call alloc() recursively.
        !            92:     */
        !            93:        if (p != NULL || releasing)
        !            94:            break;
        !            95:        releasing = TRUE;
        !            96:        try_again = mf_release_all();
        !            97:        releasing = FALSE;
        !            98:        if (!try_again)
        !            99:            break;
        !           100:    }
        !           101:
        !           102:    /*
        !           103:     * Avoid repeating the error message many times (they take 1 second each).
        !           104:     * Did_outofmem_msg is reset when a character is read.
        !           105:     */
        !           106:    if (message && p == NULL)
        !           107:        do_outofmem_msg();
        !           108:    return (p);
        !           109: }
        !           110:
        !           111:    void
        !           112: do_outofmem_msg()
        !           113: {
        !           114:    if (!did_outofmem_msg)
        !           115:    {
        !           116:        emsg(e_outofmem);
        !           117:        did_outofmem_msg = TRUE;
        !           118:    }
        !           119: }
        !           120:
        !           121: /*
        !           122:  * copy a string into newly allocated memory
        !           123:  */
        !           124:    char_u *
        !           125: strsave(string)
        !           126:    char_u         *string;
        !           127: {
        !           128:    char_u *p;
        !           129:
        !           130:    p = alloc((unsigned) (STRLEN(string) + 1));
        !           131:    if (p != NULL)
        !           132:        STRCPY(p, string);
        !           133:    return p;
        !           134: }
        !           135:
        !           136:    char_u *
        !           137: strnsave(string, len)
        !           138:    char_u      *string;
        !           139:    int         len;
        !           140: {
        !           141:    char_u *p;
        !           142:
        !           143:    p = alloc((unsigned) (len + 1));
        !           144:    if (p != NULL)
        !           145:    {
        !           146:        STRNCPY(p, string, len);
        !           147:        p[len] = NUL;
        !           148:    }
        !           149:    return p;
        !           150: }
        !           151:
        !           152: /*
        !           153:  * Same as strsave(), but any characters found in esc_chars are preceded by a
        !           154:  * backslash.
        !           155:  */
        !           156:    char_u *
        !           157: strsave_escaped(string, esc_chars)
        !           158:    char_u      *string;
        !           159:    char_u      *esc_chars;
        !           160: {
        !           161:    char_u      *p;
        !           162:    char_u      *p2;
        !           163:    char_u      *escaped_string;
        !           164:    unsigned    length;
        !           165:
        !           166:    /*
        !           167:     * First count the number of backslashes required.
        !           168:     * Then allocate the memory and insert them.
        !           169:     */
        !           170:    length = 1;                         /* count the trailing '/' and NUL */
        !           171:    for (p = string; *p; p++)
        !           172:    {
        !           173:        if (vim_strchr(esc_chars, *p) != NULL)
        !           174:            ++length;                   /* count a backslash */
        !           175:        ++length;                       /* count an ordinary char */
        !           176:    }
        !           177:    escaped_string = alloc(length);
        !           178:    if (escaped_string != NULL)
        !           179:    {
        !           180:        p2 = escaped_string;
        !           181:        for (p = string; *p; p++)
        !           182:        {
        !           183:            if (vim_strchr(esc_chars, *p) != NULL)
        !           184:                *p2++ = '\\';
        !           185:            *p2++ = *p;
        !           186:        }
        !           187:        *p2 = NUL;
        !           188:    }
        !           189:    return escaped_string;
        !           190: }
        !           191:
        !           192: /*
        !           193:  * copy a number of spaces
        !           194:  */
        !           195:    void
        !           196: copy_spaces(ptr, count)
        !           197:    char_u  *ptr;
        !           198:    size_t  count;
        !           199: {
        !           200:    register size_t i = count;
        !           201:    register char_u *p = ptr;
        !           202:
        !           203:    while (i--)
        !           204:        *p++ = ' ';
        !           205: }
        !           206:
        !           207: /*
        !           208:  * delete spaces at the end of a string
        !           209:  */
        !           210:    void
        !           211: del_trailing_spaces(ptr)
        !           212:    char_u *ptr;
        !           213: {
        !           214:    char_u  *q;
        !           215:
        !           216:    q = ptr + STRLEN(ptr);
        !           217:    while (--q > ptr && vim_iswhite(q[0]) && q[-1] != '\\' &&
        !           218:                                                           q[-1] != Ctrl('V'))
        !           219:        *q = NUL;
        !           220: }
        !           221:
        !           222: /*
        !           223:  * Isolate one part of a string option where parts are separated with commas.
        !           224:  * The part is copied into buf[maxlen].
        !           225:  * "*option" is advanced to the next part.
        !           226:  * The length is returned.
        !           227:  */
        !           228:    int
        !           229: copy_option_part(option, buf, maxlen, sep_chars)
        !           230:    char_u      **option;
        !           231:    char_u      *buf;
        !           232:    int         maxlen;
        !           233:    char        *sep_chars;
        !           234: {
        !           235:    int     len = 0;
        !           236:    char_u  *p = *option;
        !           237:
        !           238:    /* skip '.' at start of option part, for 'suffixes' */
        !           239:    if (*p == '.')
        !           240:        buf[len++] = *p++;
        !           241:    while (*p && vim_strchr((char_u *)sep_chars, *p) == NULL)
        !           242:    {
        !           243:        /*
        !           244:         * Skip backslash before a separator character and space.
        !           245:         */
        !           246:        if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
        !           247:            ++p;
        !           248:        if (len < maxlen - 1)
        !           249:            buf[len++] = *p;
        !           250:        ++p;
        !           251:    }
        !           252:    buf[len] = NUL;
        !           253:
        !           254:    p = skip_to_option_part(p); /* p points to next file name */
        !           255:
        !           256:    *option = p;
        !           257:    return len;
        !           258: }
        !           259:
        !           260: /*
        !           261:  * replacement for free() that ignores NULL pointers
        !           262:  */
        !           263:    void
        !           264: vim_free(x)
        !           265:    void *x;
        !           266: {
        !           267:    if (x != NULL)
        !           268:        free(x);
        !           269: }
        !           270:
        !           271: #ifndef HAVE_MEMSET
        !           272:    void *
        !           273: vim_memset(ptr, c, size)
        !           274:    void    *ptr;
        !           275:    int     c;
        !           276:    size_t  size;
        !           277: {
        !           278:    register char *p = ptr;
        !           279:
        !           280:    while (size-- > 0)
        !           281:        *p++ = c;
        !           282:    return ptr;
        !           283: }
        !           284: #endif
        !           285:
        !           286: #ifdef VIM_MEMMOVE
        !           287: /*
        !           288:  * Version of memmove that handles overlapping source and destination.
        !           289:  * For systems that don't have a function that is guaranteed to do that (SYSV).
        !           290:  */
        !           291:    void
        !           292: vim_memmove(dst_arg, src_arg, len)
        !           293:    void    *src_arg, *dst_arg;
        !           294:    size_t  len;
        !           295: {
        !           296:    /*
        !           297:     * A void doesn't have a size, we use char pointers.
        !           298:     */
        !           299:    register char *dst = dst_arg, *src = src_arg;
        !           300:
        !           301:                                        /* overlap, copy backwards */
        !           302:    if (dst > src && dst < src + len)
        !           303:    {
        !           304:        src +=len;
        !           305:        dst +=len;
        !           306:        while (len-- > 0)
        !           307:            *--dst = *--src;
        !           308:    }
        !           309:    else                                /* copy forwards */
        !           310:        while (len-- > 0)
        !           311:            *dst++ = *src++;
        !           312: }
        !           313: #endif
        !           314:
        !           315: /*
        !           316:  * compare two strings, ignoring case
        !           317:  * return 0 for match, 1 for difference
        !           318:  */
        !           319:    int
        !           320: vim_strnicmp(s1, s2, len)
        !           321:    char_u  *s1;
        !           322:    char_u  *s2;
        !           323:    size_t  len;
        !           324: {
        !           325:    while (len)
        !           326:    {
        !           327:        if (TO_UPPER(*s1) != TO_UPPER(*s2))
        !           328:            return 1;                       /* this character different */
        !           329:        if (*s1 == NUL)
        !           330:            return 0;                       /* strings match until NUL */
        !           331:        ++s1;
        !           332:        ++s2;
        !           333:        --len;
        !           334:    }
        !           335:    return 0;                               /* strings match */
        !           336: }
        !           337:
        !           338: /*
        !           339:  * Version of strchr() and strrchr() that handle unsigned char strings
        !           340:  * with characters above 128 correctly. Also it doesn't return a pointer to
        !           341:  * the NUL at the end of the string.
        !           342:  */
        !           343:    char_u  *
        !           344: vim_strchr(string, n)
        !           345:    char_u  *string;
        !           346:    int     n;
        !           347: {
        !           348:    while (*string)
        !           349:    {
        !           350:        if (*string == n)
        !           351:            return string;
        !           352:        ++string;
        !           353:    }
        !           354:    return NULL;
        !           355: }
        !           356:
        !           357:    char_u  *
        !           358: vim_strrchr(string, n)
        !           359:    char_u  *string;
        !           360:    int     n;
        !           361: {
        !           362:    char_u  *retval = NULL;
        !           363:
        !           364:    while (*string)
        !           365:    {
        !           366:        if (*string == n)
        !           367:            retval = string;
        !           368:        ++string;
        !           369:    }
        !           370:    return retval;
        !           371: }
        !           372:
        !           373: /*
        !           374:  * Vim has its own isspace() function, because on some machines isspace()
        !           375:  * can't handle characters above 128.
        !           376:  */
        !           377:    int
        !           378: vim_isspace(x)
        !           379:    int     x;
        !           380: {
        !           381:    return ((x >= 9 && x <= 13) || x == ' ');
        !           382: }