muddy/
muddy/CVS/
muddy/area/
muddy/area/CVS/
muddy/clans/CVS/
muddy/classes/CVS/
muddy/doc/
muddy/doc/CVS/
muddy/etc/CVS/
muddy/etc/i3/
muddy/etc/i3/CVS/
muddy/imc/CVS/
muddy/lang/CVS/
muddy/licenses/CVS/
muddy/msgdb/CVS/
muddy/new/CVS/
muddy/notes/
muddy/player/
muddy/races/CVS/
muddy/religions/CVS/
muddy/src/CVS/
muddy/src/comm/CVS/
muddy/src/db/CVS/
muddy/src/intermud/
muddy/src/intermud/CVS/
muddy/src/irc/CVS/
muddy/src/olc/CVS/
/* $Id: flag.c,v 1.666 2004/09/20 10:49:48 shrike Exp $                              */

/************************************************************************************
 *    Copyright 2004 Astrum Metaphora consortium                                    *
 *                                                                                  *
 *    Licensed under the Apache License, Version 2.0 (the "License");               *
 *    you may not use this file except in compliance with the License.              *
 *    You may obtain a copy of the License at                                       *
 *                                                                                  *
 *    http://www.apache.org/licenses/LICENSE-2.0                                    *
 *                                                                                  *
 *    Unless required by applicable law or agreed to in writing, software           *
 *    distributed under the License is distributed on an "AS IS" BASIS,             *
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.      *
 *    See the License for the specific language governing permissions and           *
 *    limitations under the License.                                                *
 *                                                                                  *
 ************************************************************************************/

/************************************************************************************
 *                                                                                  *
 *  Much time and thought has gone into this software and you are                   *
 *  benefitting.  We hope that you share your changes too.  What goes               *
 *  around, comes around.                                                           *
 *                                                                                  *
 *  This code was written by Jason Dinkel and inspired by Russ Taylor,              *
 *  and has been used here for OLC - OLC would not be what it is without            *
 *  all the previous coders who released their source code.                         *
 *                                                                                  *
 ************************************************************************************/
             
/************************************************************************************
 * The code below uses a table lookup system that is based on suggestions           *
 * from Russ Taylor.  There are many routines in handler.c that would benefit       *
 * with the use of tables.  You may consider simplifying your code base by          *
 * implementing a system like below with such functions. -Jason Dinkel              *
 ************************************************************************************/

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "util.h"

/*
 * flag_lookup -- lookup flag by name in flag table
 *                f should point to real start of table
 *                (impl. dependent values such as table type should
 *                 be skipped)
 */
const flag_t* flag_lookup(const flag_t *f, const char *name)
{
        if (IS_NULLSTR(name))
                return NULL;

        while (f->name != NULL) 
        {
                if (str_prefix(name, f->name) == 0)
                        return f;
                f++;
        }
        return NULL;
}

/*****************************************************************************
 Name:          flag_value(table, flag)
 Purpose:       Returns the value of the flags entered.  Multi-flags accepted.
 Called by:     olc.c and olc_act.c.
 ****************************************************************************/
flag64_t flag_value(const flag_t *flag64_table, const char *argument)
{
        const flag_t *f;
        const char *tname = flag64_table->name;
        flag64_t ttype = flag64_table->bit;

        flag64_table++;
        switch (ttype) 
        {
        case TABLE_BITVAL: 
        {
                flag64_t marked = 0;

                /*
                 * Accept multiple flags.
                 */
                for (;;) 
                {
                        char word[MAX_INPUT_LENGTH];
                        argument = one_argument(argument, word, sizeof(word));

                        if (word[0] == '\0')
                                break;

                        if ((f = flag_lookup(flag64_table, word)) == NULL)
                                return 0;

                        SET_BIT(marked, f->bit);
                }

                return marked;
                /* NOT REACHED */
        }

        case TABLE_INTVAL:
                if ((f = flag_lookup(flag64_table, argument)) == NULL)
                        return -1;
                return f->bit;
                /* NOT REACHED */

        default:
                log_printf("flag_value: %s: unknown table type %d",
                           tname, ttype);
                break;
        }

        return 0;
}

#define NBUFS 3
#define BUFSZ 512

/*****************************************************************************
 Name:          flag_string( table, flags/stat )
 Purpose:       Returns string with name(s) of the flags or stat entered.
 Called by:     act_olc.c, olc.c, and olc_save.c.
 ****************************************************************************/
