Blame urt/rle_putcom.c

Packit 78deda
/*
Packit 78deda
 * This software is copyrighted as noted below.  It may be freely copied,
Packit 78deda
 * modified, and redistributed, provided that the copyright notice is 
Packit 78deda
 * preserved on all copies.
Packit 78deda
 * 
Packit 78deda
 * There is no warranty or other guarantee of fitness for this software,
Packit 78deda
 * it is provided solely "as is".  Bug reports or fixes may be sent
Packit 78deda
 * to the author, who may or may not act on them as he desires.
Packit 78deda
 *
Packit 78deda
 * You may not include this software in a program or other software product
Packit 78deda
 * without supplying the source, or without informing the end-user that the 
Packit 78deda
 * source is available for no extra charge.
Packit 78deda
 *
Packit 78deda
 * If you modify this software, you should include a notice giving the
Packit 78deda
 * name of the person performing the modification, the date of modification,
Packit 78deda
 * and the reason for such modification.
Packit 78deda
 */
Packit 78deda
/* 
Packit 78deda
 * rle_putcom.c - Add a picture comment to the header struct.
Packit 78deda
 * 
Packit 78deda
 * Author:  Spencer W. Thomas
Packit 78deda
 *      Computer Science Dept.
Packit 78deda
 *      University of Utah
Packit 78deda
 * Date:    Mon Feb  2 1987
Packit 78deda
 * Copyright (c) 1987, University of Utah
Packit 78deda
 */
Packit 78deda
Packit 78deda
#include <stdio.h>
Packit 78deda
Packit 78deda
#include "netpbm/mallocvar.h"
Packit 78deda
#include "netpbm/pm.h"
Packit 78deda
#include "rle.h"
Packit 78deda
Packit 78deda
/*****************************************************************
Packit 78deda
 * TAG( match )
Packit 78deda
 * 
Packit 78deda
 * Match a name against a test string for "name=value" or "name".
Packit 78deda
 * If it matches name=value, return pointer to value part, if just
Packit 78deda
 * name, return pointer to NUL at end of string.  If no match, return NULL.
Packit 78deda
 *
Packit 78deda
 * Inputs:
Packit 78deda
 *  n:  Name to match.  May also be "name=value" to make it easier
Packit 78deda
 *      to replace comments.
Packit 78deda
 *  v:  Test string.
Packit 78deda
 * Outputs:
Packit 78deda
 *  Returns pointer as above.
Packit 78deda
 * Assumptions:
Packit 78deda
 *  [None]
Packit 78deda
 * Algorithm:
Packit 78deda
 *  [None]
Packit 78deda
 */
