File: explain.c

package info (click to toggle)
wcalc 2.3.1-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 2,444 kB
  • ctags: 926
  • sloc: ansic: 8,993; objc: 1,946; lex: 798; sh: 766; yacc: 623; makefile: 79
file content (390 lines) | stat: -rw-r--r-- 17,988 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <ctype.h> /* for isspace() */
#include "number.h"
#include "uint32_max.h"
#include "variables.h"
#include "calculator.h"
#include "list.h"
#include "extract_vars.h"
#include "evalvar.h"
#include "isconst.h"
#include "isfunc.h"
#include "explain.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif

static void explain_command(const char *);
static void explain_variable(const char *);
static void explain_constant(const char *);
static void explain_function(const char *);

void explain(const char *str)
{				       /*{{{ */
    size_t curs;
    char * mystr;

    if (str == NULL || str[0] == 0) {
	printf("Nothing to explain.\n");
	return;
    }
    mystr = strdup(str);
    /* for sanity's sake, remove any trailing whitespace */
    curs = strlen(mystr) - 1;
    while (isspace(mystr[curs]) && curs > 0) {
	mystr[curs] = 0;
	curs--;
    }
    if (!strcmp(mystr, "q")) {
	printf("Quits the program.");
    } else if (*mystr == '\\') {	       // it's a command
	explain_command(mystr);
    } else if (isconst(mystr)) {	       // it's a constant
	explain_constant(mystr);
    } else if (isfunc(mystr)) {	       // it's a function
	explain_function(mystr);
    } else if (varexists(mystr)) {       // it's a variable
	explain_variable(mystr);
    } else {			       // it's a call for help
	printf("%s is neither a command, constant, function, or variable.\n",
	       mystr);
    }
    free(mystr);
}				       /*}}} */

