/* * if.c: handles the IF command for IRCII * * Written By Michael Sandrof * * Copyright(c) 1990, 1991 * * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #include "irc.h" static char cvsrevision[] = "$Id$"; CVS_REVISION(if_c) #include "struct.h" #include "alias.h" #include "ircaux.h" #include "window.h" #include "vars.h" #include "output.h" #include "if.h" #include "commands.h" #include "misc.h" #define MAIN_SOURCE #include "modval.h" /* * next_expr finds the next expression delimited by brackets. The type * of bracket expected is passed as a parameter. Returns NULL on error. */ char *my_next_expr(char **args, char type, int whine) { char *ptr, *ptr2, *ptr3; if (!*args) return NULL; ptr2 = *args; if (!*ptr2) return 0; if (*ptr2 != type) { if (whine) say("Expression syntax"); return 0; } /* { */ ptr = MatchingBracket(ptr2 + 1, type, (type == '(') ? ')' : '}'); if (!ptr) { say("Unmatched '%c'", type); return 0; } *ptr = '\0'; do ptr2++; while (my_isspace(*ptr2)); ptr3 = ptr+1; while (my_isspace(*ptr3)) ptr3++; *args = ptr3; if (*ptr2) { ptr--; while (my_isspace(*ptr)) *ptr-- = '\0'; } return ptr2; } extern char *next_expr_failok (char **args, char type) { return my_next_expr (args, type, 0); } extern char *next_expr (char **args, char type) { return my_next_expr (args, type, 1); } /* * All new /if command -- (jfn, 1997) * * Here's the plan: * * if (expr) ...... * if (expr) {......} * if (expr) {......} {......} * if (expr) {......} else {......} * if (expr) {......} elsif (expr2) {......} * etc. */ BUILT_IN_COMMAND(ifcmd) { int unless_cmd; char *current_expr; char *current_expr_val; int result; char *current_line = NULL; int flag = 0; unless_cmd = (*command == 'U'); if (!subargs) subargs = empty_string; while (args && *args) { while (my_isspace(*args)) args++; current_expr = next_expr(&args, '('); if (!current_expr) { error("IF: Missing expression"); return; } current_expr_val = parse_inline(current_expr, subargs, &flag); if (internal_debug & DEBUG_EXPANSIONS && !in_debug_yell) debugyell("%s expression expands to: (%s)", command, current_expr_val); result = check_val(current_expr_val); new_free(¤t_expr_val); if (*args == '{') { current_line = next_expr(&args, '{'); } else current_line = args, args = NULL; /* If the expression was FALSE for IF, and TRUE for UNLESS */ if (unless_cmd == result) { if (args) { if (!my_strnicmp(args, "elsif ", 6)) { args += 6; continue; } else if (!my_strnicmp(args, "else ", 5)) args += 5; while (my_isspace(*args)) args++; if (*args == '{') current_line = next_expr(&args, '{'); else current_line = args, args = NULL; } else current_line = NULL; } if (current_line && *current_line) parse_line(NULL, current_line, subargs, 0, 0, 1); break; } } BUILT_IN_COMMAND(docmd) { char *body, *expr, *cmd, *ptr; char *newexp = NULL; int args_used = 0; int result; if (*args == '{') { if (!(body = next_expr(&args, '{'))) { error("DO: unbalanced {"); return; } if (args && *args && (cmd = next_arg(args, &args)) && !my_stricmp (cmd, "while")) { if (!(expr = next_expr(&args, '('))) { error("DO: unbalanced ("); return; } will_catch_break_exceptions++; will_catch_return_exceptions++; while (1) { parse_line (NULL, body, subargs ? subargs : empty_string, 0, 0, 1); if (break_exception) { break_exception = 0; break; } if (continue_exception) { continue_exception = 0; continue; } if (return_exception) break; malloc_strcpy(&newexp, expr); ptr = parse_inline(newexp, subargs ? subargs : empty_string, &args_used); result = check_val(ptr); new_free(&ptr); if (!result) break; } new_free(&newexp); will_catch_break_exceptions--; will_catch_continue_exceptions--; return; } /* falls through to here if its /do {...} */ parse_line (NULL, body, subargs ? subargs : empty_string, 0, 0, 1); } /* falls through to here if it its /do ... */ parse_line (NULL, args, subargs ? subargs : empty_string, 0, 0, 1); } /*ARGSUSED*/ BUILT_IN_COMMAND(whilecmd) { char *exp = NULL, *ptr = NULL, *body = NULL, *newexp = NULL; int args_used; /* this isn't used here, but is passed * to expand_alias() */ int whileval = !strcmp(command, "WHILE"); if (!(ptr = next_expr(&args, '('))) { error("WHILE: missing boolean expression"); return; } exp = LOCAL_COPY(ptr); if ((ptr = next_expr_failok(&args, '{')) == (char *) 0) ptr = args; body = LOCAL_COPY(ptr); will_catch_break_exceptions++; will_catch_continue_exceptions++; make_local_stack(NULL); while (1) { newexp = LOCAL_COPY(exp); ptr = parse_inline(newexp, subargs ? subargs : empty_string, &args_used); if (check_val(ptr) != whileval) break; new_free(&ptr); parse_line(NULL, body, subargs ? subargs : empty_string, 0, 0, 0); if (continue_exception) { continue_exception = 0; continue; } if (break_exception) { break_exception = 0; break; } if (return_exception) break; } will_catch_break_exceptions--; will_catch_continue_exceptions--; destroy_local_stack(); new_free(&ptr); } BUILT_IN_COMMAND(foreach) { char *struc = NULL, *ptr, *body = NULL, *var = NULL; char **sublist; int total; int i; int slen; int old_display; int list = VAR_ALIAS; int af; while (args && my_isspace(*args)) args++; if (*args == '-') args++, list = COMMAND_ALIAS; if ((ptr = new_next_arg(args, &args)) == NULL) { error("FOREACH: missing structure expression"); return; } struc = upper(remove_brackets(ptr, subargs, &af)); if ((var = next_arg(args, &args)) == NULL) { new_free(&struc); error("FOREACH: missing variable"); return; } while (my_isspace(*args)) args++; if ((body = next_expr(&args, '{')) == NULL) /* } */ { new_free(&struc); error("FOREACH: missing statement"); return; } if ((sublist = get_subarray_elements(struc, &total, list)) == NULL) { new_free(&struc); return; /* Nothing there. */ } slen=strlen(struc); old_display=window_display; make_local_stack(NULL); for (i=0;i