const char *flag_string(const flag_t *flag64_table, flag64_t bits)
{
        static char buf[NBUFS][BUFSZ];
        static int cnt = 0;
        int flag;
        const char *tname = flag64_table->name;
        flag64_t ttype = flag64_table->bit;

        cnt = (cnt + 1) % NBUFS;
        buf[cnt][0] = '\0';
        flag64_table++;
        for (flag = 0; flag64_table[flag].name; flag++) 
        {
                switch (ttype) 
                {
                case TABLE_BITVAL:
                        if (IS_SET(bits, flag64_table[flag].bit)) 
                        {
                                strnzcat(buf[cnt], BUFSZ, " ");
                                strnzcat(buf[cnt], BUFSZ, flag64_table[flag].name);
                        }
                        break;

                case TABLE_INTVAL:
                        if (flag64_table[flag].bit == bits) 
                        {
                                strnzcpy(buf[cnt], BUFSZ,
                                         flag64_table[flag].name);
                                return buf[cnt];
                        }
                        break;

                default:
                        log_printf("flag_value: %s: unknown table type %d", tname, ttype);
                        buf[cnt][0] = '\0';
                        return buf[cnt];
                }
        }

/*
 * if got there then buf[cnt] is filled with bitval names
 * or (in case the table is TABLE_INTVAL) value was not found
 *
 */
        switch (ttype) 
        {
        case TABLE_BITVAL:
                return buf[cnt][0] ? buf[cnt]+1 : "none";
                /* NOT REACHED */

        case TABLE_INTVAL:
                return "unknown";
                /* NOT REACHED */

        default:
                /* can't happen */
                buf[cnt][0] = '\0';
                return buf[cnt];
        }
}

void show_flags_buf(BUFFER *output, const flag_t *flag64_table)
{
        int  flag;
        int  col = 0;
 
        col = 0;
        flag64_table++;
        for (flag = 0; flag64_table[flag].name; flag++) 
        {
                if (flag64_table[flag].settable) 
                {
                        buf_printf(output, "%-19.18s", flag64_table[flag].name);
                        if (++col % 4 == 0)
                                buf_add(output, "\n");
                }
        }
 
        if (col % 4 != 0)
                buf_add(output, "\n");
}

/*****************************************************************************
 Name:          show_flags
 Purpose:       Displays settable flags and stats.
 ****************************************************************************/
void show_flags(CHAR_DATA *ch, const flag_t *flag64_table)
{
        BUFFER *output;

        output = buf_new(-1);
        show_flags_buf(output, flag64_table);
        page_to_char(buf_string(output), ch);
        buf_free(output);
}

const char *flag_dump(const flag_t *flag64_table, int value)
{
//        const flag_t   *f;
        const char     *tname = flag64_table->name;
        flag64_t        ttype = flag64_table->bit;
        int             flag;
        static char     buf[NBUFS][BUFSZ];
        static int      cnt = 0;
        
        cnt = (cnt + 1) % NBUFS;
        buf[cnt][0] = '\0';

        flag64_table++;
        
        switch (ttype) 
        {
        case TABLE_BITVAL: 
            for (flag = 0;  flag64_table[flag].name; flag++)
            {
                  if (str_cmp(flag64_table[flag].name, str_empty))
                  {
                        if (IS_SET(value, flag64_table[flag].bit))
                             if (flag64_table[flag].legend)
                                 strnzcat(buf[cnt], BUFSZ, flag64_table[flag].legend);
                             else
                                 strnzcat(buf[cnt], BUFSZ, "{R-");
                        else
                             strnzcat(buf[cnt], BUFSZ, "{D-");
                  }
            }
            strnzcat(buf[cnt], BUFSZ, "{x");
            return buf[cnt];
            break;
        
        case TABLE_INTVAL:
            for (flag = 0;  flag64_table[flag].name; flag++)
            {
                  if (str_cmp(flag64_table[flag].name, str_empty))
                  {
                        if (flag64_table[flag].bit == value)
                             if (flag64_table[flag].legend)
                                 strnzcat(buf[cnt], BUFSZ, flag64_table[flag].legend);
                             else
                                 strnzcat(buf[cnt], BUFSZ, "{R-");
                        else
                             strnzcat(buf[cnt], BUFSZ, "{D-");
                  }
            }
            strnzcat(buf[cnt], BUFSZ, "{x");
            return buf[cnt];
            break;    
               
        default:
                log_printf("flag_value: %s: unknown table type %d", tname, ttype);
                break;
        }
        
        return buf[cnt];
}