static void explain_command(const char *str)
{				       /*{{{ */
    str++;
    if (!strcmp(str, "b") || !strcmp(str, "bin") || !strcmp(str, "binary")) {
	printf("This displays the output in binary.\n");
    } else if (!strcmp(str, "store")) {
	printf
	    ("Saves the variable specified in the preload file, ~/.wcalc_preload. Use like so: \\store variablename\n");
    } else if (!strcmp(str, "q")) {
	printf("Exits the program.\n");
    } else if (!strcmp(str, "d") || !strcmp(str, "dec") ||
	       !strcmp(str, "decimal")) {
	printf("This displays the output in decimal.\n");
    } else if (!strcmp(str, "dsep")) {
	printf
	    ("Used like so: \\dsepX This sets the decimal separator to X. By default, it is a period (.).\n");
    } else if (!strcmp(str, "e") || !strcmp(str, "eng") ||
	       !strcmp(str, "engineering")) {
	printf
	    ("This toggles the formatting of output between decimal and scientific notation. This setting only applies when precision is specified.\n");
    } else if (!strcmp(str, "cons") || !strcmp(str, "conservative")) {
	printf("Toggles precision guards.\n");
    } else if (!strcmp(str, "h") || !strcmp(str, "hex") ||
	       !strcmp(str, "hexadecimal") || !strcmp(str, "x")) {
	printf("This displays the output in hexadecimal.\n");
    } else if (!strcmp(str, "help")) {
	printf("This displays a generic help message.\n");
    } else if (!strcmp(str, "hlimit")) {
	printf
	    ("This places (or removes) a limit on the number of things stored in the history. Use like this: \\hlimitX where X is a number. 0 removes the limit.\n");
    } else if (!strcmp(str, "ints")) {
	printf
	    ("Toggles whether long integers will be abbreviated or not (conflicts with engineering notation for large numbers, but not for decimals).\n");
    } else if (!strcmp(str, "li") || !strcmp(str, "list") ||
	       !strcmp(str, "listvars")) {
	printf("Prints out the currently defined variables.\n");
    } else if (!strcmp(str, "o") || !strcmp(str, "oct") ||
	       !strcmp(str, "octal")) {
	printf("This displays the output in octal.\n");
    } else if (!strcmp(str, "open")) {
	printf
	    ("Loads a saved file. Used like this: \\openXXXXX where XXXXX is the name of the file to load.\n");
    } else if (!strcmp(str, "p")) {
	printf
	    ("Sets the precision. Use it like so: \\pX where X is the desired precision. Precision here is in digits. This setting only affects display. -1 means \"auto\".\n");
    } else if (!strcmp(str, "pre") || !strcmp(str, "prefix") ||
	       !strcmp(str, "prefixes")) {
	printf("Toggles whether prefixes are shown with the output.\n");
    } else if (!strcmp(str, "pref") || !strcmp(str, "prefs") ||
	       !strcmp(str, "preferences")) {
	printf("Prints out the current preference settings.\n");
    } else if (!strcmp(str, "r") || !strcmp(str, "rad") ||
	       !strcmp(str, "radians")) {
	printf("Toggles radian mode for trigonometric functions.\n");
    } else if (!strcmp(str, "rou") || !strcmp(str, "round") ||
	       !strcmp(str, "rounding")) {
	printf
	    ("Sets the rounding indication. The possible arguments to this preference are \"none\", \"simple\", and \"sig_fig\". Use like this: \\round none\n");
    } else if (!strcmp(str, "re") || !strcmp(str, "remember") ||
	       !strcmp(str, "remember_errors")) {
	printf("Toggles whether errors are remembered in history.\n");
    } else if (!strcmp(str, "bits")) {
	printf
	    ("Sets the number of bits used internally to represent numbers. Used like this: \\bitsX where X is a number that must be above %li and below %li.\n",
	     (long int)NUM_PREC_MIN, (long int)NUM_PREC_MAX);
    } else if (!strcmp(str, "save")) {
	printf
	    ("Saves the history and variable list to a file. Used like this: \\saveXXXXX where XXXXX is the name of the file to save.\n");
    } else if (!strcmp(str, "tsep")) {
	printf
	    ("Used like this: \\tsepX Sets the thousands-place separator character to X. The default is a comma (,).\n");
    } else if (!strcmp(str, "c") || !strcmp(str, "conv") ||
	       !strcmp(str, "convert")) {
	printf
	    ("Used either like this: \"\\convert unit1 to unit2\" or like this: \"\\convert unit1 unit2\". Converts the previous answer from the first unit to the second.\n");
    } else if (!strcmp(str, "base")) {
	printf("Prints out the previous answer in any base from 2 to 36.\n");
    } else if (!strcmp(str, "verbose")) {
	printf
	    ("Prints out the lines to be evaluated before evaluating them.\n");
    } else if (!strcmp(str, "explain")) {
	printf
	    ("Gives you information about commands, variables, constants and functions.\n");
    } else if (!strcmp(str, "cmod")) {
	printf
	    ("Changes how the modulus operator (%%) behaves with negative numbers.\n The default is to behave like the C programming language modulus, the other is slightly more flexible. For example, with the default setting:\n\n\t-340 %% 60 == -40; 340 %% -60 == 40; -340 %% -60 == -40\n\nWhen this setting is toggled, it behaves like this:\n\n\t-340 %% 60 == -40; 340 %% -60 == -20; -340 %% -60 == 20\n");
    } else {
	printf("Undefined command.\n");
    }
}				       /*}}} */

static void explain_variable(const char *str)
{				       /*{{{ */
    struct answer var;

    var = getvar_full(str);
    if (var.err) {
	printf("This should never happen.\n");
	return;
    }
    if (var.exp) {		       // it's an expression (i.e. a function)
	List strings;

	printf("%s is the expression: %s\n", str, var.exp);
	printf("%s uses the following variables:\n", str);
	strings = extract_vars(var.exp);
	while (listLen(strings) > 0) {
	    char *curstr = (char *)getHeadOfList(strings);
	    char *value = evalvar(curstr);

	    printf("\t%s\t(currently: %s)\n", curstr,
		   value ? value : "undefined");
	    if (curstr) {
		free(curstr);
	    }
	    if (value) {
		free(value);
	    }
	}
	freeList(&strings);
    } else {
	char std_save;

	std_save = standard_output;
	standard_output = 0;
	printf("%s is a variable with the value: %s\n", str,
	       print_this_result(var.val));
	standard_output = std_save;
    }
    if (var.desc != NULL) {
	printf("Description: %s\n", var.desc);
    }
}				       /*}}} */

