/* Closes a CSV file after we're done with it. Returns true if successful, false if an I/O error occurred. */ bool close_writer (struct csv_writer *w) { size_t i; bool ok; if (w == NULL) return true; ok = true; if (w->file != NULL) { if (write_error (w)) ok = false; if (fclose (w->file) == EOF) ok = false; if (!ok) msg (ME, _("An I/O error occurred writing CSV file `%s'."), fh_get_file_name (w->fh)); if (ok ? !replace_file_commit (w->rf) : !replace_file_abort (w->rf)) ok = false; } fh_unlock (w->lock); fh_unref (w->fh); free (w->encoding); for (i = 0; i < w->n_csv_vars; i++) { struct csv_var *cv = &w->csv_vars[i]; mv_destroy (&cv->missing); val_labs_destroy (cv->val_labs); } free (w->csv_vars); free (w); return ok; }
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; }
/****************************************************************************** * MAIN function ******************************************************************************/ int main ( int argc, char **argv ) { trace_main = TRACE_MAIN; XtAppContext app; signal(SIGPIPE, SIG_IGN); /* ignore broken pipe on write */ m_init(); mv_init(); XtSetLanguageProc (NULL, NULL, NULL); XawInitializeWidgetSet(); /* -- Intialize Toolkit creating the application shell */ Widget appShell = XtOpenApplication (&app, APP_NAME, options, XtNumber(options), /* resources: can be set from argv */ &argc, argv, fallback_resources, sessionShellWidgetClass, NULL, 0 ); /* enable Editres support */ XtAddEventHandler(appShell, (EventMask) 0, True, _XEditResCheckMessages, NULL); XtAddCallback( appShell, XtNdieCallback, quit_gui, NULL ); /* not parsed options are removed by XtOpenApplication the only entry left should be the program name */ if (argc != 1) { m_destruct(); syntax(); exit(1); } TopLevel = appShell; /* -- Register all application specific callbacks and widget classes */ RegisterApplication ( appShell ); /* -- Register all Athena and Public widget classes, CBs, ACTs */ XpRegisterAll ( app ); /* -- Create widget tree below toplevel shell using Xrm database */ WcWidgetCreation ( appShell ); /* get application resources and widget ptr */ XtGetApplicationResources( appShell, (XtPointer)&SETTINGS, basicSettingRes, XtNumber(basicSettingRes), (ArgList)0, 0 ); InitializeApplication(appShell); /* -- Realize the widget tree and enter the main application loop */ XtRealizeWidget ( appShell ); grab_window_quit( appShell ); // pin_start_test(); XtAppMainLoop ( app ); /* use XtAppSetExitFlag */ XtDestroyWidget(appShell); v_free( SETTINGS.vset ); mv_destroy(); m_destruct(); return EXIT_SUCCESS; }