Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2001:
[Freeciv-Dev] Re: Server/ruleset unification [Was [RFC PATCH] init_techs
Home

[Freeciv-Dev] Re: Server/ruleset unification [Was [RFC PATCH] init_techs

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: rf13@xxxxxxxxxxxxxxxxxxxxxx
Cc: Arien Malec <arien_malec@xxxxxxxxx>, Freeciv developers <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: Server/ruleset unification [Was [RFC PATCH] init_techs]
From: Daniel L Speyer <dspeyer@xxxxxxxxxxx>
Date: Tue, 25 Sep 2001 16:03:11 -0400 (EDT)

I've been looking at command type-checking/parsing, and I think the best
approach might be to pass each function just an int and a char**, and then
have each function begin by demand()ing the right datatypes.  I've written
a prototype demand function (it leaks memory and is incomplete, but it
works) that takes the list of datatypes as a string (a little kludgy,
yeah, but it lets the author enter datatypes easily without polluting the
namespace).  So for the (not seriously proposed) function setallattime,
with example syntax

setallattime explorers, settlers, generator,techlevel 3 at now

The command declaration would be something like

void cmd_setallattime(int argV,char** argC){
  char* error;  
  if (error=demand(&argV,argC,"lins")){ /*List Integer Null String*/
    server_error(error);
    return;
  }
  /* do stuff */
}

and then the function would be able to assume argC was a void** containing
exactly what it needed.  argC[0] would be a struct inputlist which would
simply be an argV and ArgC of its own (which could, if needed, could be
run through demand the same way).  The demand function as written handles
the whitespace in the list properly, but would barf at whitespace within
an element of the list (actually, it's not the whitespace that upsets it,
but the argument break -- if the parser takes care of the problem through
quoting support, demand will be happy).

Here's the present code for the demand function:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct inputlist{
  int argV;
  char **argC;
};

char* demand(int *argV, char** argC, char* format){
  int fi,ai=0,oi=0,i,j,k; /*iterators: format, argument, output,
generics*/
  int tmp;
  struct inputlist* listtmp;
  for (fi=0;fi<strlen(format);fi++){
    printf("fi=%d ai=%d oi=%d\n",fi,ai,oi);
    if (ai>=*argV || oi>=*argV)
      return("Not enough argguments");
    if (format[fi]=='s'){ /*String*/
      if (ai!=oi){
        /*      free(argC[oi]);*/
        argC[oi]=(char*)malloc(sizeof(char)*strlen(argC[ai]));
        strcpy(argC[oi],argC[ai]);
      }
      ai++;
      oi++;
      continue;
    }
    if (format[fi]=='i'){ /*integer*/
      if (argC[ai][0]!='-' && (argC[ai][0]<'1' || argC[ai][0]>'9'))
        return("Not an integer");
      for(i=1;i<strlen(argC[ai]);i++)
        if (argC[ai][i]<'0' || argC[ai][i]>'9')
          return("Not an integer.");
      /*      free(argC[oi]);*/
      j=atoi(argC[ai]);
      argC[oi]=(char*)malloc(sizeof(int));
      *(int*)(argC[oi])=j;
      ai++;
      oi++;
    }
    if (format[fi]=='n'){ /*null (i.e. skip)*/
      ai++;
    }
    if (format[fi]=='l'){ /*list*/
      listtmp=(struct inputlist*)malloc(sizeof(struct inputlist));
      listtmp->argV=1;/* each comma means one *more* element */
      i=ai;
      for (j=0;argC[i][j];j++){
        if (argC[i][j]==','){
          listtmp->argV++;
          if (!argC[i][j+1] && i<*argV-1){
            i++;
            j=0;
          }
        }
      }
      listtmp->argC=(char**)malloc(listtmp->argV*sizeof(char*));
      i=ai;
      tmp=0;
      k=0;
      for (j=0;argC[i][j];j++){
        if (argC[i][j]==','){
          argC[i][j]=0;

listtmp->argC[k]=(char*)malloc(sizeof(char)*strlen(argC[i]+tmp));
          strcpy(listtmp->argC[k++],argC[i]+tmp);
          tmp=j+1;
          if (!argC[i][j+1] && i<*argV-1){
            i++;
            tmp=j=0;
          }
        }
      }
      listtmp->argC[k]=(char*)malloc(sizeof(char)*strlen(argC[i]+tmp));
      strcpy(listtmp->argC[k++],argC[i]+tmp);
      ai=i+1;
      argC[oi++]=(char*)listtmp;
    }
  }
  *argV=oi;
  return(0);
}


--Daniel Speyer
"May the /src be with you, always"





[Prev in Thread] Current Thread [Next in Thread]