static void explain_constant(const char *str)
{				       /*{{{ */
    if (!strcmp(str, "e")) {
	printf
	    ("The base of the natural logarithm function. Arbitrary precision. Occasionally called Euler's Number (after Leonhard Eulter) or Napier's Constant (after John Napier).");
    } else if (!strcmp(str, "pi") || !strcmp(str, "PI") || !strcmp(str, "pI")
	       || !strcmp(str, "Pi")) {
	printf
	    ("The ratio of a circle's circumference to its diameter. Arbitrary precision.");
    } else if (!strcmp(str, "random")) {
	printf("A random number between 0 and %u.", UINT32_MAX);
    } else if (!strcmp(str, "irandom")) {
	printf("A random integer between 0 and %u.", UINT32_MAX);
    } else if (!strcmp(str, "Na") || !strcmp(str, "NA")) {
	printf("Avogadro's Constant. The number of molecules in one mole.");
    } else if (!strcmp(str, "k")) {
	printf
	    ("Boltzmann's Constant. The physical constant relating temperature to energy.");
    } else if (!strcmp(str, "Cc")) {
	printf("Coulomb force constant. Equal to 1/(4*pi*epsilonzero).");
    } else if (!strcmp(str, "ec")) {
	printf
	    ("Elementary charge. The electric charge carried by a single proton.");
    } else if (!strcmp(str, "R")) {
	printf
	    ("Molar Gas Constant. Used in equations of state to relate various groups of state functions to one another.");
    } else if (!strcmp(str, "G")) {
	printf
	    ("The universal gravitational constant. Appears in Einstein's theory of general relativity.");
    } else if (!strcmp(str, "g")) {
	printf("The gravitational accelleration of Earth at sea-level.");
    } else if (!strcmp(str, "Me")) {
	printf("The mass of an electron in kilograms.");
    } else if (!strcmp(str, "Mp")) {
	printf("The mass of a proton in kilograms.");
    } else if (!strcmp(str, "Mn")) {
	printf("The mass of a neutron in kilograms.");
    } else if (!strcmp(str, "Md")) {
	printf("The mass of a deuteron in kilograms.");
    } else if (!strcmp(str, "u") || !strcmp(str, "amu")) {
	printf
	    ("Atomic mass unit. One twelfth of the mean mass of an atop of carbon 12 in its nuclear and electronic ground state.");
    } else if (!strcmp(str, "c")) {
	printf("The speed of light.");
    } else if (!strcmp(str, "h")) {
	printf
	    ("Planck Constant. Used to describe the sizes of quanta, central to the theory of quantum mechanics.");
    } else if (!strcmp(str, "mu0") || !strcmp(str, "muzero") ||
	       !strcmp(str, "muZERO")) {
	printf
	    ("Permeability of free space. Also known as the magnetic constant.");
    } else if (!strcmp(str, "epsilonzero") || !strcmp(str, "epsilonZERO") ||
	       !strcmp(str, "epsilon0") || !strcmp(str, "EPSILONzero") ||
	       !strcmp(str, "EPSILONZERO") || !strcmp(str, "EPSILON0")) {
	printf("Permittivity of free space. The ratio of D/E in vacuum.");
    } else if (!strcmp(str, "muB")) {
	printf("Bohr magneton. A physical constant of magnetic moment.");
    } else if (!strcmp(str, "b")) {
	printf
	    ("Wein displacement constant. Defines the relationship between the thermodynamic temperature of a black body and the wavelength at which the intensity of the radiation is the greatest.");
    } else if (!strcmp(str, "a0")) {
	printf
	    ("Bohr radius. A single electron orbiting at the lowest possible energy in a hydrogen atom orbits at this distance.");
    } else if (!strcmp(str, "F")) {
	printf
	    ("Faraday constant. The amount of electric charge in one mole of electrons.");
    } else if (!strcmp(str, "Vm") || !strcmp(str, "NAk")) {
	printf("Molar volume of ideal gas.");
    } else if (!strcmp(str, "eV")) {
	printf
	    ("Electron volt. The amount of kinetic energy gained by a single unbound electron when it passes through an electrostatic potential difference of one volt, in vacuum.");
    } else if (!strcmp(str, "sigma")) {
	printf
	    ("Stefan-Boltzmann constant. The constant of proportionality between the total energy radiated per unit surface area of a black body in unit time and the fourth power of the thermodynamic temperature, as per the Stefan-Boltzmann law.");
    } else if (!strcmp(str, "alpha")) {
	printf
	    ("Fine-structure constant. The fundamental physical constant characterizing the strength of the electromagnetic interaction.");
    } else if (!strcmp(str, "gamma")) {
	printf
	    ("Euler-Mascheroni constant. Used mainly in number theory, defined as the limiting difference between the harmonic series and the natural logarithm.");
    } else if (!strcmp(str, "re")) {
	printf
	    ("Electron radius, also known as the Compton radius or the Thomson scattering length based on a classical relativistic model of the electron.");
    } else if (!strcmp(str, "Kj")) {
	printf
	    ("Josephson Constant. The inverse of the magnetic flux quantum.");
    } else if (!strcmp(str, "Rk")) {
	printf
	    ("von Klitzing constant. Named after Klaus von Klitzing, the basic resistance unit.");
    } else if (!strcmp(str, "Rinf")) {
	printf
	    ("The \"infinity\" Rydberg constant, named after physicist Janne Rydberg. Used to calculate the Rydberg constant of any other chemical element.");
    } else if (!strcmp(str, "Eh")) {
	printf
	    ("Hartree energy. The atomic unit of energy, named after physicist Douglas Hartree.");
    } else if (!strcmp(str, "Gf")) {
	printf("Fermi Coupling Constant.");
    } else if (!strcmp(str, "Mmu")) {
	printf("The mass of a muon in kilograms.");
    } else if (!strcmp(str, "Mt") || !strcmp(str, "Mtau")) {
	printf("The tau mass in kilograms.");
    } else if (!strcmp(str, "Mh")) {
	printf("The mass of a helion in kilograms.");
    } else if (!strcmp(str, "Malpha")) {
	printf("The mass of an alpha particle in kilograms.");
    } else if (!strcmp(str, "n0") || !strcmp(str, "nzero")) {
	printf
	    ("Loschmidt constant. The number of molecules in a cubic meter of ideal gas. Equal to the Avogadro constant divided by molar volume.");
    } else if (!strcmp(str, "c1")) {
	printf("First radiation constant.");
    } else if (!strcmp(str, "c2")) {
	printf("Second radiation constant.");
    } else if (!strcmp(str, "G0") || !strcmp(str, "Gzero")) {
	printf("Conductance quantum.");
    } else if (!strcmp(str, "Z0") || !strcmp(str, "Zzero")) {
	printf
	    ("Characteristic impedance of vacuum, the characteristic impedance of electromagnetic radiation in vacuum. Equal to mu0*c.");
    } else if (!strcmp(str, "Phi0") || !strcmp(str, "Phizero") ||
	       !strcmp(str, "PhiZERO")) {
	printf
	    ("Magnetic flux quantum. The quantum of magnetic flux passing through a superconductor.");
    } else if (!strcmp(str, "K")) {
	printf
	    ("Catalan's constant commonly appears in estimates of combinatorial functions and in certain classes of sums and definite integrals.");
    } else if (!strcmp(str, "sinc")) {
	printf
	    ("Sinus cardinalis, also known as the interpolation function, filtering function, or the first spherical Bessel function, is the product of a sine function and a monotonically decreasing function.");
    }
    printf("\n");
}				       /*}}} */

