Separate settings and the SET command, for modularity.
[pspp-builds.git] / src / settings.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #include <config.h>
21 #include "settings.h"
22 #include <assert.h>
23 #include <time.h>
24 #include "format.h"
25 #include "val.h"
26 #include "xalloc.h"
27
28 static int viewlength = 24;
29 static int viewwidth = 79;
30 static bool long_view = false;
31
32 static bool safer_mode = false;
33
34 static char decimal = '.';
35 static char grouping = ',';
36
37 static char *prompt = NULL;
38 static char *cprompt = NULL;
39 static char *dprompt = NULL;
40
41 static bool echo = false;
42 static bool include = true;
43
44 static int epoch = -1;
45
46 static bool errorbreak = false;
47
48 static bool scompress = false;
49
50 static bool undefined = true;
51 static double blanks = SYSMIS;
52
53 static int mxwarns = 100;
54 static int mxerrs = 100;
55
56 static bool printback = true;
57 static bool mprint = true;
58
59 static int mxloops = 1;
60
61 static bool nulline = true;
62
63 static char endcmd = '.';
64
65 static size_t workspace = 4L * 1024 * 1024;
66
67 static struct fmt_spec default_format = {FMT_F, 8, 2};
68
69 #define CC_CNT 5
70 #define CC_INITIALIZER {"-", "", "", "", '.', ','}
71 static struct custom_currency cc[CC_CNT] = 
72   {
73     CC_INITIALIZER,
74     CC_INITIALIZER,
75     CC_INITIALIZER,
76     CC_INITIALIZER,
77     CC_INITIALIZER,
78   };
79
80 static gsl_rng *rng;
81
82 static bool testing_mode = false;
83
84 static int global_algorithm = ENHANCED;
85 static int cmd_algorithm = ENHANCED;
86 static int *algorithm = &global_algorithm;
87
88 static int syntax = ENHANCED;
89
90 static void init_viewport (void);
91
92 void
93 done_settings (void)
94 {
95   if (rng != NULL) 
96     gsl_rng_free (rng);
97
98   free (prompt);
99   free (cprompt);
100   free (dprompt);
101 }
102
103 void
104 init_settings (void)
105 {
106   init_viewport ();
107 }
108
109 /* Screen length in lines. */
110 int
111 get_viewlength (void)
112 {
113   return viewlength;
114 }
115
116 /* Sets the view length. */
117 void
118 set_viewlength (int viewlength_) 
119 {
120   viewlength = viewlength_;
121 }
122
123 /* Set view width to a very long value, and prevent it from ever
124    changing. */
125 void
126 force_long_view (void)
127 {
128   long_view = true;
129   viewwidth = 9999;
130 }
131
132 /* Screen width. */
133 int
134 get_viewwidth(void)
135 {
136   return viewwidth;
137 }
138
139 /* Sets the screen width. */
140 void
141 set_viewwidth (int viewwidth_) 
142 {
143   viewwidth = viewwidth_;
144 }
145
146 #if HAVE_LIBTERMCAP
147 static void
148 get_termcap_viewport (void)
149 {
150   char term_buffer[16384];
151   if (getenv ("TERM") == NULL)
152     return;
153   else if (tgetent (term_buffer, getenv ("TERM")) <= 0)
154     {
155       msg (IE, _("Could not access definition for terminal `%s'."), termtype);
156       return;
157     }
158
159   if (tgetnum ("li") > 0)
160     viewlength = tgetnum ("li");
161
162   if (tgetnum ("co") > 1)
163     viewwidth = tgetnum ("co") - 1;
164 }
165 #endif /* HAVE_LIBTERMCAP */
166
167 static void 
168 init_viewport (void)
169 {
170   if (long_view)
171     return;
172   
173   viewwidth = viewlength = -1;
174
175 #if HAVE_LIBTERMCAP
176   get_termcap_viewport ();
177 #endif /* HAVE_LIBTERMCAP */
178
179   if (viewwidth < 0 && getenv ("COLUMNS") != NULL)
180     viewwidth = atoi (getenv ("COLUMNS"));
181   if (viewlength < 0 && getenv ("LINES") != NULL)
182     viewlength = atoi (getenv ("LINES"));
183
184   if (viewwidth < 0)
185     viewwidth = 79;
186   if (viewlength < 0)
187     viewlength = 24;
188 }
189
190 /* Whether PSPP can erase and overwrite files. */
191 bool
192 get_safer_mode (void)
193 {
194   return safer_mode;
195 }
196
197 /* Set safer mode. */
198 void
199 set_safer_mode (void)
200 {
201   safer_mode = true;
202 }
203
204 /* The character used for a decimal point: ',' or '.'.  Only
205    respected for data input and output. */
206 char 
207 get_decimal (void)
208 {
209   return decimal;
210 }
211
212 /* Sets the character used for a decimal point, which must be
213    either ',' or '.'. */
214 void
215 set_decimal (char decimal_) 
216 {
217   assert (decimal_ == '.' || decimal_ == ',');
218   decimal = decimal_;
219 }
220
221 /* The character used for grouping in numbers: '.' or ','; the
222    opposite of set_decimal.  Only used in COMMA data input and
223    output. */
224 char
225 get_grouping (void)
226 {
227   return grouping;
228 }
229
230 /* Sets the character used for grouping, which must be either ','
231    or '.'. */
232 void
233 set_grouping (char grouping_) 
234 {
235   assert (grouping_ == '.' || grouping_ == ',');
236   grouping = grouping_;
237 }
238  
239 /* Gets the normal command prompt. */
240 const char * 
241 get_prompt (void)
242 {
243   return prompt != NULL ? prompt : "PSPP> ";
244 }
245
246 /* Sets the normal command prompt. */
247 void
248 set_prompt (const char *prompt_)
249 {
250   free (prompt);
251   prompt = xstrdup (prompt_);
252 }
253
254 /* Gets the prompt used for data (after BEGIN DATA and before END
255    DATA). */
256 const char * 
257 get_dprompt (void)
258 {
259   return dprompt != NULL ? dprompt : "data> ";
260 }
261
262 /* Sets the prompt used for data (after BEGIN DATA and before END
263    DATA). */
264 void
265 set_dprompt (const char *dprompt_)
266 {
267   free (dprompt);
268   dprompt = xstrdup (dprompt_);
269 }
270
271 /* Gets the continuation prompt used for second and subsequent
272    lines of commands. */
273 const char * 
274 get_cprompt (void)
275 {
276   return cprompt != NULL ? cprompt : "    > ";
277 }
278
279 /* Sets the continuation prompt used for second and subsequent
280    lines of commands. */
281 void
282 set_cprompt (const char *cprompt_)
283 {
284   free (cprompt);
285   cprompt = xstrdup (cprompt_);
286 }
287
288 /* Echo commands to the listing file/printer? */
289 bool
290 get_echo (void)
291 {
292   return echo;
293 }
294
295 /* Set echo. */
296 void
297 set_echo (bool echo_) 
298 {
299   echo = echo_;
300 }
301
302 /* If echo is on, whether commands from include files are echoed. */
303 bool
304 get_include (void)
305 {
306   return include;
307 }
308
309 /* Set include file echo. */
310 void
311 set_include (bool include_) 
312 {
313   include = include_;
314 }
315
316 /* What year to use as the start of the epoch. */
317 int
318 get_epoch (void) 
319 {
320   if (epoch < 0) 
321     {
322       time_t t = time (0);
323       struct tm *tm = localtime (&t);
324       epoch = (tm != NULL ? tm->tm_year + 1900 : 2000) - 69;
325     }
326
327   return epoch;
328 }
329
330 /* Sets the year that starts the epoch. */
331 void
332 set_epoch (int epoch_) 
333 {
334   epoch = epoch_;
335 }
336
337 /* Does an error stop execution? */
338 bool
339 get_errorbreak (void)
340 {
341   return errorbreak;
342 }
343
344 /* Sets whether an error stops execution. */
345 void
346 set_errorbreak (bool errorbreak_) 
347 {
348   errorbreak = errorbreak_;
349 }
350
351 /* Compress system files by default? */
352 bool 
353 get_scompression (void)
354 {
355   return scompress;
356 }
357
358 /* Set system file default compression. */
359 void
360 set_scompression (bool scompress_) 
361 {
362   scompress = scompress_;
363 }
364
365 /* Whether to warn on undefined values in numeric data. */
366 bool
367 get_undefined (void)
368 {
369   return undefined;
370 }
371
372 /* Set whether to warn on undefined values. */
373 void
374 set_undefined (bool undefined_) 
375 {
376   undefined = undefined_;
377 }
378
379 /* The value that blank numeric fields are set to when read in. */
380 double
381 get_blanks (void)
382 {
383   return blanks;
384 }
385
386 /* Set the value that blank numeric fields are set to when read
387    in. */
388 void
389 set_blanks (double blanks_) 
390 {
391   blanks = blanks_;
392 }
393
394 /* Maximum number of warnings + errors. */
395 int
396 get_mxwarns (void)
397 {  
398   return mxwarns;
399 }
400
401 /* Sets maximum number of warnings + errors. */
402 void
403 set_mxwarns (int mxwarns_) 
404 {
405   mxwarns = mxwarns_;
406 }
407
408 /* Maximum number of errors. */
409 int
410 get_mxerrs (void)
411 {
412   return mxerrs;
413 }
414
415 /* Sets maximum number of errors. */
416 void
417 set_mxerrs (int mxerrs_) 
418 {
419   mxerrs = mxerrs_;
420 }
421
422 /* Whether commands are written to the display. */
423 bool
424 get_printback (void)
425 {
426   return printback;
427 }
428
429 /* Sets whether commands are written to the display. */
430 void
431 set_printback (bool printback_) 
432 {
433   printback = printback_;
434 }
435
436 /* Independent of get_printback, controls whether the commands
437    generated by macro invocations are displayed. */
438 bool
439 get_mprint (void)
440 {
441   return mprint;
442 }
443
444 /* Sets whether the commands generated by macro invocations are
445    displayed. */
446 void
447 set_mprint (bool mprint_) 
448 {
449   mprint = mprint_;
450 }
451
452 /* Implied limit of unbounded loop. */
453 int
454 get_mxloops (void)
455 {
456   return mxloops;
457 }
458
459 /* Set implied limit of unbounded loop. */
460 void
461 set_mxloops (int mxloops_) 
462 {
463   mxloops = mxloops_;
464 }
465
466 /* Whether a blank line is a command terminator. */
467 bool
468 get_nulline (void)
469 {
470   return nulline;
471 }
472
473 /* Set whether a blank line is a command terminator. */
474 void
475 set_nulline (bool nulline_)
476 {
477   nulline = nulline_;
478 }
479
480 /* The character used to terminate commands. */
481 char
482 get_endcmd (void)
483 {
484   return endcmd;
485 }
486
487 /* Set the character used to terminate commands. */
488 void
489 set_endcmd (char endcmd_) 
490 {
491   endcmd = endcmd_;
492 }
493
494 /* Approximate maximum amount of memory to use for cases, in
495    bytes. */
496 size_t
497 get_workspace(void)
498 {
499   return workspace;
500 }
501
502 /* Set approximate maximum amount of memory to use for cases, in
503    bytes. */
504
505 void
506 set_workspace (size_t workspace_) 
507 {
508   workspace = workspace_;
509 }
510
511 /* Default format for variables created by transformations and by
512    DATA LIST {FREE,LIST}. */
513 const struct fmt_spec *
514 get_format (void)
515
516   return &default_format;
517 }
518
519 /* Set default format for variables created by transformations
520    and by DATA LIST {FREE,LIST}. */
521 void
522 set_format (const struct fmt_spec *default_format_) 
523 {
524   default_format = *default_format_;
525 }
526
527 /* Gets the custom currency specification with the given IDX. */
528 const struct custom_currency *
529 get_cc (int idx)
530 {
531   assert (idx >= 0 && idx < CC_CNT);
532   return &cc[idx];
533 }
534
535 /* Gets custom currency specification IDX to CC. */
536 void
537 set_cc (int idx, const struct custom_currency *cc_) 
538 {
539   assert (idx >= 0 && idx < CC_CNT);
540   cc[idx] = *cc_;
541 }
542
543 /* Returns the current random number generator. */
544 gsl_rng *
545 get_rng (void)
546 {
547   if (rng == NULL)
548     set_rng (time (0));
549   return rng;
550 }
551
552 /* Initializes or reinitializes the random number generator with
553    the given SEED. */
554 void
555 set_rng (unsigned long seed) 
556 {
557   rng = gsl_rng_alloc (gsl_rng_mt19937);
558   if (rng == NULL)
559     xalloc_die ();
560   gsl_rng_set (rng, seed);
561 }
562
563 /* Are we in testing mode?  (e.g. --testing-mode command line
564    option) */
565 bool
566 get_testing_mode (void) 
567 {
568   return testing_mode;
569 }
570
571 /* Set testing mode. */
572 void
573 set_testing_mode (bool testing_mode_) 
574 {
575   testing_mode = testing_mode_;
576 }
577
578 /* Return the current algorithm setting */
579 enum behavior_mode
580 get_algorithm (void)
581 {
582   return *algorithm;
583 }
584
585 /* Set the algorithm option globally. */
586 void 
587 set_algorithm (enum behavior_mode mode)
588 {
589   global_algorithm = mode;
590 }
591
592 /* Set the algorithm option for this command only */
593 void 
594 set_cmd_algorithm (enum behavior_mode mode)
595 {
596   cmd_algorithm = mode; 
597   algorithm = &cmd_algorithm;
598 }
599
600 /* Unset the algorithm option for this command */
601 void
602 unset_cmd_algorithm (void)
603 {
604   algorithm = &global_algorithm;
605 }
606
607 /* Get the current syntax setting */
608 enum behavior_mode
609 get_syntax (void)
610 {
611   return syntax;
612 }
613
614 /* Set the syntax option */
615 void 
616 set_syntax (enum behavior_mode mode)
617 {
618   syntax = mode;
619 }