commands.c-Dateireferenz

#include <moving.h>
#include <thing/language.h>
#include <exploration.h>
#include <thing/description.h>
#include <thing/commands.h>
Include-Abhängigkeitsdiagramm für commands.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define NEED_PROTOTYPES
#define DBG(x)   if(find_player("jof")) tell_object(find_player("jof"),sprintf("%O\n",x));
#define CHECK_PRESENT   1
#define CHECK_ID   2
#define CHECK_PUTGETNONE   4
#define CHECK_PUTGETDROP   8
#define CHECK_PUTGETTAKE   16
#define CHECK_PUTGET   (CHECK_PUTGETNONE|CHECK_PUTGETDROP|CHECK_PUTGETTAKE)

Funktionen

protected void create ()
protected void create_super ()
varargs void AddCmd (mixed cmd, mixed func, mixed flag, mixed cmdid)
varargs int RemoveCmd (mixed cmd, int del_norule, mixed onlyid)
static int _execute (mixed fun, string str, mixed *parsed)
static int _process_command (string str, string *noparsestr, mixed *fun, mixed *flag, mixed *rule)
public int _cl (string str)
void init ()
static void _check_copy_commands (string ind, mixed *fun, mixed *flag, mixed *rule)
static mapping _set_commands (mapping commands)
static mapping _query_commands ()

Variablen

private nosave mapping added_cmds

Makro-Dokumentation

#define CHECK_ID   2

Definiert in Zeile 256 der Datei commands.c.

Wird benutzt von _process_command().

#define CHECK_PRESENT   1

Definiert in Zeile 255 der Datei commands.c.

Wird benutzt von _process_command().

#define CHECK_PUTGET   (CHECK_PUTGETNONE|CHECK_PUTGETDROP|CHECK_PUTGETTAKE)

Definiert in Zeile 260 der Datei commands.c.

Wird benutzt von _process_command().

#define CHECK_PUTGETDROP   8

Definiert in Zeile 258 der Datei commands.c.

Wird benutzt von _process_command().

#define CHECK_PUTGETNONE   4

Definiert in Zeile 257 der Datei commands.c.

Wird benutzt von _process_command().

#define CHECK_PUTGETTAKE   16

Definiert in Zeile 259 der Datei commands.c.

Wird benutzt von _process_command().

#define DBG ( x   )     if(find_player("jof")) tell_object(find_player("jof"),sprintf("%O\n",x));

Definiert in Zeile 157 der Datei commands.c.

#define NEED_PROTOTYPES

Definiert in Zeile 40 der Datei commands.c.


Dokumentation der Funktionen

static void _check_copy_commands ( string  ind,
mixed *  fun,
mixed *  flag,
mixed *  rule 
) [static]

Definiert in Zeile 475 der Datei commands.c.

Benutzt added_cmds.

00476                                                                                             {
00477  if(pointerp(fun)) added_cmds[ind,0]=fun+allocate(0);
00478  else added_cmds[ind,0]=({fun});
00479  if(pointerp(flag)) added_cmds[ind,1]=flag+allocate(0);
00480  else if(flag) added_cmds[ind,1]=({flag});
00481  else added_cmds[ind,1]=allocate(sizeof(added_cmds[ind]));
00482  if(pointerp(rule)) added_cmds[ind,2]=rule+allocate(0);
00483  else added_cmds[ind,2]=allocate(sizeof(added_cmds[ind]));
00484 
00485  if(sizeof(added_cmds[ind])!=sizeof(added_cmds[ind,1]) ||
00486     sizeof(added_cmds[ind])!=sizeof(added_cmds[ind,2])) {
00487   added_cmds=(mapping)0;
00488   raise_error("SetProp(P_COMMANDS): corrupt commands-mapping.\n");
00489  }
00490 }

public int _cl ( string  str  ) 

Definiert in Zeile 425 der Datei commands.c.

Benutzt _execute(), _process_command(), added_cmds, EP_CMD, GiveEP(), i, ids und keys.