Packit 78deda
static const char *
Packit 78deda
match(const char * const nArg,
Packit 78deda
      const char * const vArg) {
Packit 78deda
Packit 78deda
    const char * n;
Packit 78deda
    const char * v;
Packit 78deda
Packit 78deda
    for (n = nArg, v = vArg; *n != '\0' && *n != '=' && *n == *v; ++n, ++v)
Packit 78deda
        ;
Packit 78deda
    if (*n == '\0' || *n == '=') {
Packit 78deda
        if (*v == '\0')
Packit 78deda
            return v;
Packit 78deda
        else if (*v == '=')
Packit 78deda
            return ++v;
Packit 78deda
    }
Packit 78deda
Packit 78deda
    return NULL;
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
/*****************************************************************
Packit 78deda
 * TAG( rle_putcom )
Packit 78deda
 * 
Packit 78deda
 * Put a comment into the header struct.
Packit 78deda
 * Inputs:
Packit 78deda
 *  value:      Value to add to comments.
Packit 78deda
 *  the_hdr:    Header struct to add to.
Packit 78deda
 * Outputs:
Packit 78deda
 *  the_hdr:    Modified header struct.
Packit 78deda
 *  Returns previous value;
Packit 78deda
 * Assumptions:
Packit 78deda
 *  value pointer can be used as is (data is NOT copied).
Packit 78deda
 * Algorithm:
Packit 78deda
 *  Find match if any, else add at end (realloc to make bigger).
Packit 78deda
 */
Packit 78deda
const char *
Packit 78deda
rle_putcom(const char * const value,
Packit 78deda
           rle_hdr *    const the_hdr) {
Packit 78deda
Packit 78deda
    if ( the_hdr->comments == NULL) {
Packit 78deda
        MALLOCARRAY_NOFAIL(the_hdr->comments, 2);
Packit 78deda
        the_hdr->comments[0] = value;
Packit 78deda
        the_hdr->comments[1] = NULL;
Packit 78deda
    } else {
Packit 78deda
        const char ** cp;
Packit 78deda
        const char * v;
Packit 78deda
        const char ** old_comments;
Packit 78deda
        int i;
Packit 38c941
        for (i = 2, cp = the_hdr->comments; *cp != NULL; ++i, ++cp) {
Packit 38c941
            overflow_add(i, 1);
Packit 78deda
            if (match(value, *cp) != NULL) {
Packit 78deda
                v = *cp;
Packit 78deda
                *cp = value;
Packit 78deda
                return v;
Packit 78deda
            }
Packit 38c941
        }
Packit 78deda
        /* Not found */
Packit 78deda
        /* Can't realloc because somebody else might be pointing to this
Packit 78deda
         * comments block.  Of course, if this were true, then the
Packit 78deda
         * assignment above would change the comments for two headers.
Packit 78deda
         * But at least, that won't crash the program.  Realloc will.
Packit 78deda
         * This would work a lot better in C++, where hdr1 = hdr2
Packit 78deda
         * could copy the pointers, too.
Packit 78deda
         */
Packit 78deda
        old_comments = the_hdr->comments;
Packit 78deda
        MALLOCARRAY(the_hdr->comments, i);
Packit 78deda
        if (the_hdr->comments == NULL)
Packit 78deda
            pm_error("Unable to allocate memory for comments");
Packit 78deda
        the_hdr->comments[--i] = NULL;
Packit 78deda
        the_hdr->comments[--i] = value;
Packit 78deda
        for (--i; i >= 0; --i)
Packit 78deda
            the_hdr->comments[i] = old_comments[i];
Packit 78deda
    }
Packit 78deda
Packit 78deda
    return NULL;
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
/*****************************************************************
Packit 78deda
 * TAG( rle_delcom )
Packit 78deda
 * 
Packit 78deda
 * Delete a comment from header struct.
Packit 78deda
 * Inputs:
Packit 78deda
 *  name:       Name of comment to delete.
Packit 78deda
 *  the_hdr:    Header to delete comment from.
Packit 78deda
 * Outputs:
Packit 78deda
 *  the_hdr:    Modified header struct.
Packit 78deda
 *  Returns original comment value.
Packit 78deda
 * Assumptions:
Packit 78deda
 *  [None]
Packit 78deda
 * Algorithm:
Packit 78deda
 *  [None]
Packit 78deda
 */
Packit 78deda
const char *
Packit 78deda
rle_delcom(const char * const name,
Packit 78deda
           rle_hdr *    const the_hdr) {
Packit 78deda
Packit 78deda
    const char * v = NULL;
Packit 78deda
Packit 78deda
    if (the_hdr->comments == NULL)
Packit 78deda
        v = NULL;
Packit 78deda
    else {
Packit 78deda
        const char ** cp;
Packit 78deda
Packit 78deda
        for (cp = the_hdr->comments; *cp != NULL; ++cp)
Packit 78deda
            if (match(name, *cp) != NULL) {
Packit 78deda
                v = *cp;
Packit 78deda
                for ( ; *cp != NULL; ++cp)
Packit 78deda
                    *cp = cp[1];
Packit 78deda
                break;
Packit 78deda
            }
Packit 78deda
        /* Not found */
Packit 78deda
        if (*the_hdr->comments == NULL)
Packit 78deda
            the_hdr->comments = NULL;
Packit 78deda
    }
Packit 78deda
Packit 78deda
    return v;
Packit 78deda
}