/* Performs DELETE VARIABLES command. */ int cmd_delete_variables (struct lexer *lexer, struct dataset *ds) { struct variable **vars; size_t var_cnt; bool ok; if (proc_make_temporary_transformations_permanent (ds)) msg (SE, _("DELETE VARIABLES may not be used after TEMPORARY. " "Temporary transformations will be made permanent.")); if (!parse_variables (lexer, dataset_dict (ds), &vars, &var_cnt, PV_NONE)) goto error; if (var_cnt == dict_get_var_cnt (dataset_dict (ds))) { msg (SE, _("DELETE VARIABLES may not be used to delete all variables " "from the active dataset dictionary. " "Use NEW FILE instead.")); goto error; } ok = casereader_destroy (proc_open (ds)); ok = proc_commit (ds) && ok; if (!ok) goto error; dict_delete_vars (dataset_dict (ds), vars, var_cnt); free (vars); return CMD_SUCCESS; error: free (vars); return CMD_CASCADING_FAILURE; }
int cmd_variable_labels (struct lexer *lexer, struct dataset *ds) { struct dictionary *dict = dataset_dict (ds); do { struct variable **v; size_t nv; size_t i; if (!parse_variables (lexer, dict, &v, &nv, PV_NONE)) return CMD_FAILURE; if (!lex_force_string (lexer)) { free (v); return CMD_FAILURE; } for (i = 0; i < nv; i++) var_set_label (v[i], lex_tokcstr (lexer)); lex_get (lexer); while (lex_token (lexer) == T_SLASH) lex_get (lexer); free (v); } while (lex_token (lexer) != T_ENDCMD); return CMD_SUCCESS; }
/* Parses the LEAVE command. */ int cmd_leave (struct lexer *lexer, struct dataset *ds) { struct variable **v; size_t nv; size_t i; if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE)) return CMD_CASCADING_FAILURE; for (i = 0; i < nv; i++) var_set_leave (v[i], true); free (v); return CMD_SUCCESS; }
static int do_value_labels (struct lexer *lexer, const struct dictionary *dict, bool erase) { struct variable **vars; /* Variable list. */ size_t var_cnt; /* Number of variables. */ int parse_err=0; /* true if error parsing variables */ lex_match (lexer, T_SLASH); while (lex_token (lexer) != T_ENDCMD) { parse_err = !parse_variables (lexer, dict, &vars, &var_cnt, PV_SAME_WIDTH); if (var_cnt < 1) { free(vars); return CMD_FAILURE; } if (erase) erase_labels (vars, var_cnt); while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD) if (!get_label (lexer, vars, var_cnt, dict_get_encoding (dict))) goto lossage; if (lex_token (lexer) != T_SLASH) { free (vars); break; } lex_get (lexer); free (vars); } return parse_err ? CMD_FAILURE : CMD_SUCCESS; lossage: free (vars); return CMD_FAILURE; }
int cmd_split_file (struct lexer *lexer, struct dataset *ds) { if (lex_match_id (lexer, "OFF")) dict_set_split_vars (dataset_dict (ds), NULL, 0); else { struct variable **v; size_t n; /* For now, ignore SEPARATE and LAYERED. */ (void) ( lex_match_id (lexer, "SEPARATE") || lex_match_id (lexer, "LAYERED") ); lex_match (lexer, T_BY); if (!parse_variables (lexer, dataset_dict (ds), &v, &n, PV_NO_DUPLICATE)) return CMD_CASCADING_FAILURE; dict_set_split_vars (dataset_dict (ds), v, n); free (v); } return CMD_SUCCESS; }
int cmd_missing_values (struct lexer *lexer, struct dataset *ds) { struct dictionary *dict = dataset_dict (ds); struct variable **v = NULL; size_t nv; bool ok = true; while (lex_token (lexer) != T_ENDCMD) { size_t i; if (!parse_variables (lexer, dict, &v, &nv, PV_NONE)) goto error; if (!lex_force_match (lexer, T_LPAREN)) goto error; for (i = 0; i < nv; i++) var_clear_missing_values (v[i]); if (!lex_match (lexer, T_RPAREN)) { struct missing_values mv; for (i = 0; i < nv; i++) if (var_get_type (v[i]) != var_get_type (v[0])) { const struct variable *n = var_is_numeric (v[0]) ? v[0] : v[i]; const struct variable *s = var_is_numeric (v[0]) ? v[i] : v[0]; msg (SE, _("Cannot mix numeric variables (e.g. %s) and " "string variables (e.g. %s) within a single list."), var_get_name (n), var_get_name (s)); goto error; } if (var_is_numeric (v[0])) { mv_init (&mv, 0); while (!lex_match (lexer, T_RPAREN)) { enum fmt_type type = var_get_print_format (v[0])->type; double x, y; bool ok; if (!parse_num_range (lexer, &x, &y, &type)) goto error; ok = (x == y ? mv_add_num (&mv, x) : mv_add_range (&mv, x, y)); if (!ok) ok = false; lex_match (lexer, T_COMMA); } } else { mv_init (&mv, MV_MAX_STRING); while (!lex_match (lexer, T_RPAREN)) { uint8_t value[MV_MAX_STRING]; char *dict_mv; size_t length; if (!lex_force_string (lexer)) { ok = false; break; } dict_mv = recode_string (dict_get_encoding (dict), "UTF-8", lex_tokcstr (lexer), ss_length (lex_tokss (lexer))); length = strlen (dict_mv); if (length > MV_MAX_STRING) { /* XXX truncate graphemes not bytes */ msg (SE, _("Truncating missing value to maximum " "acceptable length (%d bytes)."), MV_MAX_STRING); length = MV_MAX_STRING; } memset (value, ' ', MV_MAX_STRING); memcpy (value, dict_mv, length); free (dict_mv); if (!mv_add_str (&mv, value)) ok = false; lex_get (lexer); lex_match (lexer, T_COMMA); } } for (i = 0; i < nv; i++) { if (mv_is_resizable (&mv, var_get_width (v[i]))) var_set_missing_values (v[i], &mv); else { msg (SE, _("Missing values provided are too long to assign " "to variable of width %d."), var_get_width (v[i])); ok = false; } } mv_destroy (&mv); } lex_match (lexer, T_SLASH); free (v); v = NULL; } free (v); return ok ? CMD_SUCCESS : CMD_FAILURE; error: free (v); return CMD_FAILURE; }
/* FOR stuff */ void cmd_for(char *args) { char loopname[SMABUF]; /* Loop name - string form */ char holdbuf[NORMSIZ]; /* Command section of the for */ char val[MAXSIZ]; /* Buffer to build up things for add_queue */ int firstval = 0; /* Low val */ int lastval = -1; /* High val */ int crement; /* Decrement or increment */ int nooutput = false; /* Show or not on msg stuff */ int i; /* Counter */ char *p; char *q; char *r; p = first(args); r = args; /* Keep this, splitting string here */ if (!*p) { msg("-- Usage: for loopname min,max command"); msg(" for loopname (n1,n2,n3,...,nn) command"); return; } else { if (!strcmp(p, "-nooutput")) { nooutput = true; q = rest(r); r = q; /* For down below when we get rest */ p = first(q); debug(4, "for: nooutput is true, first is %s, rest is %s", p, r); if (!*p) { msg("-- Usage: for loopname min,max command"); msg(" for loopname (n1,n2,n3,...,nn) command"); return; } } strcpy(loopname, p); if (test_assign(loopname)) { msg("-- for: Requires an undefined loopname. Try a new name."); return; } if (!valid_assign_name(loopname)) { msg("-- for: Invalid loopname(%s). Must be char, num or _ only", loopname); return; } q = rest(r); if (!q) { *args = '\0'; } else { strcpy(args, q); } } parse_variables(args); /* foreach() stuff */ if (*args == '(') { p = strchr(args, ')'); /* Get end loop */ if (!p) { msg("-- Usage: forloopname (n1,n2,n3,...,nn) command"); return; } *p++ = '\0'; strcpy(holdbuf, p); q = args + 1; p = strchr(q, ','); while (p) { *p = '\0'; sprintf(val, "assign ^%s %s", loopname, q); add_queue(val, 1); sprintf(val, "msg \'%s\'", holdbuf); add_queue(val, 0); add_queue(holdbuf, 0); q = p + 1; p = strchr(q, ','); } sprintf(val, "assign ^%s %s", loopname, q); add_queue(val, 1); sprintf(val, "msg \'%s\'", holdbuf); add_queue(val, 0); add_queue(holdbuf, 0); sprintf(val, "assign -^%s", loopname); add_queue(val, 0); if (!nooutput) { add_queue("echo -- for done.", 0); } return; } /* Old for loop stuff below */ p = first(args); if (!p || !*p) { msg("-- Usage: for loopname min,max command"); msg(" for loopname (n1,n2,n3,...,nn) command"); return; } q = strchr(p, ','); if (!q || (!isdigit(*(q + 1)) && *(q + 1) != '-') || (*(q + 1) == '-' && !isdigit(*(q + 2)))) { msg("-- Usage: for loopname min,max command"); return; } *q = '\0'; q++; firstval = atoi(p); lastval = atoi(q); if (lastval < firstval) { crement = -1; } else { crement = 1; } q = rest(args); if (!q) { msg("-- Usage: for loopname min,max command"); return; } else { strcpy(holdbuf, q); } i = firstval; lastval += crement; while (i != lastval) { /* By pass the msg system with the ^ */ sprintf(val, "assign ^%s %d", loopname, i); add_queue(val, 1); sprintf(val, "msg \'%s\'", holdbuf); add_queue(val, 0); add_queue(holdbuf, 0); i += crement; } sprintf(val, "assign -^%s", loopname); add_queue(val, 0); if (!nooutput) { add_queue("echo -- for done.", 0); } }