00425                            {
00426  int nindex;
00427  string *keys;
00428  mixed *flag;
00429  // Verb existiert, Kommandos auch, Eintrag fuer Verb gefunden
00430  if(mappingp(added_cmds) && query_verb()) {
00431   mixed *fun, *rule, *ids;
00432 
00433   // ist das Verb ein Key im Kommandomapping?
00434   if(m_contains(&fun, &flag, &rule, &ids, added_cmds, query_verb())) {
00435    string *noparsestr;
00436    nindex=sizeof(fun);
00437    noparsestr=explode((str||"")," ")-({""});
00438    // dann matche ungeparsten Input gegen etwaige Regeln
00439    // -- nicht aendern: neue Kommandos sollen alte "ueberschreiben" koennen
00440    while(nindex--)
00441     if(_process_command(&str, noparsestr,
00442                                        fun[nindex], flag[nindex], rule[nindex]))
00443     {
00444       GiveEP(EP_CMD, query_verb());
00445       return 1;
00446     }
00447   }
00448 
00449   // keine Regel passte, unscharfe Auswertung auf alle
00450   // AddCmdverben ausdehnen
00451   keys=m_indices(added_cmds);
00452   nindex=sizeof(keys);
00453   while(nindex--)
00454    if(!strstr(query_verb(),keys[nindex]) &&
00455       member((flag=added_cmds[keys[nindex],1]),1)>=0) {
00456     int i,ret;
00457     i=sizeof(flag);
00458     // Reihenfolge nicht aendern !
00459     while(i--)
00460      if(flag[i]==1 && _execute(added_cmds[keys[nindex],0][i],str,0))
00461      {
00462        GiveEP(EP_CMD, query_verb());
00463        return 1;
00464      }
00465    }
00466  }
00467  return 0;
00468 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

static int _execute ( mixed  fun,
string  str,
mixed *  parsed 
) [static]

Definiert in Zeile 247 der Datei commands.c.

Wird benutzt von _cl() und _process_command().

00247                                                           {
00248  if(closurep(fun))
00249   return ((int)funcall(fun,str,&parsed));
00250  if(stringp(fun))
00251   return ((int)call_other(this_object(),fun,str,&parsed));
00252  return 0;
00253 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

static int _process_command ( string  str,
string *  noparsestr,
mixed *  fun,
mixed *  flag,
mixed *  rule 
) [static]

Definiert in Zeile 263 der Datei commands.c.

Benutzt _execute(), break_string(), CHECK_ID, CHECK_PRESENT, CHECK_PUTGET, CHECK_PUTGETDROP, CHECK_PUTGETNONE, CHECK_PUTGETTAKE, find_obs(), notify_fail(), PUT_GET_DROP, PUT_GET_NONE, PUT_GET_TAKE und replace_personal().

Wird benutzt von _cl().

00264                                                                                            {
00265  int tmpint;
00266  mixed *parsed, *pointermatches;
00267 
00268  // eine Regel ... auswerten ...
00269  if(pointerp(rule)) {
00270   int lastmatchpos, nrul, rs;
00271   parsed=pointermatches=allocate(0);
00272   lastmatchpos=-1;
00273 
00274   // Abgleichen der gesplitteten Eingabe mit Regeln:
00275   // vorwaerts durch die Synonymgruppen
00276   rs=sizeof(rule);
00277   while(nrul<rs) {
00278    int matchpos;
00279    string *synonym;
00280    mixed matchstr, tmp;
00281 
00282    matchpos=-1;
00283    matchstr=0;
00284 
00285    // Synonyme extrahieren
00286    tmpint=sizeof(synonym=rule[nrul]);
00287 
00288    // egal wie durch Synonyme bis Match - Abgleich mit Eingabe
00289    while(tmpint--) {
00290     // ist Synonym im Eingabestring und kommt spaeter als vorheriges Synonym?
00291     if((tmp=member(noparsestr,synonym[tmpint]))>=0 &&
00292        tmp>lastmatchpos) {
00293      // Erfolg: merken der Position im Eingabestring und den matchenden String
00294      matchpos=tmp;
00295      matchstr=noparsestr[tmp];
00296      break;
00297     }
00298    }
00299 
00300    // kein Match durch Synonyme?
00301    if(matchpos<0) {
00302     int check_present;
00303     // ist Abpruefen von ID/PRESENT in der Synonymgruppe verlangt
00304     // bei present()/find_obs gleich Grundvoraussetzung mitprufen
00305     if(member(synonym,"@ID")>=0) check_present=CHECK_ID;
00306     if(this_player()) {
00307      if(member(synonym,"@PRESENT")>=0) check_present|=CHECK_PRESENT;
00308      else if(member(synonym,"@PUT_GET_NONE")>=0)
00309                                 check_present|=CHECK_PUTGETNONE;
00310      else if(member(synonym,"@PUT_GET_TAKE")>=0)
00311                                 check_present|=CHECK_PUTGETDROP;
00312      else if(member(synonym,"@PUT_GET_DROP")>=0)
00313                                 check_present|=CHECK_PUTGETTAKE;
00314     }
00315     if(check_present) {
00316      int q,r;
00317      // wir fangen hinter dem letzten Match an
00318      if(lastmatchpos<0) q=0;
00319      else q=lastmatchpos+1;
00320      r=sizeof(noparsestr)-1;
00321 
00322      while((tmp=r-q)>=0) {
00323       mixed tmpobj;
00324 
00325       // wie weit wollen wir zurückgehen?
00326       if(tmp)
00327         if(!(check_present&CHECK_PUTGET))
00328           tmp=1;                                                // 2 Fragmente fuer @ID / @PRESENT
00329         else if(tmp>4)
00330           tmp=4;                                                // 5 Fragmente fuer @PUT_XXX 
00331 
00332       // und jetzt die Substrings prüfen
00333       while(tmp>=0 && !matchstr) {
00334        string tmpstr;
00335 
00336        if(tmp) tmpstr=implode(noparsestr[q..(q+tmp)]," ");
00337        else tmpstr=noparsestr[q];
00338 
00339        // DBG(tmpstr);
00340        if(check_present&CHECK_PRESENT &&                                        // PRESENT ?
00341           ((tmpobj=present(tmpstr,this_player())) ||
00342            (tmpobj=present(tmpstr,environment(this_player())))))
00343         matchstr=tmpobj;
00344        else if(check_present&CHECK_ID && id(tmpstr))            // ID ?
00345         matchstr=this_object();
00346        else if((check_present&CHECK_PUTGET) &&  // PUT_GET_??? ?
00347                (tmpobj=(object*)
00348                   this_player()->find_obs(tmpstr,
00349                       ([CHECK_PUTGETNONE:PUT_GET_NONE,
00350                         CHECK_PUTGETDROP:PUT_GET_TAKE,
00351                         CHECK_PUTGETTAKE:PUT_GET_DROP])
00352                                         [CHECK_PUTGET&check_present])) &&
00353                sizeof(tmpobj)) {
00354         if(sizeof(tmpobj)==1) matchstr=tmpobj[0];
00355         else {  // Arrays werden zwischengespeichert ...
00356          pointermatches+=({sizeof(parsed),tmpobj});
00357          matchstr=tmpstr;
00358         }
00359        } else {
00360         tmp--;
00361         continue;
00362        }
00363       }
00364 
00365       // Match gefunden!
00366       if(matchstr) {
00367        matchpos=tmp+q;
00368        // DBG(matchpos);
00369        break;
00370       }
00371       q++;
00372      } // end while
00373     }
00374    }
00375 
00376 
00377    // Fehlermeldung fuer diese fehlgeschlagene Synonymgruppe setzen
00378    if(matchpos<0) {
00379     // Fehlermeldungen und ein Eintrag an der Fehlerstelle?
00380     if(pointerp(flag) && sizeof(flag)>nrul) {
00381 
00382      matchstr=flag[nrul];
00383 
00384      if(stringp(matchstr) && strlen(matchstr)) {
00385       if(member(matchstr,'@')>=0) {
00386        matchstr=replace_personal(&matchstr,({this_player()})+parsed,1);
00387        tmp=((query_verb()[<1]^'e')?query_verb():query_verb()[0..<2]);
00388        matchstr=regreplace(matchstr,"@VERB",capitalize(tmp),1);
00389        matchstr=regreplace(matchstr,"@verb",tmp,1);
00390       }
00391 
00392       // ist Fehlermeldung ein WRITE?
00393       // dann return 1 !
00394       if(intp(flag[<1]) && (tmpint=flag[<1])<=nrul) {
00395        if(member(matchstr,'^')>=0) {
00396         matchstr=explode(matchstr,"^");
00397         write(capitalize(break_string(matchstr[0],78,0,1)));
00398         if(strlen(matchstr[1]))
00399          say(capitalize(break_string(matchstr[1],78,0,1)),({this_player()}) );
00400        } else write(capitalize(break_string(matchstr,78,0,1)));
00401        return 1;
00402       } else notify_fail(capitalize(break_string(matchstr,78,0,1)));
00403      }
00404     }
00405     return 0;
00406    }
00407 
00408    // Updaten der Hilfsvariablen
00409    parsed+=({matchstr});
00410    lastmatchpos=matchpos;
00411    nrul++;
00412   } // end while(nrul<rs) ... Erfolg ... ab zum naechsten Regelteil
00413  }
00414 
00415  // Arrays resubstituieren
00416  if((tmpint=sizeof(pointermatches)))
00417   while((tmpint-=2)>=0)
00418    parsed[pointermatches[tmpint]]=pointermatches[tmpint+1];
00419 
00420  // erfolgreich Methode gefunden/eine Regel bis zum Ende durchgeparst:
00421  return(_execute(&fun,&str,&parsed));
00422 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

static mapping _query_commands (  )  [static]

Definiert in Zeile 504 der Datei commands.c.

00504                                  {
00505  if (mappingp(added_cmds))
00506    return(deep_copy(added_cmds));
00507  else
00508    return (mapping)0;
00509 }

static mapping _set_commands ( mapping  commands  )  [static]

Definiert in Zeile 492 der Datei commands.c.

Benutzt added_cmds.

00492                                                {
00493  if(!commands) added_cmds=(mapping)0;
00494  else if(mappingp(commands)) {
00495   added_cmds=m_allocate(sizeof(commands),4);
00496   walk_mapping(commands,#'_check_copy_commands);
00497  }
00498  if (mappingp(added_cmds))
00499    return(deep_copy(added_cmds));
00500  else
00501    return (mapping)0;
00502 }

varargs void AddCmd ( mixed  cmd,
mixed  func,
mixed  flag,
mixed  cmdid 
)

Definiert in Zeile 55 der Datei commands.c.

Benutzt added_cmds, cl und i.

Wird benutzt von create(), MakeDrink() und SetTravelCmds().

00055                                                                     {
00056  int i,j;
00057  closure cl;
00058  mixed *rule;
00059 
00060  // potentielle AddCmd mit Regel?
00061  if(stringp(cmd)) {
00062   // eine Regel? - aufsplitten
00063   if((i=member(cmd,'&'))>0) {
00064    // ... in Array mit Verknuepfungselementen
00065    rule=explode(cmd[(i+1)..],"&");
00066    j=sizeof(rule);
00067    // ... in Array mit Arrays mit Alternativelementen:
00068    // "p|q&r|s" -> ({ ({"p","q"}), ({"r","s"}} })
00069    while(j--)
00070     rule[j]=explode(rule[j],"|");
00071 
00072    // Regeln von Kommandoverben abschneiden
00073    cmd=cmd[0..(i-1)];
00074   }
00075   // Kommandoverben extrahieren
00076   cmd=explode(cmd,"|");
00077 
00078   // Satz von Regeln existiert: Aufsplitten von Fehlermeldungen
00079   if(rule)
00080    if(stringp(flag)) {
00081     mixed *fail;
00082     // in einfaches Array mit jeweiligen Fehlermeldungen
00083     fail=explode(flag,"|");
00084     j=0;
00085     i=sizeof(fail);
00086     while(j<i) {
00087      // write - Fehlermeldung entdeckt - Position ggf. eintragen
00088      if(member(fail[j],'^')>=0 && !intp(fail[<1]))
00089       fail+=({j});
00090      if(member(fail[j],'@')>=0) {
00091       int s;
00092       flag=regexplode(fail[j], "@WE[A-SU]*[0-9]");
00093       s=sizeof(flag);
00094       while((s-=2)>0) {
00095        int tmpint;
00096        tmpint=flag[s][<1]-'1';
00097        if(tmpint<0 || tmpint>j)
00098         raise_error(sprintf(
00099          "AddCmd: error-message %d contains out-of-bounds @WExx-rule.\n",j+1));
00100       }
00101      }
00102      j++;
00103     }
00104     // "Was?|Wie das?" -> ({"Was?","Wie das?"})
00105     // "Was?|Wie das?^|Womit das?|Worauf das?^@WER1 macht was." ->
00106     //  ({"Was?",
00107     //    "Wie das?^Womit das?",
00108     //            "Worauf das?^@WER1 macht was.",1})
00109     flag=sizeof(fail);
00110     if(flag && flag<sizeof(rule))
00111      raise_error(
00112       "AddCmd: number of error-messages does not match number of rules.\n");
00113     flag=fail; // ueberschreiben mit den parsefreundlichen Format
00114   } else if(flag)
00115    raise_error("AddCmd: rules exist but flags are not an error-string.\n");
00116  } // end if(stringp(cmd)) ... kein Regelstring vorhanden
00117 
00118  // kein Kommandoarray gewesen noch erzeugt?
00119  if(!pointerp(cmd))
00120    raise_error("AddCmd: missing string/pointer-parameter for command.\n");
00121 
00122  // Closure aus einem String erzeugen, wenn moeglich und sicher
00123  // (function_exists() filtert unnoetigerweise auch reine "static" funs,
00124  //  die genaue Pruefung ueber functionlist() kostet jedoch zuviel)
00125  if(stringp(func) &&
00126     (!extern_call() || function_exists(func,this_object())) &&
00127     closurep(cl=symbol_function(func,this_object())))
00128   func=cl;
00129 
00130  // jedes einzelne Verb mit seinen Regeln und Funktionen eintragen
00131  i=sizeof(cmd);
00132  if(!added_cmds) added_cmds=m_allocate(i,4);
00133  while(i--) {
00134   string str;
00135   str=cmd[i];
00136   if(!func)
00137    if(extern_call()) func=previous_object();
00138    else func=this_object();
00139   if(!member(added_cmds,str))
00140    added_cmds+=([str:allocate(0);allocate(0);allocate(0);0]);
00141   // existierendes Verb ergaenzen
00142   added_cmds[str,0]+=({func});
00143   added_cmds[str,1]+=({flag});
00144   added_cmds[str,2]+=({rule});
00145   // ggf. id in das ID-Mapping eintragen
00146   if(cmdid) {
00147    mixed *tmp;
00148    j=sizeof((string*)added_cmds[str,0]);
00149    tmp=added_cmds[str,3]||allocate(j);
00150    if(sizeof(tmp)<j) tmp+=allocate(j-sizeof(tmp));
00151    tmp[<1]=cmdid;
00152    added_cmds[str,3]=tmp;
00153   }
00154  }
00155 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

protected void create (  ) 

Definiert in Zeile 47 der Datei commands.c.

00048 {
00049 }

protected void create_super (  ) 

Definiert in Zeile 51 der Datei commands.c.

Benutzt set_next_reset().

00051                               {
00052   set_next_reset(-1);
00053 }     

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

void init (  ) 

Definiert in Zeile 470 der Datei commands.c.

Benutzt init(), ob() und set_light().

00470             {
00471  add_action("_cl","",1);
00472 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

varargs int RemoveCmd ( mixed  cmd,
int  del_norule,
mixed  onlyid 
)

Definiert in Zeile 160 der Datei commands.c.

Benutzt added_cmds, dtime(), flag, i, ids, log_file und m_delete().

Wird benutzt von MakeDrink().

00160                                                                {
00161  int ret;
00162 
00163  // Falls Magier das RemoveCmd falsch nutzen (z.B. analog zu AddCmd)
00164  // wird das Regelsystem verwirrt. Da das del_norule nur int sein darf,
00165  // gibt es hier eine gute Chance den Fehler abwaertskompatibel zu ent-
00166  // decken. Damit Spieler den Fehler nicht mitbekommen, wird hier auf
00167  // ein raise_error verzichtet, und statt dessen in ein Logfile ge-
00168  // schrieben.
00169  if (!intp(del_norule))
00170  {
00171    log_file("REMOVE_CMD",
00172      sprintf("\n-- %s --\nIllegal RemoveCommand() in Object [%O]:\n %O\n",
00173        dtime(time()), this_object(), cmd));
00174    del_norule=0;
00175    onlyid=0;
00176  }
00177  
00178  if(!added_cmds || (!cmd && !del_norule && !onlyid))
00179   added_cmds=(mapping)0; 
00180  else {
00181   int i, j;
00182   mixed *rule, *flag, *fun, *delrule, *ids;
00183 
00184   if(stringp(cmd)) {
00185    // Regeln entdeckt - Zerlegen (wie AddCmd)
00186    if((i=member(cmd,'&'))>0) {
00187     delrule=explode(cmd[(i+1)..],"&");
00188     j=sizeof(delrule);
00189     while(j--)
00190      delrule[j]=explode(delrule[j],"|");
00191     cmd=cmd[0..(i-1)];
00192    }
00193    cmd=explode(cmd,"|");
00194   } else if(del_norule || onlyid) cmd=m_indices(added_cmds);
00195 
00196   if(!pointerp(cmd))
00197    raise_error("RemoveCmd: missing string/pointer-parameter.\n");
00198   i=sizeof(cmd);
00199 
00200   while(i--) {
00201    // keine Regeln da und Regeln loeschen erlaubt: alles loeschen
00202    if(!delrule && !del_norule && !onlyid) efun::m_delete(added_cmds,cmd[i]);
00203    else if(m_contains(&fun, &flag, &rule, &ids, added_cmds, cmd[i])) {
00204     j=sizeof(fun);
00205     while(j--) {
00206      int k;
00207      // DBG(rule[j]);
00208                 // Regeln nicht löschen und Regel?
00209      if(!(del_norule && pointerp(rule[j])) &&
00210         // nur bestimmte ID löschen und ID passt nicht?
00211         !(onlyid && (!pointerp(ids) || sizeof(ids)<=j || ids[j]!=onlyid)) &&
00212         // Löschregel existiert und passt nicht auf Regel?
00213         !(delrule && (k=sizeof(rule[j]))!=sizeof(delrule))) {
00214       // partielles Testen einer Löschregel ...
00215       if(delrule) {
00216        while(k--)
00217         if(!sizeof(rule[j][k]&delrule[k])) break;
00218        if(k>=0) continue;
00219       }
00220       // alles korrekt: Löschen!
00221       // (Arraybereich durch leeres Array loeschen)
00222       flag[j..j]  = allocate(0);
00223       fun[j..j]   = allocate(0);
00224       rule[j..j]  = allocate(0);
00225       if(ids) {
00226        ids[j..j] = allocate(0);
00227        if(!sizeof(ids-allocate(1))) ids=(mixed*)0;
00228       }
00229       ret++;
00230      }
00231     } // end while(j--) {
00232    }
00233    // Funktions/Regelliste update oder ggf. Kommando voellig loeschen
00234    if(sizeof(rule)) {
00235     added_cmds[cmd[i],0]=fun;
00236     added_cmds[cmd[i],1]=flag;
00237     added_cmds[cmd[i],2]=rule;
00238     added_cmds[cmd[i],3]=ids;
00239    } else efun::m_delete(added_cmds,cmd[i]);
00240   }
00241   if(!sizeof(added_cmds)) added_cmds=(mapping)0;
00242  }
00243  return ret;
00244 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:


Variablen-Dokumentation

private nosave mapping added_cmds

Definiert in Zeile 45 der Datei commands.c.

Wird benutzt von _check_copy_commands(), _cl(), _set_commands(), AddCmd() und RemoveCmd().

Erzeugt am Thu Jun 3 14:43:04 2010 für MorgenGrauen Mudlib von  doxygen 1.6.3