00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00029 #include <string.h>
00030 #include "global.h"
00031 #include "define.h"
00032 #include "object.h"
00033 #include "dialog.h"
00034
00039 void free_dialog_information(object *op) {
00040 struct_dialog_message *current, *next;
00041 struct_dialog_reply *currep, *nextrep;
00042
00043 if (!QUERY_FLAG(op, FLAG_DIALOG_PARSED))
00044 return;
00045
00046 CLEAR_FLAG(op, FLAG_DIALOG_PARSED);
00047 if (!op->dialog_information)
00048 return;
00049
00050 current = op->dialog_information->all_messages;
00051 while (current) {
00052 next = current->next;
00053 free(current->match);
00054 free(current->message);
00055 currep = current->replies;
00056 while (currep) {
00057 nextrep = currep->next;
00058 free(currep->reply);
00059 free(currep->message);
00060 currep = nextrep;
00061 }
00062 free(current);
00063 current = next;
00064 }
00065
00066 currep = op->dialog_information->all_replies;
00067 while (currep) {
00068 nextrep = currep->next;
00069 free(currep->reply);
00070 free(currep->message);
00071 free(currep);
00072 currep = nextrep;
00073 }
00074
00075 free(op->dialog_information);
00076 op->dialog_information = NULL;
00077 }
00078
00086 static int matches(const char *exp, const char *text) {
00087 char *pipe, *save, *msg;
00088 int match = 0;
00089
00090 if (exp[0] == '*')
00091 return 1;
00092
00093 msg = strdup(exp);
00094
00095 pipe = strtok_r(msg, "|", &save);
00096 while (pipe) {
00097 if (re_cmp(text, pipe)) {
00098 match = 1;
00099 break;
00100 }
00101 pipe = strtok_r(NULL, "|", &save);
00102 }
00103
00104 free(msg);
00105 return match;
00106 }
00107
00114 static void parse_dialog_information(object *op) {
00115 struct_dialog_message *message = NULL, *last = NULL;
00116 struct_dialog_reply *reply = NULL;
00117 char *current, *save, *msg, *cp;
00118 int len;
00119
00120 char *tmp = NULL;
00121 size_t tmplen = 0;
00122
00123 if (QUERY_FLAG(op, FLAG_DIALOG_PARSED))
00124 return;
00125 SET_FLAG(op, FLAG_DIALOG_PARSED);
00126
00127 op->dialog_information = (struct_dialog_information *)calloc(1, sizeof(struct_dialog_information));
00128
00129 if (!op->msg)
00130 return;
00131
00132 msg = strdup(op->msg);
00133 current = strtok_r(msg, "\n", &save);
00134
00135 while (current) {
00136 if (strncmp(current, "@match ", 7) == 0) {
00137 if (message) {
00138 message->message = tmp;
00139 tmp = NULL;
00140 tmplen = 0;
00141 }
00142
00143 message = (struct_dialog_message *)calloc(1, sizeof(struct_dialog_message));
00144 if (last)
00145 last->next = message;
00146 else
00147 op->dialog_information->all_messages = message;
00148 last = message;
00149
00150 message->match = strdup(current+7);
00151 } else if ((strncmp(current, "@reply ", 7) == 0 && (len = 7)) || (strncmp(current, "@question ", 10) == 0 && (len = 10))) {
00152 if (message) {
00153 reply = (struct_dialog_reply *)calloc(1, sizeof(struct_dialog_reply));
00154 reply->type = (len == 7 ? rt_reply : rt_question);
00155 cp = strchr(current+len, ' ');
00156 if (cp) {
00157 *cp = '\0';
00158 reply->reply = strdup(current+len);
00159 reply->message = strdup(cp+1);
00160 } else {
00161 reply->reply = strdup(current+len);
00162 reply->message = strdup(reply->reply);
00163 LOG(llevDebug, "Warning: @reply/@question without message for %s!\n", op->name);
00164 }
00165 reply->next = message->replies;
00166 message->replies = reply;
00167
00168 reply = (struct_dialog_reply *)calloc(1, sizeof(struct_dialog_reply));
00169 reply->reply = strdup(message->replies->reply);
00170 reply->message = strdup(message->replies->message);
00171 reply->type = message->replies->type;
00172 reply->next = op->dialog_information->all_replies;
00173 op->dialog_information->all_replies = reply;
00174 } else
00175 LOG(llevDebug, "Warning: @reply not in @match block for %s!\n", op->name);
00176 } else if (message) {
00177
00178 int wasnull = FALSE;
00179 tmplen += strlen(current)+2;
00180 if (!tmp)
00181 wasnull = TRUE;
00182 tmp = realloc(tmp, tmplen*sizeof(char));
00183 if (!tmp)
00184 fatal(OUT_OF_MEMORY);
00185 if (wasnull)
00186 tmp[0] = 0;
00187 strncat(tmp, current, tmplen-strlen(tmp)-1);
00188 strncat(tmp, "\n", tmplen-strlen(tmp)-1);
00189 }
00190 current = strtok_r(NULL, "\n", &save);
00191 }
00192
00193 if (message) {
00194 if (!tmp)
00195 message->message = strdup("");
00196 else
00197 message->message = tmp;
00198 tmp = NULL;
00199 tmplen = 0;
00200 }
00201
00202 free(msg);
00203 }
00204
00214 int get_dialog_message(object *op, const char *text, struct_dialog_message **message, struct_dialog_reply **reply) {
00215 if (!QUERY_FLAG(op, FLAG_DIALOG_PARSED))
00216 parse_dialog_information(op);
00217
00218 for (*message = op->dialog_information->all_messages; *message; *message = (*message)->next) {
00219 if (matches((*message)->match, text)) {
00220 break;
00221 }
00222 }
00223 if (!*message)
00224 return 0;
00225
00226 for (*reply = op->dialog_information->all_replies; *reply; *reply = (*reply)->next) {
00227 if (strcmp((*reply)->reply, text) == 0)
00228 break;
00229 }
00230
00231 return 1;
00232 }