From f652a1fef51cc4a3a77c28baa6c954f6b7e98666 Mon Sep 17 00:00:00 2001 From: Sean Arms <67096+lesserwhirls@users.noreply.github.com> Date: Thu, 24 Sep 2026 10:39:33 -0600 Subject: [PATCH 1/5] Improve udunits grammar to resolve warnings Modify the udunits grammar to properly distinguish signed exponents, whitespace within parentheses, repeated delimiters, and leading decimal factors. --- udunits/src/main/javacc/StandardUnitFormat.jj | 11 +++++++---- udunits/src/test/java/ucar/units/TestUdunits.java | 10 +++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/udunits/src/main/javacc/StandardUnitFormat.jj b/udunits/src/main/javacc/StandardUnitFormat.jj index 6cd24c9d6f..b9a4c50ce1 100644 --- a/udunits/src/main/javacc/StandardUnitFormat.jj +++ b/udunits/src/main/javacc/StandardUnitFormat.jj @@ -1,6 +1,6 @@ /* - * Copyright 1999, 2009 University Corporation for Atmospheric Research/Unidata - * See file LICENSE for legal details. + * Copyright (c) 1998-2026 University Corporation for Atmospheric Research/Unidata + * See LICENSE for license information. */ options @@ -560,18 +560,20 @@ Unit productExpr(UnitDB unitDB) { unit=powerExpr(unitDB) ( + LOOKAHEAD(2) + ( unit2 = powerExpr(unitDB) { unit = unit.divideBy(unit2); } | - LOOKAHEAD(2) - [ | | ] + [ LOOKAHEAD(2) ( | | ) ] unit2=powerExpr(unitDB) { unit = unit.multiplyBy(unit2); } + ) )* { return unit; @@ -592,6 +594,7 @@ Unit powerExpr(UnitDB unitDB) { unit=basicExpr(unitDB) [ + LOOKAHEAD(2) [ ] exponent=integer() { diff --git a/udunits/src/test/java/ucar/units/TestUdunits.java b/udunits/src/test/java/ucar/units/TestUdunits.java index 8d550d2233..fe58cb01e3 100644 --- a/udunits/src/test/java/ucar/units/TestUdunits.java +++ b/udunits/src/test/java/ucar/units/TestUdunits.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata + * Copyright (c) 1998-2026 University Corporation for Atmospheric Research/Unidata * See LICENSE for license information. */ @@ -310,6 +310,14 @@ public void testStandardUnitFormat() throws Exception { .multiplyBy(m.raiseTo(-1).multiplyBy(1e9)).multiplyBy(s.raiseTo(-1).multiplyBy(1e9).raiseTo(-1)) .multiplyBy(m).divideBy(s)); myAssert(parser, "m/km", m.divideBy(m.multiplyBy(1e3))); + myAssert(parser, "m+2", m.raiseTo(2)); + myAssert(parser, "m^+2", m.raiseTo(2)); + myAssert(parser, "m+1 s-2", m.raiseTo(1).multiplyBy(s.raiseTo(-2))); + myAssert(parser, "(m )", m); + myAssert(parser, "(m s )", m.multiplyBy(s)); + myAssert(parser, "m s", m.multiplyBy(s)); + myAssert(parser, ".5 m", m.multiplyBy(0.5)); + myAssert(parser, "m .5 s", m.multiplyBy(0.5).multiplyBy(s)); LineNumberReader lineInput = new LineNumberReader(new InputStreamReader(System.in)); From ab50691a6e98b9293e9d9d88403919519decd4b0 Mon Sep 17 00:00:00 2001 From: Sean Arms <67096+lesserwhirls@users.noreply.github.com> Date: Thu, 24 Sep 2026 10:49:59 -0600 Subject: [PATCH 2/5] Remove test code from the parser class definition --- udunits/src/main/javacc/StandardUnitFormat.jj | 97 ------------------- 1 file changed, 97 deletions(-) diff --git a/udunits/src/main/javacc/StandardUnitFormat.jj b/udunits/src/main/javacc/StandardUnitFormat.jj index b9a4c50ce1..01656cc93b 100644 --- a/udunits/src/main/javacc/StandardUnitFormat.jj +++ b/udunits/src/main/javacc/StandardUnitFormat.jj @@ -366,103 +366,6 @@ PARSER_BEGIN(StandardUnitFormat) prefix = prefixDB.getPrefixBySymbol(string); return prefix; } - - - private static void myAssert(StandardUnitFormat parser, final String spec, - final Unit unit) throws NoSuchUnitException, - UnitParseException, SpecificationException, UnitDBException, - PrefixDBException, UnitSystemException - { - if (!parser.parse(spec).equals(unit)) { - throw new AssertionError(spec + " != " + unit); - } - System.out.println(spec + " -> " + unit); - } - - - /** - * Test this class. - */ - public static void main(String[] args) - throws Exception - { - StandardUnitFormat parser = - StandardUnitFormat.instance(); - final Unit m = parser.parse("m"); - final Unit s = parser.parse("s"); - final Unit epoch = parser.parse("s @ 1970-01-01 00:00:00 UTC"); - myAssert(parser, "m m", m.multiplyBy(m)); - myAssert(parser, "m.m", m.multiplyBy(m)); - myAssert(parser, "(m)(m)", m.multiplyBy(m)); - myAssert(parser, "m/s/s", m.divideBy(s).divideBy(s)); - myAssert(parser, "m2", m.raiseTo(2)); - myAssert(parser, "m2.s", m.raiseTo(2).multiplyBy(s)); - myAssert(parser, "m2/s", m.raiseTo(2).divideBy(s)); - myAssert(parser, "m^2/s", m.raiseTo(2).divideBy(s)); - myAssert(parser, "m s @ 5", m.multiplyBy(s).shiftTo(5.0)); - myAssert(parser, "m2 s @ 5", m.raiseTo(2).multiplyBy(s).shiftTo(5)); - myAssert(parser, "m2 s-1 @ 5", m.raiseTo(2).multiplyBy(s.raiseTo(-1)) - .shiftTo(5)); - myAssert(parser, "m s from 5", m.multiplyBy(s).shiftTo(5)); - myAssert(parser, "s@19700101", epoch); - myAssert(parser, "s@19700101T000000", epoch); - myAssert(parser, "s@19700101T000000.00", epoch); - myAssert(parser, "s @ 1970-01-01T00:00:00.00", epoch); - myAssert(parser, "s @ 1970-01-01 00:00:00.00", epoch); - myAssert(parser, "s @ 1970-01-01 00:00:00.00 +0", epoch); - myAssert(parser, "s @ 1970-01-01T00:00:00.00 -12", epoch - .shiftTo(new Date(12 * 60 * 60 * 1000))); - if (!parser.parse("days since 2009-06-14 04:00:00").equals( - parser.parse("days since 2009-06-14 04:00:00 +00:00"))) { - throw new AssertionError(); - } - myAssert(parser, "lg(re: 1)", DerivedUnitImpl.DIMENSIONLESS.log(10)); - myAssert(parser, "0.1 lg(re 1 mm)", m.multiplyBy(1e-3).log(10) - .multiplyBy(0.1)); - myAssert(parser, "m", m); - myAssert(parser, "2 m s", m.multiplyBy(s).multiplyBy(2)); - myAssert(parser, "3.14 m.s", m.multiplyBy(s).multiplyBy(3.14)); - myAssert(parser, "1e9 (m)", m.multiplyBy(1e9)); - myAssert(parser, "(m s)2", m.multiplyBy(s).raiseTo(2)); - myAssert(parser, "m2.s-1", m.raiseTo(2).divideBy(s)); - myAssert(parser, "m2 s^-1", m.raiseTo(2).divideBy(s)); - myAssert(parser, "(m/s)2", m.divideBy(s).raiseTo(2)); - myAssert(parser, "m2/s-1", m.raiseTo(2).divideBy(s.raiseTo(-1))); - myAssert(parser, "m2/s^-1", m.raiseTo(2).divideBy(s.raiseTo(-1))); - myAssert(parser, ".5 m/(.25 s)2", m.multiplyBy(.5).divideBy( - s.multiplyBy(.25).raiseTo(2))); - myAssert(parser, "m.m-1.m", m.multiplyBy(m.raiseTo(-1)).multiplyBy(m)); - myAssert(parser, "2.0 m 1/2 s-1*(m/s^1)^-1 (1e9 m-1)(1e9 s-1)-1.m/s", m - .multiplyBy(2).multiplyBy(1. / 2.).multiplyBy( - s.raiseTo(-1)).multiplyBy( - m.divideBy(s.raiseTo(1)).raiseTo(-1)) - .multiplyBy(m.raiseTo(-1).multiplyBy(1e9)).multiplyBy( - s.raiseTo(-1).multiplyBy(1e9).raiseTo(-1)) - .multiplyBy(m).divideBy(s)); - myAssert(parser, "m/km", m.divideBy(m.multiplyBy(1e3))); - - LineNumberReader lineInput = new LineNumberReader( - new InputStreamReader(System.in)); - - for (;;) - { - System.out.print("Enter a unit specification or ^D to quit: "); - - String spec = lineInput.readLine(); - if (spec == null) - break; - - try - { - System.out.println(parser.parse(spec.trim())); - } - catch (Exception e) - { - System.out.println(e.getMessage()); - } - } - System.out.println(""); - } } PARSER_END(StandardUnitFormat) From d11f812cb3fc6ffb26a14f81e402c34fc74be2c7 Mon Sep 17 00:00:00 2001 From: Sean Arms <67096+lesserwhirls@users.noreply.github.com> Date: Thu, 24 Sep 2026 10:51:21 -0600 Subject: [PATCH 3/5] Remove ex config file --- udunits/src/main/java/ucar/units/.exrc | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 udunits/src/main/java/ucar/units/.exrc diff --git a/udunits/src/main/java/ucar/units/.exrc b/udunits/src/main/java/ucar/units/.exrc deleted file mode 100644 index dd6fcd7290..0000000000 --- a/udunits/src/main/java/ucar/units/.exrc +++ /dev/null @@ -1,2 +0,0 @@ -set aw sm sw=4 nobf ts=8 ai terse ic ws wm=0 redraw -set para=IPLPPPQPTPP\ LIpplpipnpbp' From 5928a1b6115c602c01b2f11a991dce3f9f88c352 Mon Sep 17 00:00:00 2001 From: Sean Arms <67096+lesserwhirls@users.noreply.github.com> Date: Thu, 24 Sep 2026 10:51:45 -0600 Subject: [PATCH 4/5] Remove udunits VERSION file --- udunits/src/main/java/ucar/units/VERSION | 1 - 1 file changed, 1 deletion(-) delete mode 100644 udunits/src/main/java/ucar/units/VERSION diff --git a/udunits/src/main/java/ucar/units/VERSION b/udunits/src/main/java/ucar/units/VERSION deleted file mode 100644 index 3b04cfb60d..0000000000 --- a/udunits/src/main/java/ucar/units/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.2 From b14359b7e7f86464d3ad4f5f379147a9713b2a5d Mon Sep 17 00:00:00 2001 From: Sean Arms <67096+lesserwhirls@users.noreply.github.com> Date: Thu, 24 Sep 2026 10:56:07 -0600 Subject: [PATCH 5/5] Remove files that are duplicated or no longer needed --- udunits/src/main/java/ucar/units/HISTORY | 20 ------- udunits/src/main/java/ucar/units/LICENSE | 30 ---------- udunits/src/main/java/ucar/units/README.html | 58 ------------------- udunits/src/main/java/ucar/units/package-list | 1 - 4 files changed, 109 deletions(-) delete mode 100644 udunits/src/main/java/ucar/units/HISTORY delete mode 100644 udunits/src/main/java/ucar/units/LICENSE delete mode 100644 udunits/src/main/java/ucar/units/README.html delete mode 100644 udunits/src/main/java/ucar/units/package-list diff --git a/udunits/src/main/java/ucar/units/HISTORY b/udunits/src/main/java/ucar/units/HISTORY deleted file mode 100644 index fe12f3a2f7..0000000000 --- a/udunits/src/main/java/ucar/units/HISTORY +++ /dev/null @@ -1,20 +0,0 @@ -VERSION/DATE COMMENTS ------------- -------- - -0.2 2009-04-09 - Added support for logarithmic units. - - Rewrote parser. - -0.1 YYYY-MM-DD - - Added to StandardUnitFormat the printing on standard error - of the message "Unknown unit: ...". - - Added Unit.getCanonicalString(). - - Fixed bug in handling of timezones and daylight savings time. - -0.0 1999-04-09 - - Released for internal use. diff --git a/udunits/src/main/java/ucar/units/LICENSE b/udunits/src/main/java/ucar/units/LICENSE deleted file mode 100644 index 63f0aebc5c..0000000000 --- a/udunits/src/main/java/ucar/units/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -Copyright 1999 University Corporation for Atmospheric Research/Unidata - -Portions of this software were developed by the Unidata Program at the -University Corporation for Atmospheric Research. - -Access and use of this software shall impose the following obligations -and understandings on the user. The user is granted the right, without -any fee or cost, to use, copy, modify, alter, enhance and distribute -this software, and any derivative works thereof, and its supporting -documentation for any purpose whatsoever, provided that this entire -notice appears in all copies of the software, derivative works and -supporting documentation. Further, UCAR requests that the user credit -UCAR/Unidata in any publications that result from the use of this -software or in any product that includes this software. The names UCAR -and/or Unidata, however, may not be used in any advertising or publicity -to endorse or promote any products or commercial entity unless specific -written permission is obtained from UCAR/Unidata. The user also -understands that UCAR/Unidata is not obligated to provide the user with -any support, consulting, training or assistance of any kind with regard -to the use, operation and performance of this software nor to provide -the user with any updates, revisions, new versions or "bug fixes." - -THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, -INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING -FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION -WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/udunits/src/main/java/ucar/units/README.html b/udunits/src/main/java/ucar/units/README.html deleted file mode 100644 index d0a24e92fb..0000000000 --- a/udunits/src/main/java/ucar/units/README.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - -
-

-ucar.units

- -

-Introduction

-The ucar.units Java package is for decoding and encoding formatted -unit specifications (e.g. "m/s"), converting numeric values between compatible -units (e.g. between "m/s" and "knot"), and for performing arithmetic -operations on units (e.g. dividing one unit by another, raising a unit -to a power). -
-

-Where to get this package

- Binary -Distribution -
-Contains the Java .class files; doesn't contain any .html -(i.e. javadoc) files.
- -
-Source -Distribution
- -
-Contains the Java .java files.  This release is necessary -in  order to build the javadoc .html files. -
- -

-Installation

-If you get the binary distribution, then all you need do is to put the -.jar file somewhere appropriate and add the pathname of the file to -your CLASSPATH environment variable. -

If you want to build the package from scratch (for better optimization, -for example)  then get the source distribution and compile it.  -On a UNIX system, you may do this by editing the file macros.make, -making changes as appropriate, and then executing the command make.  -This will compile the Java source files into the $(CLASSDIR) directory. -

If you want to generate javadoc .html files, then get the  -source directory and follow the instructions for your system for generating -javadoc .html files. -
-


-

-Questions and Comments

-Questions on or comments about the ucar.units package should be -sent to <support@unidata.ucar.edu>. - - diff --git a/udunits/src/main/java/ucar/units/package-list b/udunits/src/main/java/ucar/units/package-list deleted file mode 100644 index 21c66f6a37..0000000000 --- a/udunits/src/main/java/ucar/units/package-list +++ /dev/null @@ -1 +0,0 @@ -ucar.units