static void explain_function(const char *str)
{				       /*{{{ */
    if (!strcmp(str, "sin") || !strcmp(str, "cos") || !strcmp(str, "tan") ||
	!strcmp(str, "cot")) {
	printf("A trigonometric function.");
    } else if (!strcmp(str, "asin") || !strcmp(str, "acos") ||
	       !strcmp(str, "atan") || !strcmp(str, "acot") ||
	       !strcmp(str, "arcsin") || !strcmp(str, "arccos") ||
	       !strcmp(str, "arctan") || !strcmp(str, "arccot")) {
	printf("The inverse of the standard trigonometric function.");
    } else if (!strcmp(str, "sinh") || !strcmp(str, "cosh") ||
	       !strcmp(str, "tanh") || !strcmp(str, "coth")) {
	printf("A standard hyperbolic trigonometric function.");
    } else if (!strcmp(str, "asinh") || !strcmp(str, "acosh") ||
	       !strcmp(str, "atanh") || !strcmp(str, "acoth")
	       || !strcmp(str, "areasinh") || !strcmp(str, "areacosh") ||
	       !strcmp(str, "areatanh") || !strcmp(str, "areacoth")) {
	printf
	    ("The inverse of the standard hyperbolic trigonometric function.");
    } else if (!strcmp(str, "log")) {
	printf("A logarithm (base 10).");
    } else if (!strcmp(str, "logtwo")) {
	printf("A logarithm (base 2).");
    } else if (!strcmp(str, "ln")) {
	printf("A logarithm (base e). Also known as the \"natural\" log.");
    } else if (!strcmp(str, "round")) {
	printf("Returns the closest integer to the input number.");
    } else if (!strcmp(str, "abs")) {
	printf("The absolute value (the distance of the number from zero).");
    } else if (!strcmp(str, "sqrt")) {
	printf("The square root function.");
    } else if (!strcmp(str, "floor")) {
	printf
	    ("Returns the biggest integer that is not bigger than the input number.");
    } else if (!strcmp(str, "ceil") || !strcmp(str, "ceiling")) {
	printf
	    ("Returns the smallest integer that is not smaller than the input number.");
    } else if (!strcmp(str, "cbrt")) {
	printf("The cube root function.");
    } else if (!strcmp(str, "rand")) {
	printf("Returns a random number between 0 and the input number.");
    } else if (!strcmp(str, "irand")) {
	printf("Returns a random integer between 0 and the input number.");
    } else if (!strcmp(str, "fact")) {
	printf("Returns the factorial of the input number.");
    } else if (!strcmp(str, "comp")) {
	printf("Returns the one's complement of the input number.");
    } else if (!strcmp(str, "zeta")) {
	printf
	    ("Returns the Riemann zeta function of the input number. This is used primarily in number theory, but also has applications in physics, probability theory, and applied statistics.");
    } else if (!strcmp(str, "Gamma")) {
	printf
	    ("Returns the Gamma function of the input number. The Gamma function extends the factorial function to complex and non-natural numbers.");
    } else if (!strcmp(str, "lnGamma")) {
	printf
	    ("Returns the natural log of the Gamma function of the input number.");
    } else if (!strcmp(str, "eint")) {
	printf("The exponential integral function.");
    } else if (!strcmp(str, "sinc")) {
	printf("Returns the sampling function, which is 1 if the input is 0, or sin(x)/x otherwise.");
    } else if (!strcmp(str, "exp")) {
	printf("Returns the value of e to the given power. Equivalent to: e^");
    } else {
	printf
	    ("Hrm... this function doesn't have any documentation! Pester the developer!");
    }
    printf("\n");
}				       /*}}} */