APPLY_RSA
authorbyungjai.im <byungjai.im@samsung.com>
Tue, 21 Aug 2012 12:50:48 +0000 (21:50 +0900)
committerbyungjai.im <byungjai.im@samsung.com>
Tue, 21 Aug 2012 12:50:48 +0000 (21:50 +0900)
387 files changed:
03_mainmenu_icon_calculator.png [new file with mode: 0644]
CMakeLists.txt
LICENSE
calculator.edc
debian/changelog
debian/control
debian/org.tizen.calculator.install.in
debian/rules
edc/Inc.calculator.main.edc
edc/Inc.calculator.pannel.lan.edc [new file with mode: 0644]
edc/Inc.calculator.pannel.por.edc
edc/edc-macro.edc
images/P04_calculator_bg.png [deleted file]
images/P04_calculator_btn_01.png
images/P04_calculator_btn_01_press.png
images/P04_calculator_btn_02.png
images/P04_calculator_btn_02_press.png
images/P04_calculator_btn_03.png
images/P04_calculator_btn_03_press.png
images/P04_calculator_btn_04.png
images/P04_calculator_btn_04_press.png
images/P04_calculator_btn_05.png
images/P04_calculator_btn_05_press.png
images/P04_calculator_btn_06.png
images/P04_calculator_btn_06_press.png
images/P04_calculator_btn_07.png
images/P04_calculator_btn_07_press.png
images/P04_calculator_btn_08.png
images/P04_calculator_btn_08_press.png
images/P04_calculator_btn_09.png
images/P04_calculator_btn_09_press.png
images/P04_calculator_btn_10.png
images/P04_calculator_btn_10_press.png
images/P04_calculator_btn_n00.png
images/P04_calculator_btn_n00_press.png
images/P04_calculator_btn_n01.png
images/P04_calculator_btn_n01_press.png
images/P04_calculator_btn_n02.png
images/P04_calculator_btn_n02_press.png
images/P04_calculator_btn_n03.png
images/P04_calculator_btn_n03_press.png
images/P04_calculator_btn_n04.png
images/P04_calculator_btn_n04_press.png
images/P04_calculator_btn_n05.png
images/P04_calculator_btn_n05_press.png
images/P04_calculator_btn_n06.png
images/P04_calculator_btn_n06_press.png
images/P04_calculator_btn_n07.png
images/P04_calculator_btn_n07_press.png
images/P04_calculator_btn_n08.png
images/P04_calculator_btn_n08_press.png
images/P04_calculator_btn_n09.png
images/P04_calculator_btn_n09_press.png [changed mode: 0644->0755]
images/P04_calculator_button_clear.png [deleted file]
images/P04_calculator_button_clear_dim.png [deleted file]
images/P04_calculator_button_clear_focus.png [deleted file]
images/P04_calculator_button_clear_press.png [deleted file]
images/P04_calculator_down_handle.png [moved from images/P04_calculator_up_arrow.png with 74% similarity, mode: 0755]
images/P04_calculator_down_handle_press.png [new file with mode: 0644]
images/P04_calculator_input_bg.png [deleted file]
images/P04_calculator_input_bg_02.png [deleted file]
images/P04_calculator_keypad_bg.png [deleted file]
images/P04_calculator_up_handle.png [new file with mode: 0644]
images/P04_calculator_up_handle_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_01.png [new file with mode: 0755]
images/landscape/P04_calculator_btn_01_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_02.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_02_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_03.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_03_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_04.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_04_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_05.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_05_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_06.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_06_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_07.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_07_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_08.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_08_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_09.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_09_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_10.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_1011.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_10_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_11.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_11_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_12.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_12_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_13.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_13_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_14.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_14_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_15.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_15_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_16.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_16_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_17.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_17_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_18.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_18_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_19.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_19_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_20.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_20_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_21.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_21_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_22.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_22_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_23.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_23_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_24.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_24_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_25.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_25_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n00.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n00_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n01.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n01_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n02.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n02_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n03.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n03_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n04.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n04_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n05.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n05_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n06.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n06_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n07.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n07_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n08.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n08_press.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n09.png [new file with mode: 0644]
images/landscape/P04_calculator_btn_n09_press.png [new file with mode: 0644]
images/landscape/P04_calculator_down_handle_land.png [new file with mode: 0644]
images/landscape/P04_calculator_down_handle_land_press.png [new file with mode: 0644]
images/landscape/P04_calculator_up_handle_land.png [new file with mode: 0644]
images/landscape/P04_calculator_up_handle_land_press.png [new file with mode: 0644]
include/calc-expression.h
include/calc-main.h
include/calc-string.h
include/calc-view.h
include/calculator_parser.h
org.tizen.calculator.desktop.in [deleted file]
org.tizen.calculator.png
org.tizen.calculator.xml [new file with mode: 0755]
packaging/org.tizen.calculator.spec
po/CMakeLists.txt
po/ar.po [new file with mode: 0644]
po/bg.po [new file with mode: 0644]
po/ca.po [new file with mode: 0644]
po/cs.po [new file with mode: 0644]
po/da.po [new file with mode: 0644]
po/en_US.po [new file with mode: 0644]
po/fi.po [new file with mode: 0644]
po/he.po [new file with mode: 0644]
po/hi.po [new file with mode: 0644]
po/hr.po [new file with mode: 0644]
po/hu.po [new file with mode: 0644]
po/id.po [new file with mode: 0644]
po/lt.po [new file with mode: 0644]
po/lv.po [new file with mode: 0644]
po/ms.po [new file with mode: 0644]
po/no.po [new file with mode: 0644]
po/pl.po [new file with mode: 0644]
po/ro.po [new file with mode: 0644]
po/sk.po [new file with mode: 0644]
po/sl.po [new file with mode: 0644]
po/sr.po [new file with mode: 0644]
po/sv.po [new file with mode: 0644]
po/th.po [new file with mode: 0644]
po/uk.po [new file with mode: 0644]
po/vi.po [new file with mode: 0644]
src/calc-expression.c
src/calc-main.c
src/calc-string.c
src/calc-view.c
src/calculator_edje.c
src/calculator_parser.c
src/decnumber/decContext.c [new file with mode: 0644]
src/decnumber/decContext.h [new file with mode: 0644]
src/decnumber/decNumber.c [new file with mode: 0644]
src/decnumber/decNumber.h [new file with mode: 0644]
src/decnumber/decNumberLocal.h [new file with mode: 0644]
theme/03_mainmenu_icon_calculator.png [new file with mode: 0644]
theme/CMakeLists.txt [new file with mode: 0644]
theme/LICENSE [new file with mode: 0644]
theme/NOTICE [new file with mode: 0644]
theme/calculator.edc [new file with mode: 0644]
theme/calculator.ini [new file with mode: 0644]
theme/calculator_theme.edc
theme/debian/changelog [new file with mode: 0644]
theme/debian/compat [new file with mode: 0644]
theme/debian/control [new file with mode: 0644]
theme/debian/dirs [new file with mode: 0644]
theme/debian/docs [new file with mode: 0644]
theme/debian/org.tizen.calculator.install.in [new file with mode: 0644]
theme/debian/org.tizen.calculator.postinst [new file with mode: 0644]
theme/debian/rules [new file with mode: 0755]
theme/edc/Inc.calculator.main.edc [new file with mode: 0644]
theme/edc/Inc.calculator.pannel.lan.edc [new file with mode: 0644]
theme/edc/Inc.calculator.pannel.por.edc [new file with mode: 0644]
theme/edc/edc-macro.edc [new file with mode: 0644]
theme/images/P04_calculator_btn_01.png [new file with mode: 0644]
theme/images/P04_calculator_btn_01_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_02.png [new file with mode: 0644]
theme/images/P04_calculator_btn_02_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_03.png [new file with mode: 0644]
theme/images/P04_calculator_btn_03_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_04.png [new file with mode: 0644]
theme/images/P04_calculator_btn_04_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_05.png [new file with mode: 0644]
theme/images/P04_calculator_btn_05_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_06.png [new file with mode: 0644]
theme/images/P04_calculator_btn_06_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_07.png [new file with mode: 0644]
theme/images/P04_calculator_btn_07_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_08.png [new file with mode: 0644]
theme/images/P04_calculator_btn_08_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_09.png [new file with mode: 0644]
theme/images/P04_calculator_btn_09_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_10.png [new file with mode: 0644]
theme/images/P04_calculator_btn_10_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n00.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n00_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n01.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n01_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n02.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n02_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n03.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n03_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n04.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n04_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n05.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n05_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n06.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n06_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n07.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n07_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n08.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n08_press.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n09.png [new file with mode: 0644]
theme/images/P04_calculator_btn_n09_press.png [new file with mode: 0755]
theme/images/P04_calculator_down_handle.png [moved from images/P04_calculator_down_arrow.png with 74% similarity, mode: 0755]
theme/images/P04_calculator_down_handle_press.png [new file with mode: 0644]
theme/images/P04_calculator_up_handle.png [new file with mode: 0644]
theme/images/P04_calculator_up_handle_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_01.png [new file with mode: 0755]
theme/images/landscape/P04_calculator_btn_01_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_02.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_02_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_03.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_03_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_04.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_04_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_05.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_05_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_06.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_06_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_07.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_07_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_08.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_08_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_09.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_09_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_10.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_1011.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_10_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_11.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_11_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_12.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_12_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_13.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_13_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_14.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_14_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_15.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_15_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_16.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_16_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_17.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_17_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_18.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_18_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_19.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_19_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_20.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_20_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_21.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_21_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_22.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_22_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_23.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_23_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_24.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_24_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_25.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_25_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n00.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n00_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n01.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n01_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n02.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n02_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n03.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n03_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n04.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n04_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n05.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n05_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n06.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n06_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n07.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n07_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n08.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n08_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n09.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_btn_n09_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_down_handle_land.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_down_handle_land_press.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_up_handle_land.png [new file with mode: 0644]
theme/images/landscape/P04_calculator_up_handle_land_press.png [new file with mode: 0644]
theme/include/calc-expression.h [new file with mode: 0644]
theme/include/calc-main.h [new file with mode: 0644]
theme/include/calc-string.h [new file with mode: 0644]
theme/include/calc-view.h [new file with mode: 0644]
theme/include/calculator_parser.h [new file with mode: 0644]
theme/org.tizen.calculator.png [new file with mode: 0644]
theme/org.tizen.calculator.xml [new file with mode: 0755]
theme/packaging/org.tizen.calculator.spec [new file with mode: 0644]
theme/po/CMakeLists.txt [new file with mode: 0644]
theme/po/POTFILES.in [new file with mode: 0644]
theme/po/ar.po [new file with mode: 0644]
theme/po/bg.po [new file with mode: 0644]
theme/po/ca.po [new file with mode: 0644]
theme/po/calculator.pot [new file with mode: 0644]
theme/po/cs.po [new file with mode: 0644]
theme/po/csv2po_v2 [new file with mode: 0644]
theme/po/da.po [new file with mode: 0644]
theme/po/de_DE.po [new file with mode: 0644]
theme/po/el_GR.po [new file with mode: 0644]
theme/po/en.po [new file with mode: 0644]
theme/po/en_US.po [new file with mode: 0644]
theme/po/es_ES.po [new file with mode: 0644]
theme/po/fi.po [new file with mode: 0644]
theme/po/fr_FR.po [new file with mode: 0644]
theme/po/he.po [new file with mode: 0644]
theme/po/hi.po [new file with mode: 0644]
theme/po/hr.po [new file with mode: 0644]
theme/po/hu.po [new file with mode: 0644]
theme/po/id.po [new file with mode: 0644]
theme/po/it_IT.po [new file with mode: 0644]
theme/po/ja_JP.po [new file with mode: 0644]
theme/po/ko_KR.po [new file with mode: 0644]
theme/po/lt.po [new file with mode: 0644]
theme/po/lv.po [new file with mode: 0644]
theme/po/ms.po [new file with mode: 0644]
theme/po/nl_NL.po [new file with mode: 0644]
theme/po/no.po [new file with mode: 0644]
theme/po/pl.po [new file with mode: 0644]
theme/po/pt_PT.po [new file with mode: 0644]
theme/po/ro.po [new file with mode: 0644]
theme/po/ru_RU.po [new file with mode: 0644]
theme/po/sk.po [new file with mode: 0644]
theme/po/sl.po [new file with mode: 0644]
theme/po/sr.po [new file with mode: 0644]
theme/po/sv.po [new file with mode: 0644]
theme/po/th.po [new file with mode: 0644]
theme/po/tr_TR.po [new file with mode: 0644]
theme/po/uk.po [new file with mode: 0644]
theme/po/update-po.sh [new file with mode: 0644]
theme/po/vi.po [new file with mode: 0644]
theme/po/zh_CN.po [new file with mode: 0644]
theme/po/zh_HK.po [new file with mode: 0644]
theme/po/zh_TW.po [new file with mode: 0644]
theme/src/calc-expression.c [new file with mode: 0644]
theme/src/calc-main.c [new file with mode: 0644]
theme/src/calc-string.c [new file with mode: 0644]
theme/src/calc-view.c [new file with mode: 0644]
theme/src/calculator_edje.c [new file with mode: 0644]
theme/src/calculator_parser.c [new file with mode: 0644]
theme/src/decnumber/decContext.c [new file with mode: 0644]
theme/src/decnumber/decContext.h [new file with mode: 0644]
theme/src/decnumber/decNumber.c [new file with mode: 0644]
theme/src/decnumber/decNumber.h [new file with mode: 0644]
theme/src/decnumber/decNumberLocal.h [new file with mode: 0644]

diff --git a/03_mainmenu_icon_calculator.png b/03_mainmenu_icon_calculator.png
new file mode 100644 (file)
index 0000000..07612bb
Binary files /dev/null and b/03_mainmenu_icon_calculator.png differ
index c2f5b0d..9804dfc 100644 (file)
@@ -7,12 +7,13 @@ SET(SRCS
     src/calculator_parser.c
     src/calc-expression.c
     src/calc-string.c
-    src/calc-view.c)
+    src/calc-view.c
+       src/decnumber/decNumber.c
+       src/decnumber/decContext.c)
     
-SET(ORG "org")
 SET(VENDOR "tizen")
 SET(PACKAGE ${PROJECT_NAME})
-SET(PKGNAME "${ORG}.${VENDOR}.${PACKAGE}")
+SET(PKGNAME "org.${VENDOR}.${PACKAGE}")
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 #SET(INSTALL_DIR_APPS "/opt/apps/${PKGNAME}")
 SET(INSTALL_DIR_PRE "/opt")
@@ -43,6 +44,10 @@ EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
 IF("${ARCH}" STREQUAL "arm")
     INSTALL(FILES ${CMAKE_SOURCE_DIR}/org.tizen.calculator.png DESTINATION ${ICONDIR})
     MESSAGE("install confidential icon ...")
+ELSE("${ARCH}" STREQUAL "arm")
+    INSTALL(FILES ${CMAKE_SOURCE_DIR}/03_mainmenu_icon_calculator.png DESTINATION ${ICONDIR} RENAME
+    org.tizen.calculator.png)
+    MESSAGE("install releasable icon ...")
 ENDIF("${ARCH}" STREQUAL "arm")
 
 ADD_DEFINITIONS(${pkgs_CFLAGS})
@@ -98,7 +103,5 @@ ADD_SUBDIRECTORY(po)
 
 # desktop icon
 set(PREFIX ${CMAKE_INSTALL_PREFIX})
-configure_file(org.tizen.calculator.desktop.in org.tizen.calculator.desktop)
-install(FILES ${CMAKE_SOURCE_DIR}/org.tizen.calculator.desktop DESTINATION 
-/opt/share/applications)
-install(FILES ${CMAKE_SOURCE_DIR}/org.tizen.calculator.png DESTINATION ${DESKTOPICONDIR})
+install(FILES ${CMAKE_SOURCE_DIR}/org.tizen.calculator.xml DESTINATION /opt/share/packages)
+install(FILES ${CMAKE_SOURCE_DIR}/org.tizen.calculator.png DESTINATION  /opt/share/icons/default/small)
diff --git a/LICENSE b/LICENSE
index 7ccb5b5..05d9069 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,75 +1,76 @@
-Flora License
-
-Version 1.0, May, 2012
-
-http://www.tizenopensource.org/license
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
-
-"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
-
-"Tizen Certified Platform" shall mean a software platform that complies with the standards set forth in the Compatibility Definition Document and passes the Compatibility Test Suite as defined from time to time by the Tizen Technical Steering Group and certified by the Tizen Association or its designated agent.
-
-2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work solely as incorporated into a Tizen Certified Platform, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work solely as incorporated into a Tizen Certified Platform to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof pursuant to the copyright license above, in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
-
-  1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
-
-  2. You must cause any modified files to carry prominent notices stating that You changed the files; and
-
-  3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
-
-  4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Flora License to your work
-
-To apply the Flora License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Flora License, Version 1.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.tizenopensource.org/license
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
+Flora License\r
+\r
+Version 1.0, May, 2012\r
+\r
+http://www.tizenopensource.org/license\r
+\r
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+1. Definitions.\r
+\r
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\r
+\r
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.\r
+\r
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\r
+\r
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\r
+\r
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\r
+\r
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\r
+\r
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\r
+\r
+"Tizen Certified Platform" shall mean a software platform that complies with the standards set forth in the Compatibility Definition Document and passes the Compatibility Test Suite as defined from time to time by the Tizen Technical Steering Group and certified by the Tizen Association or its designated agent.\r
+\r
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\r
+\r
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work solely as incorporated into a Tizen Certified Platform, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work solely as incorporated into a Tizen Certified Platform to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\r
+\r
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof pursuant to the copyright license above, in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\r
+\r
+  1. You must give any other recipients of the Work or Derivative Works a copy of this License; and\r
+\r
+  2. You must cause any modified files to carry prominent notices stating that You changed the files; and\r
+\r
+  3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\r
+\r
+  4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\r
+\r
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\r
+\r
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\r
+\r
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\r
+\r
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.\r
+\r
+END OF TERMS AND CONDITIONS\r
+\r
+APPENDIX: How to apply the Flora License to your work\r
+\r
+To apply the Flora License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.\r
+\r
+   Copyright 2012  Samsung Electronics Co., Ltd\r
+\r
+   Licensed under the Flora License, Version 1.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.tizenopensource.org/license\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
index 8c990c7..0ca57f6 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #include "edc/edc-macro.edc"
 
@@ -26,9 +26,6 @@
 #define HEIGHT_POR                             1280
 images {
         /*portrait*/
-
-        image: "images/P04_calculator_bg.png" COMP;
-        image: "images/P04_calculator_keypad_bg.png" COMP;
         image: "images/P04_calculator_btn_01.png" COMP;
         image: "images/P04_calculator_btn_01_press.png" COMP;
         image: "images/P04_calculator_btn_02.png" COMP;
@@ -70,20 +67,92 @@ images {
         image: "images/P04_calculator_btn_n09.png" COMP;
         image: "images/P04_calculator_btn_n09_press.png" COMP;
 
-        image: "images/P04_calculator_down_arrow.png" COMP;
-        image: "images/P04_calculator_up_arrow.png" COMP;
-       // image: "P04_calculator_up_arrow.png" COMP;
+        image: "images/P04_calculator_down_handle.png" COMP;
+        image: "images/P04_calculator_up_handle.png" COMP;
+        image: "images/P04_calculator_down_handle_press.png" COMP;
+        image: "images/P04_calculator_up_handle_press.png" COMP;
+
+        /*landscape*/
+        image: "images/landscape/P04_calculator_btn_01.png" COMP;
+        image: "images/landscape/P04_calculator_btn_01_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_02.png" COMP;
+        image: "images/landscape/P04_calculator_btn_02_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_03.png" COMP;
+        image: "images/landscape/P04_calculator_btn_03_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_04.png" COMP;
+        image: "images/landscape/P04_calculator_btn_04_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_05.png" COMP;
+        image: "images/landscape/P04_calculator_btn_05_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_06.png" COMP;
+        image: "images/landscape/P04_calculator_btn_06_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_07.png" COMP;
+        image: "images/landscape/P04_calculator_btn_07_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_08.png" COMP;
+        image: "images/landscape/P04_calculator_btn_08_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_09.png" COMP;
+        image: "images/landscape/P04_calculator_btn_09_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_10.png" COMP;
+        image: "images/landscape/P04_calculator_btn_10_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_11.png" COMP;
+        image: "images/landscape/P04_calculator_btn_11_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_12.png" COMP;
+        image: "images/landscape/P04_calculator_btn_12_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_13.png" COMP;
+        image: "images/landscape/P04_calculator_btn_13_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_14.png" COMP;
+        image: "images/landscape/P04_calculator_btn_14_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_15.png" COMP;
+        image: "images/landscape/P04_calculator_btn_15_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_16.png" COMP;
+        image: "images/landscape/P04_calculator_btn_16_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_17.png" COMP;
+        image: "images/landscape/P04_calculator_btn_17_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_18.png" COMP;
+        image: "images/landscape/P04_calculator_btn_18_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_19.png" COMP;
+        image: "images/landscape/P04_calculator_btn_19_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_20.png" COMP;
+        image: "images/landscape/P04_calculator_btn_20_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_21.png" COMP;
+        image: "images/landscape/P04_calculator_btn_21_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_22.png" COMP;
+        image: "images/landscape/P04_calculator_btn_22_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_23.png" COMP;
+        image: "images/landscape/P04_calculator_btn_23_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_24.png" COMP;
+        image: "images/landscape/P04_calculator_btn_24_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_25.png" COMP;
+        image: "images/landscape/P04_calculator_btn_25_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n00.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n00_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n01.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n01_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n02.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n02_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n03.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n03_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n04.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n04_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n05.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n05_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n06.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n06_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n07.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n07_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n08.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n08_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n09.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n09_press.png" COMP;
 
-        image: "images/P04_calculator_input_bg.png" COMP;
-        image: "images/P04_calculator_input_bg_02.png" COMP;
+        image: "images/landscape/P04_calculator_down_handle_land.png" COMP;
+        image: "images/landscape/P04_calculator_up_handle_land.png" COMP;
+        image: "images/landscape/P04_calculator_down_handle_land_press.png" COMP;
+        image: "images/landscape/P04_calculator_up_handle_land_press.png" COMP;
 
-        image: "images/P04_calculator_button_clear.png" COMP;
-        image: "images/P04_calculator_button_clear_dim.png" COMP;
-        image: "images/P04_calculator_button_clear_focus.png" COMP;
-        image: "images/P04_calculator_button_clear_press.png" COMP;
 
     }
 collections {
        #include "edc/Inc.calculator.main.edc"
        #include "edc/Inc.calculator.pannel.por.edc"
+       #include "edc/Inc.calculator.pannel.lan.edc"
 }
index 3e4a7e1..7ba69e0 100644 (file)
+calculator (0.1.19-1) unstable; urgency=low
+
+  * [Others]Remove UI-idlecapture to fix build error
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.19-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Thu, 02 Aug 2012 09:23:18 +0800
+
+calculator (0.1.18-1) unstable; urgency=low
+
+  * [Bug]<P120731-4507>Make the digit not jump when in minimized window
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.18-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 01 Aug 2012 13:15:56 +0800
+
+calculator (0.1.17-1) unstable; urgency=low
+
+  * [Bug]<P120725-0073>Make the cursor move to the last digit
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.17-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  SAT, 28 Jul 2012 15:15:30 +0800
+
+calculator (0.1.16-1) unstable; urgency=low
+
+  * [Bug]<P120725-0072>Calculator history not full displayed when minimized window
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.16-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 25 Jul 2012 15:39:42 +0800
+
+calculator (0.1.15-1) unstable; urgency=low
+
+  * [Others]Apply new white theme
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.15-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 24 Jul 2012 16:40:02 +0800
+
+calculator (0.1.14-1) unstable; urgency=low
+
+  * [Others]Change font size when switch to monitor
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.14-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 21 Jul 2012 14:52:23 +0800
+
+calculator (0.1.13-1) unstable; urgency=low
+
+  * [GUI][V0.8][P6]Change auto font resizing rule
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.13-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 13 Jul 2012 14:01:39 +0800
+
+calculator (0.1.12-1) unstable; urgency=low
+
+  * [Bug]<S1-5240>Add elm_object_focus_set to show cursor
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.12-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 10 Jul 2012 10:53:05 +0800
+
+calculator (0.1.11-1) unstable; urgency=low
+
+  * [Others]Hide recover and exit button for monitor mode of mini window
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.11-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 06 Jul 2012 11:51:01 +0800
+
+calculator (0.1.10-1) unstable; urgency=low
+
+  * [GUI][v0.8][P12]Rewrite edc for minimized window
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.10-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Thu, 05 Jul 2012 14:39:57 +0800
+
+calculator (0.1.9-1) unstable; urgency=low
+
+  * [Others]Modify app in app requirement in desktop mode
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.9-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  SAT, 30 Jun 2012 15:51:05 +0800
+
+calculator (0.1.8-1) unstable; urgency=low
+
+  * [Others]Fix app in app bug that show size abnormal in desktop mode
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.8-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 27 Jun 2012 19:31:34 +0800
+
+calculator (0.1.7-1) unstable; urgency=low
+
+  * [Others]Apply calculator app in app mode
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.7-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Mon, 25 Jun 2012 10:42:08 +0800
+
+calculator (0.1.6-12) unstable; urgency=low
+
+  * [Bug]<S1-3527>Change e^x to 10^x
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-12
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Mon, 25 Jun 2012 18:12:13 +0800
+
+calculator (0.1.6-11) unstable; urgency=low
+
+  * [GUI][Ver0.5][P13]Apply landscape mode view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-11
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 15 Jun 2012 10:45:51 +0800
+
+calculator (0.1.6-10) unstable; urgency=low
+
+  * [GUI][Ver0.6][Page7]Apply new portrait mode view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-10
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 12 Jun 2012 10:51:01 +0800
+
+calculator (0.1.6-9) unstable; urgency=low
+
+  * [Others]Change layout theme set
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-9
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 08 Jun 2012 16:07:54 +0800
+
+calculator (0.1.6-8) unstable; urgency=low
+
+  * [Others]Show the number which is less then 0.00001
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-8
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 06 Jun 2012 09:40:14 +0800
+
+calculator (0.1.6-7) unstable; urgency=low
+
+  * [Bug]<NCR-32>Press input button cause memory leak
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-7
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 05 Jun 2012 09:59:32 +0800
+
+calculator (0.1.6-6) unstable; urgency=low
+
+  * [Others]Apply scientific calculation result with different length when switch por/lan view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-6
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 02 Jun 2012 17:03:03 +0800
+
+calculator (0.1.6-5) unstable; urgency=low
+
+  * [Others]Input dot without numbers, automatically add 0 before dot
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-5
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 30 May 2012 16:39:46 +0800
+
+calculator (0.1.6-4) unstable; urgency=low
+
+  * [Others]Sync spec file with OBS in desktop icon install path
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-4
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 30 May 2012 15:19:19 +0800
+
+calculator (0.1.6-3) unstable; urgency=low
+
+  * [Request]Change default desktop icon install path
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-3
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 23 May 2012 10:00:50 +0800
+
+calculator (0.1.6-2) unstable; urgency=low
+
+  * [Request]Sync version as OBS package
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-2
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 21 May 2012 14:15:30 +0800
+
+calculator (0.1.3-80) unstable; urgency=low
+
+  * [Request]Add strip option
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-80
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 18 May 2012 15:51:30 +0800
+
+calculator (0.1.3-79) unstable; urgency=low
+
+  *  [Bug]Copy function cannot work well in history view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-79
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 15 May 2012 17:34:29 +0800
+
+calculator (0.1.3-78) unstable; urgency=low
+
+  *  [Request]Add text_class to font field in edc file
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-78
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 15 May 2012 14:08:41 +0800
+
+calculator (0.1.3-77) unstable; urgency=low
+
+  *  [Bug]Fix bug that input dot when calculated shows error
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-77
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 11 May 2012 16:58:10 +0800
+
+calculator (0.1.3-76) unstable; urgency=low
+
+  *  [Request]Distinguish negative and minus symbol in color and length
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-76
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Thu, 10 May 2012 10:42:09 +0800
+
+calculator (0.1.3-75) unstable; urgency=low
+
+  *  [Bug]S1-2986/S1-2988 show clear button on normal view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-75
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 08 May 2012 10:26:23 +0800
+
+calculator (0.1.3-74) unstable; urgency=low
+
+  *  [Request]Fix round error issue
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-74
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 05 May 2012 11:32:03 +0800
+
+calculator (0.1.3-73) unstable; urgency=low
+
+  *  [Request]Remove install usr/share folder
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-73
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 04 May 2012 18:02:38 +0800
+
+calculator (0.1.3-72) unstable; urgency=low
+
+  *  [Request]Apply auto font resizing rule in UI v1.1 p15
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-72
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 25 Apr 2012 15:43:49 +0800
+
+calculator (0.1.3-71) unstable; urgency=low
+
+  *  [Bug]Fix bug that input dot issues as N_SE-877 on public
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-71
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 24 Apr 2012 15:53:31 +0800
+
+calculator (0.1.3-70) unstable; urgency=low
+
+  *  [Request]Apply 2012.04.18 GUI v0.3
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-70
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Mon, 23 Apr 2012 20:33:35 +0800
+
+calculator (0.1.3-69) unstable; urgency=low
+
+  *  [Request]Add po and delete invalid comment
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-69
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 20 Apr 2012 09:57:45 +0800
+
+calculator (0.1.3-68) unstable; urgency=low
+
+  *  [Bug]Fix bug '+number' error as N_SE-527 on public
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-68
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 18 Apr 2012 14:47:40 +0800
+
+calculator (0.1.3-67) unstable; urgency=low
+
+  *  [Bug]fix bug S1-2584/2560 and fix continuously input =
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-67
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 14 Apr 2012 17:52:49 +0800
+
+calculator (0.1.3-66) unstable; urgency=low
+
+  *  [Bug]Fix the bug S1-2589 & S1-2588
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-66
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 14 Apr 2012 10:08:52 +0800
+
+calculator (0.1.3-65) unstable; urgency=low
+
+  * [Bug]Fix the bug that Proper error message is not displaying when the editor exceeds the range
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-65
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 27 Mar 2012 17:39:22 -0800
+calculator (0.1.3-64) unstable; urgency=low
+
+  * [Bug]Fix the bug that Cut, Copy & Paste operations are not functioning
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-64
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 24 Mar 2012 14:39:22 -0800
+calculator (0.1.3-63) unstable; urgency=low
+
+  * [Request]Change spec files name
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-63
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 23 Mar 2012 17:50:22 -0800
+calculator (0.1.3-62) unstable; urgency=low
+
+  * [Bug]Fix the change line problem
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-62
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 21 Mar 2012 10:50:22 -0800
+calculator (0.1.3-61) unstable; urgency=low
+
+  * [Request]remove the ui-idlecapture annotation code
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-61
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 17 Mar 2012 08:50:22 -0800
+calculator (0.1.3-60) unstable; urgency=low
+
+  * [Request]Changing SLP Prefix
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-60
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 16 Mar 2012 09:50:22 -0800
 calculator (0.1.3-59) unstable; urgency=low
 
-  * Fix the bug that calculate wrong ,such as (2+2)9 
-  * Git: apps/c/calculator
+  * [Request]Change font size
+  * Git: slp/apps/c/calculator
   * Tag: calculator_0.1.3-59
 
- -- Goo Lee <goo81.lee@samsung.com>  Mon, 1 Apr 2012 17:24:22 +0900
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 15 Mar 2012 16:30:22 -0800
+calculator (0.1.3-58) unstable; urgency=low
+
+  * [Request]Modify the parameter of elm_win_indicator_mode_set
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-58
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 15 Mar 2012 14:30:22 -0800
+calculator (0.1.3-57) unstable; urgency=low
+
+  * [Request]Apply oneline concept 
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-57
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 14 Mar 2012 19:30:22 -0800
+calculator (0.1.3-56) unstable; urgency=low
+
+  * [Request]Apply API and Winset changes
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-56
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 13 Mar 2012 17:30:22 -0800
+calculator (0.1.3-55) unstable; urgency=low
+
+  * [Request]Add performance log
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-55
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 12 Mar 2012 14:30:22 -0800
+calculator (0.1.3-54) unstable; urgency=low
+
+  * [Request]Shrink font size to fit it as one line
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-54
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 09 Mar 2012 09:30:22 -0800
+calculator (0.1.3-53) unstable; urgency=low
+
+  * [Bug]Remove the error message that can't adapt to multi-language
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-53
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 22 Feb 2012 14:30:22 -0800
+calculator (0.1.3-52) unstable; urgency=low
+
+  * [Request]Replace deprecated API
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-52
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 20 Feb 2012 17:30:22 -0800
+calculator (0.1.3-51) unstable; urgency=low
+
+  * [Bug]Fix the bug that the number is a little broken 
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-51
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 20 Feb 2012 17:03:22 -0800
+calculator (0.1.3-50) unstable; urgency=low
+
+  * [Bug]Fix the bug that CUT&PASTE functionality is improper
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-50
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 7 Feb 2012 17:13:22 -0800
+calculator (0.1.3-49) unstable; urgency=low
+
+  * [Request]Update maintainer
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-49
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 6 Feb 2012 09:13:22 -0800
+calculator (0.1.3-48) unstable; urgency=low
+
+  * [Request]Remove white theme
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-48
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 2 Feb 2012 14:13:22 -0800
+calculator (0.1.3-47) unstable; urgency=low
+
+  * [Request]Error message is displayed in the input field instead of pop up
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-47
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 1 Feb 2012 16:13:22 -0800
+calculator (0.1.3-46) unstable; urgency=low
+
+  * [Bug]The deivce can't display the number under landscapde mode after hiding the handler under portrait mode 
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-46
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 31 Jan 2012 09:53:22 -0800
+calculator (0.1.3-45) unstable; urgency=low
+
+  * [Request]Modify for improving touch performance 
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-45
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 16 Jan 2012 14:43:22 -0800
+calculator (0.1.3-44) unstable; urgency=low
+
+  * [Bug]Fix the issue that popup message can't adapt to multi-language
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-44
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 11 Jan 2012 10:43:22 -0800
+calculator (0.1.3-43) unstable; urgency=low
+
+  * [Request]Apply CAPI
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-43
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 5 Jan 2012 15:43:22 -0800
+calculator (0.1.3-42) unstable; urgency=low
+
+  * [Bug]On different language modes pop up information is always displayed in English language
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-42
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 5 Jan 2012 14:43:22 -0800
+calculator (0.1.3-41) unstable; urgency=low
+
+  * [Request]Theme Name Change from nbeat to tizen
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-41
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 16 Dec 2011 15:32:08 -0800
+calculator (0.1.3-40) unstable; urgency=low
+
+  * [Bug]Fix the issue that menu screen is shown when popup is displayed
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-40
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 15 Dec 2011 13:08:35 -0700
+calculator (0.1.3-39) unstable; urgency=low
+
+  * [Bug]Add automatic operator if the "p" or "e" close to digital
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-39
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 9 Dec 2011 14:08:35 -0700
+calculator (0.1.3-38) unstable; urgency=low
+
+  * [Bug]Cursor automatically move to next line after rotating device
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-38
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 7 Dec 2011 17:08:35 -0700
+calculator (0.1.3-37) unstable; urgency=low
+
+  * [Bug]Disable entry's magnifier to resolve the issue that no number seen in black magnifying window
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-37
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 7 Dec 2011 10:08:35 -0700
+calculator (0.1.3-36) unstable; urgency=low
+
+  * [Bug]Fix the issue that Warning pop up still remains after pressing home key
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-36
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 6 Dec 2011 21:08:35 -0700
+calculator (0.1.3-35) unstable; urgency=low
+
+  * [Bug]Fix the issue that select box created in input entry remains shown in history view
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-35
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 6 Dec 2011 14:15:35 -0700
+calculator (0.1.3-34) unstable; urgency=low
+
+  * [Request]Apply new License bolierplate
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-34
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 5 Dec 2011 10:45:35 -0700
+calculator (0.1.3-33) unstable; urgency=low
+
+  * [Request]If input "=" after an operator,previous input will be duplicated and calculate the expression
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-33
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 2 Dec 2011 16:05:35 -0700
+calculator (0.1.3-32) unstable; urgency=low
+
+  * [Request]Apply elm_entry copy&paste mode
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-32
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 2 Dec 2011 14:05:35 -0700
+calculator (0.1.3-31) unstable; urgency=low
+
+  * [Request]Apply new License
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-31
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 2 Dec 2011 09:45:35 -0700
+calculator (0.1.3-30) unstable; urgency=low
+
+  * [CQ]H0100137603: restrict invalid charactors inputted in number input field
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-30
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 28 Nov 2011 16:45:35 -0700
+calculator (0.1.3-29) unstable; urgency=low
+
+  * Apply Public emulator image
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-29
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 25 Nov 2011 15:45:35 -0700
+calculator (0.1.3-28) unstable; urgency=low
+
+  * [CQ]H0100137014: Fix the bug that Warning message pop up hided by the clipboard screen
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-28
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 23 Nov 2011 16:39:06 -0700
+calculator (0.1.3-27) unstable; urgency=low
+
+  * [CQ]H0100137274: Remain entry empty when inputting '*' and '/'operators with no numbers
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-27
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 22 Nov 2011 14:39:06 -0700
+calculator (0.1.3-26) unstable; urgency=low
+
+  * [CQ]H0100137220:Add popup if unvalid charactors are found ,when calculating
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-26
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 22 Nov 2011 10:39:06 -0700
+calculator (0.1.3-25) unstable; urgency=low
+
+  * Fix the issue that popup get duplicated display
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-25
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 18 Nov 2011 21:39:06 -0700
+calculator (0.1.3-24) unstable; urgency=low
+
+  * Add the operation to close parentheses automatically
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-24
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 18 Nov 2011 13:58:06 -0700
+calculator (0.1.3-23) unstable; urgency=low
+
+  * Apply new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-23
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 10 Nov 2011 09:37:06 -0700
+calculator (0.1.3-22) unstable; urgency=low
+
+  * Fix errors from checkpatch
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-22
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 10 Nov 2011 09:37:06 -0700
+calculator (0.1.3-21) unstable; urgency=low
+
+  * Fix the crash when cut&paste
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-21
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 4 Nov 2011 16:37:06 -0700
+calculator (0.1.3-20) unstable; urgency=low
+
+  * Fix desk file removable issue
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-20
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 31 Oct 2011 16:37:06 -0700
+calculator (0.1.3-19) unstable; urgency=low
+
+  * Add keypad image
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-19
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 26 Oct 2011 10:57:06 -0700
+calculator (0.1.3-18) unstable; urgency=low
+
+  * Update the license
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-18
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 20 Oct 2011 16:31:06 -0700
+calculator (0.1.3-17) unstable; urgency=low
+
+  * Unity the style
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-17
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 19 Oct 2011 15:31:06 -0700
+calculator (0.1.3-16) unstable; urgency=low
+
+  * Fix bug about cut&&paste
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-16
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 19 Oct 2011 14:31:06 -0700
+calculator (0.1.3-15) unstable; urgency=low
+
+  * Modify desktop icon
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-15
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 19 Oct 2011 09:55:06 -0700
+calculator (0.1.3-14) unstable; urgency=low
+
+  * Add warning for unvalid charactor from hardware keypad input
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-14
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 15 Oct 2011 16:26:06 -0700
+calculator (0.1.3-13) unstable; urgency=low
+
+  * Fix bug about hardware keypad input
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-13
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 14 Oct 2011 16:26:06 -0700
+calculator (0.1.3-12) unstable; urgency=low
+
+  * Support hardware keypad
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-12
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 14 Oct 2011 09:49:06 -0700
+calculator (0.1.3-11) unstable; urgency=low
+
+  * Let Inserted operation always visible after expanding Input area
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-11
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 12 Oct 2011 09:49:06 -0700
+calculator (0.1.3-10) unstable; urgency=low
+
+  * apply HD GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-10
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 12 Oct 2011 09:49:06 -0700
+calculator (0.1.3-9) unstable; urgency=low
+
+  * apply NBEAT HD Black Theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-9
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 10 Oct 2011 13:14:06 -0700
+calculator (0.1.3-8) unstable; urgency=low
+
+  * Filter out end key
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-8
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 10 Oct 2011 09:40:06 -0700
+calculator (0.1.3-7) unstable; urgency=low
+
+  * Modify the customized theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-7
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 22 Sep 2011 15:22:06 -0700
+calculator (0.1.3-6) unstable; urgency=low
+
+  * change the charactor color on black theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-6
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 22 Sep 2011 09:22:06 -0700
+calculator (0.1.3-5) unstable; urgency=low
+
+  * Correct the behavior of () button
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-5
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 20 Sep 2011 14:57:06 -0700
+calculator (0.1.3-4) unstable; urgency=low
+
+  * Update entry theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-4
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 20 Sep 2011 10:57:06 -0700
+calculator (0.1.3-3) unstable; urgency=low
+
+  * change the charactor color on black theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-3
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 17 Sep 2011 16:43:06 -0700
+calculator (0.1.3-2) unstable; urgency=low
+
+  * Resolve the leak of memory in calculate
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-2
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 16 Sep 2011 09:00:06 -0700
+calculator (0.1.3-1) unstable; urgency=low
+
+  * Restrict the validity of input on paste
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-1
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 13 Sep 2011 16:30:06 -0700
+calculator (0.1.2-99) unstable; urgency=low
+
+  * Fix the bug about strcpy and strcat on prevent
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-99
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 08 Sep 2011 10:30:06 -0700
+
+calculator (0.1.2-98) unstable; urgency=low
+
+  * Fix the bug that the same popup display many times
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-98
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 05 Sep 2011 16:50:06 -0700
+
+calculator (0.1.2-97) unstable; urgency=low
+
+  * Solve a issue that long expression inputting get slower.
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-97
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 03 Sep 2011 13:43:15 +0800
+
+calculator (0.1.2-96) unstable; urgency=low
+
+  * Fix rotate issue when popup shown.
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-96
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 03 Sep 2011 10:24:58 +0800
+
+calculator (0.1.2-95) unstable; urgency=low
+
+  * Correct cursor position in landscape.
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-95
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 03 Sep 2011 09:56:05 +0800
+
+calculator (0.1.2-94) unstable; urgency=low
+
+  * Replace the hard code about muti Language and add shake and sound on keypad
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-94
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 2 Sep 2011 11:20:06 -0700
+calculator (0.1.2-93) unstable; urgency=low
+
+  * Fix the wrong popup shows in Turkce
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-93
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 25 Aug 2011 16:20:06 -0700
+calculator (0.1.2-92) unstable; urgency=low
+
+  * Fix bugs caused by multi language
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-92
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 10 Aug 2011 13:45:06 -0700
+calculator (0.1.2-91) unstable; urgency=low
+
+  * Modify entry theme for adapt to the black Theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-91
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 03 Aug 2011 16:45:06 -0700
+calculator (0.1.2-90) unstable; urgency=low
+
+  * Correct the line wrap way of entry and remove the unused code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-90
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 29 Jul 2011 08:45:06 -0700
+calculator (0.1.2-89) unstable; urgency=low
+
+  * Modify for history entry display unormally caused by Elementary Migration
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-89
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 27 Jul 2011 10:06:06 -0700
+calculator (0.1.2-88) unstable; urgency=low
+
+  * Elementary Migration and remove warnings
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-88
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 21 Jul 2011 13:18:06 -0700
+calculator (0.1.2-86) unstable; urgency=low
+
+  * Clean up code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-86
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 13 Jul 2011 11:18:06 -0700
+calculator (0.1.2-85) unstable; urgency=low
+
+  * Fix the bug unable to delete copied numbers
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-85
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 4 May 2011 13:40:06 -0700
+calculator (0.1.2-84) unstable; urgency=low
+
+  * fix the bug that sensitive is too low on backspace button
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-84
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 3 May 2011 16:40:06 -0700
+calculator (0.1.2-83) unstable; urgency=low
+
+  * Change unsafe string C library function
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-83
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 3 May 2011 11:40:06 -0700
+calculator (0.1.2-82) unstable; urgency=low
+
+  * change the transparency of the clear image and fix the bug about unexpected exit
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-82
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 29 Apr 2011 16:40:06 -0700
+calculator (0.1.2-81) unstable; urgency=low
+
+  * change the use of CFLAGS
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-81
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 27 Apr 2011 19:01:06 -0700
+
+calculator (0.1.2-80) unstable; urgency=low
+
+  * fix the bug can't focus the result in entry
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-80
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 27 Apr 2011 11:36:51 +0800
+calculator (0.1.2-79) unstable; urgency=low
+
+  * Set different font when rotate
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-79
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 23 Apr 2011 15:36:51 +0800
+calculator (0.1.2-78) unstable; urgency=low
+
+  * modify for new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-78
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 22 Apr 2011 08:53:51 +0800
+
+calculator (0.1.2-77) unstable; urgency=low
+
+  * modify for new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-77
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 21 Apr 2011 17:23:23 +0800
+
+calculator (0.1.2-76) unstable; urgency=low
+
+  * ../util.sh -P -m "modify the background and icon"
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-76
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 19 Apr 2011 13:46:24 +0800
+
+calculator (0.1.2-75) unstable; urgency=low
+
+  * develop the new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-75
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 18 Apr 2011 17:50:25 +0800
+
+calculator (0.1.2-74) unstable; urgency=low
+
+  * develop the new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-74
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 18 Apr 2011 17:48:15 +0800
+
+calculator (0.1.2-73) unstable; urgency=low
+
+  * develop the new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-73
+
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 18 Apr 2011 17:36:19 +0800
+
+calculator (0.1.2-72) unstable; urgency=low
+
+  * apply new  App. name policy
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-72
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 11 Apr 2011 18:07:19 +0800
+
+calculator (0.1.2-71) unstable; urgency=low
+
+  * fix BS after paste many charactor
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-71
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 31 Mar 2011 08:32:11 +0800
+
+calculator (0.1.2-70) unstable; urgency=low
+
+  * remove fakeimage
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-70
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 18 Mar 2011 09:58:12 +0800
+
+calculator (0.1.2-69) unstable; urgency=low
+
+  * add long press function for delete
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-69
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 17 Mar 2011 08:59:32 +0800
+
+calculator (0.1.2-68) unstable; urgency=low
+
+  * fix application directory
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-68
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 11 Mar 2011 10:06:42 +0800
+
+calculator (0.1.2-67) unstable; urgency=low
+
+  * fix the bug
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-67
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 03 Mar 2011 10:15:42 +0800
+
+calculator (0.1.2-66) unstable; urgency=low
+
+  * deupload
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-66
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 24 Feb 2011 16:53:24 +0800
+
+calculator (0.1.2-65) unstable; urgency=low
+
+  * reduce the size of images
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-65
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 24 Feb 2011 15:12:12 +0800
+
+calculator (0.1.2-64) unstable; urgency=low
+
+  * fix CQ bug
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-64
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 17 Feb 2011 13:43:10 +0800
+
+calculator (0.1.2-63) unstable; urgency=low
+
+  * fix the CQ bug
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-63
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 16 Feb 2011 17:00:35 +0800
+
+calculator (0.1.2-62) unstable; urgency=low
+
+  * rollback, the calculator is allowed to be opened as landscape mode
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-62
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 16 Feb 2011 15:58:58 +0800
+
+calculator (0.1.2-61) unstable; urgency=low
+
+  * modify for prevent test and fix bug H0100119893
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-61
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 12 Feb 2011 15:29:21 +0800
+
+calculator (0.1.2-60) unstable; urgency=low
+
+  * fix prevent defect
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-60
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 11 Feb 2011 19:11:16 +0800
+
+calculator (0.1.2-59) unstable; urgency=low
+
+  * add history to calculator
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-59
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 10 Feb 2011 17:46:25 +0800
+
+calculator (0.1.2-58) unstable; urgency=low
+
+  * add history to calculator
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-58
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 10 Feb 2011 16:01:07 +0800
+
+calculator (0.1.2-57) unstable; urgency=low
+
+  * Change icon for new launcher
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-57
+
+ -- Junho Lee <junho4810.lee@samsung.com>  Tue, 08 Feb 2011 21:48:39 +0900
+
+calculator (0.1.2-56) unstable; urgency=low
+
+  * Change icon for new launcher
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-56
+
+ -- Junho Lee <junho4810.lee@samsung.com>  Tue, 08 Feb 2011 21:07:53 +0900
+
+calculator (0.1.2-55) unstable; urgency=low
+
+  * Change icon path
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-55
+
+ -- Junho Lee <junho4810.lee@samsung.com>  Mon, 07 Feb 2011 09:57:18 +0900
+
+calculator (0.1.2-54) unstable; urgency=low
+
+  * rollback the desktop icon
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-54
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 31 Jan 2011 18:40:28 +0800
+
+calculator (0.1.2-53) unstable; urgency=low
+
+  * apply new desktop icon
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-53
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 31 Jan 2011 11:59:30 +0800
+
+calculator (0.1.2-52) unstable; urgency=low
+
+  * fix CQ bugs and change the icon path
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-52
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 29 Jan 2011 18:20:53 +0800
+
+calculator (0.1.2-51) unstable; urgency=low
+
+  * use text only in entry
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-51
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 24 Jan 2011 15:53:00 +0800
+
+calculator (0.1.2-50) unstable; urgency=low
+
+  * remove hard code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-50
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 19 Jan 2011 11:07:50 +0800
+
+calculator (0.1.2-49) unstable; urgency=low
+
+  * remove hard code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-49
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 18 Jan 2011 17:07:18 +0800
+
+calculator (0.1.2-48) unstable; urgency=low
+
+  * remove hard code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-48
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 18 Jan 2011 12:31:54 +0800
+
+calculator (0.1.2-47) unstable; urgency=low
+
+  * change application directory
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-47
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 17 Jan 2011 12:08:57 +0800
+
+calculator (0.1.2-46) unstable; urgency=low
+
+  * change application directory
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-46
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 17 Jan 2011 12:08:50 +0800
+
+calculator (0.1.2-45) unstable; urgency=low
+
+  * change application directory
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-45
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 15 Jan 2011 17:44:37 +0800
+
+calculator (0.1.2-44) unstable; urgency=low
+
+  * remove the API elm_ entry _text_align_set
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-44
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 14 Jan 2011 14:31:47 +0800
+
+calculator (0.1.2-43) unstable; urgency=low
+
+  * prevent pasting image
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-43
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 20 Dec 2010 14:16:10 +0800
+
+calculator (0.1.2-42) unstable; urgency=low
+
+  * increase a version
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-42
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 14 Dec 2010 16:43:37 +0800
+
+calculator (0.1.2-41) unstable; urgency=low
+
+  * for GUI v0.5
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-41
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 11 Dec 2010 13:37:13 +0800
+
+calculator (0.1.2-40) unstable; urgency=low
+
+  * modify git address in changelog
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-40
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 07 Dec 2010 14:52:58 +0800
+
+calculator (0.1.2-39) unstable; urgency=low
+
+  * modify git address in changelog
+  * Git: git@165.213.180.234:slp/apps/c/calculator/
+  * Tag: calculator_0.1.2-39
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 07 Dec 2010 14:38:42 +0800
+
+calculator (0.1.2-38) unstable; urgency=low
+
+  * update
+  * Git: 165.213.180.234:slp/apps/c/calculator/
+  * Tag: calculator_0.1.2-38
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 07 Dec 2010 09:11:24 +0800
+
+calculator (0.1.2-37) unstable; urgency=low
+
+  * update for new git repository
+  * Git: 165.213.180.234:slp/apps/c/calculator/
+  * Tag: calculator_0.1.2-37
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 06 Dec 2010 13:41:51 +0800
+
+calculator (0.1.2-36) unstable; urgency=low
+
+  * fix bug about cut & paste
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-36
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 03 Dec 2010 10:26:40 +0800
+
+calculator (0.1.2-35) unstable; urgency=low
+
+  * fix bugs H0100113897 and H0100113899
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-35
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 02 Dec 2010 10:23:20 +0800
+
+calculator (0.1.2-34) unstable; urgency=low
+
+  * increase a version
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-34
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 29 Nov 2010 14:04:34 +0800
+
+calculator (0.1.2-33) unstable; urgency=low
+
+  * increase a version
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-33
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 26 Nov 2010 15:30:02 +0800
+
+calculator (0.1.2-32) unstable; urgency=low
+
+  * correct debian/deb.com.samsung.calculator.postinst
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-32
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 25 Nov 2010 15:37:34 +0800
+
+calculator (0.1.2-31) unstable; urgency=low
+
+  * comment debian/deb.com.samsung.calculator.postinst
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-31
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 25 Nov 2010 14:14:12 +0800
+
+calculator (0.1.2-30) unstable; urgency=low
+
+  * modify debian/deb.com.samsung.calculator.postinst
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-30
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 25 Nov 2010 14:11:19 +0800
+
+calculator (0.1.2-29) unstable; urgency=low
+
+  * rename postinst file
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-29
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 24 Nov 2010 16:18:13 +0800
+
+calculator (0.1.2-28) unstable; urgency=low
+
+  * rename package name & modify desktop file
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-28
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 24 Nov 2010 12:29:09 +0800
+
+calculator (0.1.2-27) unstable; urgency=low
+
+  * correct help string
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-27
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 23 Nov 2010 09:13:52 +0800
+
+calculator (0.1.2-26) unstable; urgency=low
+
+  * Bracket add automatically.
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-26
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 22 Nov 2010 11:22:06 +0800
+
+calculator (0.1.2-25) unstable; urgency=low
+
+  * modify debian/rules for dbg-package
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-25
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 11 Nov 2010 08:42:02 +0800
+
+calculator (0.1.2-24) unstable; urgency=low
+
+  * remove libui-window dependence
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-24
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 04 Nov 2010 08:50:30 +0800
+
+calculator (0.1.2-23) unstable; urgency=low
+
+  * change in to ln
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-23
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 03 Nov 2010 16:39:54 +0800
+
+calculator (0.1.2-22) unstable; urgency=low
+
+  * fix bugs on CQ and dupload.
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-22
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 01 Nov 2010 13:46:58 +0800
+
+calculator (0.1.2-21) unstable; urgency=low
+
+  * fix a bug about +/- with science number.
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-21
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 30 Oct 2010 17:20:06 +0800
+
+calculator (0.1.2-20) unstable; urgency=low
+
+  * update font size and color
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-20
+
+ -- Zhou Zhibin <zhibin.zhou@samsung.com>  Wed, 27 Oct 2010 16:31:07 +0800
+
+calculator (0.1.2-19) unstable; urgency=low
+
+  * update po files
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-19
+
+ -- Zhou Zhibin <zhibin.zhou@samsung.com>  Tue, 26 Oct 2010 16:37:07 +0800
+
+calculator (0.1.2-18) unstable; urgency=low
+
+  * update po files
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-18
+
+ -- Chen Hanwen <hanwen.chen@samsung.com>  Thu, 21 Oct 2010 16:29:29 +0800
+
+calculator (0.1.2-17) unstable; urgency=low
+
+  * Update main menu icon
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-17
+
+ -- Chen Hanwen <hanwen.chen@samsung.com>  Thu, 21 Oct 2010 10:23:08 +0800
+
+calculator (0.1.2-16) unstable; urgency=low
+
+  * reupload
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-16
+
+ -- Chen Hanwen <hanwen.chen@samsung.com>  Mon, 18 Oct 2010 14:05:32 +0800
+
+calculator (0.1.2-15) unstable; urgency=low
+
+  * update changelog
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-15
+
+ -- Zhou Zhibin <zhibin.zhou@samsung.com>  Mon, 18 Oct 2010 13:48:44 +0800
+
+calculator (0.1.2-14) unstable; urgency=low
+
+  * apply latest GUI and modify desktop.in
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-14
+
+ -- Zhou Zhibin <zhibin.zhou@samsung.com>  Mon, 18 Oct 2010 13:29:09 +0800
+
+calculator (0.1.2-13) unstable; urgency=low
+
+  * apply multi languages: System string
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-13
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 11 Oct 2010 13:14:02 +0800
+
+calculator (0.1.2-12) unstable; urgency=low
+
+  * add ui_idlecapture_exists
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-12
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 11 Oct 2010 10:07:00 +0800
+
+calculator (0.1.2-11) unstable; urgency=low
+
+  * dupload
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-11
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 29 Sep 2010 11:27:25 +0800
+
+calculator (0.1.2-10) unstable; urgency=low
+
+  * scalable ui
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-10
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 27 Sep 2010 16:26:33 +0800
+
+calculator (0.1.2-9) unstable; urgency=low
+
+  * correct idle image
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-9
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 25 Sep 2010 17:21:09 +0800
+
+calculator (0.1.2-8) unstable; urgency=low
+
+  * modify for sin/cos/tan without '('
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-8
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 24 Sep 2010 15:44:18 +0800
+
+calculator (0.1.2-7) unstable; urgency=low
+
+  * set text align to right & clean up help string
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-7
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 23 Sep 2010 16:32:31 +0800
+
+calculator (0.1.2-6) unstable; urgency=low
+
+  * add ui-window dependence for build break
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-6
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 21 Sep 2010 17:17:51 +0800
+
+calculator (0.1.2-5) unstable; urgency=low
+
+  * modify desktop file for  multi-resolution
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-5
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 21 Sep 2010 17:09:39 +0800
+
+calculator (0.1.2-4) unstable; urgency=low
+
+  * fix cursor & clean
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-4
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 15 Sep 2010 10:55:00 +0800
+
+calculator (0.1.2-3) unstable; urgency=low
+
+  * change new theme API
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-3
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 13 Sep 2010 16:48:12 +0800
+
+calculator (0.1.2-2) unstable; urgency=low
+
+  * update
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-2
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 13 Sep 2010 09:55:40 +0800
+
+converter (0.1.2-1) unstable; urgency=low
+
+  * implement new GUI
+  * Git: 165.213.180.234:/git/slp/apps/converter/
+  * Tag: converter_0.1.2-1
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 13 Sep 2010 09:48:29 +0800
+
+calculator (0.1.1-92) unstable; urgency=low
+
+  * change for upload
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.1-92
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 11 Sep 2010 10:38:06 +0800
+
+calculator (0.1.1-91) unstable; urgency=low
+
+  * remove deleting long press
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.1-91
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 09 Sep 2010 13:09:13 +0800
+
+calculator (0.1.1-90) unstable; urgency=low
+
+  * delay deleting timer
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.1-90
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 09 Sep 2010 10:58:06 +0800
+
+calculator (0.1.1-89) unstable; urgency=low
+
+  * update version
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.1-89
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 08 Sep 2010 10:35:01 +0800
+
+calculator (0.1.1-88) unstable; urgency=low
+
+  * optimze launching tmie & fix bug
+  * Git: 165.213.180.234:/git/slp/apps/calcualtor/
+  * Tag: calculator_0.1.1-88
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 08 Sep 2010 10:23:58 +0800
+
+calculator (0.1.1-87) unstable; urgency=low
+
+  * use LED font
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-87
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 04 Sep 2010 16:05:54 +0800
+
+calculator (0.1.1-86) unstable; urgency=low
+
+  * add input area scroller
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-86
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 02 Sep 2010 17:13:54 +0800
+
+calculator (0.1.1-85) unstable; urgency=low
+
+  * add comma
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-85
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 01 Sep 2010 17:19:21 +0800
+
+calculator (0.1.1-84) unstable; urgency=low
+
+  * update input area
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-84
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 31 Aug 2010 14:56:13 +0800
+
+calculator (0.1.1-83) unstable; urgency=low
+
+  * use modeless popup
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-83
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 27 Aug 2010 13:24:59 +0800
+
+calculator (0.1.1-82) unstable; urgency=low
+
+  * fix bug about popup
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-82
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 14 Aug 2010 10:10:36 +0800
+
+calculator (0.1.1-81) unstable; urgency=low
+
+  * apply new appcore frame
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-81
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 05 Aug 2010 09:17:32 +0800
+
+calculator (0.1.1-80) unstable; urgency=low
+
+  * modify exprssion parser
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-80
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 31 Jul 2010 14:17:24 +0800
+
+calculator (0.1.1-79) unstable; urgency=low
+
+  * modify security
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-79
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 28 Jul 2010 09:22:58 +0800
+
+calculator (0.1.1-78) unstable; urgency=low
+
+  * optimize +/- func
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-78
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 27 Jul 2010 13:15:13 +0800
+
+calculator (0.1.1-77) unstable; urgency=low
+
+  * correct cursor position when press +/-
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-77
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 23 Jul 2010 17:14:24 +0800
+
+calculator (0.1.1-76) unstable; urgency=low
+
+  * omit parenthesis of sin/cos/tan
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-76
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 23 Jul 2010 08:20:22 +0800
+
+calculator (0.1.1-75) unstable; urgency=low
+
+  * fix a bug about cursor
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-75
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 20 Jul 2010 09:06:45 +0800
+
+calculator (0.1.1-74) unstable; urgency=low
+
+  * fix version
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-74
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 16 Jul 2010 15:03:56 +0800
+
+calculator (0.1.1-73) unstable; urgency=low
+
+  * Fix bug about system keypad popup
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-73
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 16 Jul 2010 14:00:12 +0800
+
+calculator (0.1.1-72) unstable; urgency=low
+
+  * modify cursor moving.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-72
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 06 July 2010 10:30:00 +0800
+
+calculator (0.1.1-71) unstable; urgency=low
+
+  * back to original expression at violating rules.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-71
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 06 July 2010 10:00:00 +0800
+
+calculator (0.1.1-70) unstable; urgency=low
+
+  * solve repeat tapping same key problem.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-70
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 05 July 2010 16:30:00 +0800
+
+calculator (0.1.1-69) unstable; urgency=low
+
+  * short response time at tapping key.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-69
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 28 June 2010 11:30:00 +0800
+
+calculator (0.1.1-68) unstable; urgency=low
+
+  * auto font after paste.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-68
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 28 June 2010 11:00:00 +0800
+
+calculator (0.1.1-67) unstable; urgency=low
+
+  * add expression length check before tapping '='.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-67
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 24 June 2010 17:40:00 +0800
+
+calculator (0.1.1-66) unstable; urgency=low
+
+  * modify calculator_expression_check function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-66
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 24 June 2010 15:40:00 +0800
+
+calculator (0.1.1-65) unstable; urgency=low
+
+  * modify calculator_expression_check function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-65
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 24 June 2010 11:40:00 +0800
+
+calculator (0.1.1-64) unstable; urgency=low
+
+  * modify calculator_expression_check function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-64
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 24 June 2010 11:00:00 +0800
+
+calculator (0.1.1-63) unstable; urgency=low
+
+  * modify calculator_expression_check function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-63
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 23 June 2010 15:30:00 +0800
+
+calculator (0.1.1-62) unstable; urgency=low
+
+  * modify copy/cut/paste function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-62
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 22 June 2010 17:00:00 +0800
+
+calculator (0.1.1-61) unstable; urgency=low
+
+  * update Widget_Entry_Data structure.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-61
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 18 June 2010 10:30:00 +0800
+
+calculator (0.1.1-60) unstable; urgency=low
+
+  * remove UI-window dependency.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-60
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 18 June 2010 10:30:00 +0800
+
+calculator (0.1.1-59) unstable; urgency=low
+
+  * fix potential overflow.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-59
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 17 June 2010 15:00:00 +0800
+
+calculator (0.1.1-58) unstable; urgency=low
+
+  * solve auto font problem.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-58
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 16 June 2010 10:30:00 +0800
+
+calculator (0.1.1-57) unstable; urgency=low
+
+  * remove applog.h.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-57
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 16 June 2010 9:00:00 +0800
+
+calculator (0.1.1-56) unstable; urgency=low
+
+  * apply new dlog.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-56
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 15 June 2010 15:30:00 +0800
+
+calculator (0.1.1-55) unstable; urgency=low
+
+  * modify debian rules.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-55
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 14 June 2010 21:30:00 +0800
+
+calculator (0.1.1-54) unstable; urgency=low
+
+  * repackage.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-54
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 14 June 2010 21:00:00 +0800
+
+calculator (0.1.1-53) unstable; urgency=low
+
+  * EFL update.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-53
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 11 June 2010 9:30:00 +0800
+
+calculator (0.1.1-52) unstable; urgency=low
+
+  * EFL update.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-52
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 11 June 2010 9:00:00 +0800
+
+calculator (0.1.1-51) unstable; urgency=low
+
+  * solve problem that sometimes more than one chars are deleted at one tapping.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-51
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 9 June 2010 17:00:00 +0800
+
+calculator (0.1.1-50) unstable; urgency=low
+
+  * replace elm_notify widget with elm_popup widget.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-50
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 9 June 2010 9:00:00 +0800
+
+calculator (0.1.1-49) unstable; urgency=low
+
+  * close debug macro.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-49
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tue, 8 June 2010 11:00:00 +0800
+
+calculator (0.1.1-48) unstable; urgency=low
+
+  * remove permission to executable file from calculator.postinst.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-48
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thus, 3 June 2010 13:30:00 +0800
+
+calculator (0.1.1-47) unstable; urgency=low
+
+  * modify font entry width setting to auto font accurately.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-47
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thus, 3 June 2010 10:00:00 +0800
+
+calculator (0.1.1-46) unstable; urgency=low
+
+  * remove some deprecated source code.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-46
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 2 June 2010 10:00:00 +0800
+
+calculator (0.1.1-45) unstable; urgency=low
+
+  * re-fix problem that digits overlap with indicator.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-45
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 1 June 2010 17:00:00 +0800
+
+calculator (0.1.1-44) unstable; urgency=low
+
+  * use appcore to manage app's life cycle.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-44
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 1 June 2010 17:00:00 +0800
+
+calculator (0.1.1-43) unstable; urgency=low
+
+  * fix problem that digits overlap with indicator.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-43
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 1 June 2010 11:00:00 +0800
+
+calculator (0.1.1-42) unstable; urgency=low
+
+  * modify entry for scalable ui.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-42
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 31 May 2010 13:30:00 +0800
+
+calculator (0.1.1-41) unstable; urgency=low
+
+  * remove libprivilege-control package.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-41
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 31 May 2010 10:00:00 +0800
+
+calculator (0.1.1-40) unstable; urgency=low
+
+  * modify entry for font auto suitable.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-40
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Sun, 30 May 2010 11:40:16 +0800
+
+calculator (0.1.1-39) unstable; urgency=low
+
+  * remove sysman and modify for scalable.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-39
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Sat, 29 May 2010 15:00:16 +0800
+
+calculator (0.1.1-38) unstable; urgency=low
+
+  * clean maintainer in debian/control.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-38
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 28 May 2010 15:50:16 +0800
+
+calculator (0.1.1-37) unstable; urgency=low
+
+  * add sysman and libslp-sysman-dev to CMakeLists.txt and debian/control.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-37
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 27 May 2010 13:30:16 +0800
+
+calculator (0.1.1-36) unstable; urgency=low
+
+  * change appfwk to appcore.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-36
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 27 May 2010 22:30:16 +0800
+
+calculator (0.1.1-35) unstable; urgency=low
+
+  * cleanup deprecated functions
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-35
+
+ -- Chen Hanwen <hanwen.chen@samsung.com>  Wed, 19 May 2010 11:08:16 +0800
+
+calculator (0.1.1-34) unstable; urgency=low
+
+  * apply libprivilege-control package.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-34
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 19 May 2010 15:04:12 +0800
+
+calculator (0.1.1-33) unstable; urgency=low
+
+  * EFL update.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-33
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 18 May 2010 17:33:12 +0800
+
+calculator (0.1.1-32) unstable; urgency=low
+
+  * fix UI break problem.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-32
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 26 Apr 2010 16:30:12 +0900
+
+calculator (0.1.1-31) unstable; urgency=low
+
+  * fix flash phenomenon and flash at switching to landscape.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-31
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 21 Apr 2010 11:00:12 +0900
+
+calculator (0.1.1-30) unstable; urgency=low
+
+  * modify calculator.postinst.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-30
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Sat, 17 Apr 2010 17:00:12 +0900
+
+calculator (0.1.1-29) unstable; urgency=low
+
+  * apply permission and ownership
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-29
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 16 Apr 2010 17:00:12 +0900
+
+calculator (0.1.1-28) unstable; urgency=low
+
+  * apply -fpie and -pie build option
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-28
+
+ -- deokjin kim <deokjin81.kim@samsung.com>  Mon, 12 Apr 2010 12:57:12 +0900
+
+calculator (0.1.1-27) unstable; urgency=low
+
+  * fix can't enter calculator problem in p1
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 06 Apr 2010 14:41:47 +0800
+
+calculator (0.1.1-26) unstable; urgency=low
+
+  * bug fix
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 30 Mar 2010 10:41:47 +0800
+
+calculator (0.1.1-25) unstable; urgency=low
+
+  * bug fix
+
+ -- Ge Lu <lu.ge@samsung.com>  Sat, 27 Mar 2010 12:41:47 +0800
+
+calculator (0.1.1-24) unstable; urgency=low
+
+  * Toolchain upgrade.
+
+ -- Ge Lu <lu.ge@samsung.com>  Thu, 25 Mar 2010 13:41:47 +0800
+
+calculator (0.1.1-23) unstable; urgency=low
+
+  * fix bugs about error message.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 23 Mar 2010 20:41:47 +0800
+
+calculator (0.1.1-22) unstable; urgency=low
+
+  * bug fix
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 19 Mar 2010 15:41:47 +0800
+
+calculator (0.1.1-21) unstable; urgency=low
+
+  * apply new rules
+
+ -- Ge Lu <lu.ge@samsung.com>  Thu, 18 Mar 2010 16:41:47 +0800
+
+calculator (0.1.1-20) unstable; urgency=low
+
+  * reupload
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 16 Mar 2010 9:43:43 +0800
+
+calculator (0.1.1-19) unstable; urgency=low
+
+  * fix the bugs about display
+
+ -- Ge Lu <lu.ge@samsung.com>  Mon, 15 Mar 2010 17:43:43 +0800
+
+calculator (0.1.1-18) unstable; urgency=low
+
+  * change theme
+
+ -- Ge Lu <lu.ge@samsung.com>  Thu, 11 Mar 2010 10:40:35 +0800
+
+calculator (0.1.1-17) unstable; urgency=low
+
+  * bug fix.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 09 Mar 2010 12:40:35 +0800
+
+calculator (0.1.1-16) unstable; urgency=low
+
+  * font change.
+
+ -- Ge Lu <lu.ge@samsung.com>  Mon, 01 Mar 2010 11:40:35 +0800
+
+calculator (0.1.1-15) unstable; urgency=low
+
+  * scalable calculator, pannel slide effect.
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 26 Feb 2010 17:30:35 +0800
+
+calculator (0.1.1-14) unstable; urgency=low
+
+  * scalable calculator.
+
+ -- Ge Lu <lu.ge@samsung.com>  Thur, 25 Feb 2010 10:30:35 +0800
+
+calculator (0.1.1-13) unstable; urgency=low
+
+  * apply new requirement.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 23 Feb 2010 18:10:35 +0800
+
+calculator (0.1.1-12) unstable; urgency=low
+
+  * reupload
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 23 Feb 2010 10:10:35 +0800
+
+calculator (0.1.1-11) unstable; urgency=low
+
+  * new indicator.
+
+ -- Ge Lu <lu.ge@samsung.com>  Mon, 22 Feb 2010 15:10:35 +0800
+
+calculator (0.1.1-10) unstable; urgency=low
+
+  * fix the defect, enable softkey pad button work
+
+ -- Jiping Cui <jiping.cui@samsung.com>  Fri, 19 Feb 2010 16:44:35 +0800
+
+calculator (0.1.1-9) unstable; urgency=low
+
+  * flick pannel, rotate with resize.
+
+ -- Ge Lu <lu.ge@samsung.com>  Thu, 11 Feb 2010 9:57:09 +0800
+
+calculator (0.1.1-8) unstable; urgency=low
+
+  * fix BS problem when change win mode.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 09 Feb 2010 16:57:09 +0800
+
+calculator (0.1.1-7) unstable; urgency=low
+
+  * yellow operator.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 09 Feb 2010 15:57:09 +0800
+
+calculator (0.1.1-6) unstable; urgency=low
+
+  * auto font entry. yellow text.
+
+ -- Ge Lu <lu.ge@samsung.com>  Mon, 08 Feb 2010 19:57:09 +0800
+
+calculator (0.1.1-5) unstable; urgency=low
+
+  * increase limit for overflow.
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 05 Feb 2010 19:57:09 +0800
+
+calculator (0.1.1-4) unstable; urgency=low
+
+  * fix pannel overlap with text problem in landscape.
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 05 Feb 2010 19:26:09 +0800
+
+calculator (0.1.1-3) unstable; urgency=low
+
+  * resize popup textblock.
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 05 Feb 2010 13:26:09 +0800
+
+calculator (0.1.1-2) unstable; urgency=low
+
+  * add changelog
+
+ -- jiyoun jeon <jyjeon@samsung.com>  Fri, 05 Feb 2010 10:06:09 +0900
+
+calculator (0.1.1-1) unstable; urgency=low
+
+  * add multi-lingual
+
+ -- jiyoun jeon <jyjeon@samsung.com>  Thu, 04 Feb 2010 20:28:10 +0900
+
+calculator (0.1.0-11.10) unstable; urgency=low
+
+  * support multi-lingual for menutree
+
+ -- jiyoun jeon <jyjeon@samsung.com>  Thu, 04 Feb 2010 13:21:16 +0900
+
+calculator (0.1.0-11.9) unstable; urgency=low
+
+  * add maintainer
+
+ -- Xiang Chun <chun.xiang@samsung.com>  Wed, 03 Feb 2010 22:31:55 +0800
+
+calculator (0.1.0-11.8) unstable; urgency=low
+
+  * use standard layout
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 3 Feb 2010 20:00:14 +0800
+
+calculator (0.1.0-11.7) unstable; urgency=low
+
+  * apply new GUI.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 2 Feb 2010 19:00:14 +0800
+
+calculator (0.1.0-11.6) unstable; urgency=low
+
+  * clean up old api.
+
+ -- Ji-Youn Jeon <jyjeon@samsung.com>  Sat, 30 Jan 2010 18:00:14 +0800
+
+calculator (0.1.0-11.5) unstable; urgency=low
+
+  * apply new fwk API.
+
+ -- Ji-Youn Jeon <jyjeon@samsung.com>  Wed, 27 Jan 2010 10:00:14 +0800
+
+calculator (0.1.0-11.4) unstable; urgency=low
+
+  * apply new cursor
+
+ -- Young-June Woo <june@samsung.com>  Sun, 24 Jan 2010 15:40:40 +0800
+
+calculator (0.1.0-11.3) unstable; urgency=low
+
+  * change popup, cursor
+
+ -- Young-June Woo <june@samsung.com>  Sat, 23 Jan 2010 21:40:40 +0800
+
+calculator (0.1.0-11.2) unstable; urgency=low
+
+  * update icon.
+
+ -- Young-June Woo <june@samsung.com>  Sat, 23 Jan 2010 15:30:40 +0800
+
+calculator (0.1.0-11.1) unstable; urgency=low
+
+  * remove warning.
+
+ -- Young-June Woo <june@samsung.com>  Sat, 23 Jan 2010 11:30:40 +0800
+
+calculator (0.1.0-11) unstable; urgency=low
+
+  * long press, negtive, GUI
+
+ -- Young-June Woo <june@samsung.com>  Fri, 22 Jan 2010 16:30:40 +0800
+
+calculator (0.1.0-10.19) unstable; urgency=low
+
+  * apply new EFL widgets
+
+ -- Young-June Woo <june@samsung.com>  Fri, 22 Jan 2010 13:30:40 +0800
+
+calculator (0.1.0-10.18) unstable; urgency=low
+
+  * update for new efl
+
+ -- Young-June Woo <june@samsung.com>  Fri, 22 Jan 2010 11:00:40 +0800
+
+calculator (0.1.0-10.17) unstable; urgency=low
+
+  * bug fix.
+
+ -- Young-June Woo <june@samsung.com>  Tue, 19 Jan 2010 11:40:40 +0800
+
+calculator (0.1.0-10.16) unstable; urgency=low
+
+  * update desktop file.
+
+ -- Young-June Woo <june@samsung.com>  Mon, 18 Jan 2010 16:40:40 +0800
+
+calculator (0.1.0-10.15.5) unstable; urgency=low
+
+  * Modified text size
+
+ -- Sun Choi <sun0467.choi@samsung.com>  Sat, 16 Jan 2010 16:36:46 +0900
+
+calculator (0.1.0-10.15.4) unstable; urgency=low
+
+  * change control file.
+
+ -- Young-June Woo <june@samsung.com>  Fri, 15 Jan 2010 17:40:40 +0800
+
+calculator (0.1.0-10.15.3) unstable; urgency=low
+
+  * pannel down screen.
+
+ -- GeLu <lu.ge@samsung.com>  Tur, 14 Jan 2010 17:30:40 +0800
+
+calculator (0.1.0-10.15.2) unstable; urgency=low
+
+  * change font, 1/x.
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 13 Jan 2010 21:30:40 +0800
+
+calculator (0.1.0-10.15.1) unstable; urgency=low
+
+  * apply new GUI
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 13 Jan 2010 17:00:40 +0800
+
+calculator (0.1.0-10.15) unstable; urgency=low
+
+  * landscape
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 12 Jan 2010 17:00:40 +0800
+
+calculator (0.1.0-10.14) unstable; urgency=low
+
+  * bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 5 Jan 2010 10:40:40 +0800
+
+calculator (0.1.0-10.13) unstable; urgency=low
+
+  * bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Mon, 4 Jan 2010 11:40:40 +0800
+
+calculator (0.1.0-10.12) unstable; urgency=low
+
+  * add backspace key.
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 30 Dec 2009 10:29:40 +0800
+
+calculator (0.1.0-10.11) unstable; urgency=low
+
+  * add maintainers in control file.
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 29 Dec 2009 17:29:40 +0800
+
+calculator (0.1.0-10.10) unstable; urgency=low
+
+  * truncate result. bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 28 Dec 2009 10:55:40 +0800
+
+calculator (0.1.0-10.9) unstable; urgency=low
+
+  * format input and output
+
+ -- GeLu <lu.ge@samsung.com>  Sat, 26 Dec 2009 14:37:40 +0800
+
+calculator (0.1.0-10.8) unstable; urgency=low
+
+  * add popup to show syntax error.
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 23 Dec 2009 16:05:40 +0800
+
+calculator (0.1.0-10.7) unstable; urgency=low
+
+  * change '()' key
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 22 Dec 2009 21:05:40 +0800
+
+calculator (0.1.0-10.6) unstable; urgency=low
+
+  * max len bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 22 Dec 2009 20:37:40 +0800
+
+calculator (0.1.0-10.5) unstable; urgency=low
+
+  * bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 22 Dec 2009 20:11:40 +0800
+
+calculator (0.1.0-10.4) unstable; urgency=low
+
+  * remove pannel, add "back", remove result area when input
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 22 Dec 2009 16:13:40 +0800
+
+calculator (0.1.0-10.3) unstable; urgency=low
+
+  * prepare demo
+
+ -- GeLu <lu.ge@samsung.com>  Mon, 21 Dec 2009 21:34:40 +0800
+
+calculator (0.1.0-10.2) unstable; urgency=low
+
+  * portrait only
+
+ -- GeLu <lu.ge@samsung.com>  Mon, 21 Dec 2009 18:11:40 +0800
+
+calculator (0.1.0-10.1) unstable; urgency=low
+
+  * landscape UI.
+
+ -- GeLu <lu.ge@samsung.com>  Fri, 18 Dec 2009 12:28:40 +0800
+
+calculator (0.1.0-10) unstable; urgency=low
+
+  * add state control and input check. basic calculator finish.
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 16 Dec 2009 16:55:40 +0800
+
+calculator (0.1.0-9) unstable; urgency=low
+
+  * implement pannel according to GUI, fix abnormal exit bug, fix popup
+    message bug.
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 15 Dec 2009 14:55:40 +0800
+
+calculator (0.1.0-8) unstable; urgency=low
+
+  * Modify API parameter
+
+ -- Seo Hee <heeya.seo@samsung.com>  Tue, 01 Dec 2009 16:01:40 +0900
+
+calculator (0.1.0-7) unstable; urgency=low
+
+  * Bugfix - Change control file
+
+ -- Seo Hee <heeya.seo@samsung.com>  Mon, 23 Nov 2009 16:36:52 +0900
+
+calculator (0.1.0-6) unstable; urgency=low
+
+  * Remove X1, SL
+
+ -- Seo Hee <heeya.seo@samsung.com>  Fri, 20 Nov 2009 20:24:01 +0900
+
+calculator (0.1.0-5) unstable; urgency=low
+
+  * Change control file
+
+ -- Seo Hee <heeya.seo@samsung.com>  Fri, 20 Nov 2009 11:22:01 +0900
+
+calculator (0.1.0-4) unstable; urgency=low
+
+  * debian/changelog
+
+ -- Seo Hee <heeya.seo@samsung.com>  Fri, 20 Nov 2009 09:53:20 +0900
+
+calculator (0.1.0-3) unstable; urgency=low
+
+  * Change copyright
+
+ -- Seo Hee <heeya.seo@samsung.com>  Tue, 17 Nov 2009 16:26:17 +0900
+
+calculator (0.1.0-2) unstable; urgency=low
+
+  * Change section value
+
+ -- Seo Hee <heeya.seo@samsung.com>  Mon, 16 Nov 2009 15:08:19 +0900
+
+calculator (0.1.0-1) unstable; urgency=low
+
+  * Unblock dn_makeshlibs
+
+ -- Seo Hee <heeya.seo@samsung.com>  Mon, 16 Nov 2009 11:31:58 +0900
+
+calculator (0.1.0) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Seo Hee <heeya.seo@samsung.com>  Sat, 14 Nov 2009 17:13:10 +0900
index 05c4062..0f6a904 100644 (file)
@@ -1,7 +1,7 @@
 Source: calculator
 Section: devel
 Priority: extra
-Maintainer: Zhao Danni <danni.zhao@samsung.com>, Yang Qing <qing_.yang@samsung.com>, Zhou Zhibin <zhibin.zhou@samsung.com>
+Maintainer: Zhang Xiang <x1986.zhang@samsung.com>, Wang YongJun <yj.wang@samsung.com>, Zhou Zhibin <zhibin.zhou@samsung.com>
 Uploaders:
 Build-Depends: debhelper (>= 5), libelm-dev, libslp-utilx-dev, dlog-dev, libsvi-dev, libevas-dev, libedje-dev, capi-appfw-application-dev
 Standards-Version: 0.1.0
index 0f08e2f..72ce7c6 100644 (file)
@@ -5,4 +5,4 @@
 @PREFIX@/data
 /opt/share/applications/*
 /opt/share/process-info/*
-
+/opt/share/icons/default/small/*
index 5e411d0..ade4792 100755 (executable)
@@ -101,9 +101,9 @@ binary-indep: build install
 binary-arch: build install
        dh_testdir
        dh_testroot
-       dh_installchangelogs 
-       dh_installdocs
-       dh_installexamples
+#      dh_installchangelogs
+#      dh_installdocs
+#      dh_installexamples
        dh_install --sourcedir=debian/tmp
 #      dh_installmenu
 #      dh_installdebconf       
@@ -117,7 +117,7 @@ binary-arch: build install
 #      dh_installinfo
        dh_installman
        dh_link
-#      dh_strip --dbg-package=org.tizen.calculator-dbg
+       dh_strip --dbg-package=org.tizen.calculator-dbg
        dh_compress
        dh_fixperms
 #      dh_perl
index ba7ecab..89a4e12 100644 (file)
@@ -1,93 +1,87 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
-#define PADDING_TOP_POR         60
-#define PADDING_BOTTOM_POR       50
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#define PADDING_TOP_POR         24
+#define PADDING_BOTTOM_POR       12
 #define PADDING_LEFT_POR        24
 #define PADDING_RIGHT_POR       24
 
+#define PADDING_TOP_LAN         13
+#define PADDING_BOTTOM_LAN       3
+#define PADDING_LEFT_LAN        42
+#define PADDING_RIGHT_LAN       42
 
 group {
     name: "main";
 
     script {
+        public pannel_state;
         public result_show;
     }
 
     parts {
         /* background */
-        //EDC_PART_BG("bg")
-        part {
-               name: "head";
+           part {
+               name: "bg";
                type: RECT;
                mouse_events: 0;
                description {
                    state: "default" 0.0;
                    rel1 { relative: 0.0 0.0;}
-                   rel2 { relative: 1.0 50/1280;}
-                   color: 0 0 0 255;
+                   rel2 { relative: 1.0 (1.0+1.0/1280);}
+                   color:50 50 50 255;
                }
                description {
-                   state: "default" 0.0;
+                   state: "landscape" 0.0;
+                   inherit: "default" 0.0;
                    rel1 { relative: 0.0 0.0;}
-                   rel2 { relative: 0.0 0.0;}
-                   color: 0 0 0 255;
+                   rel2 { relative: 1.0 (1.0+1.0/720);}
+                  color:50 50 50 255;
                }
            }
-           part {
-               name: "bg";
-               type: RECT;
-               mouse_events: 0;
-               description {
-                   state: "default" 0.0;
-                   rel1 { relative: 0.0 50/1280;}
-                   rel2 { relative: 1.0 (1.0+1.0/1280);}
-                   color: 0 0 0 0;
-               }
-           }
-        //EDC_PART_IMAGE("bg_img", "bg", EDC_IMAGE("images/59_calculator_bg.png")) /* DON'T REMOVE */
-        EDC_PART_IMAGE("bg_img", "bg", EDC_IMAGE("images/P04_calculator_bg.png"))
-
-        EDC_PART_PADDING_BR("entry_img_pad_br_por", EDC_SIZE(PADDING_RIGHT_POR, 0), "bg")
 
         /* Input Entry */
         part {
             name: "entry/rect";
-            type: IMAGE;
+            type: RECT;
             mouse_events: 1;
             scale: 1;
 
             description {
                 state: "default" 0.0;
-                visible: 1;
-                min: 0 252;
-                fixed: 0 1;
-                align: 0.5 0;
-                rel1 {relative: 24/720 110/1280;}
-                rel2 {relative: (720-24)/720 (50+60+252)/1280;}
-                image {
-                    normal: "images/P04_calculator_input_bg.png";
-                    border: 24 24 79 24;
-                    border_scale: 1;
-                }
+                rel1 {relative: 0.0 0.0; to:"bg";}
+                rel2 {relative: 1.0 (24+300+13)/(1280-50-114); to:"bg";}
+                color:50 50 50 255;
+            }
+
+            description {
+                state: "landscape" 0.0;
+                inherit: "default" 0.0;
+                min: 0 144;
+                rel1 {relative: 0.0 0.0; to:"bg";}
+                rel2 {relative: 1.0 (0+187)/(720-95-50);  to:"bg";}
             }
         }
 
-        EDC_PART_PADDING_TL("entry_swl_pad_tl_por", EDC_SIZE(32, 38), "entry/rect")
-        EDC_PART_PADDING_BR("entry_swl_pad_br_por", EDC_SIZE(32, 46), "entry/rect")
+        EDC_PART_PADDING_TL("entry_swl_pad_tl_por", EDC_SIZE(32, 24), "entry/rect")
+        EDC_PART_PADDING_BR("entry_swl_pad_br_por", EDC_SIZE(0, 13), "entry/rect")
+        EDC_PART_PADDING_TL("entry_swl_pad_tl_lan", EDC_SIZE(52, 32), "entry/rect")
+        EDC_PART_PADDING_BR("entry_swl_pad_br_lan", EDC_SIZE(20, 47), "entry/rect")
 
         part {
             name: "input/entry";
@@ -99,96 +93,63 @@ group {
                 rel1 {relative: 1.0 1.0; to: "entry_swl_pad_tl_por";}
                 rel2 {relative: 0.0 0.0; to: "entry_swl_pad_br_por";}
             }
-        }
 
-        /* History Entry */
-        part {
-            name: "history_rect_padding_br";
-            type: RECT;
-            mouse_events: 0;
             description {
-                state: "default" 0.0;
-                rel1 {relative: 24/720 (1280-61)/1280;}
-                rel2 {relative: (720-24)/720 1.0;}
-                color: 0 0 0 0;
+                state: "landscape" 0.0;
+                rel1 {relative: 1.0 1.0; to: "entry_swl_pad_tl_lan";}
+                rel2 {relative: 0.0 0.0; to: "entry_swl_pad_br_lan";}
             }
         }
+
+
         part {
             name: "history/rect";
-            type: IMAGE;
+            type: RECT;
             mouse_events: 0;
             description {
                 state: "default" 0.0;
                 visible: 0;
-                rel1 { relative: 0.0 0.0; to: "entry/rect";}
-                rel2 {
-                    relative: 1.0 0.0;
-                    to_x: "entry/rect";
-                    to_y: "history_rect_padding_br";
-                }
-                image {
-                    normal: "images/P04_calculator_input_bg.png";
-                    border: 24 24 79 24;
-                    border_scale: 1;
-                }
+                rel1 {relative:1.0 1.0; to: "bg";}
+                rel2 {relative:1.0 1.0; to: "bg";}
             }
-           description {
+            description {
                 state: "show" 0.0;
-                inherit: "default" 0.0;
                 visible: 1;
-                image {
-                    normal: "images/P04_calculator_input_bg_02.png";
-                    border: 24 24 79 24;
-                    border_scale: 1;
-                }
+                rel1 {relative:0.0 0.0; to: "bg";}
+                rel2 {relative:1.0 1.0; to: "bg";}
+                color: 50 50 50 255;
             }
         }
 
-        EDC_PART_RECT_PADDING("history/rect2", "history/rect",
-           EDC_COOR(32, 32), EDC_COOR(32, 42))
-        EDC_PART_SWALLOW_HIDE_SHOW("history/scroll", "history/rect2")
 
-        /* Keypad */
-        EDC_PART_SWALLOW_SHOW_HIDE("por_pannel/rect", "bg")
-        EDC_PART_SWALLOW_SHOW_HIDE("lan_pannel/rect", "bg")
+        EDC_PART_PADDING_TL("entry_his_pad_tl_por", EDC_SIZE(32, 15), "history/rect")
+        EDC_PART_PADDING_BR("entry_his_pad_br_por", EDC_SIZE(32, 80), "history/rect")
+        EDC_PART_PADDING_TL("entry_his_pad_tl_lan", EDC_SIZE(52, 32), "history/rect")
+        EDC_PART_PADDING_BR("entry_his_pad_br_lan", EDC_SIZE(52, 0), "history/rect")
 
-        part {
-            name: "history/clear/image";
-            type: IMAGE;
+       // EDC_PART_SWALLOW_HIDE_SHOW("history/scroll", "history/rect2")
+        part {
+            name: "history/scroll";
+            type: SWALLOW;
             mouse_events: 1;
             description {
                 state: "default" 0.0;
-                visible: 0;
-
-                rel1 { relative: 0.0 0.0; to: "history/rect"; offset: 32 38;}
-                   rel2 { relative: 0.0 0.0; to: "history/rect"; offset: 96 102;}
-                image {
-                    normal: "images/P04_calculator_button_clear_dim.png";
-                   // border: 24 24 79 24;
-                   // border_scale: 1;
-                }
-            }
-            description {
-                state: "up" 0.0;
-                inherit: "default" 0.0;
                 visible: 1;
-                image {
-                    normal: "images/P04_calculator_button_clear_dim.png";
-
-                }
+                rel1 {relative: 1.0 1.0; to: "entry_his_pad_tl_por";}
+                rel2 {relative: 0.0 0.0; to: "entry_his_pad_br_por";}
             }
 
             description {
-                state: "press" 0.0;
-                inherit: "default" 0.0;
+                state: "landscape" 0.0;
                 visible: 1;
-                image {
-                    normal: "images/P04_calculator_button_clear_press.png";
-
-                }
+                rel1 {relative: 1.0 1.0; to: "entry_his_pad_tl_lan";}
+                rel2 {relative: 0.0 0.0; to: "entry_his_pad_br_lan";}
             }
         }
 
+        /* Keypad */
+        EDC_PART_SWALLOW_SHOW_HIDE("por_pannel/rect", "bg")
+        EDC_PART_SWALLOW_SHOW_HIDE("lan_pannel/rect", "bg")
     }
 
     programs {
@@ -196,6 +157,7 @@ group {
             name: "group_load";
             signal: "load";
             script {
+                set_int(pannel_state, 0);
                 set_int(result_show, 0);
             }
         }
@@ -205,10 +167,7 @@ group {
             signal: "show,hist";
             source: "";
             script {
-                set_state(PART:"history/scroll", "show", 0.0);
                 set_state(PART:"history/rect", "show", 0.0);
-                set_state(PART:"history/clear/image", "up", 0.0);
-
             }
         }
         program {
@@ -216,10 +175,22 @@ group {
             signal: "hide,hist";
             source: "";
             script {
-                set_state(PART:"history/scroll", "default", 0.0);
                 set_state(PART:"history/rect", "default", 0.0);
-                set_state(PART:"history/clear/image", "default", 0.0);
+            }
+        }
 
+        program {
+            name: "to_landscape";
+            signal: "landscape";
+            source: "";
+            script {
+                set_int(pannel_state, 1);
+                set_state(PART:"entry/rect", "landscape", 0.0);
+                set_state(PART:"input/entry", "landscape", 0.0);
+                set_state(PART:"history/scroll", "landscape", 0.0);
+                set_state(PART:"lan_pannel/rect", "default", 0.0);
+                set_state(PART:"por_pannel/rect", "hide", 0.0);
+                set_state(PART:"bg", "landscape", 0.0);
             }
         }
         program {
@@ -227,37 +198,15 @@ group {
             signal: "portrait";
             source: "";
             script {
+                set_int(pannel_state, 0);
                 set_state(PART:"entry/rect", "default", 0.0);
                 set_state(PART:"input/entry", "default", 0.0);
+                set_state(PART:"history/scroll", "default", 0.0);
                 set_state(PART:"lan_pannel/rect", "hide", 0.0);
                 set_state(PART:"por_pannel/rect", "default", 0.0);
-                set_state(PART:"bg_img", "default", 0.0);
                 set_state(PART:"bg", "default", 0.0);
-                set_state(PART:"head", "default", 0.0);
             }
         }
-
-        program {
-                       name: "clear_click";
-                       signal: "mouse,clicked,1";
-                       source: "history/clear/image";
-            action: SIGNAL_EMIT "clicked" "";
-               }
-               program {
-                       name: "clear_click1";
-                       signal: "mouse,down,1";
-                       source: "history/clear/image";
-            action: STATE_SET "press" 0.0;
-                       target: "history/clear/image";
-               }
-               program {
-                       name: "clear_click2";
-                       signal: "mouse,up,1";
-                       source: "history/clear/image";
-            action: STATE_SET "up" 0.0;
-                       target: "history/clear/image";
-               }
-
     }
 }
 
diff --git a/edc/Inc.calculator.pannel.lan.edc b/edc/Inc.calculator.pannel.lan.edc
new file mode 100644 (file)
index 0000000..172552e
--- /dev/null
@@ -0,0 +1,547 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#define BG_H_LAN               (720-95-50)
+#define PANNEL_FULL_W_LAN              1280
+#define PANNEL_FULL_H_LAN              380
+
+#define PANNEL_X_LOFF_LAN              46
+#define PANNEL_Y_LOFF_LAN              12
+#define MIDDLE_MARGIN  48
+
+#define PANNEL_KEY_W_PAD_LAN    4
+#define PANNEL_KEY_H_PAD_LAN    2
+#define PANNEL_KEY_W_LAN               160
+#define PANNEL_KEY_H_LAN               72
+#define PANNEL_KEY_FULL_W_LAN   (PANNEL_KEY_W_LAN+PANNEL_KEY_W_PAD_LAN)
+#define PANNEL_KEY_FULL_H_LAN   (PANNEL_KEY_H_LAN+PANNEL_KEY_H_PAD_LAN)
+
+#define PANNEL_COR_LAN_REF1_X(X,Y)   ((PANNEL_X_LOFF_LAN+PANNEL_KEY_FULL_W_LAN*(Y))/PANNEL_FULL_W_LAN)
+#define PANNEL_COR_LAN_REF1_Y(X,Y)   ((PANNEL_Y_LOFF_LAN+PANNEL_KEY_FULL_H_LAN*(X))/PANNEL_FULL_H_LAN)
+#define PANNEL_COR_LAN_REF2_X(X,Y)   ((PANNEL_X_LOFF_LAN+PANNEL_KEY_FULL_W_LAN*(Y)+PANNEL_KEY_W_LAN)/PANNEL_FULL_W_LAN)
+#define PANNEL_COR_LAN_REF2_Y(X,Y)   ((PANNEL_Y_LOFF_LAN+PANNEL_KEY_FULL_H_LAN*(X)+PANNEL_KEY_H_LAN)/PANNEL_FULL_H_LAN)
+
+#define PANNEL_COR_LAN_REF1_RIGHT_X(X,Y)   ((PANNEL_X_LOFF_LAN+MIDDLE_MARGIN+PANNEL_KEY_FULL_W_LAN*(Y))/PANNEL_FULL_W_LAN)
+#define PANNEL_COR_LAN_REF2_RIGHT_X(X,Y)   ((PANNEL_X_LOFF_LAN+MIDDLE_MARGIN+PANNEL_KEY_FULL_W_LAN*(Y)+PANNEL_KEY_W_LAN)/PANNEL_FULL_W_LAN)
+
+
+
+#define KEYPAD_KEY_IMG_LAN(key_name, relx1, rely1, relx2, rely2, bg_img, bg_img_press, text_img, text_img_press, to_part) \
+    EDC_PART_RECT_RELATIVE(key_name, to_part, relx1, rely1, relx2, rely2)\
+    EDC_PART_BUTTON_IMG(key_name"_bg", key_name, EDC_IMAGE(bg_img), EDC_IMAGE(bg_img))\
+    EDC_PART_BUTTON_IMG(key_name"_txt", key_name, EDC_IMAGE(text_img), EDC_IMAGE(text_img_press))
+
+#define KEYPAD_KEY_TXT_LAN(key_name, relx1, rely1, relx2, rely2, bg_img, bg_img_press, text_txt, text_txt_press, to_part) \
+    EDC_PART_RECT_RELATIVE(key_name, to_part, relx1, rely1, relx2, rely2)\
+    EDC_PART_BUTTON_IMG(key_name"_bg", key_name, EDC_IMAGE(bg_img),EDC_IMAGE(bg_img))\
+    EDC_PART_TEXT(key_name"_txt", key_name, SHADOW, \
+    EDC_TEXT_SHADOW(text_txt, 56, "SLP:style=Roman", "slp_roman", EDC_COLOR(255,255,255,255), EDC_COLOR(0,0,0,255)))\
+
+
+
+#define CALCULATOR_PROGRAMS(part_name) \
+                       program { \
+                               name: "mouse_down_"part_name; \
+                               signal: "mouse,down,1"; \
+                               source:  part_name; \
+                               action:   STATE_SET "pressed" 0.0; \
+                               target: part_name"_bg"; \
+                               target: part_name"_txt"; \
+                       } \
+                       program { \
+                               name: "mouse_up_"part_name; \
+                               signal: "mouse,up,1"; \
+                               source:  part_name; \
+                               action: STATE_SET "default" 0.0; \
+                               target: part_name"_bg"; \
+                               target: part_name"_txt"; \
+                       }
+
+///////////////////// landscape pannel  ////////////////////////////////////////
+       group {
+               name: "lan_pannel";
+               script {
+                       public pannel_state;
+               }
+               parts {
+                       /* rect for pannel keys */
+                       part {
+                               name: "lan_pannel/in";//1280*464
+                               type: RECT;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 0;
+                                       rel1 { relative: 0.0 187/BG_H_LAN;}
+                                       rel2 { relative: 1.0 (BG_H_LAN-8)/BG_H_LAN;}
+                               }
+                               description {
+                                       state: "down" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 1.0; offset: 0 0;}
+                                       rel2 { relative: 1.0 1.0; offset: 0 388;}
+                               }
+                       }
+
+                       part {
+                               name: "lan_pannel/BG";
+                               type: RECT;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 1;
+                                       rel1 { relative: 0.0 187/BG_H_LAN;}
+                                       rel2 { relative: 1.0 1.0; }
+                                       color: 59 70 85 140;
+                               }
+                               description {
+                                       state: "down" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 1.0; offset: 0 0;}
+                                       rel2 { relative: 1.0 1.0; offset: 0 388;}
+                               }
+                       }
+
+                       /* close&open icon */
+                       part {
+                               name: "pannel/icon";
+                               type: IMAGE;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 127/BG_H_LAN;}
+                                       rel2 { relative: 188/1280 (127+60)/BG_H_LAN;}
+                                       image { normal: "images/landscape/P04_calculator_down_handle_land.png"; }
+                               }
+                               description {
+                                       state: "open" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 (BG_H_LAN-60)/BG_H_LAN;}
+                                       rel2 { relative: 188/1280 (BG_H_LAN)/BG_H_LAN;}
+                                       image { normal: "images/landscape/P04_calculator_up_handle_land.png"; }
+                               }
+                               description {
+                                       state: "default_press" 0.0;
+                                       rel1 { relative: 0.0 127/BG_H_LAN;}
+                                       rel2 { relative: 188/1280 (127+60)/BG_H_LAN;}
+                                       image { normal: "images/landscape/P04_calculator_down_handle_land_press.png"; }
+                               }
+                               description {
+                                       state: "open_press" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 (BG_H_LAN-60)/BG_H_LAN;}
+                                       rel2 { relative: 188/1280 (BG_H_LAN)/BG_H_LAN;}
+                                       image { normal: "images/landscape/P04_calculator_up_handle_land_press.png"; }
+                               }
+                       }
+
+
+
+                       /* create pannel keys */
+                       // %, sqrt, x!, c, /, *, <-
+                       KEYPAD_KEY_IMG_LAN("item_fac",
+                               PANNEL_COR_LAN_REF1_X(0,0), PANNEL_COR_LAN_REF1_Y(0,0),
+                               PANNEL_COR_LAN_REF2_X(0,0), PANNEL_COR_LAN_REF2_Y(0,0),
+                               "images/landscape/P04_calculator_btn_03.png", "images/landscape/P04_calculator_btn_03_press.png",
+                               "images/landscape/P04_calculator_btn_03.png", "images/landscape/P04_calculator_btn_03_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_sqr",
+                               PANNEL_COR_LAN_REF1_X(0,1), PANNEL_COR_LAN_REF1_Y(0,1),
+                               PANNEL_COR_LAN_REF2_X(0,1), PANNEL_COR_LAN_REF2_Y(0,1),
+                               "images/landscape/P04_calculator_btn_02.png", "images/landscape/P04_calculator_btn_02_press.png",
+                               "images/landscape/P04_calculator_btn_02.png", "images/landscape/P04_calculator_btn_02_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_per",
+                               PANNEL_COR_LAN_REF1_X(0,2), PANNEL_COR_LAN_REF1_Y(0,2),
+                               PANNEL_COR_LAN_REF2_X(0,2), PANNEL_COR_LAN_REF2_Y(0,2),
+                               "images/landscape/P04_calculator_btn_01.png", "images/landscape/P04_calculator_btn_01_press.png",
+                               "images/landscape/P04_calculator_btn_01.png", "images/landscape/P04_calculator_btn_01_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_c",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(0,3), PANNEL_COR_LAN_REF1_Y(0,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(0,3), PANNEL_COR_LAN_REF2_Y(0,3),
+                               "images/landscape/P04_calculator_btn_16.png", "images/landscape/P04_calculator_btn_16_press.png",
+                               "images/landscape/P04_calculator_btn_16.png", "images/landscape/P04_calculator_btn_16_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_div",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(0,4), PANNEL_COR_LAN_REF1_Y(0,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(0,4), PANNEL_COR_LAN_REF2_Y(0,4),
+                               "images/landscape/P04_calculator_btn_17.png", "images/landscape/P04_calculator_btn_17_press.png",
+                               "images/landscape/P04_calculator_btn_17.png", "images/landscape/P04_calculator_btn_17_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_mul",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(0,5), PANNEL_COR_LAN_REF1_Y(0,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(0,5), PANNEL_COR_LAN_REF2_Y(0,5),
+                               "images/landscape/P04_calculator_btn_18.png", "images/landscape/P04_calculator_btn_18_press.png",
+                               "images/landscape/P04_calculator_btn_18.png", "images/landscape/P04_calculator_btn_18_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_del",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(0,6), PANNEL_COR_LAN_REF1_Y(0,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(0,6), PANNEL_COR_LAN_REF2_Y(0,6),
+                               "images/landscape/P04_calculator_btn_19.png", "images/landscape/P04_calculator_btn_19_press.png",
+                               "images/landscape/P04_calculator_btn_19.png", "images/landscape/P04_calculator_btn_19_press.png",
+                               "lan_pannel/in");
+
+
+                       // sin, cos, tan, 7, 8, 9, -
+                       KEYPAD_KEY_IMG_LAN("item_sin",
+                               PANNEL_COR_LAN_REF1_X(1,0), PANNEL_COR_LAN_REF1_Y(1,0),
+                               PANNEL_COR_LAN_REF2_X(1,0), PANNEL_COR_LAN_REF2_Y(1,0),
+                               "images/landscape/P04_calculator_btn_04.png", "images/landscape/P04_calculator_btn_04_press.png",
+                               "images/landscape/P04_calculator_btn_04.png", "images/landscape/P04_calculator_btn_04_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_cos",
+                               PANNEL_COR_LAN_REF1_X(1,1), PANNEL_COR_LAN_REF1_Y(1,1),
+                               PANNEL_COR_LAN_REF2_X(1,1), PANNEL_COR_LAN_REF2_Y(1,1),
+                               "images/landscape/P04_calculator_btn_05.png", "images/landscape/P04_calculator_btn_05_press.png",
+                               "images/landscape/P04_calculator_btn_05.png", "images/landscape/P04_calculator_btn_05_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_tan",
+                               PANNEL_COR_LAN_REF1_X(1,2), PANNEL_COR_LAN_REF1_Y(1,2),
+                               PANNEL_COR_LAN_REF2_X(1,2), PANNEL_COR_LAN_REF2_Y(1,2),
+                               "images/landscape/P04_calculator_btn_06.png", "images/landscape/P04_calculator_btn_06_press.png",
+                               "images/landscape/P04_calculator_btn_06.png", "images/landscape/P04_calculator_btn_06_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num7",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(1,3), PANNEL_COR_LAN_REF1_Y(1,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(1,3), PANNEL_COR_LAN_REF2_Y(1,3),
+                               "images/landscape/P04_calculator_btn_n07.png", "images/landscape/P04_calculator_btn_n07_press.png",
+                               "images/landscape/P04_calculator_btn_n07.png", "images/landscape/P04_calculator_btn_n07_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num8",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(1,4), PANNEL_COR_LAN_REF1_Y(1,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(1,4), PANNEL_COR_LAN_REF2_Y(1,4),
+                               "images/landscape/P04_calculator_btn_n08.png", "images/landscape/P04_calculator_btn_n08_press.png",
+                               "images/landscape/P04_calculator_btn_n08.png", "images/landscape/P04_calculator_btn_n08_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num9",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(1,5), PANNEL_COR_LAN_REF1_Y(1,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(1,5), PANNEL_COR_LAN_REF2_Y(1,5),
+                               "images/landscape/P04_calculator_btn_n09.png", "images/landscape/P04_calculator_btn_n09_press.png",
+                               "images/landscape/P04_calculator_btn_n09.png", "images/landscape/P04_calculator_btn_n09_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_sub",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(1,6), PANNEL_COR_LAN_REF1_Y(1,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(1,6), PANNEL_COR_LAN_REF2_Y(1,6),
+                               "images/landscape/P04_calculator_btn_20.png", "images/landscape/P04_calculator_btn_20_press.png",
+                               "images/landscape/P04_calculator_btn_20.png", "images/landscape/P04_calculator_btn_20_press.png",
+                               "lan_pannel/in");
+
+                       // ln, log, 1/x, 4, 5, 6, +
+                       KEYPAD_KEY_IMG_LAN("item_ln",
+                               PANNEL_COR_LAN_REF1_X(2,0), PANNEL_COR_LAN_REF1_Y(2,0),
+                               PANNEL_COR_LAN_REF2_X(2,0), PANNEL_COR_LAN_REF2_Y(2,0),
+                               "images/landscape/P04_calculator_btn_07.png", "images/landscape/P04_calculator_btn_07_press.png",
+                               "images/landscape/P04_calculator_btn_07.png", "images/landscape/P04_calculator_btn_07_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_log",
+                               PANNEL_COR_LAN_REF1_X(2,1), PANNEL_COR_LAN_REF1_Y(2,1),
+                               PANNEL_COR_LAN_REF2_X(2,1), PANNEL_COR_LAN_REF2_Y(2,1),
+                               "images/landscape/P04_calculator_btn_08.png", "images/landscape/P04_calculator_btn_08_press.png",
+                               "images/landscape/P04_calculator_btn_08.png", "images/landscape/P04_calculator_btn_08_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_1x",
+                               PANNEL_COR_LAN_REF1_X(2,2), PANNEL_COR_LAN_REF1_Y(2,2),
+                               PANNEL_COR_LAN_REF2_X(2,2), PANNEL_COR_LAN_REF2_Y(2,2),
+                               "images/landscape/P04_calculator_btn_09.png", "images/landscape/P04_calculator_btn_09_press.png",
+                               "images/landscape/P04_calculator_btn_09.png", "images/landscape/P04_calculator_btn_09_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num4",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(2,3), PANNEL_COR_LAN_REF1_Y(2,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(2,3), PANNEL_COR_LAN_REF2_Y(2,3),
+                               "images/landscape/P04_calculator_btn_n04.png", "images/landscape/P04_calculator_btn_n04_press.png",
+                               "images/landscape/P04_calculator_btn_n04.png", "images/landscape/P04_calculator_btn_n04_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num5",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(2,4), PANNEL_COR_LAN_REF1_Y(2,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(2,4), PANNEL_COR_LAN_REF2_Y(2,4),
+                               "images/landscape/P04_calculator_btn_n05.png", "images/landscape/P04_calculator_btn_n05_press.png",
+                               "images/landscape/P04_calculator_btn_n05.png", "images/landscape/P04_calculator_btn_n05_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num6",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(2,5), PANNEL_COR_LAN_REF1_Y(2,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(2,5), PANNEL_COR_LAN_REF2_Y(2,5),
+                               "images/landscape/P04_calculator_btn_n06.png", "images/landscape/P04_calculator_btn_n06_press.png",
+                               "images/landscape/P04_calculator_btn_n06.png", "images/landscape/P04_calculator_btn_n06_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_plus",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(2,6), PANNEL_COR_LAN_REF1_Y(2,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(2,6), PANNEL_COR_LAN_REF2_Y(2,6),
+                               "images/landscape/P04_calculator_btn_21.png", "images/landscape/P04_calculator_btn_21_press.png",
+                               "images/landscape/P04_calculator_btn_21.png", "images/landscape/P04_calculator_btn_21_press.png",
+                               "lan_pannel/in");
+
+
+                       // x^2, 10^2, x^y, 1, 2, 3, ()
+                       KEYPAD_KEY_IMG_LAN("item_x2",
+                               PANNEL_COR_LAN_REF1_X(3,0), PANNEL_COR_LAN_REF1_Y(3,0),
+                               PANNEL_COR_LAN_REF2_X(3,0), PANNEL_COR_LAN_REF2_Y(3,0),
+                               "images/landscape/P04_calculator_btn_10.png", "images/landscape/P04_calculator_btn_10_press.png",
+                               "images/landscape/P04_calculator_btn_10.png", "images/landscape/P04_calculator_btn_10_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_10x",
+                               PANNEL_COR_LAN_REF1_X(3,1), PANNEL_COR_LAN_REF1_Y(3,1),
+                               PANNEL_COR_LAN_REF2_X(3,1), PANNEL_COR_LAN_REF2_Y(3,1),
+                               "images/landscape/P04_calculator_btn_11.png", "images/landscape/P04_calculator_btn_11_press.png",
+                               "images/landscape/P04_calculator_btn_11.png", "images/landscape/P04_calculator_btn_11_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_xy",
+                               PANNEL_COR_LAN_REF1_X(3,2), PANNEL_COR_LAN_REF1_Y(3,2),
+                               PANNEL_COR_LAN_REF2_X(3,2), PANNEL_COR_LAN_REF2_Y(3,2),
+                               "images/landscape/P04_calculator_btn_12.png", "images/landscape/P04_calculator_btn_12_press.png",
+                               "images/landscape/P04_calculator_btn_12.png", "images/landscape/P04_calculator_btn_12_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num1",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(3,3), PANNEL_COR_LAN_REF1_Y(3,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(3,3), PANNEL_COR_LAN_REF2_Y(3,3),
+                               "images/landscape/P04_calculator_btn_n01.png", "images/landscape/P04_calculator_btn_n01_press.png",
+                               "images/landscape/P04_calculator_btn_n01.png", "images/landscape/P04_calculator_btn_n01_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num2",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(3,4), PANNEL_COR_LAN_REF1_Y(3,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(3,4), PANNEL_COR_LAN_REF2_Y(3,4),
+                               "images/landscape/P04_calculator_btn_n02.png", "images/landscape/P04_calculator_btn_n02_press.png",
+                               "images/landscape/P04_calculator_btn_n02.png", "images/landscape/P04_calculator_btn_n02_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num3",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(3,5), PANNEL_COR_LAN_REF1_Y(3,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(3,5), PANNEL_COR_LAN_REF2_Y(3,5),
+                               "images/landscape/P04_calculator_btn_n03.png", "images/landscape/P04_calculator_btn_n03_press.png",
+                               "images/landscape/P04_calculator_btn_n03.png", "images/landscape/P04_calculator_btn_n03_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_brack",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(3,6), PANNEL_COR_LAN_REF1_Y(3,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(3,6), PANNEL_COR_LAN_REF2_Y(3,6),
+                               "images/landscape/P04_calculator_btn_22.png", "images/landscape/P04_calculator_btn_22_press.png",
+                               "images/landscape/P04_calculator_btn_22.png", "images/landscape/P04_calculator_btn_22_press.png",
+                               "lan_pannel/in");
+
+
+                       // abs, pi, e, +/-, 0, ., =
+                       KEYPAD_KEY_IMG_LAN("item_abs",
+                               PANNEL_COR_LAN_REF1_X(4,0), PANNEL_COR_LAN_REF1_Y(4,0),
+                               PANNEL_COR_LAN_REF2_X(4,0), PANNEL_COR_LAN_REF2_Y(4,0),
+                               "images/landscape/P04_calculator_btn_13.png", "images/landscape/P04_calculator_btn_13_press.png",
+                               "images/landscape/P04_calculator_btn_13.png", "images/landscape/P04_calculator_btn_13_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_pi",
+                               PANNEL_COR_LAN_REF1_X(4,1), PANNEL_COR_LAN_REF1_Y(4,1),
+                               PANNEL_COR_LAN_REF2_X(4,1), PANNEL_COR_LAN_REF2_Y(4,1),
+                               "images/landscape/P04_calculator_btn_14.png", "images/landscape/P04_calculator_btn_14_press.png",
+                               "images/landscape/P04_calculator_btn_14.png", "images/landscape/P04_calculator_btn_14_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_e",
+                               PANNEL_COR_LAN_REF1_X(4,2), PANNEL_COR_LAN_REF1_Y(4,2),
+                               PANNEL_COR_LAN_REF2_X(4,2), PANNEL_COR_LAN_REF2_Y(4,2),
+                               "images/landscape/P04_calculator_btn_15.png", "images/landscape/P04_calculator_btn_15_press.png",
+                               "images/landscape/P04_calculator_btn_15.png", "images/landscape/P04_calculator_btn_15_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num0",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(4,3), PANNEL_COR_LAN_REF1_Y(4,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(4,3), PANNEL_COR_LAN_REF2_Y(4,3),
+                               "images/landscape/P04_calculator_btn_n00.png", "images/landscape/P04_calculator_btn_n00_press.png",
+                               "images/landscape/P04_calculator_btn_n00.png", "images/landscape/P04_calculator_btn_n00_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_dot",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(4,4), PANNEL_COR_LAN_REF1_Y(4,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(4,4), PANNEL_COR_LAN_REF2_Y(4,4),
+                               "images/landscape/P04_calculator_btn_25.png", "images/landscape/P04_calculator_btn_25_press.png",
+                               "images/landscape/P04_calculator_btn_25.png", "images/landscape/P04_calculator_btn_25_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_neg",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(4,5), PANNEL_COR_LAN_REF1_Y(4,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(4,5), PANNEL_COR_LAN_REF2_Y(4,5),
+                               "images/landscape/P04_calculator_btn_24.png", "images/landscape/P04_calculator_btn_24_press.png",
+                               "images/landscape/P04_calculator_btn_24.png", "images/landscape/P04_calculator_btn_24_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_eq",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(4,6), PANNEL_COR_LAN_REF1_Y(4,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(4,6), PANNEL_COR_LAN_REF2_Y(4,6),
+                               "images/landscape/P04_calculator_btn_23.png", "images/landscape/P04_calculator_btn_23_press.png",
+                               "images/landscape/P04_calculator_btn_23.png", "images/landscape/P04_calculator_btn_23_press.png",
+                               "lan_pannel/in");
+               }
+
+
+               programs {
+                       program {
+                               name: "group_load";
+                               signal: "load";
+                               script {
+                                       set_int(pannel_state, 1);
+                               }
+                       }
+
+                       program {
+                               name:"icon_tween_down";
+                               action: STATE_SET  "open"  0.0;
+                               transition: ACCELERATE 0.4;
+                               target: "pannel/icon";
+                       }
+
+                       program {
+                               name:"icon_tween_up";
+                               action: STATE_SET  "default"  0.0;
+                               transition: ACCELERATE 0.3;
+                               target: "pannel/icon";
+                       }
+
+                       /* pannel open/close program */
+                       //press up/down
+                       program {
+                               name: "icon_click_down";
+                               signal: "mouse,down,1";
+                               source: "pannel/icon";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               set_state(PART:"pannel/icon", "default_press", 0.0);
+                                       } else {
+                                               set_state(PART:"pannel/icon", "open_press", 0.0);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "icon_click_up";
+                               signal: "mouse,up,1";
+                               source: "pannel/icon";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               run_program(PROGRAM:"icon_tween_down");
+                                               emit("pannel,down", "lan");
+                                               set_int(pannel_state, 0);
+                                       } else {
+                                               run_program(PROGRAM:"icon_tween_up");
+                                               emit("pannel,up", "lan");
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       //flick up/down
+                       program {
+                               name: "icon_click";
+                               signal: "pannel,flick";
+                               source: "";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               emit("pannel,down", "lan");
+                                               set_state(PART:"pannel/icon", "open", 0.0);
+                                               set_int(pannel_state, 0);
+                                       } else {
+                                               emit("pannel,up", "lan");
+                                               set_state(PART:"pannel/icon", "default", 0.0);
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "pannel/down";
+                               signal: "pannel,down";
+                               source: "*";
+                               action: STATE_SET "down" 0.0;
+                               target: "lan_pannel/in";
+                               target: "lan_pannel/BG";
+                               transition: ACCELERATE 0.4;
+                               after: "check_icon_open";
+                       }
+                       program {
+                               name: "pannel/down_i";
+                               signal: "pannel,down_i";
+                               source: "*";
+                               action: STATE_SET "down" 0.0;
+                               target: "lan_pannel/in";
+                               target: "lan_pannel/BG";
+                               after: "check_icon_open";
+                       }
+                       program {
+                               name: "pannel/up";
+                               signal: "pannel,up";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "lan_pannel/in";
+                               target: "lan_pannel/BG";
+                               transition: ACCELERATE 0.3;
+                               after: "check_icon_default";
+                       }
+
+                       program {
+                               name: "check_icon_open";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               set_state(PART:"pannel/icon", "open", 0.0);
+                                               set_int(pannel_state, 0);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "check_icon_default";
+                               script {
+                                       if (get_int(pannel_state) == 0) {
+                                               set_state(PART:"pannel/icon", "default", 0.0);
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       /* programs for pennel items */
+                       CALCULATOR_PROGRAMS("item_per");
+                       CALCULATOR_PROGRAMS("item_sqr");
+                       CALCULATOR_PROGRAMS("item_fac");
+                       CALCULATOR_PROGRAMS("item_c");
+                       CALCULATOR_PROGRAMS("item_div");
+                       CALCULATOR_PROGRAMS("item_mul");
+                       CALCULATOR_PROGRAMS("item_del");
+
+                       CALCULATOR_PROGRAMS("item_sin");
+                       CALCULATOR_PROGRAMS("item_cos");
+                       CALCULATOR_PROGRAMS("item_tan");
+                       CALCULATOR_PROGRAMS("item_num7");
+                       CALCULATOR_PROGRAMS("item_num8");
+                       CALCULATOR_PROGRAMS("item_num9");
+                       CALCULATOR_PROGRAMS("item_sub");
+
+                       CALCULATOR_PROGRAMS("item_ln");
+                       CALCULATOR_PROGRAMS("item_log");
+                       CALCULATOR_PROGRAMS("item_1x");
+                       CALCULATOR_PROGRAMS("item_num4");
+                       CALCULATOR_PROGRAMS("item_num5");
+                       CALCULATOR_PROGRAMS("item_num6");
+                       CALCULATOR_PROGRAMS("item_plus");
+
+                       CALCULATOR_PROGRAMS("item_10x");
+                       CALCULATOR_PROGRAMS("item_x2");
+                       CALCULATOR_PROGRAMS("item_xy");
+                       CALCULATOR_PROGRAMS("item_num1");
+                       CALCULATOR_PROGRAMS("item_num2");
+                       CALCULATOR_PROGRAMS("item_num3");
+                       CALCULATOR_PROGRAMS("item_brack");
+
+                       CALCULATOR_PROGRAMS("item_abs");
+                       CALCULATOR_PROGRAMS("item_pi");
+                       CALCULATOR_PROGRAMS("item_e");
+                       CALCULATOR_PROGRAMS("item_dot");
+                       CALCULATOR_PROGRAMS("item_num0");
+                       CALCULATOR_PROGRAMS("item_neg");
+                       CALCULATOR_PROGRAMS("item_eq");
+               }
+       }
+///////////////////// ladscape pannel  finish ////////////////////////////////////////
+
index 2333f75..ca74fc1 100644 (file)
@@ -1,32 +1,35 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#define BG_H_POR       (1280-114-50)
 #define PANNEL_W_POR                   720
-#define PANNEL_H_POR              (807+61)             //558
+#define PANNEL_H_POR              (682+23)
 #define PANNEL_FULL_W_POR              720
 //#define PANNEL_FULL_H_POR            584
-#define PANNEL_FULL_H_POR              857
+#define PANNEL_FULL_H_POR              (682+12)
 
-#define PANNEL_X_LOFF_POR              24
-#define PANNEL_Y_LOFF_POR              50//???
+#define PANNEL_X_LOFF_POR              16
+#define PANNEL_Y_LOFF_POR              12//???
 
-#define PANNEL_KEY_W_PAD_POR    16
-#define PANNEL_KEY_H_PAD_POR    18
-#define PANNEL_KEY_W_POR               156
-#define PANNEL_KEY_H_POR               147
+#define PANNEL_KEY_W_PAD_POR    8
+#define PANNEL_KEY_H_PAD_POR    8
+#define PANNEL_KEY_W_POR               166
+#define PANNEL_KEY_H_POR               130
 #define PANNEL_KEY_FULL_W_POR   (PANNEL_KEY_W_POR+PANNEL_KEY_W_PAD_POR)
 #define PANNEL_KEY_FULL_H_POR   (PANNEL_KEY_H_POR+PANNEL_KEY_H_PAD_POR)
 
@@ -44,7 +47,7 @@
     EDC_PART_RECT_RELATIVE(key_name, to_part, relx1, rely1, relx2, rely2)\
     EDC_PART_BUTTON_IMG(key_name"_bg", key_name, EDC_IMAGE(bg_img), EDC_IMAGE(bg_img)))\
     EDC_PART_TEXT(key_name"_txt", key_name, SHADOW, \
-    EDC_TEXT_SHADOW(text_txt, 67, "SLP:style=Medium", EDC_COLOR(255,255,255,255), EDC_COLOR(0,0,0,255)))\
+    EDC_TEXT_SHADOW(text_txt, 70, "SLP:style=Medium", "slp_medium", EDC_COLOR(255,255,255,255), EDC_COLOR(0,0,0,255)))\
 
 
 #define KEYPAD_KEY_PROG(key_name) \
                                description {
                                        state: "default" 0.0;
                                        visible: 0;
-                                       rel1 { relative: 0.0 (60+252)/(1280-50));}
-                                       rel2 { relative: 1.0 (1280-61)/1280; }
+                                       rel1 { relative: 0.0 (24+300+13+64)/BG_H_POR; }
+                                       rel2 { relative: 1.0 (BG_H_POR-23)/BG_H_POR; }
                                }
                                description {
                                        state: "down" 0.0;
                                        inherit: "default" 0.0;
-                                       rel1 { relative: 0.0 1.0; offset: 0 0;}
+                                       rel1 { relative: 0.0 1.0; offset: 0 -12;}
                                        rel2 { relative: 1.0 1.0; offset: 0 PANNEL_H_POR;}
                                }
                        }
                        part {
                                name: "por_pannel/BG";
-                               type: IMAGE;
+                               type: RECT;
                                mouse_events: 1;
                                description {
                                        state: "default" 0.0;
                                        visible: 1;
-                                       rel1 { relative: 0.0 (60+50+252)/(1280-50);}
-                                       rel2 { relative: 1.0 1.0; }
-                                       image { normal: "images/P04_calculator_keypad_bg.png"; }
+                                       rel1 { relative: 0.0 (24+300+13+60)/BG_H_POR;}
+                                       rel2 { relative: 1.0 1.1; }
+                                       color: 59 70 85 140;
                                }
                                description {
                                        state: "down" 0.0;
                                        inherit: "default" 0.0;
-                                       rel1 { relative: 0.0 1.0; offset: 0 0;}
+                                       rel1 { relative: 0.0 1.0; offset: 0 -12;}
                                        rel2 { relative: 1.0 1.0; offset: 0 PANNEL_H_POR;}
-                                       image { normal: "images/P04_calculator_keypad_bg.png"; }
                                }
                        }
 
                        part {
                                name: "pannel/icon";
                                type: IMAGE;
-                               mouse_events: 0;
+                               mouse_events: 1;
                                description {
                                        state: "default" 0.0;
-                                       rel1 { relative: (24+32+291)/720 (60+50+252-16-6-20)/1280;}
-                                       rel2 { relative: (24+32+291+26)/720 (60+50+252-6-20)/1280;}
-                                       image { normal: "images/P04_calculator_down_arrow.png"; }
+                                       rel1 { relative: 0.0 (24+300+13)/BG_H_POR;}
+                                       rel2 { relative: 1.0 (24+300+13+64)/BG_H_POR;}
+                                       image { normal: "images/P04_calculator_down_handle.png"; }
                                }
                                description {
                                        state: "open" 0.0;
                                        inherit: "default" 0.0;
-                                       rel1 { relative: (24+32+291)/720 (1280-61-16-6-8)/1280;}
-                                       rel2 { relative: (24+32+291+26)/720 (1280-61-6-8)/1280;}
-                                       image { normal: "images/P04_calculator_up_arrow.png"; }
+                                       rel1 { relative: 0.0 (BG_H_POR-10-64)/BG_H_POR;}
+                                       rel2 { relative: 1.0 (BG_H_POR-10)/BG_H_POR;}
+                                       image { normal: "images/P04_calculator_up_handle.png"; }
                                }
-                       }
-                       part {
-                               name: "pannel/icon/rect";
-                               type: RECT;
-                               mouse_events: 0;
                                description {
-                                       state: "default" 0.0;
-                                       rel1 { relative: (24+32+291-50)/720 (60+50+252-16-6-75)/1280;}
-                                       rel2 { relative: (24+32+291+26+50)/720 (60+50+252-6+75)/1280;}
-                                       color: 0 0 0 0;
+                                       state: "default_press" 0.0;
+                                       rel1 { relative: 0.0  (24+300+13)/BG_H_POR;}
+                                       rel2 { relative: 1.0  (24+300+13+64)/BG_H_POR;}
+                                       image { normal: "images/P04_calculator_down_handle_press.png"; }
                                }
                                description {
-                                       state: "open" 0.0;
+                                       state: "open_press" 0.0;
                                        inherit: "default" 0.0;
-                                       rel1 { relative: (24+32+291-50)/720 (1280-61-6-16-75)/1280;}
-                                       rel2 { relative: (24+32+291+26+50)/720 (1280-61-6+75)/1280;}
+                                       rel1 { relative: 0.0 (BG_H_POR-10-64)/BG_H_POR;}
+                                       rel2 { relative: 1.0 (BG_H_POR-10)/BG_H_POR;}
+                                       image { normal: "images/P04_calculator_up_handle_press.png"; }
                                }
                        }
 
-
                        /* create pannel keys */
                        // c, /, *, <-
                        KEYPAD_KEY_IMG("item_c",
                                "por_pannel/in");
 
 
-                       // 1, 2, 3, -
-                       KEYPAD_KEY_IMG("item_num1",
+                       // 7, 8, 9, -
+                       KEYPAD_KEY_IMG("item_num7",
                                PANNEL_COR_POR_REF1_X(1,0), PANNEL_COR_POR_REF1_Y(1,0),
                 PANNEL_COR_POR_REF2_X(1,0), PANNEL_COR_POR_REF2_Y(1,0),
-                "images/P04_calculator_btn_n01.png", "images/P04_calculator_btn_n01_press.png",
-                               "images/P04_calculator_btn_n01.png", "images/P04_calculator_btn_n01_press.png",
+                               "images/P04_calculator_btn_n07.png", "images/P04_calculator_btn_n07_press.png",
+                               "images/P04_calculator_btn_n07.png", "images/P04_calculator_btn_n07_press.png",
                                "por_pannel/in");
-                       KEYPAD_KEY_IMG("item_num2",
+                       KEYPAD_KEY_IMG("item_num8",
                                PANNEL_COR_POR_REF1_X(1,1), PANNEL_COR_POR_REF1_Y(1,1),
                 PANNEL_COR_POR_REF2_X(1,1), PANNEL_COR_POR_REF2_Y(1,1),
-                "images/P04_calculator_btn_n02.png", "images/P04_calculator_btn_n02_press.png",
-                               "images/P04_calculator_btn_n02.png", "images/P04_calculator_btn_n02_press.png",
+                               "images/P04_calculator_btn_n08.png", "images/P04_calculator_btn_n08_press.png",
+                               "images/P04_calculator_btn_n08.png", "images/P04_calculator_btn_n08_press.png",
                                "por_pannel/in");
-                       KEYPAD_KEY_IMG("item_num3",
+                       KEYPAD_KEY_IMG("item_num9",
                                PANNEL_COR_POR_REF1_X(1,2), PANNEL_COR_POR_REF1_Y(1,2),
                 PANNEL_COR_POR_REF2_X(1,2), PANNEL_COR_POR_REF2_Y(1,2),
-                "images/P04_calculator_btn_n03.png", "images/P04_calculator_btn_n03_press.png",
-                               "images/P04_calculator_btn_n03.png", "images/P04_calculator_btn_n03_press.png",
+                               "images/P04_calculator_btn_n09.png", "images/P04_calculator_btn_n09_press.png",
+                               "images/P04_calculator_btn_n09.png", "images/P04_calculator_btn_n09_press.png",
                                "por_pannel/in");
                        KEYPAD_KEY_IMG("item_sub",
                                PANNEL_COR_POR_REF1_X(1,3), PANNEL_COR_POR_REF1_Y(1,3),
 
 
 
-                       // 7, 8, 9, ()
-                       KEYPAD_KEY_IMG("item_num7",
+                       // 1, 2, 3, ()
+                       KEYPAD_KEY_IMG("item_num1",
                                PANNEL_COR_POR_REF1_X(3,0), PANNEL_COR_POR_REF1_Y(3,0),
                 PANNEL_COR_POR_REF2_X(3,0), PANNEL_COR_POR_REF2_Y(3,0),
-                               "images/P04_calculator_btn_n07.png", "images/P04_calculator_btn_n07_press.png",
-                               "images/P04_calculator_btn_n07.png", "images/P04_calculator_btn_n07_press.png",
+                "images/P04_calculator_btn_n01.png", "images/P04_calculator_btn_n01_press.png",
+                               "images/P04_calculator_btn_n01.png", "images/P04_calculator_btn_n01_press.png",
                                "por_pannel/in");
-                       KEYPAD_KEY_IMG("item_num8",
+                       KEYPAD_KEY_IMG("item_num2",
                                PANNEL_COR_POR_REF1_X(3,1), PANNEL_COR_POR_REF1_Y(3,1),
                 PANNEL_COR_POR_REF2_X(3,1), PANNEL_COR_POR_REF2_Y(3,1),
-                               "images/P04_calculator_btn_n08.png", "images/P04_calculator_btn_n08_press.png",
-                               "images/P04_calculator_btn_n08.png", "images/P04_calculator_btn_n08_press.png",
+                "images/P04_calculator_btn_n02.png", "images/P04_calculator_btn_n02_press.png",
+                               "images/P04_calculator_btn_n02.png", "images/P04_calculator_btn_n02_press.png",
                                "por_pannel/in");
-                       KEYPAD_KEY_IMG("item_num9",
+                       KEYPAD_KEY_IMG("item_num3",
                                PANNEL_COR_POR_REF1_X(3,2), PANNEL_COR_POR_REF1_Y(3,2),
                 PANNEL_COR_POR_REF2_X(3,2), PANNEL_COR_POR_REF2_Y(3,2),
-                               "images/P04_calculator_btn_n09.png", "images/P04_calculator_btn_n09_press.png",
-                               "images/P04_calculator_btn_n09.png", "images/P04_calculator_btn_n09_press.png",
+                "images/P04_calculator_btn_n03.png", "images/P04_calculator_btn_n03_press.png",
+                               "images/P04_calculator_btn_n03.png", "images/P04_calculator_btn_n03_press.png",
                                "por_pannel/in");
                        KEYPAD_KEY_IMG("item_brack",
                                PANNEL_COR_POR_REF1_X(3,3), PANNEL_COR_POR_REF1_Y(3,3),
 
                programs {
                        program {
-                   name: "group_load";
-                   signal: "load";
-                   script {
-                       set_int(pannel_state, 1);
-                   }
-            }
+                               name: "group_load";
+                               signal: "load";
+                               script {
+                                       set_int(pannel_state, 1);
+                               }
+                       }
+
+                       program {
+                               name:"icon_tween_down";
+                               action: STATE_SET  "open"  0.0;
+                               transition: ACCELERATE 0.4;
+                               target: "pannel/icon";
+                       }
+
+                       program {
+                               name:"icon_tween_up";
+                               action: STATE_SET  "default"  0.0;
+                               transition: ACCELERATE 0.3;
+                               target: "pannel/icon";
+                       }
+
                        /* pannel open/close program */
                        //press up/down
                        program {
-                               name: "icon_click2";
-                               //signal: "mouse,down,1";
-                               //source: "pannel/icon";
-                               source: "pannel/icon/rect";
+                               name: "icon_click2_down";
+                               signal: "mouse,down,1";
+                               source: "pannel/icon";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               set_state(PART:"pannel/icon", "default_press", 0.0);
+                                       } else {
+                                               set_state(PART:"pannel/icon", "open_press", 0.0);
+                                       }
+                               }
+                       }
 
+                       program {
+                               name: "icon_click2_up";
+                               signal: "mouse,up,1";
+                               source: "pannel/icon";
                                script {
-                                       if(get_int(pannel_state) == 1)
-                                       {
+                                       if (get_int(pannel_state) == 1) {
+                                               run_program(PROGRAM:"icon_tween_down");
                                                emit("pannel,down", "por");
-                                               set_state(PART:"pannel/icon", "open", 0.0);
-                                               set_state(PART:"pannel/icon/rect", "open", 0.0);
                                                set_int(pannel_state, 0);
-                                       }
-                                       else
-                                       {
+                                       } else {
+                                               run_program(PROGRAM:"icon_tween_up");
                                                emit("pannel,up", "por");
-                                               set_state(PART:"pannel/icon", "default", 0.0);
-                                               set_state(PART:"pannel/icon/rect", "default", 0.0);
                                                set_int(pannel_state, 1);
                                        }
                                }
                        //flick up/down
                        program {
                                name: "icon_click";
-                               //signal: "pannel,flick";
+                               signal: "pannel,flick";
                                source: "";
                                script {
-                                       if(get_int(pannel_state) == 1)
-                                       {
+                                       if (get_int(pannel_state) == 1) {
                                                emit("pannel,down", "por");
                                                set_state(PART:"pannel/icon", "open", 0.0);
-                                               set_state(PART:"pannel/icon/rect", "open", 0.0);
                                                set_int(pannel_state, 0);
-                                       }
-                                       else
-                                       {
+                                       } else {
                                                emit("pannel,up", "por");
                                                set_state(PART:"pannel/icon", "default", 0.0);
-                                               set_state(PART:"pannel/icon/rect", "default", 0.0);
                                                set_int(pannel_state, 1);
                                        }
                                }
                                after: "check_icon_open";
                        }
                        program {
+                               name: "pannel/down_i";
+                               signal: "pannel,down_i";
+                               source: "*";
+                               action: STATE_SET "down" 0.0;
+                               target: "por_pannel/in";
+                               target: "por_pannel/BG";
+                               after: "check_icon_open";
+                       }
+                       program {
                                name: "pannel/up";
                                signal: "pannel,up";
                                source: "*";
                        program {
                                name: "check_icon_open";
                                script {
-                                       if(get_int(pannel_state) == 1)
-                                       {
+                                       if (get_int(pannel_state) == 1) {
                                                set_state(PART:"pannel/icon", "open", 0.0);
-                                               set_state(PART:"pannel/icon/rect", "open", 0.0);
                                                set_int(pannel_state, 0);
                                        }
                                }
                        program {
                                name: "check_icon_default";
                                script {
-                                       if(get_int(pannel_state) == 0)
-                                       {
+                                       if (get_int(pannel_state) == 0) {
                                                set_state(PART:"pannel/icon", "default", 0.0);
-                                               set_state(PART:"pannel/icon/rect", "default", 0.0);
                                                set_int(pannel_state, 1);
                                        }
                                }
index 9583f1f..0348109 100644 (file)
@@ -1,18 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #ifndef __EDC_MACRO_H__
 #define __EDC_MACRO_H__
     image {normal: sImage; border: imgBorder; border_scale: 1;}
 
 /* Text */
-#define EDC_TEXT(sText, nSize, sFont, crFill) \
+#define EDC_TEXT(sText, nSize, sFont, tClass, crFill) \
     color: crFill;\
     text { \
         text: sText; \
         size: nSize; \
         align: 0.5 0.5; \
         font: sFont; \
+               text_calss: tClass; \
     }
 
-#define EDC_TEXT_SHADOW(sText, nSize, sFont, crFill, crShadow) \
+#define EDC_TEXT_SHADOW(sText, nSize, sFont, tClass, crFill, crShadow) \
     color2: crShadow;\
-    EDC_TEXT(sText, nSize, sFont, crFill)
+    EDC_TEXT(sText, nSize, sFont, tClass, crFill)
 
 
 /* Relative */
diff --git a/images/P04_calculator_bg.png b/images/P04_calculator_bg.png
deleted file mode 100644 (file)
index fd412f9..0000000
Binary files a/images/P04_calculator_bg.png and /dev/null differ
index 54852dd..a359535 100644 (file)
Binary files a/images/P04_calculator_btn_01.png and b/images/P04_calculator_btn_01.png differ
index c22eb76..e7a74f3 100644 (file)
Binary files a/images/P04_calculator_btn_01_press.png and b/images/P04_calculator_btn_01_press.png differ
index 1836801..48eb309 100644 (file)
Binary files a/images/P04_calculator_btn_02.png and b/images/P04_calculator_btn_02.png differ
index ca8ae8b..f5d1775 100644 (file)
Binary files a/images/P04_calculator_btn_02_press.png and b/images/P04_calculator_btn_02_press.png differ
index 88b6e3a..2b34de6 100644 (file)
Binary files a/images/P04_calculator_btn_03.png and b/images/P04_calculator_btn_03.png differ
index c5dac66..3a0fa83 100644 (file)
Binary files a/images/P04_calculator_btn_03_press.png and b/images/P04_calculator_btn_03_press.png differ
index 4201fc7..63d68ec 100644 (file)
Binary files a/images/P04_calculator_btn_04.png and b/images/P04_calculator_btn_04.png differ
index 1fc4e9f..4606568 100644 (file)
Binary files a/images/P04_calculator_btn_04_press.png and b/images/P04_calculator_btn_04_press.png differ
index 1680a7a..e7aaef5 100644 (file)
Binary files a/images/P04_calculator_btn_05.png and b/images/P04_calculator_btn_05.png differ
index ed6de3b..45cca0b 100644 (file)
Binary files a/images/P04_calculator_btn_05_press.png and b/images/P04_calculator_btn_05_press.png differ
index a015396..15143b8 100644 (file)
Binary files a/images/P04_calculator_btn_06.png and b/images/P04_calculator_btn_06.png differ
index 9ad7152..f593641 100644 (file)
Binary files a/images/P04_calculator_btn_06_press.png and b/images/P04_calculator_btn_06_press.png differ
index 42b1e03..ff49f90 100644 (file)
Binary files a/images/P04_calculator_btn_07.png and b/images/P04_calculator_btn_07.png differ
index e91bf49..47b09cc 100644 (file)
Binary files a/images/P04_calculator_btn_07_press.png and b/images/P04_calculator_btn_07_press.png differ
index 5a82e76..f3c550b 100644 (file)
Binary files a/images/P04_calculator_btn_08.png and b/images/P04_calculator_btn_08.png differ
index 5cc2f83..f6230e3 100644 (file)
Binary files a/images/P04_calculator_btn_08_press.png and b/images/P04_calculator_btn_08_press.png differ
index 44552db..8538496 100644 (file)
Binary files a/images/P04_calculator_btn_09.png and b/images/P04_calculator_btn_09.png differ
index 453ca45..33b8abe 100644 (file)
Binary files a/images/P04_calculator_btn_09_press.png and b/images/P04_calculator_btn_09_press.png differ
index 0d638d9..79409a3 100644 (file)
Binary files a/images/P04_calculator_btn_10.png and b/images/P04_calculator_btn_10.png differ
index 43bb831..d243091 100644 (file)
Binary files a/images/P04_calculator_btn_10_press.png and b/images/P04_calculator_btn_10_press.png differ
index f64f3c9..1c69966 100644 (file)
Binary files a/images/P04_calculator_btn_n00.png and b/images/P04_calculator_btn_n00.png differ
index c9bde8f..bb8c045 100644 (file)
Binary files a/images/P04_calculator_btn_n00_press.png and b/images/P04_calculator_btn_n00_press.png differ
index fbdfe38..cb20456 100644 (file)
Binary files a/images/P04_calculator_btn_n01.png and b/images/P04_calculator_btn_n01.png differ
index 1f87f11..7b1660b 100644 (file)
Binary files a/images/P04_calculator_btn_n01_press.png and b/images/P04_calculator_btn_n01_press.png differ
index bf7c998..db3f725 100644 (file)
Binary files a/images/P04_calculator_btn_n02.png and b/images/P04_calculator_btn_n02.png differ
index 25c24b7..de1b4af 100644 (file)
Binary files a/images/P04_calculator_btn_n02_press.png and b/images/P04_calculator_btn_n02_press.png differ
index 74dfb64..414c484 100644 (file)
Binary files a/images/P04_calculator_btn_n03.png and b/images/P04_calculator_btn_n03.png differ
index af57892..be8d401 100644 (file)
Binary files a/images/P04_calculator_btn_n03_press.png and b/images/P04_calculator_btn_n03_press.png differ
index 5076092..b5a1d07 100644 (file)
Binary files a/images/P04_calculator_btn_n04.png and b/images/P04_calculator_btn_n04.png differ
index 4a64fa8..7a69390 100644 (file)
Binary files a/images/P04_calculator_btn_n04_press.png and b/images/P04_calculator_btn_n04_press.png differ
index 4789e6c..0605be5 100644 (file)
Binary files a/images/P04_calculator_btn_n05.png and b/images/P04_calculator_btn_n05.png differ
index 825d1fe..2d73744 100644 (file)
Binary files a/images/P04_calculator_btn_n05_press.png and b/images/P04_calculator_btn_n05_press.png differ
index 505bcb7..851e041 100644 (file)
Binary files a/images/P04_calculator_btn_n06.png and b/images/P04_calculator_btn_n06.png differ
index 0e0489b..f73337f 100644 (file)
Binary files a/images/P04_calculator_btn_n06_press.png and b/images/P04_calculator_btn_n06_press.png differ
index a7f5f4f..287ba59 100644 (file)
Binary files a/images/P04_calculator_btn_n07.png and b/images/P04_calculator_btn_n07.png differ
index e0614f6..512982d 100644 (file)
Binary files a/images/P04_calculator_btn_n07_press.png and b/images/P04_calculator_btn_n07_press.png differ
index 1a5548a..e936d80 100644 (file)
Binary files a/images/P04_calculator_btn_n08.png and b/images/P04_calculator_btn_n08.png differ
index 27059b0..bda8637 100644 (file)
Binary files a/images/P04_calculator_btn_n08_press.png and b/images/P04_calculator_btn_n08_press.png differ
index 0f66737..6b5cab0 100644 (file)
Binary files a/images/P04_calculator_btn_n09.png and b/images/P04_calculator_btn_n09.png differ
old mode 100644 (file)
new mode 100755 (executable)
index 9a38fe6..ed409dd
Binary files a/images/P04_calculator_btn_n09_press.png and b/images/P04_calculator_btn_n09_press.png differ
diff --git a/images/P04_calculator_button_clear.png b/images/P04_calculator_button_clear.png
deleted file mode 100644 (file)
index 034e384..0000000
Binary files a/images/P04_calculator_button_clear.png and /dev/null differ
diff --git a/images/P04_calculator_button_clear_dim.png b/images/P04_calculator_button_clear_dim.png
deleted file mode 100644 (file)
index 3f79aa9..0000000
Binary files a/images/P04_calculator_button_clear_dim.png and /dev/null differ
diff --git a/images/P04_calculator_button_clear_focus.png b/images/P04_calculator_button_clear_focus.png
deleted file mode 100644 (file)
index 18e9379..0000000
Binary files a/images/P04_calculator_button_clear_focus.png and /dev/null differ
diff --git a/images/P04_calculator_button_clear_press.png b/images/P04_calculator_button_clear_press.png
deleted file mode 100644 (file)
index e46bf15..0000000
Binary files a/images/P04_calculator_button_clear_press.png and /dev/null differ
old mode 100644 (file)
new mode 100755 (executable)
similarity index 74%
rename from images/P04_calculator_up_arrow.png
rename to images/P04_calculator_down_handle.png
index 49e9d4a..b692928
Binary files a/images/P04_calculator_up_arrow.png and b/images/P04_calculator_down_handle.png differ
diff --git a/images/P04_calculator_down_handle_press.png b/images/P04_calculator_down_handle_press.png
new file mode 100644 (file)
index 0000000..ffe24e1
Binary files /dev/null and b/images/P04_calculator_down_handle_press.png differ
diff --git a/images/P04_calculator_input_bg.png b/images/P04_calculator_input_bg.png
deleted file mode 100644 (file)
index 0845328..0000000
Binary files a/images/P04_calculator_input_bg.png and /dev/null differ
diff --git a/images/P04_calculator_input_bg_02.png b/images/P04_calculator_input_bg_02.png
deleted file mode 100644 (file)
index 2d86705..0000000
Binary files a/images/P04_calculator_input_bg_02.png and /dev/null differ
diff --git a/images/P04_calculator_keypad_bg.png b/images/P04_calculator_keypad_bg.png
deleted file mode 100644 (file)
index d95f173..0000000
Binary files a/images/P04_calculator_keypad_bg.png and /dev/null differ
diff --git a/images/P04_calculator_up_handle.png b/images/P04_calculator_up_handle.png
new file mode 100644 (file)
index 0000000..ddaac85
Binary files /dev/null and b/images/P04_calculator_up_handle.png differ
diff --git a/images/P04_calculator_up_handle_press.png b/images/P04_calculator_up_handle_press.png
new file mode 100644 (file)
index 0000000..f0c5c23
Binary files /dev/null and b/images/P04_calculator_up_handle_press.png differ
diff --git a/images/landscape/P04_calculator_btn_01.png b/images/landscape/P04_calculator_btn_01.png
new file mode 100755 (executable)
index 0000000..a66588d
Binary files /dev/null and b/images/landscape/P04_calculator_btn_01.png differ
diff --git a/images/landscape/P04_calculator_btn_01_press.png b/images/landscape/P04_calculator_btn_01_press.png
new file mode 100644 (file)
index 0000000..ea9da9a
Binary files /dev/null and b/images/landscape/P04_calculator_btn_01_press.png differ
diff --git a/images/landscape/P04_calculator_btn_02.png b/images/landscape/P04_calculator_btn_02.png
new file mode 100644 (file)
index 0000000..2f10a72
Binary files /dev/null and b/images/landscape/P04_calculator_btn_02.png differ
diff --git a/images/landscape/P04_calculator_btn_02_press.png b/images/landscape/P04_calculator_btn_02_press.png
new file mode 100644 (file)
index 0000000..e3274af
Binary files /dev/null and b/images/landscape/P04_calculator_btn_02_press.png differ
diff --git a/images/landscape/P04_calculator_btn_03.png b/images/landscape/P04_calculator_btn_03.png
new file mode 100644 (file)
index 0000000..15ca5ed
Binary files /dev/null and b/images/landscape/P04_calculator_btn_03.png differ
diff --git a/images/landscape/P04_calculator_btn_03_press.png b/images/landscape/P04_calculator_btn_03_press.png
new file mode 100644 (file)
index 0000000..43f2789
Binary files /dev/null and b/images/landscape/P04_calculator_btn_03_press.png differ
diff --git a/images/landscape/P04_calculator_btn_04.png b/images/landscape/P04_calculator_btn_04.png
new file mode 100644 (file)
index 0000000..aa28c4e
Binary files /dev/null and b/images/landscape/P04_calculator_btn_04.png differ
diff --git a/images/landscape/P04_calculator_btn_04_press.png b/images/landscape/P04_calculator_btn_04_press.png
new file mode 100644 (file)
index 0000000..81b1618
Binary files /dev/null and b/images/landscape/P04_calculator_btn_04_press.png differ
diff --git a/images/landscape/P04_calculator_btn_05.png b/images/landscape/P04_calculator_btn_05.png
new file mode 100644 (file)
index 0000000..e068988
Binary files /dev/null and b/images/landscape/P04_calculator_btn_05.png differ
diff --git a/images/landscape/P04_calculator_btn_05_press.png b/images/landscape/P04_calculator_btn_05_press.png
new file mode 100644 (file)
index 0000000..ab17023
Binary files /dev/null and b/images/landscape/P04_calculator_btn_05_press.png differ
diff --git a/images/landscape/P04_calculator_btn_06.png b/images/landscape/P04_calculator_btn_06.png
new file mode 100644 (file)
index 0000000..de3d39d
Binary files /dev/null and b/images/landscape/P04_calculator_btn_06.png differ
diff --git a/images/landscape/P04_calculator_btn_06_press.png b/images/landscape/P04_calculator_btn_06_press.png
new file mode 100644 (file)
index 0000000..29dffc2
Binary files /dev/null and b/images/landscape/P04_calculator_btn_06_press.png differ
diff --git a/images/landscape/P04_calculator_btn_07.png b/images/landscape/P04_calculator_btn_07.png
new file mode 100644 (file)
index 0000000..c11494a
Binary files /dev/null and b/images/landscape/P04_calculator_btn_07.png differ
diff --git a/images/landscape/P04_calculator_btn_07_press.png b/images/landscape/P04_calculator_btn_07_press.png
new file mode 100644 (file)
index 0000000..bc28cc2
Binary files /dev/null and b/images/landscape/P04_calculator_btn_07_press.png differ
diff --git a/images/landscape/P04_calculator_btn_08.png b/images/landscape/P04_calculator_btn_08.png
new file mode 100644 (file)
index 0000000..238680b
Binary files /dev/null and b/images/landscape/P04_calculator_btn_08.png differ
diff --git a/images/landscape/P04_calculator_btn_08_press.png b/images/landscape/P04_calculator_btn_08_press.png
new file mode 100644 (file)
index 0000000..864999d
Binary files /dev/null and b/images/landscape/P04_calculator_btn_08_press.png differ
diff --git a/images/landscape/P04_calculator_btn_09.png b/images/landscape/P04_calculator_btn_09.png
new file mode 100644 (file)
index 0000000..bcabc05
Binary files /dev/null and b/images/landscape/P04_calculator_btn_09.png differ
diff --git a/images/landscape/P04_calculator_btn_09_press.png b/images/landscape/P04_calculator_btn_09_press.png
new file mode 100644 (file)
index 0000000..1982608
Binary files /dev/null and b/images/landscape/P04_calculator_btn_09_press.png differ
diff --git a/images/landscape/P04_calculator_btn_10.png b/images/landscape/P04_calculator_btn_10.png
new file mode 100644 (file)
index 0000000..bf27fc8
Binary files /dev/null and b/images/landscape/P04_calculator_btn_10.png differ
diff --git a/images/landscape/P04_calculator_btn_1011.png b/images/landscape/P04_calculator_btn_1011.png
new file mode 100644 (file)
index 0000000..726751c
Binary files /dev/null and b/images/landscape/P04_calculator_btn_1011.png differ
diff --git a/images/landscape/P04_calculator_btn_10_press.png b/images/landscape/P04_calculator_btn_10_press.png
new file mode 100644 (file)
index 0000000..b6d3f29
Binary files /dev/null and b/images/landscape/P04_calculator_btn_10_press.png differ
diff --git a/images/landscape/P04_calculator_btn_11.png b/images/landscape/P04_calculator_btn_11.png
new file mode 100644 (file)
index 0000000..46d51af
Binary files /dev/null and b/images/landscape/P04_calculator_btn_11.png differ
diff --git a/images/landscape/P04_calculator_btn_11_press.png b/images/landscape/P04_calculator_btn_11_press.png
new file mode 100644 (file)
index 0000000..4b72b7f
Binary files /dev/null and b/images/landscape/P04_calculator_btn_11_press.png differ
diff --git a/images/landscape/P04_calculator_btn_12.png b/images/landscape/P04_calculator_btn_12.png
new file mode 100644 (file)
index 0000000..0c01def
Binary files /dev/null and b/images/landscape/P04_calculator_btn_12.png differ
diff --git a/images/landscape/P04_calculator_btn_12_press.png b/images/landscape/P04_calculator_btn_12_press.png
new file mode 100644 (file)
index 0000000..6c1fb45
Binary files /dev/null and b/images/landscape/P04_calculator_btn_12_press.png differ
diff --git a/images/landscape/P04_calculator_btn_13.png b/images/landscape/P04_calculator_btn_13.png
new file mode 100644 (file)
index 0000000..4c13a57
Binary files /dev/null and b/images/landscape/P04_calculator_btn_13.png differ
diff --git a/images/landscape/P04_calculator_btn_13_press.png b/images/landscape/P04_calculator_btn_13_press.png
new file mode 100644 (file)
index 0000000..b26f02c
Binary files /dev/null and b/images/landscape/P04_calculator_btn_13_press.png differ
diff --git a/images/landscape/P04_calculator_btn_14.png b/images/landscape/P04_calculator_btn_14.png
new file mode 100644 (file)
index 0000000..83f3058
Binary files /dev/null and b/images/landscape/P04_calculator_btn_14.png differ
diff --git a/images/landscape/P04_calculator_btn_14_press.png b/images/landscape/P04_calculator_btn_14_press.png
new file mode 100644 (file)
index 0000000..c70220c
Binary files /dev/null and b/images/landscape/P04_calculator_btn_14_press.png differ
diff --git a/images/landscape/P04_calculator_btn_15.png b/images/landscape/P04_calculator_btn_15.png
new file mode 100644 (file)
index 0000000..4970270
Binary files /dev/null and b/images/landscape/P04_calculator_btn_15.png differ
diff --git a/images/landscape/P04_calculator_btn_15_press.png b/images/landscape/P04_calculator_btn_15_press.png
new file mode 100644 (file)
index 0000000..fbe233b
Binary files /dev/null and b/images/landscape/P04_calculator_btn_15_press.png differ
diff --git a/images/landscape/P04_calculator_btn_16.png b/images/landscape/P04_calculator_btn_16.png
new file mode 100644 (file)
index 0000000..16cad92
Binary files /dev/null and b/images/landscape/P04_calculator_btn_16.png differ
diff --git a/images/landscape/P04_calculator_btn_16_press.png b/images/landscape/P04_calculator_btn_16_press.png
new file mode 100644 (file)
index 0000000..6a2d7d4
Binary files /dev/null and b/images/landscape/P04_calculator_btn_16_press.png differ
diff --git a/images/landscape/P04_calculator_btn_17.png b/images/landscape/P04_calculator_btn_17.png
new file mode 100644 (file)
index 0000000..cc2b329
Binary files /dev/null and b/images/landscape/P04_calculator_btn_17.png differ
diff --git a/images/landscape/P04_calculator_btn_17_press.png b/images/landscape/P04_calculator_btn_17_press.png
new file mode 100644 (file)
index 0000000..c0e99c4
Binary files /dev/null and b/images/landscape/P04_calculator_btn_17_press.png differ
diff --git a/images/landscape/P04_calculator_btn_18.png b/images/landscape/P04_calculator_btn_18.png
new file mode 100644 (file)
index 0000000..d36f63a
Binary files /dev/null and b/images/landscape/P04_calculator_btn_18.png differ
diff --git a/images/landscape/P04_calculator_btn_18_press.png b/images/landscape/P04_calculator_btn_18_press.png
new file mode 100644 (file)
index 0000000..58fbaf7
Binary files /dev/null and b/images/landscape/P04_calculator_btn_18_press.png differ
diff --git a/images/landscape/P04_calculator_btn_19.png b/images/landscape/P04_calculator_btn_19.png
new file mode 100644 (file)
index 0000000..9372bbf
Binary files /dev/null and b/images/landscape/P04_calculator_btn_19.png differ
diff --git a/images/landscape/P04_calculator_btn_19_press.png b/images/landscape/P04_calculator_btn_19_press.png
new file mode 100644 (file)
index 0000000..e62d237
Binary files /dev/null and b/images/landscape/P04_calculator_btn_19_press.png differ
diff --git a/images/landscape/P04_calculator_btn_20.png b/images/landscape/P04_calculator_btn_20.png
new file mode 100644 (file)
index 0000000..5b37951
Binary files /dev/null and b/images/landscape/P04_calculator_btn_20.png differ
diff --git a/images/landscape/P04_calculator_btn_20_press.png b/images/landscape/P04_calculator_btn_20_press.png
new file mode 100644 (file)
index 0000000..02978c8
Binary files /dev/null and b/images/landscape/P04_calculator_btn_20_press.png differ
diff --git a/images/landscape/P04_calculator_btn_21.png b/images/landscape/P04_calculator_btn_21.png
new file mode 100644 (file)
index 0000000..f661a32
Binary files /dev/null and b/images/landscape/P04_calculator_btn_21.png differ
diff --git a/images/landscape/P04_calculator_btn_21_press.png b/images/landscape/P04_calculator_btn_21_press.png
new file mode 100644 (file)
index 0000000..23bf199
Binary files /dev/null and b/images/landscape/P04_calculator_btn_21_press.png differ
diff --git a/images/landscape/P04_calculator_btn_22.png b/images/landscape/P04_calculator_btn_22.png
new file mode 100644 (file)
index 0000000..6f1a8d9
Binary files /dev/null and b/images/landscape/P04_calculator_btn_22.png differ
diff --git a/images/landscape/P04_calculator_btn_22_press.png b/images/landscape/P04_calculator_btn_22_press.png
new file mode 100644 (file)
index 0000000..d168b99
Binary files /dev/null and b/images/landscape/P04_calculator_btn_22_press.png differ
diff --git a/images/landscape/P04_calculator_btn_23.png b/images/landscape/P04_calculator_btn_23.png
new file mode 100644 (file)
index 0000000..d5d495a
Binary files /dev/null and b/images/landscape/P04_calculator_btn_23.png differ
diff --git a/images/landscape/P04_calculator_btn_23_press.png b/images/landscape/P04_calculator_btn_23_press.png
new file mode 100644 (file)
index 0000000..ec56f12
Binary files /dev/null and b/images/landscape/P04_calculator_btn_23_press.png differ
diff --git a/images/landscape/P04_calculator_btn_24.png b/images/landscape/P04_calculator_btn_24.png
new file mode 100644 (file)
index 0000000..73e3d5b
Binary files /dev/null and b/images/landscape/P04_calculator_btn_24.png differ
diff --git a/images/landscape/P04_calculator_btn_24_press.png b/images/landscape/P04_calculator_btn_24_press.png
new file mode 100644 (file)
index 0000000..4571ca0
Binary files /dev/null and b/images/landscape/P04_calculator_btn_24_press.png differ
diff --git a/images/landscape/P04_calculator_btn_25.png b/images/landscape/P04_calculator_btn_25.png
new file mode 100644 (file)
index 0000000..ea0fe61
Binary files /dev/null and b/images/landscape/P04_calculator_btn_25.png differ
diff --git a/images/landscape/P04_calculator_btn_25_press.png b/images/landscape/P04_calculator_btn_25_press.png
new file mode 100644 (file)
index 0000000..9449c53
Binary files /dev/null and b/images/landscape/P04_calculator_btn_25_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n00.png b/images/landscape/P04_calculator_btn_n00.png
new file mode 100644 (file)
index 0000000..6500ede
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n00.png differ
diff --git a/images/landscape/P04_calculator_btn_n00_press.png b/images/landscape/P04_calculator_btn_n00_press.png
new file mode 100644 (file)
index 0000000..8f3f0d1
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n00_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n01.png b/images/landscape/P04_calculator_btn_n01.png
new file mode 100644 (file)
index 0000000..d3e6be3
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n01.png differ
diff --git a/images/landscape/P04_calculator_btn_n01_press.png b/images/landscape/P04_calculator_btn_n01_press.png
new file mode 100644 (file)
index 0000000..c6e62c7
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n01_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n02.png b/images/landscape/P04_calculator_btn_n02.png
new file mode 100644 (file)
index 0000000..a350714
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n02.png differ
diff --git a/images/landscape/P04_calculator_btn_n02_press.png b/images/landscape/P04_calculator_btn_n02_press.png
new file mode 100644 (file)
index 0000000..c368242
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n02_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n03.png b/images/landscape/P04_calculator_btn_n03.png
new file mode 100644 (file)
index 0000000..6404e11
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n03.png differ
diff --git a/images/landscape/P04_calculator_btn_n03_press.png b/images/landscape/P04_calculator_btn_n03_press.png
new file mode 100644 (file)
index 0000000..14bf490
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n03_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n04.png b/images/landscape/P04_calculator_btn_n04.png
new file mode 100644 (file)
index 0000000..541df0e
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n04.png differ
diff --git a/images/landscape/P04_calculator_btn_n04_press.png b/images/landscape/P04_calculator_btn_n04_press.png
new file mode 100644 (file)
index 0000000..4eb5f75
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n04_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n05.png b/images/landscape/P04_calculator_btn_n05.png
new file mode 100644 (file)
index 0000000..f7a5b54
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n05.png differ
diff --git a/images/landscape/P04_calculator_btn_n05_press.png b/images/landscape/P04_calculator_btn_n05_press.png
new file mode 100644 (file)
index 0000000..22c8501
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n05_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n06.png b/images/landscape/P04_calculator_btn_n06.png
new file mode 100644 (file)
index 0000000..a3d9399
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n06.png differ
diff --git a/images/landscape/P04_calculator_btn_n06_press.png b/images/landscape/P04_calculator_btn_n06_press.png
new file mode 100644 (file)
index 0000000..d27b3a3
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n06_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n07.png b/images/landscape/P04_calculator_btn_n07.png
new file mode 100644 (file)
index 0000000..186b40d
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n07.png differ
diff --git a/images/landscape/P04_calculator_btn_n07_press.png b/images/landscape/P04_calculator_btn_n07_press.png
new file mode 100644 (file)
index 0000000..4915e5b
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n07_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n08.png b/images/landscape/P04_calculator_btn_n08.png
new file mode 100644 (file)
index 0000000..bebada7
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n08.png differ
diff --git a/images/landscape/P04_calculator_btn_n08_press.png b/images/landscape/P04_calculator_btn_n08_press.png
new file mode 100644 (file)
index 0000000..fd33ef4
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n08_press.png differ
diff --git a/images/landscape/P04_calculator_btn_n09.png b/images/landscape/P04_calculator_btn_n09.png
new file mode 100644 (file)
index 0000000..0b09b7c
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n09.png differ
diff --git a/images/landscape/P04_calculator_btn_n09_press.png b/images/landscape/P04_calculator_btn_n09_press.png
new file mode 100644 (file)
index 0000000..61eb62b
Binary files /dev/null and b/images/landscape/P04_calculator_btn_n09_press.png differ
diff --git a/images/landscape/P04_calculator_down_handle_land.png b/images/landscape/P04_calculator_down_handle_land.png
new file mode 100644 (file)
index 0000000..5351bec
Binary files /dev/null and b/images/landscape/P04_calculator_down_handle_land.png differ
diff --git a/images/landscape/P04_calculator_down_handle_land_press.png b/images/landscape/P04_calculator_down_handle_land_press.png
new file mode 100644 (file)
index 0000000..0da3bb8
Binary files /dev/null and b/images/landscape/P04_calculator_down_handle_land_press.png differ
diff --git a/images/landscape/P04_calculator_up_handle_land.png b/images/landscape/P04_calculator_up_handle_land.png
new file mode 100644 (file)
index 0000000..15b53a6
Binary files /dev/null and b/images/landscape/P04_calculator_up_handle_land.png differ
diff --git a/images/landscape/P04_calculator_up_handle_land_press.png b/images/landscape/P04_calculator_up_handle_land_press.png
new file mode 100644 (file)
index 0000000..3676bff
Binary files /dev/null and b/images/landscape/P04_calculator_up_handle_land_press.png differ
index d7fc5ae..a7ad73d 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #ifndef __DEF_CALC_EXPRESSION_H_
 #define __DEF_CALC_EXPRESSION_H_
index 0b540aa..1bcc066 100644 (file)
@@ -1,19 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #ifndef __DEF_CALCULATOR_H_
 #define __DEF_CALCULATOR_H_
@@ -24,6 +25,8 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdbool.h>
+#include <dlog.h>
+#include <app.h>
 
 /* Path & Name */
 #define PACKAGE                                "calculator"
@@ -34,6 +37,7 @@
 #define GRP_POR_PANNEL                         "por_pannel"
 #define GRP_LAN_PANNEL                         "lan_pannel"
 
+//#define COM_SAMSUNG_S           "com.samsung.%s"
 
 #define SAVE_HISTORY
 
@@ -60,6 +64,8 @@
 #define EXPONENT                               2.718281828459045235360287471352662497757
 #define RADIAN_FACTOR                  (PI/180)
 #define DEGREEN_FACTOR                         (180/PI)
+#define PI_STR                                 "3.1415926535897932384626433832795"
+#define EXPONENT_STR                   "2.718281828459045235360287471352662497757"
 
 /* Function */
 #ifndef _EDJ
 #define CALCULATOR_MIN_RESULT_SUM2                             (-10e+100)                              /**<minimum num of result sum*/
 
 /* BEGIN DEBUG LOG MACRO */
-//#define _DEBUG
-#ifdef _DEBUG
-/* use prefix 'P' means print */
-#define PTAG fprintf(stdout, "[%s : %d]\n", __FILE__, __LINE__)
-#define PLOG(fmt, arg...) fprintf(stderr, " ## "fmt, ##arg)
+#ifdef  LOG_TAG
+#undef  LOG_TAG
+#endif
+#define LOG_TAG "CALCULATOR"
+
+#define CALC_INFO(fmt, arg...) LOGD("[%s:%d] "fmt,__FILE__, __LINE__, ##arg);
+#define FONT_COLOR_RESET    "\033[0m"
+#define FONT_COLOR_RED      "\033[31m"
+#define FONT_COLOR_GREEN    "\033[32m"
+#define FONT_COLOR_YELLOW   "\033[33m"
+#define FONT_COLOR_BLUE     "\033[34m"
+#define FONT_COLOR_PURPLE   "\033[35m"
+#define FONT_COLOR_CYAN     "\033[36m"
+#define FONT_COLOR_GRAY     "\033[37m"
+
+#define CALC_INFO_RED(fmt, arg...) CALC_INFO(FONT_COLOR_RED fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_GREEN(fmt, arg...) CALC_INFO(FONT_COLOR_GREEN fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_YELLOW(fmt, arg...) CALC_INFO(FONT_COLOR_YELLOW fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_BLUE(fmt, arg...) CALC_INFO(FONT_COLOR_BLUE fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_PURPLE(fmt, arg...) CALC_INFO(FONT_COLOR_PURPLE fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_CYAN(fmt, arg...) CALC_INFO(FONT_COLOR_CYAN fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_GRAY(fmt, arg...) CALC_INFO(FONT_COLOR_GRAY fmt FONT_COLOR_RESET, ##arg)
+
+
+//#define PERFORMANCE_LOG
+#ifdef PERFORMANCE_LOG
+#define DBG(fmt, arg...) SLOGD("%s(%d) " fmt, __FUNCTION__, __LINE__, ##arg)
+#define CALC_FUN_BEG() DBG("START")
+#define CALC_FUN_END() DBG("END")
 #else
-#define PTAG(fmt, arg...)
-#define PLOG(fmt, arg...)
+#define CALC_FUN_BEG()
+#define CALC_FUN_END()
 #endif
-#define CONV_FUNC_IN() PLOG("FUNC: %s .......... in\n", __func__)
-#define CONV_FUNC_OUT() PLOG("FUNC: %s .......... out\n", __func__)
-
-#define ALARM_INFO_RED(fmt, arg...) PLOG(FONT_COLOR_RED fmt FONT_COLOR_RESET, ##arg)
-//#define ALARM_INFO(fmt, arg...) fprintf("[%s:%d] "fmt,__FILE__, __LINE__,##arg);
-
-/* END DEBUG LOG MACRO */
 
 /* Help String of UI Guideline */
 #define CALC_MSG_MAX_DIGIT                 _("IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE")
 
 /* Custtom Error Message */
 #define CALC_MSG_OP_FIRST                  _("IDS_CCL_POP_NO_OPERATOR_ERROR")
-#define CALC_MSG_INVALID_LN                _("Invalid input for ln function")
-#define CALC_MSG_INVALID_XY                _("Invalid param for x^y")
-#define CALC_MSG_INVALID_TAN           _("Invalid param for tan")
-#define CALC_MSG_ENTRY_LIMIT           _("Already had decimal in digit")
-
 #define CALC_MSG_SYNTAX_ERROR       _("IDS_CCL_POP_SYNTAX_ERROR")
-
-/* System String */
-#define SYS_STR_WARNING             dgettext("sys_string", "IDS_COM_POP_WARNING")      /* "Warning" */
-#define SYS_STR_OK                  dgettext("sys_string", "IDS_COM_SK_OK")    /* "OK" */
+#if 0
+#define CALC_MSG_INVALID_LN         _("Invalid input for ln function")
+#define CALC_MSG_INVALID_XY         _("Invalid param for x^y")
+#define CALC_MSG_INVALID_TAN        _("Invalid param for tan")
+#define CALC_MSG_ENTRY_LIMIT        _("Already had decimal in digit")
+#endif
 #define ARRAY_SIZE(array)  (sizeof(array)/sizeof(array[0]))
 
 struct appdata {
@@ -148,12 +168,17 @@ struct appdata {
        Evas_Object *input_entry;
        Evas_Object *por_pannel;
        Evas_Object *lan_pannel;
-       Evas_Object *popup;
        Evas_Object *btn;
 
        Ecore_Timer *calc_timer;
        Ecore_Timer *wrong_timer;
        int svi_handle;
+
+       Evas_Object *nf;
+       Elm_Object_Item *navi_it;
+       Evas_Object *tool_bar;
+       Elm_Object_Item *clear_btn;
+       Elm_Object_Item *invalid_btn;
 #ifdef SAVE_HISTORY
        Evas_Object *hist_scroll;
        Evas_Object *hist_area;
index 581790c..3d163db 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #ifndef __DEF_CALC_STRING_H_
 #define __DEF_CALC_STRING_H_
index c8c5de7..28a52a7 100644 (file)
@@ -1,28 +1,33 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #ifndef __DEF_CALC_VIEW_H_
 #define __DEF_CALC_VIEW_H_
 
 #include "calc-main.h"
+
+/**
+* @struct      history_item
+* @brief       store the calculation history
+*/
 struct history_item  {
-       char expression[MAX_EXPRESSION_LENGTH];
-        char result[MAX_RESULT_LENGTH];
+       char expression[MAX_EXPRESSION_LENGTH]; /**<Store the express in string format */
+       double result;  /**<Store the calculate result in double format */
 };
 
 /**
@@ -49,17 +54,6 @@ void calc_view_load_in_idle(struct appdata *ad);
 * @describe
 *
 *
-* @param    msg
-* @param    ad
-* @return    void
-* @exception
-*/
-void calc_view_show_popup(char *msg, struct appdata *ad);
-
-/**
-* @describe
-*
-*
 * @param    ad
 * @return    void
 * @exception
@@ -75,8 +69,10 @@ void calc_view_revise_input_scroller(struct appdata *ad);
 * @return    void
 * @exception
 */
+//void calc_view_show_result(const char *result, struct appdata *ad, int font_size);
 void calc_view_show_result(const char *result, struct appdata *ad);
 
+
 /**
 * @describe
 *
index e6e11e9..9c216a6 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #ifndef __CALCULATOR_PARSER_H
 #define __CALCULATOR_PARSER_H
@@ -147,7 +147,7 @@ extern "C" {
                OP_LOG,
                OP_1X,
 
-               OP_EX,          // 30
+               OP_10X,         // 30
                OP_X2,
                OP_XY,
 
@@ -170,7 +170,8 @@ extern "C" {
 
 */
        typedef struct {
-               double tmp_result;                                                      /**<store result by temoprary*/
+               //double tmp_result;                                                    /**<store result by temoprary*/
+               char tmp_result[MAX_RESULT_LENGTH];
                calculator_calculate_priority_t node_calcu_priority;
                                                                /**<node calculation priority*/
                operator_type_t operator_type;                                  /**<node operator type*/
diff --git a/org.tizen.calculator.desktop.in b/org.tizen.calculator.desktop.in
deleted file mode 100644 (file)
index 4fbea2c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-Name=calculator
-Type=Application
-Exec=@BINDIR@/@PROJECT_NAME@
-Icon=@PKGNAME@.png
-nodisplay=False
-Version=0.1.0
-X-TIZEN-TaskManage=True
-X-TIZEN-Multiple=False
-X-TIZEN-Removable=False 
-
-Name[en_US]=Calculator
-Name[nl_NL]=Calculator
-Name[de_DE]=Rechner
-Name[zh_HK]=計算機
-Name[zh_CN]=计算器
-Name[ru_RU]=Калькулятор
-Name[ko_KR]=계산기
-Name[zh_TW]=計算器
-Name[ja_JP]=電卓
-Name[es_ES]=Calculadora
-Name[el_GR]=Αριθμομηχανή
-Name[it_IT]=Calcolatrice
-Name[tr_TR]=Hesap makinesi
-Name[pt_PT]=Calculadora
-Name[fr_FR]=Calculatrice
-
-
-
-
index d8a7adb..056893b 100644 (file)
Binary files a/org.tizen.calculator.png and b/org.tizen.calculator.png differ
diff --git a/org.tizen.calculator.xml b/org.tizen.calculator.xml
new file mode 100755 (executable)
index 0000000..a2ce990
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?> \r
+<manifest xmlns="http://tizen.org/ns/packages" package="org.tizen.calculator" version="0.1.12" install-location="internal-only">\r
+       <label>Calculator</label> \r
+       <description>Calculator</description> \r
+       <ui-application appid="org.tizen.calculator" exec="/opt/apps/org.tizen.calculator/bin/calculator" nodisplay="false" multiple="false" type="capp" taskmanage="true">\r
+               <icon>org.tizen.calculator.png</icon> \r
+               <label>Calculator</label> \r
+               <label xml:lang="en-us">Calculator</label> \r
+               <label xml:lang="nl-nl">Calculator</label> \r
+               <label xml:lang="de-de">Rechner</label> \r
+               <label xml:lang="zh-hk">計算機</label> \r
+               <label xml:lang="zh-cn">计算器</label> \r
+               <label xml:lang="ru-ru">Калькулятор</label> \r
+               <label xml:lang="zh-tw">計算器</label> \r
+               <label xml:lang="ja-jp">電卓</label> \r
+               <label xml:lang="es-es">Calculadora</label> \r
+               <label xml:lang="el-gr">Αριθμομηχανή</label> \r
+               <label xml:lang="it-it">Calcolatrice</label> \r
+               <label xml:lang="tr-tr">Hesap makinesi</label> \r
+               <label xml:lang="pt-pt">Calculadora</label> \r
+               <label xml:lang="fr-fr">Calculatrice</label> \r
+               <label xml:lang="ko-kr">계산기</label> \r
+       </ui-application>\r
+</manifest>\r
index 6815770..e1b00a2 100644 (file)
@@ -1,21 +1,25 @@
-%define _app_prefix /opt/apps/org.tizen.calculator
+#sbs-git:slp/apps/c/calculator calculator 0.1.3 3ce35911eff2a8f151a092f346ab7239d7d0658e
+%define PREFIX /opt/apps/org.tizen.calculator
 Name: org.tizen.calculator
-Version:       0.1.4
-Release: 3
-Summary: Calculator application
+Version:    0.1.22
+Release:    1
+Summary: SLP Calculator application
+URL: http://slp-source.sec.samsung.net
 Source: %{name}-%{version}.tar.gz
-License: Flora Software License
-Group: Applications
+License: TIZEN
+Group: tizen/Application
 BuildRequires: cmake
 BuildRequires: pkgconfig(edje)
 BuildRequires: pkgconfig(embryo)
 BuildRequires: pkgconfig(ecore)
 BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(utilX)
-BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(appcore-efl)
 BuildRequires: pkgconfig(appcore-common)
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(svi)
+BuildRequires: pkgconfig(capi-appfw-application)
+
 BuildRequires: gettext-tools
 BuildRequires: edje-bin, embryo-bin
 
@@ -27,30 +31,25 @@ SLP Calculator application
 
 %build
 
-LDFLAGS+="-Wl,--rpath=%{_app_prefix}/lib -Wl,--as-needed -Wl,--hash-style=both"; export LDFLAGS
+LDFLAGS+="-Wl,--rpath=%{PREFIX}/lib -Wl,--as-needed -Wl,--hash-style=both"; export LDFLAGS
 
-cmake . -DCMAKE_INSTALL_PREFIX=%{_app_prefix}
+cmake . -DCMAKE_INSTALL_PREFIX=%{PREFIX}
 
 make %{?jobs:-j%jobs}
 
-%post
-chown -R 5000:5000 %{_app_prefix}/data
-
 %install
 rm -rf %{buildroot}
 %make_install
 
-
-mkdir -p %{buildroot}%{_app_prefix}/data
-
-%find_lang calculator
-
-%files -f calculator.lang
-%{_app_prefix}/data
+%files
+%defattr(-,root,root,-)
+%attr(-,inhouse,inhouse)
 /opt/apps/org.tizen.calculator/bin/calculator
 /opt/apps/org.tizen.calculator/res/edje/calculator.edj
 /opt/apps/org.tizen.calculator/res/edje/calculator_theme.edj
-/opt/apps/org.tizen.calculator/res/icons/default/small/org.tizen.calculator.png
-/opt/share/applications/org.tizen.calculator.desktop
+/opt/share/icons/default/small/org.tizen.calculator.png
+/opt/apps/org.tizen.calculator/res/icons/org.tizen.calculator.png
+/opt/apps/org.tizen.calculator/res/locale/*
+/opt/share/packages/org.tizen.calculator.xml
 /opt/share/process-info/calculator.ini
 
index abba08d..d496ff3 100644 (file)
@@ -1,6 +1,6 @@
 # for i18n
 
-SET(POFILES de_DE.po  el_GR.po  en.po  es_ES.po  fr_FR.po  it_IT.po  ja_JP.po  ko_KR.po  nl_NL.po  pt_PT.po  ru_RU.po  tr_TR.po  zh_CN.po  zh_HK.po  zh_TW.po)
+SET(POFILES ar.po  de_DE.po  fi.po     hu.po     lt.po     pl.po     sl.po     uk.po bg.po  el_GR.po  fr_FR.po  id.po     lv.po     pt_PT.po  sr.po     vi.po ca.po  en.po     he.po     it_IT.po  ms.po     ro.po     sv.po     zh_CN.po cs.po  en_US.po  hi.po     ja_JP.po  nl_NL.po  ru_RU.po  th.po     zh_HK.po da.po  es_ES.po  hr.po     ko_KR.po  no.po     sk.po     tr_TR.po  zh_TW.po)
 
 SET(MSGFMT "/usr/bin/msgfmt")
 
diff --git a/po/ar.po b/po/ar.po
new file mode 100644 (file)
index 0000000..f45c1b9
--- /dev/null
+++ b/po/ar.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "التحويل إلى"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "خطأ لغوي"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "يتوفر عدد 5 أرقام عشرية بحد أقصى"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "يتوفر عدد 20 معامل بحد أقصى"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "تتعذر القسمة على صفر"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "أدخل الرقم أولا"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "خارج المدى"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "إدخال رقم بعد التشغيل"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "إدخال غير صالح لدالة الجذر التربيعي"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "إدخال غير صالح لدالة اللوغاريتم"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "رقم طبيعي فقط لدالة x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "أدخل رقما قبل إدخال الدالة 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "أدخل رقما قبل إدخال الدالة x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "أدخل رقما قبل إدخال الدالة x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "أدخل رقما قبل إدخال الدالة x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "أدخل المزود أولا"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "يتوفر 15 رقمًا بحد أقصى"
+
diff --git a/po/bg.po b/po/bg.po
new file mode 100644 (file)
index 0000000..1f86c09
--- /dev/null
+++ b/po/bg.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Във валута:"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Синтактична грешка"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Възможни до 5 десетични знака"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Възможни до 20 оператора"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Не може да се дели на нула"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Първо въвед. число"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Извън обхват"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Въведете число след оператора"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Невалидно въвеждане за функция квадратен корен"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Невалидно въвеждане за функцията log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Само естествено число за функцията x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Въведете число, преди да изберете функцията 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Въведете число, преди да изберете функцията x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Въведете число, преди да изберете функцията x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Въведете число, преди да изберете функцията x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Първо във. оператор"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Възможни до 15 цифри"
+
diff --git a/po/ca.po b/po/ca.po
new file mode 100644 (file)
index 0000000..ab87aef
--- /dev/null
+++ b/po/ca.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Convertir a"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Error de sintaxi"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Fins a 5 decimals disponibles"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Fins a 20 operadors disponibles"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "No es pot dividir per zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Introdueixi primer el número"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Fora de rang"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Introdueixi un número després de l'operador"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Entrada no vàlida per a la funció d'arrel quadrada"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Entrada no vàlida per a la funció log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Només un número natural per a la funció x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Introdueixi un número abans d'introduir la funció 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Introdueixi un número abans d'introduir la funció x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Introdueixi un número abans d'introduir la funció x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Introdueixi un número abans d'introduir la funció x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Introdueixi primer l'operador"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Fins a 15 dígits disponibles"
+
diff --git a/po/cs.po b/po/cs.po
new file mode 100644 (file)
index 0000000..02f2a40
--- /dev/null
+++ b/po/cs.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Převést na"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Chyba syntaxe"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Až 5 desetinných míst"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Až 20 operátorů"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nulou nelze dělit"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Zadejte číslo"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Mimo rozsah"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Za operátorem zadejte číslo"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neplatné zadání pro funkci odmocniny"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neplatné zadání pro funkci logaritmu"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Pro funkci x! lze použít pouze přirozená čísla"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Před zadáním funkce 1/x zadejte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Před zadáním funkce x^2 zadejte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Před zadáním funkce x^y zadejte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Před zadáním funkce x! zadejte číslo"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Zadejte operátor"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Až 15 cifer"
+
diff --git a/po/da.po b/po/da.po
new file mode 100644 (file)
index 0000000..c83fb3e
--- /dev/null
+++ b/po/da.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konverter til"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaksfejl"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Op til 5 tilgængelige decimaler"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Op til 20 tilgængelige operatører"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Kan ikke dividere med nul"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Indtast først nr."
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Uden for rækkevidde"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Indtast nummer efter operatør"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Ugyldig indtastning til kvadratrodsfunktion"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Ugyldigt input til log-funktion"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Naturligt tal kun for x!-funktionen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Indtast tal inden indtastning af 1/x-funktionen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Indtast tal inden indtastning af x^2-funktionen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Indtast tal inden indtastning af x^y-funktionen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Indtast tal inden indtastning af x!-funktionen"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Tast operator først"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Op til 15 tilgængelige cifre"
+
diff --git a/po/en_US.po b/po/en_US.po
new file mode 100644 (file)
index 0000000..beaa509
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Convert to"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntax error"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Up to 5 decimals available"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Up to 20 operators available"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Unable to divide by zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Enter number first"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Out of range"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Enter number after operator"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Invalid input for square root function"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Invalid input for log function"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Natural number only for x! function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Enter number before inputting 1/x function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Enter number before inputting x^2 function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Enter number before inputting x^y function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Enter number before inputting x! function"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Enter operator first"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Up to 15 digits available"
+
diff --git a/po/fi.po b/po/fi.po
new file mode 100644 (file)
index 0000000..e05734c
--- /dev/null
+++ b/po/fi.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Muunna yksiköksi"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaksivirhe"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Enintään 5 desimaalia"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Enintään 20 operaattoria"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Ei voi jakaa nollalla"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Anna ensin numero"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Liian suuri tai pieni"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Anna numero operaattorin jälkeen"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neliöjuuritoiminnon syötetiedot ovat virheelliset"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Lokitoiminnon syötetiedot ovat virheelliset"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "x!-toiminnon kanssa voi käyttää vain luonnollista numeroa"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Anna numero ennen 1/x-toiminnon käyttöä"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Anna numero ennen x^2-toiminnon käyttöä"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Anna numero ennen x^y-toiminnon käyttöä"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Anna numero ennen x!-toiminnon käyttöä"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Anna ensin operaattori"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Enintään 15 numeroa"
+
diff --git a/po/he.po b/po/he.po
new file mode 100644 (file)
index 0000000..6af1446
--- /dev/null
+++ b/po/he.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "המר ל"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "שגיאת תחביר"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "עד 5 מקומות אחרי הנקודה העשרונית זמינים"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "עד 20 אופרטורים זמינים"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "לא ניתן לחלק באפס"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "הזן מספר תחילה"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "מחוץ לטווח"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "הזן מספר לאחר האופרטור"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "קלט לא חוקי עבור פונקציית שורש ריבועי"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "קלט לא חוקי עבור פונקציית יומן"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "מספר טבעי עבור פונקציית x! בלבד"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "הזן מספר לפני הזנת פונקציית 1‎/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "הזן מספר לפני הזנת פונקציית x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "הזן מספר לפני הזנת פונקציית x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "הזן מספר לפני הזנת פונקציית x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "ראשית הכנס פונקציה"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "עד 15 ספרות זמינות"
+
diff --git a/po/hi.po b/po/hi.po
new file mode 100644 (file)
index 0000000..1d87d32
--- /dev/null
+++ b/po/hi.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "इसमें परिवर्तित करें"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "सिंटैक्स में त्रुटी"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "5 दशमलव तक उपलब्‍ध"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "20 ऑपरेटर तक उपलब्‍ध"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "शून्‍य से विभाजित करने में अक्षम"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "पहले नंबर प्रविष्ट करें"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "सीमा से बाहर"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "ऑपरेटर के बाद नंबर दर्ज करें"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "स्क्वेयर रूट फंक्शन के लिए अमान्‍य इनपुट"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "लॉग फंक्शन के लिए अमान्‍य इनपुट"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "नैचुरल नंबर केवल x! फंक्शन के लिए"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "1/x फंक्शन इनपुट करने के पहले नंबर दर्ज करें"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "x^2 फंक्शन इनपुट करने के पहले नंबर एडिट करें"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "x^y फंक्शन इनपुट करने के पहले नंबर दर्ज करें"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "x! फंक्शन इनपुट करने के पहले नंबर दर्ज करें"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "पहले ऑपरेटर प्रविष्ट करें"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "15 अंकों तक उपलब्‍ध"
+
diff --git a/po/hr.po b/po/hr.po
new file mode 100644 (file)
index 0000000..a2fbaad
--- /dev/null
+++ b/po/hr.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Preračunaj u"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Greška unosa"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Dostupno do 5 decimala"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Dostupno do 20 operatora"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nemoguće dijeljenje s nulom"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Prvo unesite broj"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Izvan dosega"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Unesite broj nakon operatora"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neispravan unos za funkciju korjenovanja"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Netočan unos za funkciju log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Za funkciju x! unesite samo prirodni broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Prije odabira funkcije 1/x unesite broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Prije odabira funkcije x^2 unesite broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Prije odabira funkcije x^y unesite broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Prije odabira funkcije x! unesite broj"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Prvo unesite operaciju"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Dostupno do 15 znamenaka"
+
diff --git a/po/hu.po b/po/hu.po
new file mode 100644 (file)
index 0000000..4fc5b1f
--- /dev/null
+++ b/po/hu.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Átalakítás erre:"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Szintaktikai hiba"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Legfeljebb 5 tizedesjegy lehetséges"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Legfeljebb 20 szolgáltató lehetséges"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nullával nem lehet osztani"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Előbb szám kell"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Túl nagy szám"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "A műveleti jel után adjon meg egy számot"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Érvénytelen bevitel a négyzetgyök függvényhez"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Érvénytelen bevitel a log függvényhez"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Az x! függvény csak természetes számmal használható"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Az 1/x függvény kiválasztása előtt adjon meg egy számot"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Az x^2 függvény kiválasztása előtt adjon meg egy számot"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Az x^y függvény kiválasztása előtt adjon meg egy számot"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Az x! függvény kiválasztása előtt adjon meg egy számot"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Előbb operátor kell"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Legfeljebb 15 számjegy lehetséges"
+
diff --git a/po/id.po b/po/id.po
new file mode 100644 (file)
index 0000000..d35495d
--- /dev/null
+++ b/po/id.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konversi ke"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Kesalahan Syntax"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Hingga 5 desimal tersedia"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Hingga 20 operator tersedia"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Tdk bisa dibagi dengan nol"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Masukkan nomor lebih dulu"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Diluar jangkauan"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Masukkan angka setelah operator"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Masukan tdk berlaku untuk fungsi akar persegi"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Masukan tdk berlaku utk fungsi log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Angka alami hanya untuk x! fungsi"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Masukkan angka sebelum memasukkan fungsi 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Masukkan angka sebelum memasukkan fungsi x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Masukkan angka sebelum memasukkan fungsi x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Masukkan angka sebelum memasukkan fungsi x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Masukkan Operator lebih dulu"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Hingga 15 digit tersedia"
+
diff --git a/po/lt.po b/po/lt.po
new file mode 100644 (file)
index 0000000..ed2ebe2
--- /dev/null
+++ b/po/lt.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Keisti į"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Sintaksės klaida"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Leidžiama iki 5 dešimtainių"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Leidžiama iki 20 operatorių"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Dalyba iš nulio negalima"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Pirma įveskite sk."
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Už ribų"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Po operatoriaus įveskite numerį"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neteisinga įvestis kvadratinės šaknies funkcijai"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neteisinga įvestis log funkcijai"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "x! funkcijai – tik natūralus skaičius"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Skaičių įveskite prieš įvesdami 1/x funkciją"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Skaičių įveskite prieš įvesdami x^2 funkciją"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Skaičių įveskite prieš įvesdami x^y funkciją"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Skaičių įveskite prieš įvesdami x! funkciją"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Pirma įvesk. operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Leidžiama iki 15 skaitmenų"
+
diff --git a/po/lv.po b/po/lv.po
new file mode 100644 (file)
index 0000000..416c09f
--- /dev/null
+++ b/po/lv.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Pārvērst par"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Sintakses kļūda"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Pieejami ne vairāk kā 5 decimālskaitļi"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Pieejami ne vairāk kā 20 operatori"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nevar dalīt ar nulli"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Visp.iev. skaitli"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Ārpus robežas"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Ievadiet skaitli pēc operatora"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Nederīga ievade kvadrātsaknes funkcijā"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Nederīga ievade log funkcijai"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Naturālais skaitlis paredzēts tikai funkcijai x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Ievadiet skaitli pirms funkcijas 1/x ievadīšanas"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Ievadiet skaitli pirms funkcijas x^2 ievadīšanas"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Ievadiet skaitli pirms funkcijas x^y ievadīšanas"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Ievadiet skaitli pirms funkcijas x! ievadīšanas"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Visp. ievad. operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Pieejami ne vairāk kā 15 cipari"
+
diff --git a/po/ms.po b/po/ms.po
new file mode 100644 (file)
index 0000000..027565a
--- /dev/null
+++ b/po/ms.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Tukar kepada"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Ralat sintaks"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Sehingga 5 perpuluhan tersedia"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Sehingga 20 pengendali didpti"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Tdk dpt dibahagi dengan kosong"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Masukkan Nombor Dahulu"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Di luar julat"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Masukkan nombor selepas pengendali"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Kemasukan tdk sah utk fungsi punca kuasa dua"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Kemasukan tdk sah utk fungsi log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Nombor lazim hanya utk fungsi x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Masukkan nombor sebelum masukkan fungsi 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Masukkan nombor sebelum memasukkan fungsi x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Masukkan nombor sebelum memasukkan fungsi x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Masukkan nombor sebelum memasukkan fungsi x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Masukkan Pengendali Dulu"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Sehingga 15 digit tersedia"
+
diff --git a/po/no.po b/po/no.po
new file mode 100644 (file)
index 0000000..04831f7
--- /dev/null
+++ b/po/no.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konverter til"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaksfeil"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Opptil 5 desimaler tilgjengelig"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Opptil 20 operatører tilgjengelig"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Kan ikke dele på null"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Skriv først nummer"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Utenfor verdiområdet"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Angi nummer etter operatør"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Ugyldig inndata for kvadratrotfunksjon"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Ugyldig inndata for loggfunksjon"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Naturlig nummer bare for funksjonen x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Angi nummer før du skriver inn 1/x-funksjonen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Angi nummer før du skriver inn x^2-funksjonen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Angi nummer før du skriver inn x^y-funksjonen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Angi nummer før du skriver inn x!-funksjonen"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Skriv først operatør"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Opptil 15 sifre tilgjengelig"
+
diff --git a/po/pl.po b/po/pl.po
new file mode 100644 (file)
index 0000000..e13b146
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Przelicz na"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Błąd składni"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Dostępne maksymalnie 5 miejsc dziesiętnych"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Dostępne maksymalnie 20 operatorów"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nie można dzielić przez zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Wprowadź liczbę"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Poza zakresem"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Po operatorze wprowadź liczbę"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Nieprawidłowe dane wejściowe do wyliczenia pierwiastka kwadratowego"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Nieprawidłowe dane wejściowe do wyliczenia logarytmu"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Funkcja x! wymaga wyłącznie liczb naturalnych"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Przed wstawieniem funkcji 1/x wprowadź liczbę"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Przed wstawieniem funkcji x^2 wprowadź liczbę"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Przed wstawieniem funkcji x^y wprowadź liczbę"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Przed wstawieniem funkcji x! wprowadź liczbę"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Najpierw wpr. znak"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Dostępne maksymalnie 15 cyfr"
+
diff --git a/po/ro.po b/po/ro.po
new file mode 100644 (file)
index 0000000..08d597c
--- /dev/null
+++ b/po/ro.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Conversie în"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Eroare de sintaxă"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Până la 5 zecimale disponibile"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Până la 20 de operatori disponibili"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Imposibil de împărţit la zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Introd. întâi nr."
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "În afara limitelor"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Introduceţi numărul după operator"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Intrare nevalidă pentru funcţia rădăcină pătrată"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Intrare nevalidă pentru funcţia logaritm"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Numai număr natural pentru funcţia x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Introduceţi numărul înainte de a introduce funcţia 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Introduceţi numărul înainte de a introduce funcţia x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Introduceţi numărul înainte de a introduce funcţia x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Introduceţi numărul înainte de a introduce funcţia x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Introd. întâi operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Până la 15 cifre disponibile"
+
diff --git a/po/sk.po b/po/sk.po
new file mode 100644 (file)
index 0000000..188f8a2
--- /dev/null
+++ b/po/sk.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konvertovať na"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Chyba syntaxe"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "K dispozícii je max. 5 desatinných miest"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "K dispozícii je max. 20 operátorov"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nulou sa nedá deliť"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Najprv zad. číslo"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Mimo rozsahu"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Zadajte číslo po operátore"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neplatný vstup pre funkciu druhej odmocniny"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neplatný vstup pre funkciu log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Prirodzené číslo iba pre funkciu x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Pred zadaním funkcie 1/x zadajte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Pred zadaním funkcie x^2 zadajte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Pred zadaním funkcie x^y zadajte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Pred zadaním funkcie x! zadajte číslo"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Najprv zad. operátor"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "K dispozícii je max. 15 číslic"
+
diff --git a/po/sl.po b/po/sl.po
new file mode 100644 (file)
index 0000000..813320e
--- /dev/null
+++ b/po/sl.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Pretvori v"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Napaka sintakse"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Na voljo je do 5 decimalnih mest"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Na voljo je do 20 operaterjev"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Deljenje z 0 ni mogoče"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Najprej vnesi št."
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Izven dovoljenega obsega"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Vnesite številko za operacijo"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neveljaven vnos za kvadratno korensko funkcijo"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neveljaven vnos za logaritemsko funkcijo"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Za funkcijo x! uporabite samo naravna števila"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Vnesite številko, preden vstavite funkcijo 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Vnesite številko, preden vstavite funkcijo x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Vnesite številko, preden vstavite funkcijo x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Vnesite številko, preden vstavite funkcijo x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Najprej vnes.operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Na voljo je do 15 mest"
+
diff --git a/po/sr.po b/po/sr.po
new file mode 100644 (file)
index 0000000..02f5b3c
--- /dev/null
+++ b/po/sr.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konvertuj u"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Sintaksna greška"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Dostupno do 5 decimala"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Dostupno do 20 operatera"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nemoguće deliti sa nulom"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Prvo unesi broj"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Van opsega"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Unesi broj nakon operatora"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neispravan unos za funkciju kvadratnog korena"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neispravan unos za funkciju log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Funkcija x! zahteva prirodan broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Unesi broj pre unosa funkcije 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Unesi broj pre unosa funkcije x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Unesi broj pre unosa funkcije x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Unesi broj pre unosa funkcije x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Prvo unesi operatora"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Dostupno do 15 cifara"
+
diff --git a/po/sv.po b/po/sv.po
new file mode 100644 (file)
index 0000000..da2781c
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konvertera till"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaxfel"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Upp till 5 decimaler kan anges"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Upp till 20 operatorer kan anges"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Det går inte att dividera med noll"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Ange siffra först"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Utanför område"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Ange nummer efter operatör"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Ogiltig inmatning för kvadratrotsfunktion"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Ogiltig inmatning för loggfunktionen"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Endast naturligt tal för funktionen x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Ange nummer före inmatning av funktionen 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Ange nummer före inmatning av funktionen x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Ange nummer före inmatning av funktionen x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Ange nummer före inmatning av funktionen x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Ange operator först"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Upp till 15 siffror kan anges"
+
diff --git a/po/th.po b/po/th.po
new file mode 100644 (file)
index 0000000..80883f8
--- /dev/null
+++ b/po/th.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "แปลง​เป็น"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "ซิ​นแท็ก​ซ์​ผิด"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "ได้​ถึง 5 ​ตัว​เลข"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "ได้​ถึง 20 ​เครื่อง​หมาย​"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "หาร​ด้วย​\nศูนย์​ไม่​ได้"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "ใส่​เลข​ก่อน"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "อยู่​นอก​ช่วง"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "ใส่​ตัว​เลข​หลัง​โอ​เปอร์เร​เตอร์"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "การ​ใส่​ข้อ​มูล​ฟังก์​ชั่นสแควร์​รู​ท​ไม่​ถูก​ต้อง"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "การ​ใส่​ข้อมูล​ฟังก์ชัน​ล็อก​ไม่​ถูก​ต้อง"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "หมาย​เลข​ธรรมชาติ​สำ​หรับ​ฟัง​ก์ชั่น x! ​เท่า​นั้น"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "ใส่​หมาย​เลข​ก่อน​ใส่​ข้อมูล​ฟังก์ชัน 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "ใส่​หมาย​เลข​ก่อน​ใส่​ข้อมูล​ฟังก์ชัน x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "ใส่​หมาย​เลข​ก่อน​ใส่​ข้อมูล​ฟังก์ชัน x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "ใส่​หมาย​เลข​ก่อน​ใส่​ข้อมูล​ฟังก์ชัน x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "ใส่​เครื่อง​หมาย​ก่อน"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "​ได้​ถึง 15 ​ดิ​จิต"
+
diff --git a/po/uk.po b/po/uk.po
new file mode 100644 (file)
index 0000000..0a85210
--- /dev/null
+++ b/po/uk.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Перетворити на"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Синтаксична помилка"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Доступно до 5 десяткових знаків"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Доступно до 20 операторів"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Неможливо ділити на нуль"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Введіть номер"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Поза мережею"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Введіть номер після оператора"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Хибне введення для функції квадратного кореня"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Хибне введення для функції логарифму"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Лише натуральні числа для функції x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Введіть число перед введенням функції 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Введіть число перед введенням функції x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Введіть число перед введенням функції x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Введіть число перед введенням функції x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Введіть оператора"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Доступно до 15 цифр"
+
diff --git a/po/vi.po b/po/vi.po
new file mode 100644 (file)
index 0000000..2d19a99
--- /dev/null
+++ b/po/vi.po
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Chuyển đổi thành"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Lỗi cú pháp"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Cho phép lên đến 5 số thập phân"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Cho phép lên đến 20 phép tính"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Không chia được cho 0"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Nhập số trước"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Số quá lớn"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Nhập số sau toán tử"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Đầu vào không hợp lệ cho hàm bậc hai"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Đầu vào không hợp lệ cho hàm lôgarít"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Số tự nhiên chỉ cho hàm x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Nhập số trước khi nhập hàm 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Nhập số trước khi nhập hàm x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Nhập số trước khi nhập hàm x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Nhập số trước khi nhập hàm x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Nhập phép tính trước"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Cho phép tối đa 15 số"
+
index e4e0a0b..b82070d 100644 (file)
@@ -1,19 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #include <string.h>
 #include <stdbool.h>
 #define DIVIDE                                         "\xc3\xb7"
 #define MULTIPLY                               "\xc3\x97"
 #define SQRT                                   "\xe2\x88\x9a"
+#define MINUS                                  "\xe2\x88\x92"
 extern char decimal_ch;
 extern char separator_ch;
+extern int scientific_result_len;
 struct calc_func_t calc_func[] = {
            {OP_PERCENT, "%"},
     {OP_ROOT, "sqrt("},
@@ -41,7 +44,7 @@ struct calc_func_t calc_func[] = {
     {OP_LN, "ln("},
     {OP_LOG, "log("},
     {OP_1X, "1/x"},
-    {OP_EX, "e^("}, {OP_X2, "^2"}, {OP_XY, "^("}, {OP_ABS, "abs("},
+    {OP_10X, "10^("}, {OP_X2, "^2"}, {OP_XY, "^("}, {OP_ABS, "abs("},
 };
 
 
@@ -136,22 +139,24 @@ static bool _calc_expr_get_number_position(const char *expr, int *begin,
  */
 void calc_expr_replace_with_special_char(char *expr)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        string_replace(expr, "p", PI_S);
        string_replace(expr, "x", MULTIPLY);
        string_replace(expr, "/", DIVIDE);
+       string_replace(expr,"-",MINUS);
        string_replace(expr, "sqrt", SQRT);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 void calc_expr_replace_from_special_char(char *expr)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        string_replace(expr, PI_S, "p");
        string_replace(expr, MULTIPLY, "x");
        string_replace(expr, DIVIDE, "/");
+       string_replace(expr,MINUS,"-");
        string_replace(expr, SQRT, "sqrt");
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /*
@@ -159,7 +164,7 @@ void calc_expr_replace_from_special_char(char *expr)
  */
 void calc_expr_format_expression(const char *expr_in, char *expr_out)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        char number1[NUMBER_LENGTH] = { 0 };
        char number2[NUMBER_LENGTH] = { 0 };
        const char *in = expr_in;
@@ -178,7 +183,7 @@ void calc_expr_format_expression(const char *expr_in, char *expr_out)
          }
          strcpy(out, in);
        calc_expr_replace_with_special_char(expr_out);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 int calc_expr_get_operator_num(const char *expr)
@@ -237,26 +242,42 @@ void calc_expr_num_remove_end_zero(char *number)
        }
 }
 
+/**
+* @description
+* Format calculate result to show it suitably in the entry
+* Mainly, remove end zero, if too long, change it to scientific form
+*
+* @param[in]   result  The calculate result
+* @param[out]  text    The format string of the result
+* @return      void
+* @exception
+*/
 void calc_expr_num_format_result(double result, char *text)
 {
+       CALC_FUN_BEG();
        char buf[MAX_EXPRESSION_LENGTH] = { 0 };
-       if (FLOAT_EQUAL(result, 0)) {/* Solve the bug of "-0". This judge can't remove. */
-               strcpy(text, "0");
-               return;
-       }
-       snprintf(buf, sizeof(buf), "%.*lf", MAX_DECIMAL_NUM, result);
-       calc_expr_num_remove_end_zero(buf);
-       printf("%s\n", buf);
-       if (strlen(buf) > MAX_NUM_LENGTH) {
-               double revise_result = result;
+       if ((fabs(result) - 0.00001) < 0) {
+               /* Solve the bug of "-0" */
+               if (ceil(fabs(result)) - 0 < 0.000000000001) {
+                       strcpy(text, "0");
+                       return;
+               }
+               snprintf(buf, sizeof(buf), "%.*E", scientific_result_len, result);
+       } else {
+               snprintf(buf, sizeof(buf), "%.*lf", MAX_DECIMAL_NUM, result);
+               calc_expr_num_remove_end_zero(buf);
+               if (strlen(buf) > MAX_NUM_LENGTH) {
+                       double revise_result = result;
                    /* 12345678650*100,000 The result should be 1.23456787+E15, not 1.23456786+E15. */
-           if (buf[9] == '5') {
-               buf[9] = '6';
-               sscanf(buf, "%lf", &revise_result);
-           }
-               snprintf(buf, sizeof(buf), "%.8E", revise_result);
+                        if (buf[9] == '5') {
+                               buf[9] = '6';
+                               sscanf(buf, "%lf", &revise_result);
+                       }
+                       snprintf(buf, sizeof(buf), "%.*E", scientific_result_len, revise_result);
+               }
        }
        strcpy(text, buf);
+       CALC_FUN_END();
 }
 
 
@@ -284,7 +305,6 @@ char *calc_expr_get_current_func_at_cursor(char *expr, int cursor)
                }
                if (!strncmp(calc_func[i].symbol, expr + t, strlen(calc_func[i].symbol)))       //equal
                {
-                       PLOG("current function : %s\n", calc_func[i].symbol);
                        return calc_func[i].symbol;
                }
        }
index 153fd20..dd3f225 100644 (file)
@@ -1,21 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
-#include <app.h>
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 #include <dlog.h>
 #include <Ecore_X.h>           /* ecore_x_window_size_get */
 #include <utilX.h>             /* KEY_END */
 extern char calculator_input_str[];
 extern int calculator_cursor_pos;
 
-static int max_fontsize = 67;
-extern void calc_xxx(struct appdata *ap);      /* will be removed */
+extern int cur_fontsize;
+extern int default_fontsize;
+extern int min_len;
+extern int max_len;
+extern int small_fontsize;
+extern int scientific_result_len;
 
+extern void calc_xxx(struct appdata *ap);      /* will be removed */
+extern void _calc_entry_text_set_rotate(struct appdata *ad);
+extern void calc_por_pannel_load(struct appdata *ad);
+extern void calc_lans_pannel_load(struct appdata *ad);
 Evas_Object *load_edj(Evas_Object * parent, const char *file, const char *group)
 {
+       CALC_FUN_BEG();
        Evas_Object *eo;
        int r;
        eo = elm_layout_add(parent);
@@ -43,72 +51,126 @@ Evas_Object *load_edj(Evas_Object * parent, const char *file, const char *group)
                evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND,
                                                 EVAS_HINT_EXPAND);
        }
+       CALC_FUN_END();
        return eo;
 }
 
 /**
 * @describe
-*
-*
-* @param    ad
-* @param    angle
-* @return    void
+* @When rotate to landscape view (Scientific calculation)
+* @param[in]   ad      The appdata
+* @param[in]   angle   The rotate angle 90 or 270
+* @return      void
 * @exception
 */
-static void _to_portrait(struct appdata *ad, int angle)
+static void __to_landscape(struct appdata *ad, int angle)
 {
+       CALC_FUN_BEG();
+       if (ad == NULL) {
+               return;
+       }
        elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
-       edje_object_signal_emit(_EDJ(ad->edje), "portrait", "");
+       calc_lans_pannel_load(ad);
+       edje_object_signal_emit(_EDJ(ad->edje), "landscape", "");
        elm_win_rotation_with_resize_set(ad->win, angle);
        elm_win_rotation_with_resize_set(ad->eo, angle);/*when rotating, resize the window eo*/
-       max_fontsize = 67;
-}
-
-int get_max_fontsize()
-{
-       return max_fontsize;
+       default_fontsize = 98;
+       cur_fontsize = 98;
+       small_fontsize = 98;
+       min_len = 30;
+       max_len = 37;
+       scientific_result_len = 13;
+       _calc_entry_text_set_rotate(ad);
+       CALC_FUN_END();
 }
 
 /**
 * @describe
-*
-*
-* @param    data
-* @param    obj
-* @param    event_info
-* @return    void
+* @When rotate to protrait view (Basic calculation)
+* @param[in]   ad      The appdata
+* @param[in]   angle   The rotate angle 0 or 180
+* @return      void
 * @exception
 */
-static void _win_del(void *data, Evas_Object * obj, void *event_info)
+static void __to_portrait(struct appdata *ad, int angle)
 {
-       elm_exit();
+    CALC_FUN_BEG();
+       if (ad == NULL) {
+               return;
+       }
+       elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
+       calc_por_pannel_load(ad);
+       edje_object_signal_emit(_EDJ(ad->edje), "portrait", "");
+       elm_win_rotation_with_resize_set(ad->win, angle);
+       elm_win_rotation_with_resize_set(ad->eo, angle);/*when rotating, resize the window eo*/
+       default_fontsize = 70;
+       cur_fontsize = 70;
+       small_fontsize = 58;
+       min_len = 13;
+       max_len = 16;
+       scientific_result_len = 8;
+       _calc_entry_text_set_rotate(ad);
+       CALC_FUN_END();
 }
 
-#if 0
 /**
 * @describe
 *
 *
+* @param    mode
 * @param    data
 * @return    int
 * @exception
 */
-static int _capture_idle_image(void *data)
+static  void _rotate(app_device_orientation_e  mode, void *data)
 {
+       CALC_FUN_BEG();
+       if (data == NULL) {
+               return;
+       }
        struct appdata *ad = (struct appdata *)data;
 
-       char name[128];
-       //snprintf(name, sizeof(name), COM_SAMSUNG_S, PACKAGE);
-       snprintf(name, sizeof(name), "com.%s.%s", VENDOR, PACKAGE);
-       Evas *evas = evas_object_evas_get(ad->win);
+       switch (mode) {
+       case APP_DEVICE_ORIENTATION_0:  //[1]0
+               __to_portrait(ad, 0);
+               break;
 
-       if (ui_idlecapture_exists(name) == EINA_FALSE) {
-               ui_idlecapture_set(evas, name);
+       case APP_DEVICE_ORIENTATION_180:        //[2]180
+               __to_portrait(ad, 180);
+               break;
+
+       case APP_DEVICE_ORIENTATION_270:        //[3]-90
+               __to_landscape(ad, 270);
+               break;
+
+       case APP_DEVICE_ORIENTATION_90: //[4]90
+               __to_landscape(ad, 90);
+               break;
+
+       default:
+               break;
        }
 
-       return ECORE_CALLBACK_CANCEL;   //0
+       /* When rotate, the size of input scroller will be changed. So it should adjust to cursor position. */
+       calc_view_revise_input_scroller(ad);
+       CALC_FUN_END();
 }
-#endif
+
+/**
+* @describe
+*
+*
+* @param    data
+* @param    obj
+* @param    event_info
+* @return    void
+* @exception
+*/
+static void _win_del(void *data, Evas_Object * obj, void *event_info)
+{
+       elm_exit();
+}
+
 /**
 * @describe
 *
@@ -119,10 +181,11 @@ static int _capture_idle_image(void *data)
 */
 static int _set_input_entry_focus(void *data)
 {
+       CALC_FUN_BEG();
        struct appdata *ad = (struct appdata *)data;
        elm_object_focus_set(ad->input_entry, EINA_TRUE);       //set focus
        _calc_entry_clear(ad->input_entry);
-
+       CALC_FUN_END();
        return ECORE_CALLBACK_CANCEL;   //0
 }
 
@@ -136,9 +199,10 @@ static int _set_input_entry_focus(void *data)
 */
 static int _load_idle_view(void *data)
 {
+       CALC_FUN_BEG();
        struct appdata *ad = (struct appdata *)data;
        calc_view_load_in_idle(ad);
-
+       CALC_FUN_END();
        return ECORE_CALLBACK_CANCEL;   //0
 }
 
@@ -152,18 +216,19 @@ static int _load_idle_view(void *data)
 */
 static Evas_Object *_create_win(const char *name)
 {
+    CALC_FUN_BEG();
        Evas_Object *eo;
        int w, h;
        eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
        if (eo) {
                elm_win_title_set(eo, name);
-               elm_win_borderless_set(eo, EINA_TRUE);
                evas_object_smart_callback_add(eo, "delete,request", _win_del,
                                               NULL);
                ecore_x_window_size_get(ecore_x_window_root_first_get(), &w,
                                        &h);
                evas_object_resize(eo, w, h);
        }
+       CALC_FUN_END();
        return eo;
 }
 
@@ -177,13 +242,7 @@ static Evas_Object *_create_win(const char *name)
 */
 static void _on_exit(struct appdata *ad)
 {
-       //ui_bgimg_fini_noti();
-
-       if (ad->popup) {
-               evas_object_del(ad->popup);
-               ad->popup = NULL;
-       }
-
+       CALC_FUN_BEG();
        if (ad->por_pannel) {
                evas_object_del(ad->por_pannel);
                ad->por_pannel = NULL;
@@ -198,6 +257,30 @@ static void _on_exit(struct appdata *ad)
                evas_object_del(ad->input_entry);
                ad->input_entry = NULL;
        }
+       if (ad->clear_btn) {
+               elm_object_item_del(ad->clear_btn);
+               ad->clear_btn = NULL;
+       }
+
+       if (ad->invalid_btn) {
+               elm_object_item_del(ad->invalid_btn);
+               ad->invalid_btn = NULL;
+       }
+
+       if (ad->tool_bar) {
+               evas_object_del(ad->tool_bar);
+               ad->tool_bar = NULL;
+       }
+
+       if (ad->navi_it) {
+               elm_object_item_del(ad->navi_it);
+               ad->navi_it = NULL;
+       }
+
+       if (ad->nf) {
+               evas_object_del(ad->nf);
+               ad->nf = NULL;
+       }
 #ifdef SAVE_HISTORY
        if (ad->hist_area) {
                evas_object_del(ad->hist_area);
@@ -220,6 +303,11 @@ static void _on_exit(struct appdata *ad)
                ad->layout = NULL;
        }
 
+       if (ad->bg) {
+               evas_object_del(ad->bg);
+               ad->bg = NULL;
+       }
+
        if (ad->win) {
                evas_object_del(ad->win);
                ad->win = NULL;
@@ -230,18 +318,30 @@ static void _on_exit(struct appdata *ad)
                ecore_timer_del(ad->calc_timer);
                ad->calc_timer = NULL;
        }
+       if (ad->wrong_timer) {
+               ecore_timer_del(ad->wrong_timer);
+               ad->wrong_timer = NULL;
+       }
        if (ad->svi_handle) {
                svi_fini(ad->svi_handle);
        }
+       CALC_FUN_END();
 }
 
-static bool app_launch(void *data)
+/**
+* @describe
+*
+*
+* @param    data
+* @return    int
+* @exception
+*/
+static bool app_create(void *data)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        struct appdata *ad = (struct appdata *)data;
 
-       /*      Use elm_theme_extension_add() API before creating any widgets */
-       //elm_theme_overlay_add(NULL, CALCULATOR_THEME);
+       /*  Use elm_theme_extension_add() API before creating any widgets */
        elm_theme_extension_add(NULL, CALCULATOR_THEME);
 
        /* main widnow */
@@ -258,28 +358,16 @@ static bool app_launch(void *data)
 
        /* load main view */
        calc_view_load(ad);
-       _to_portrait(ad, 0);
+
+       app_device_orientation_e curr = app_get_device_orientation();
+       _rotate(curr, ad);
 
        /* register callback */
-       //ecore_idler_add((Ecore_Task_Cb)_capture_idle_image, ad);
        ecore_idler_add((Ecore_Task_Cb) _set_input_entry_focus, ad);
        ecore_idler_add((Ecore_Task_Cb) _load_idle_view, ad);
-
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return TRUE;            //EXIT_SUCCESS
-}
 
-/**
-* @describe
-*
-*
-* @param    data
-* @return    int
-* @exception
-*/
-static bool app_create(void *data)
-{
-       return TRUE;            //EXIT_SUCCESS
 }
 
 /**
@@ -292,6 +380,7 @@ static bool app_create(void *data)
 */
 static void app_terminate(void *data)
 {
+       // Release all resources
        struct appdata *ad = (struct appdata *)data;
        _on_exit(ad);
 }
@@ -322,21 +411,6 @@ static void app_resume(void *data)
        // Take necessary actions when application becomes visible.
 }
 
-static void app_service(service_h service, void *data)
-{
-       CONV_FUNC_IN();
-       struct appdata *ad = (struct appdata *)data;
-
-       if (ad->win != NULL) { /* calculator has already launced. */
-               elm_win_activate(ad->win);
-               return;
-       }
-       app_launch(ad);
-       evas_object_show(ad->win);
-       CONV_FUNC_OUT();
-}
-
-
 /**
 * @describe
 *   The entry of the program
@@ -348,6 +422,7 @@ static void app_service(service_h service, void *data)
 */
 int main(int argc, char *argv[])
 {
+    CALC_FUN_BEG();
        struct appdata ad;
 
        app_event_callback_s event_callback;
@@ -356,15 +431,14 @@ int main(int argc, char *argv[])
        event_callback.terminate = app_terminate;
        event_callback.pause = app_pause;
        event_callback.resume = app_resume;
-       event_callback.service = app_service;
+       event_callback.service = NULL;
        event_callback.low_memory = NULL;
        event_callback.low_battery = NULL;
-       event_callback.device_orientation = NULL;
+       event_callback.device_orientation = _rotate;
        event_callback.language_changed = NULL;
        event_callback.region_format_changed = NULL;
 
        memset(&ad, 0x0, sizeof(struct appdata));
-
        return app_efl_main(&argc, &argv, &event_callback, &ad);
 }
 
index 4481b79..9237df8 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #include <stdio.h>
 #include <string.h>
@@ -52,13 +52,15 @@ void string_replace(char *str, char *a, char *b)
 {
        char *pch = NULL;
        char buf[BUFLEN] = { 0 };
-       while ((pch = strstr(str, a)) != NULL) {
-               strncpy(buf, str, pch - str);
-               buf[pch - str] = '\0';
-               g_strlcat(buf, b, sizeof(buf));
-               g_strlcat(buf, pch + strlen(a), sizeof(buf));
-               strcpy(str, buf);
-        }
+       if(strcmp(a, b)){
+               while ((pch = strstr(str, a)) != NULL) {
+                       strncpy(buf, str, pch - str);
+                       buf[pch - str] = '\0';
+                       g_strlcat(buf, b, sizeof(buf));
+                       g_strlcat(buf, pch + strlen(a), sizeof(buf));
+                       strcpy(str, buf);
+               }
+       }
 }
 
 void string_remove_at(char *str, int at, int length)
@@ -70,14 +72,6 @@ void string_remove_at(char *str, int at, int length)
 }
 
 
-/* @ attention
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
-
 #ifdef _DEBUG
 /* @attention   DON'T REMOVE
 char* itoa(int i)
index 5ffbe69..754459a 100644 (file)
@@ -1,24 +1,25 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+#include <app.h>
 #include <Elementary.h>
 #include <stdbool.h>
 #include "calc-main.h"
+#include "calc-string.h"
 #include "calc-expression.h"
 #include "calc-view.h"
 #include <Ecore_X.h>
@@ -27,8 +28,10 @@ extern char decimal_ch;
 extern char separator_ch;
 extern char calculator_input_str[];
 extern void _calc_add_tag(char *string, char *format_string);
-extern int get_max_fontsize();
+extern int cur_fontsize;
+extern void _calc_view_keypad_cb_register(Evas_Object * keypad);
 extern calculator_state_t calculator_get_state();
+static bool calculator_pannel_show = TRUE;
 
 /*
  * BEGIN INPUT SCROLLER REVISE
@@ -47,6 +50,7 @@ extern calculator_state_t calculator_get_state();
 */
 static Eina_Bool  _calc_view_revise_input_scroller_timer_cb(void *data)
 {
+       CALC_FUN_BEG();
        struct appdata *ad = (struct appdata *)data;
        int child_w, child_h;
        elm_scroller_child_size_get(ad->input_scroller, &child_w, &child_h);
@@ -58,6 +62,7 @@ static Eina_Bool  _calc_view_revise_input_scroller_timer_cb(void *data)
        int region_y = child_h - scroller_h;
        elm_scroller_region_bring_in(ad->input_scroller, 0, region_y,
                                       scroller_w, scroller_h);
+       CALC_FUN_BEG();
        return ECORE_CALLBACK_CANCEL;   //0
 }
 
@@ -72,9 +77,11 @@ static Eina_Bool  _calc_view_revise_input_scroller_timer_cb(void *data)
 void  calc_view_revise_input_scroller(struct appdata *ad)
 {
 
-           /* Because return ECORE_CALLBACK_CANCEL, the timer will be deleted automatically */
-           ecore_timer_add(0.05, _calc_view_revise_input_scroller_timer_cb,
-                           ad);
+       CALC_FUN_BEG();
+    /* Because return ECORE_CALLBACK_CANCEL, the timer will be deleted automatically */
+    ecore_timer_add(0.05, _calc_view_revise_input_scroller_timer_cb,
+                   ad);
+       CALC_FUN_END();
 }
 
 /* END INPUT SCROLLER REVISE */
@@ -83,11 +90,11 @@ void  calc_view_show_result(const char *result, struct appdata *ad)
        char buf[MAX_RESULT_LENGTH] = { 0 };
        char temp[MAX_RESULT_LENGTH] = { 0 };
        snprintf(buf, MAX_RESULT_LENGTH,
-                 "<br><+ font_size=%d><color=#855B11FF><yellow>=</yellow>",
-                 get_max_fontsize());
+                 "<br><+ font_size=%d><color=#FFB400FF>=",
+                 cur_fontsize);
        snprintf(temp, MAX_RESULT_LENGTH,
-                 "<+ font_size=%d><color=#000000ff><yellow>%s</yellow>",
-                 get_max_fontsize(), result);
+                 "<+ font_size=%d><color=#FFB400FF>%s",
+                 cur_fontsize, result);
        strncat(buf, temp, strlen(temp));
 
 #if 0
@@ -95,6 +102,7 @@ void  calc_view_show_result(const char *result, struct appdata *ad)
 
 #else  /*  */
            elm_entry_cursor_end_set(ad->input_entry);
+       elm_object_focus_set(ad->input_entry, EINA_TRUE);
        elm_entry_entry_insert(ad->input_entry, buf);
        calc_view_revise_input_scroller(ad);
 
@@ -123,18 +131,25 @@ _calc_view_cursor_correct_position(Evas_Object * entry, int cur_pos)
        int i = 0, len = cur_pos;
        int count_sqrt = 0;     /* the number of sqrt before cursor */
        int count_comma = 0;    /* the number of comma before cursor */
+       int count_br = 0;
        for (i = 0; i < len; ++i) {
                if (buf[i] == separator_ch){
                        count_comma++;
                } else if (buf[i] == '\xcf' || buf[i] == '\xc3') {
                        len += 1;
                } else if (buf[i] == '\xe2') {
-                       len += 2;
-                       count_sqrt++;
+                       if (buf[i+2]=='\x92') {
+                               len += 2;
+                       } else if (buf[i+2]=='\x9a') {
+                               len += 2;
+                               count_sqrt++;
+                       }
+               }else if (buf[i]==10) {
+                       count_br++;
                }
        }
        SFREE(ss);
-       return cur_pos + count_sqrt * 3 - count_comma;
+       return cur_pos + count_sqrt * 3 - count_comma-count_br;
 }
 
 int calc_view_cursor_get_position(Evas_Object * entry)
@@ -145,6 +160,7 @@ int calc_view_cursor_get_position(Evas_Object * entry)
 
 void calc_view_cursor_set_position(Evas_Object * entry, int pos)
 {
+       CALC_FUN_BEG();
        const char *expr =
            elm_entry_markup_to_utf8(elm_entry_entry_get(entry));
        const char *input = calculator_input_str;
@@ -177,66 +193,120 @@ void calc_view_cursor_set_position(Evas_Object * entry, int pos)
                        j += 4;
                        }
 
+               else if (expr[i] == '\xe2' && input[j] == '-')  /* sqrt */
+                        {
+                       cur_pos++;
+                       i += 3;
+                       j ++;
+                       }
+
                else if (expr[i] == '*' && input[j] == 'x')
                         {
                        cur_pos++;
                        i++;
                        j++;
                        }
+               else if(expr[i]==10) {
+                       cur_pos++;
+                       i++;
+                       }
 
                else
                         {
-                       PLOG("ERROR %s [%c %c]\n", __func__, expr[i],
-                             input[j]);
                        break;
                        }
                }
        elm_entry_cursor_pos_set(entry, cur_pos);
        elm_object_focus_set(entry, EINA_TRUE);
        SFREE(expr);
+       CALC_FUN_END();
 }
 
-/* END ABOUT CURSOR */
-
 #ifdef SAVE_HISTORY
 
 /* BEGIN ABOUT HISTORY */
 static struct history_item history[MAX_HISTORY_NUM];
 static int history_index = 0;
+
+/**
+* @descrption
+* @Save the current calculate result to history
+* @Called by "__calculator_op_equal" function in calculator_edje.c
+* @param[in]   item    The history item will be stored
+* @return      void
+* @exception
+*/
 void calc_view_save_history(struct history_item item)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        history[history_index] = item;
        history_index = (1 + history_index) % MAX_HISTORY_NUM;
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
-void _calc_view_show_newest_histroy(Evas_Object * entry)
+
+/**
+* @descrption
+* @Show calculate result when switch between protrait/landscape view
+* @Called by "_calc_entry_text_set_rotate" function in calculator_edje.c
+* @param[in]   entry   The input entry
+* @return      void
+* @exception
+*/
+void _calc_view_show_newest_histroy(Evas_Object *entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
        char content[MAX_TAG_EXPRESSION_LENGTH + MAX_RESULT_LENGTH] = { 0 };
        char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
        char buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_format[MAX_RESULT_LENGTH] = { 0 };
        int new_index = (history_index - 1) % MAX_HISTORY_NUM;
+       if (strlen(history[new_index].expression) == 0) {
+               return;
+       }
        _calc_add_tag(history[new_index].expression, tag_text);
        strncat(content, tag_text, strlen(tag_text));
        snprintf(buf, MAX_RESULT_LENGTH,
-                 "<br><align=right><+ font_size=%d><color=#855B11FF><yellow>=</yellow>",
-                 get_max_fontsize());
+                 "<br><align=right><+ font_size=%d><color=#FFB400FF>=",
+                 cur_fontsize);
        strncat(content, buf, strlen(buf));
+       calc_expr_num_format_result(history[new_index].result, result_buf);
+       calc_expr_format_expression(result_buf, result_format);
+       if (result_buf[0] == '-') {
+               string_replace(result_format, "\xe2\x88\x92", "-");
+       }
        snprintf(buf, MAX_RESULT_LENGTH,
-                 "<align=right><color=#000000ff><+ font_size=%d><yellow>%s</yellow><br>",
-                 get_max_fontsize(), history[new_index].result);
+                 "<align=right><color=#FFB400FF><+ font_size=%d>%s",
+                 cur_fontsize, result_format);
        strncat(content, buf, strlen(buf));
        elm_entry_entry_set(entry, content);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
-static void _calc_view_show_histroy(Evas_Object * entry)
+
+/**
+* @descrption
+* @Show calculate history when history view is load
+* @Called by "_calc_view_show_history_cb" function
+* @param[in]   entry   The history view entry
+* @return      void
+* @exception
+*/
+static void __calc_view_show_histroy(Evas_Object *entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
        char content[(MAX_TAG_EXPRESSION_LENGTH + MAX_TAG_EXPRESSION_LENGTH) *
                      MAX_HISTORY_NUM] = { 0 };
+
        char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
        char buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_format[MAX_RESULT_LENGTH] = { 0 };
        char input_str[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
        char input_str_tag[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
        int i = 0;
@@ -248,64 +318,84 @@ static void _calc_view_show_histroy(Evas_Object * entry)
                        strncat(content, tag_text, strlen(tag_text));
                        memset(tag_text, 0, sizeof(tag_text));
                        snprintf(buf, MAX_RESULT_LENGTH,
-                                 "<br><align=right><+ font_size=%d><color=#855B11FF><yellow>=</yellow>",
-                                 get_max_fontsize());
+                                 "<br><align=right><+ font_size=%d><color=#FFB400FF>=",
+                                 cur_fontsize);
                        strncat(content, buf, strlen(buf));
+                       memset(result_buf, 0, sizeof(result_buf));
+                       calc_expr_num_format_result(history[j].result, result_buf);
+                       memset(result_format, 0, sizeof(result_format));
+                       calc_expr_format_expression(result_buf, result_format);
+                       if (result_buf[0] == '-') {
+                               string_replace(result_format, "\xe2\x88\x92", "-");
+                       }
                        snprintf(buf, MAX_RESULT_LENGTH,
-                                 "<align=right><color=#000000ff><+ font_size=%d><yellow>%s</yellow><br><+ font_size=20> <br>",
-                                 get_max_fontsize(), history[j].result);
+                                 "<align=right><color=#FFB400FF><+ font_size=%d>%s<br>",
+                                       cur_fontsize, result_format);
                        strncat(content, buf, strlen(buf));
                 }
        }
        calculator_state_t tmp_state = calculator_get_state();
-       if (tmp_state != CALCULATOR_CALCULATED){
+       if (tmp_state != CALCULATOR_CALCULATED) {
                calc_expr_format_expression(calculator_input_str, input_str);
                _calc_add_tag(input_str, input_str_tag);
                strncat(content, input_str_tag, strlen(input_str_tag));
-        }
+       }
        elm_entry_entry_set(entry, content);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
-void _calc_view_clear_histroy(Evas_Object * entry)
+/**
+* @descrption
+* @Clear calculate history "Clear History" Button is clicked
+* @param[in]   entry   The history view entry
+* @return      void
+* @exception
+*/
+void _calc_view_clear_histroy(Evas_Object *entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
        int i = 0;
        for (i = history_index + MAX_HISTORY_NUM - 1; i >= history_index; --i) {
                int j = i % MAX_HISTORY_NUM;
-               if (strlen(history[j].expression) > 0)
-                        {
+               if (strlen(history[j].expression) > 0) {
                        memset(history[j].expression, 0,
                                sizeof(history[j].expression));
-                       memset(history[j].result, 0,
-                               sizeof(history[j].result));
+                       history[j].result = 0;
                        }
                }
        _calc_entry_clear(entry);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
-static void _calc_view_show_history_cb
+void _calc_view_show_history_cb
     (void *data, Evas_Object * o, const char *emission, const char *source)
  {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
+       calculator_pannel_show = FALSE;
        struct appdata *ad = (struct appdata *)data;
        evas_object_hide(ad->input_entry);/*hide the input entry,before showing history area*/
-       _calc_view_show_histroy(ad->hist_area);
+       evas_object_hide(ad->input_scroller);
+       edje_object_part_unswallow(_EDJ(ad->edje), ad->input_scroller);
+       evas_object_show(ad->hist_area);
+       evas_object_show(ad->hist_scroll);
+       __calc_view_show_histroy(ad->hist_area);
        edje_object_signal_emit(_EDJ(ad->edje), "show,hist", "");
-
     /* sync lan & por pannel state */
     Evas_Object * pannel =
            !strcmp(source, "por") ? ad->lan_pannel : ad->por_pannel;
        edje_object_signal_emit(_EDJ(pannel), "pannel,down", source);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
-static void
+void
 _calc_view_hide_history_cb(void *data, Evas_Object * o, const char *emission,
                           const char *source)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
+       calculator_pannel_show = TRUE;
        struct appdata *ad = (struct appdata *)data;
        edje_object_signal_emit(_EDJ(ad->edje), "hide,hist", "");
 
@@ -313,29 +403,36 @@ _calc_view_hide_history_cb(void *data, Evas_Object * o, const char *emission,
     Evas_Object * pannel =
            !strcmp(source, "por") ? ad->lan_pannel : ad->por_pannel;
        edje_object_signal_emit(_EDJ(pannel), "pannel,up", source);
+       evas_object_hide(ad->hist_area);
+       evas_object_hide(ad->hist_scroll);
+       evas_object_show(ad->input_scroller);
        evas_object_show(ad->input_entry);  /*show the input entry,after hide history area */
+       edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
+                                ad->input_scroller);
        elm_object_focus_set(ad->input_entry, EINA_TRUE);       //can't remove show cursor
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 static Evas_Object *
 _calc_view_create_history_entry(Evas_Object * parent)
 {
+    CALC_FUN_BEG();
        Evas_Object * entry = elm_entry_add(parent);
        elm_entry_single_line_set(entry, EINA_FALSE);
        elm_entry_line_wrap_set(entry, ELM_WRAP_WORD);
        elm_entry_editable_set(entry, EINA_FALSE);
        elm_entry_entry_set(entry, "<align=right>");
-       elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
        evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0.0);
        evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0.0);
        evas_object_show(entry);
+       CALC_FUN_END();
        return entry;
 }
 
 static Evas_Object *
 _calc_view_create_history_scroller(Evas_Object * parent)
 {
+    CALC_FUN_BEG();
        Evas_Object * scroller = elm_scroller_add(parent);
        elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
        evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
@@ -343,6 +440,7 @@ _calc_view_create_history_scroller(Evas_Object * parent)
        evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
                                         EVAS_HINT_FILL);
        evas_object_show(scroller);
+       CALC_FUN_END();
        return scroller;
 }
 
@@ -352,9 +450,7 @@ _calc_view_create_history_scroller(Evas_Object * parent)
 #endif /*  */
 void calc_view_load_in_idle(struct appdata *ad)
 {
-       CONV_FUNC_IN();
-       PLOG("%s run.\n", __func__);
-
+       CALC_FUN_BEG();
 #ifdef SAVE_HISTORY
            /* history area */
        ad->hist_area = _calc_view_create_history_entry(ad->edje);
@@ -362,14 +458,55 @@ void calc_view_load_in_idle(struct appdata *ad)
        elm_object_content_set(ad->hist_scroll, ad->hist_area);
        edje_object_part_swallow(_EDJ(ad->edje), "history/scroll",
                                  ad->hist_scroll);
-
-           /* callbacks */
-           edje_object_signal_callback_add(_EDJ(ad->por_pannel), "pannel,down",
-                                           "por", _calc_view_show_history_cb,
-                                           ad);
-       edje_object_signal_callback_add(_EDJ(ad->por_pannel), "pannel,up",
-                                        "por", _calc_view_hide_history_cb,
-                                        ad);
 #endif /*  */
-           CONV_FUNC_OUT();
+       CALC_FUN_END();
+}
+
+/* pannels */
+void calc_por_pannel_load(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       if(ad->por_pannel == NULL)
+    {
+               ad->por_pannel = load_edj(ad->edje, LAYOUT_EDJ_NAME, GRP_POR_PANNEL);
+               edje_object_part_swallow(_EDJ(ad->edje), "por_pannel/rect",
+                                ad->por_pannel);
+               _calc_view_keypad_cb_register(_EDJ(ad->por_pannel));
+
+               edje_object_signal_callback_add(_EDJ(ad->por_pannel), "pannel,down",
+                                                 "por", _calc_view_show_history_cb,
+                                                 ad);
+               edje_object_signal_callback_add(_EDJ(ad->por_pannel), "pannel,up",
+                                                 "por", _calc_view_hide_history_cb,
+                                                 ad);
+
+    }
+       if(!calculator_pannel_show){
+               edje_object_signal_emit(_EDJ(ad->por_pannel), "pannel,down_i", "por");
+       }
+       CALC_FUN_END();
 }
+
+void calc_lans_pannel_load(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       if(ad->lan_pannel == NULL)
+    {
+               ad->lan_pannel = load_edj(ad->edje, LAYOUT_EDJ_NAME, GRP_LAN_PANNEL);
+               edje_object_part_swallow(_EDJ(ad->edje), "lan_pannel/rect",
+                                        ad->lan_pannel);
+               _calc_view_keypad_cb_register(_EDJ(ad->lan_pannel));
+               edje_object_signal_callback_add(_EDJ(ad->lan_pannel), "pannel,down",
+                                             "lan", _calc_view_show_history_cb,
+                                             ad);
+               edje_object_signal_callback_add(_EDJ(ad->lan_pannel), "pannel,up",
+                                                 "lan", _calc_view_hide_history_cb,
+                                                 ad);
+    }
+       if(!calculator_pannel_show){
+               edje_object_signal_emit(_EDJ(ad->lan_pannel), "pannel,down_i", "lan");
+       }
+       CALC_FUN_END();
+}
+
+
index 7ffa2e1..0dfcddf 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #include <stdbool.h>           /*  true/false */
 #include <Elementary.h>
 #define CALCULATOR_IS_DIGIT_DOT(ch, decimal) (isdigit(ch) || decimal == (ch))
 
 static Elm_Entry_Filter_Limit_Size limit_filter_data;
-
-extern int get_max_fontsize();
 extern void _calc_view_show_newest_histroy(Evas_Object * entry);
 extern void _calc_view_clear_histroy(Evas_Object * entry);
 extern gboolean __calculator_search_function(char *op, int* len);
 static void __calculator_wrong_format_create(char * wrong_string);
-extern gboolean __calculator_search_function(char *op, int* len);
 
 static struct appdata *ad;     /* will be removed */
 static calculator_state_t calculator_state = CALCULATOR_WAITING_INPUT;
 static double last_result = 0.0;
-
 int calculator_cursor_pos = 0;
 char calculator_input_str[MAX_EXPRESSION_LENGTH] = { 0 };
 char calculator_before_paste_str[MAX_EXPRESSION_LENGTH] = { 0 };
-
 bool paste_flag = FALSE;
 
 struct lconv *locale = NULL;
@@ -58,6 +53,14 @@ char *separator = NULL;
 char decimal_ch = 0;
 char separator_ch = 0;
 
+int cur_fontsize = 70;
+int small_fontsize = 58;
+int default_fontsize = 0;
+int min_len = 13;
+int max_len = 0;
+int scientific_result_len = 8;
+
+
 static op_item_t calc_op_item[] = {
        {OP_INVALID, "", NULL},
 
@@ -100,7 +103,7 @@ static op_item_t calc_op_item[] = {
        {OP_LOG, "log", "log("},
        {OP_1X, "1/x", "1/x"},
 
-       {OP_EX, "e^x", "e^("},
+       {OP_10X, "10^x", "10^("},
        {OP_X2, "x^2", "^2"},
        {OP_XY, "x^y", "^("},
 
@@ -127,7 +130,6 @@ char *error_string[] = {
     "IDS_CCL_POP_SYNTAX_ERROR",
 };
 
-
 calculator_state_t calculator_get_state()
 {
        return calculator_state;
@@ -135,7 +137,7 @@ calculator_state_t calculator_get_state()
 
 void _calc_add_tag(char *string, char *format_string)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        int i = 0;
        int begin = 0;
        int end = 0;
@@ -144,7 +146,16 @@ void _calc_add_tag(char *string, char *format_string)
        char *p = NULL;
        while (string[i] != '\0') {
                if (CALCULATOR_CHAR_IS_DIGITAL(string[i])
-                   || string[i] == separator_ch || string[i] == decimal_ch) {
+                   || string[i] == separator_ch || string[i] == decimal_ch
+                   ||( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92')) {
+                       if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
+                               memset(buf, 0, sizeof(buf));
+                               snprintf(buf, sizeof(buf),
+                                "<align=right><font_size=%d><color=#7A9CC6FF>(<align=right><font_size=%d><color=#FFFFFFFF>-",
+                                cur_fontsize, cur_fontsize);
+                               strcat(format_string, buf);
+                               i=i+4;
+                       }
                        begin = i;
                        p = &string[begin];
                        while (CALCULATOR_CHAR_IS_DIGITAL(string[i])
@@ -157,8 +168,8 @@ void _calc_add_tag(char *string, char *format_string)
                        tmp[end - begin + 1] = '\0';
                        memset(buf, 0, sizeof(buf));
                        snprintf(buf, sizeof(buf),
-                                "<align=right><+ font_size=%d><color=#000000ff>%s",
-                                get_max_fontsize(), tmp);
+                                "<align=right><font_size=%d><color=#FFFFFFFF>%s",
+                                cur_fontsize, tmp);
                        strcat(format_string, buf);
                } else {
                        begin = i;
@@ -167,24 +178,120 @@ void _calc_add_tag(char *string, char *format_string)
                               && string[i] != separator_ch
                               && string[i] != decimal_ch
                               && string[i] != '\0') {
-                               i++;
+                              if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
+                                       break;
+                              } else {
+                                       i++;
+                              }
                        }
                        end = i - 1;
                        strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
                        tmp[end - begin + 1] = '\0';
                        memset(buf, 0, sizeof(buf));
                        snprintf(buf, sizeof(buf),
-                                "<align=right><+ font_size=%d><color=#855B11FF>%s",
-                                get_max_fontsize(), tmp);
+                                "<align=right><font_size=%d><color=#7A9CC6FF>%s",
+                                cur_fontsize, tmp);
                        strcat(format_string, buf);
                }
 
        }
-       PLOG("Expression with tag : %s\n", format_string);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+* Change line and font size when it is needed.
+* Refer to the auto font resizing rules.
+* @param       tag_text                The text with tags.
+* @return      void
+* @exception
+*/
+void _calc_add_br(char *tag_text)
+{
+       CALC_FUN_BEG();
+       if (tag_text  == NULL) {
+               return;
+       }
+       int line_valid_num = 0;
+       int whole_valid_num = 0;
+       int operator_tag = -1;
+       int operator_location = -1;
+       /* record is there an operator in one line? */
+       bool operator_flag = FALSE;
+       /* when change to small font, we should rescan the tag_text */
+       bool rescan_flag = FALSE;
+       int cur_len = 0;
+       char buf[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
+       strcpy(buf, tag_text);
+       int br_number = 0;
+       int i = 0;
+       int j = 0;
+       for ( ; tag_text[i] != '\0' && calculator_input_str[j] != '\0'; ) {
+               while (tag_text[i] == '<') {
+                       while (tag_text[i++] != '>');
+               }
+               /* if calculator_input_str[j] is "*" or "/", tag_text[i] would be
+                       "\xc3\x97" or "\xc3\xb7" */
+               if (tag_text[i] == calculator_input_str[j] || (tag_text[i] == '\xc3') ||
+                       ((tag_text[i] == '\xe2') && (tag_text[i+1] == '\x88') && (tag_text[i+2] == '\x92'))) {
+
+                       if ((CALCULATOR_CHAR_IS_OPERATOR(calculator_input_str[j])) &&
+                               (!(calculator_input_str[j] == '-' && calculator_input_str[j-1] == '('))) {
+                               if (!operator_flag || rescan_flag) {
+                                       operator_location = j;
+                                       operator_tag = i;
+                                       operator_flag = TRUE;
+                               }
+                       }
+
+                       whole_valid_num++;
+                       line_valid_num++;
+                       if (br_number < 2) {
+                               cur_fontsize = default_fontsize;
+                               cur_len = min_len;
+                       } else {
+                               if ((line_valid_num >= min_len) && (!rescan_flag)) {
+                                       rescan_flag = TRUE;
+                                       cur_fontsize = small_fontsize;
+                                       strcpy(tag_text, buf);
+                                       /* restore to the original state, then scan from the begin */
+                                       i = 0;
+                                       j = 0;
+                                       whole_valid_num = 1;
+                                       line_valid_num = 1;
+                                       operator_flag = FALSE;
+                                       operator_tag = -1;
+                                       operator_location = -1;
+                                       cur_len = max_len + 1;
+                               }
+                       }
+
+                       if (line_valid_num >= cur_len) {
+                               if (operator_flag && operator_tag > 0) {
+                                       string_insert(tag_text, operator_tag, "<br>");
+                                       line_valid_num = whole_valid_num-operator_location;
+                                       operator_flag = FALSE;
+                                       operator_tag = -1;
+                                       operator_location = -1;
+                               } else {
+                                       string_insert(tag_text, i, "<br>");
+                                       line_valid_num = 0;
+
+                               }
+                               i = i + 4;
+                               if (br_number < 2) {
+                                       br_number++;
+                               }
+                       }
+                       i++;
+                       j++;
+               }else {
+                       i++;
+               }
+    }
+    CALC_FUN_END();
 }
 
-/* BEGIN INPUT ENTRY RELATED */
 
 /**
 * @describe
@@ -197,9 +304,11 @@ void _calc_add_tag(char *string, char *format_string)
 */
 static void _calc_entry_text_set(Evas_Object * entry, const char *str)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
        char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
+       char new_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
+       char old_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
 
        if (str == NULL) {
                return;
@@ -207,27 +316,39 @@ static void _calc_entry_text_set(Evas_Object * entry, const char *str)
 
        if (strlen(str) == 0) {
                elm_entry_entry_set(entry, "");
-               calc_view_cursor_set_position(entry, calculator_cursor_pos);
+               elm_entry_cursor_end_set(entry);
+               elm_object_focus_set(entry, EINA_TRUE);
+               CALC_FUN_END();
                return;
        }
        calc_expr_format_expression(str, tmp);
        _calc_add_tag(tmp, tag_text);
+       int pre_fontsize = cur_fontsize;
+       _calc_add_br(tag_text);
+       snprintf(old_font_str, sizeof(old_font_str), "=%d", pre_fontsize);
+       snprintf(new_font_str, sizeof(new_font_str), "=%d", cur_fontsize);
+       string_replace(tag_text, old_font_str, new_font_str);
        elm_entry_entry_set(entry, tag_text);
-
-       calc_view_cursor_set_position(entry, calculator_cursor_pos);
-       calc_view_revise_input_scroller(ad);
-       CONV_FUNC_OUT();
-
+       if(calculator_cursor_pos == strlen(calculator_input_str)){
+               elm_entry_cursor_end_set(entry);
+               elm_object_focus_set(entry, EINA_TRUE);
+       }else {
+               calc_view_cursor_set_position(entry, calculator_cursor_pos);
+       }
+       CALC_FUN_END();
 }
 
 void _calc_entry_text_set_rotate(struct appdata *ad)
 {
+    CALC_FUN_BEG();
        if (calculator_state == CALCULATOR_CALCULATED) {
                _calc_view_show_newest_histroy(ad->input_entry);
                elm_entry_cursor_end_set(ad->input_entry);
+               elm_object_focus_set(ad->input_entry, EINA_TRUE);
        } else {
                _calc_entry_text_set(ad->input_entry, calculator_input_str);
        }
+       CALC_FUN_END();
 }
 
 /**
@@ -241,12 +362,11 @@ void _calc_entry_text_set_rotate(struct appdata *ad)
 */
 static void _calc_entry_text_insert(Evas_Object * entry, char *str)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        calc_expr_input_insert(calculator_input_str, &calculator_cursor_pos,
                               str);
-       printf("calculator_input_str=%s, str=%s, calculator_cursor_pos=%d\n", calculator_input_str, str, calculator_cursor_pos);
        _calc_entry_text_set(entry, calculator_input_str);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
@@ -262,12 +382,12 @@ static void _calc_entry_text_insert(Evas_Object * entry, char *str)
 static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
                                    const int end_pos)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        string_remove_at(calculator_input_str, from_pos,
                         end_pos - from_pos + 1);
        calculator_cursor_pos = from_pos;
        _calc_entry_text_set(entry, calculator_input_str);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
@@ -280,9 +400,9 @@ static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
 */
 static void _calc_entry_cursor_set(Evas_Object * entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        calc_view_cursor_set_position(entry, calculator_cursor_pos);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
@@ -295,10 +415,10 @@ static void _calc_entry_cursor_set(Evas_Object * entry)
 */
 static void _calc_entry_backspace(Evas_Object * entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
        _calc_entry_text_set(entry, calculator_input_str);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
@@ -311,33 +431,42 @@ static void _calc_entry_backspace(Evas_Object * entry)
 */
 void _calc_entry_clear(Evas_Object * entry)
 {
+       CALC_FUN_BEG();
        memset(calculator_input_str, 0, sizeof(calculator_input_str));
        calculator_cursor_pos = 0;
        _calc_entry_text_set(entry, "");
        calc_view_cursor_set_position(entry, calculator_cursor_pos);
+       CALC_FUN_END();
 }
 
 /* END INPUT ENTRY RELATED */
 
 /**
 * @describe
+* Get the operand start and end location where the cursor in.
+* 1.2+6.|43 (cursor is before 4), then return begin=4 end=7
+* Espcially, cursor is after +, it means the operand which follows
+* the operator, so it return the same result as before.
+* This is add by on 2012/5/29
 *
-*
-* @param    text
-* @param    begin
-* @param    end
-* @return    void
+* @param[in]   text    The current calculator input string
+* @param[out]  begin   The start location of an operand
+* @param[out]  end     The end location of an operand
+* @return              Is cursor in an operand
+* @retval      true    The cursor is in the operand
+* @retval      false   The cursor is not in the operand
 * @exception
 */
 static bool
 __calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
                                              int *begin, int *end)
 {
-       CONV_FUNC_IN();
-
+       CALC_FUN_BEG();
+       if (text == NULL) {
+               return false;
+       }
        int pos = cur_pos - 1;
        if (pos < 0) {
-               pos++;
                pos = 0;
        }
        int _begin = 0;
@@ -368,29 +497,45 @@ __calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
                *begin = _begin;
                *end = _end;
                return true;
+       } else if (CALCULATOR_CHAR_IS_OPERATOR(text[pos]) || text[pos] == '(') {
+               for (_end = pos + 1;
+                    CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
+                    && _end < strlen(text); ++_end) {
+                       ;       /* NULL */
+               }
+               _end--;
+               *begin = pos+1;
+               *end = _end;
+               return true;
        } else {
                return false;
        }
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
 * @describe
+* Get the operand start and end location where the cursor in the operand
+* Actually, it would call "__calculator_get_float_num_in_cursor_position"
+* function to recognize whether the cursor is in the operand.
 *
-*
-* @param    entry_text
-* @param    str
-* @param    from
-* @param    end
-* @return    void
+* @param[in]   entry_text      The current calcualtor input string
+* @param[out]  str     The operand which the cursor in
+* @param[out]  from    The operand start location which contain the cursor
+* @param[out]  end     The operand end location which contain the cursor
+* @return              Is cursor in an operand
+* @retval      true    The cursor is in the operand
+* @retval      false   The cursor is not in the operand
 * @exception
 */
 static bool
 __calculator_get_cursor_position_float_string(char *entry_text, char *str,
                                              int cur_pos, int *from, int *end)
 {
-       CONV_FUNC_IN();
-
+       CALC_FUN_BEG();
+       if (entry_text == NULL) {
+               return false;
+       }
        int from_pos = cur_pos;
        int end_pos = cur_pos;
 
@@ -411,7 +556,7 @@ __calculator_get_cursor_position_float_string(char *entry_text, char *str,
 
        strncpy(str, entry_text + from_pos, end_pos - from_pos + 1);
        str[end_pos - from_pos + 1] = '\0';
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return true;
 }
 
@@ -427,7 +572,7 @@ __calculator_get_cursor_position_float_string(char *entry_text, char *str,
 static bool
 __calculator_get_before_cursor_float_string(char *entry_text, char *str)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
 
        int from_pos = calculator_cursor_pos;
        int end_pos = calculator_cursor_pos;
@@ -441,7 +586,7 @@ __calculator_get_before_cursor_float_string(char *entry_text, char *str)
        }
        snprintf(str, calculator_cursor_pos - from_pos + 1, "%s",
                 entry_text + from_pos);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return true;
 }
 
@@ -457,7 +602,7 @@ __calculator_get_before_cursor_float_string(char *entry_text, char *str)
 static void
 __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
 
        if (calculator_cursor_pos > 0) {
                strncpy(str, entry_text, calculator_cursor_pos);
@@ -465,7 +610,7 @@ __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
        } else {
                strcpy(str, "");
        }
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
@@ -479,7 +624,7 @@ __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
 */
 static last_char_t __calculator_string_get_char_type( char ch_in)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        if (ch_in == '\0') {
                return CHAR_IS_NULL;
        }
@@ -508,14 +653,14 @@ static last_char_t __calculator_string_get_char_type( char ch_in)
                return CHAR_IS_POINT;
        }
        return CHAR_IS_CHARACTER;
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 static bool  __calculator_string_digit_in(const char *input)
 {
        int i =0;
        while(input[i]!='\0'){
-               if(CALCULATOR_CHAR_IS_DIGITAL(input[i])){
+               if(IS_DIGITAL(input[i])){/*here ,digit include "p" and "e"*/
                        return TRUE;
                }else{
                        i++;
@@ -530,7 +675,7 @@ static bool  __calculator_string_digit_in(const char *input)
 */
 static bool __calculator_string_char_search(const char *input, int *index)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        int len_cp = strlen(input);
        if(len_cp <= 0){
                return FALSE;
@@ -544,7 +689,7 @@ static bool __calculator_string_char_search(const char *input, int *index)
                }
        }
        return FALSE;
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /*
@@ -587,7 +732,7 @@ static void
 __calculator_control_panel_number_button_clicked(Evas_Object * entry,
                                                 op_item_t * op_item)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
 
        /* replace special characters */
        char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
@@ -632,7 +777,10 @@ __calculator_control_panel_number_button_clicked(Evas_Object * entry,
                   CHAR_IS_PI
                   || __calculator_string_get_char_type(before_cursor[before_len - 1]) ==
                   CHAR_IS_E)) {
-               __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+               /* input digital after "e" or "p", the "x" opeartor will be added automatically */
+               _calc_entry_text_insert(entry, "x");
+               _calc_entry_text_insert(entry, op_item->op_sym);
+               calculator_state = CALCULATOR_OPERAND_INPUT;
                return;
        } else if (before_len > 0
                   && ((before_cursor[before_len - 1] == '(')
@@ -644,28 +792,30 @@ __calculator_control_panel_number_button_clicked(Evas_Object * entry,
                calculator_state = CALCULATOR_OPERAND_INPUT;
                return;
        } else if (before_len > 0 && (before_cursor[before_len - 1] == ')')) {
-               _calc_entry_text_insert(entry, op_item->op_sym);
+               __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
                return;
        } else {
                _calc_entry_text_insert(entry, op_item->op_sym);
                calculator_state = CALCULATOR_OPERAND_INPUT;
                return;
        }
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
 * @describe
+* Deal the event when dot clicked on the keyboard
 *
-*
-* @param    entry
-* @return    void
+* @param[in]   entry   The input entry
+* @return              void
 * @exception
 */
-static void _calc_btn_dot_clicked(Evas_Object * entry)
+static void _calc_btn_dot_clicked(Evas_Object *entry)
 {
-       CONV_FUNC_IN();
-       char temp[MAX_RESULT_LENGTH] = { 0 };
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
        char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
        int str_num_len = 0;
 
@@ -676,13 +826,8 @@ static void _calc_btn_dot_clicked(Evas_Object * entry)
        strncpy(entry_text, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
 
        if (calculator_state == CALCULATOR_CALCULATED) {
-               calc_expr_num_format_result(last_result, temp);
-               if (strchr(temp, 'E') != NULL) {
-                       return;
-               }
-               /* science number */
                _calc_entry_clear(entry);
-               _calc_entry_text_insert(entry, temp);
+               memset(entry_text,0x00,sizeof(entry_text));
        }
 
        int from_pos = 0;
@@ -690,14 +835,13 @@ static void _calc_btn_dot_clicked(Evas_Object * entry)
        if (!__calculator_get_cursor_position_float_string
            (entry_text, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
                if (calculator_cursor_pos == 0
-                   || IS_OPERATOER(calculator_input_str[from_pos - 1])) {
+                   || IS_OPERATOER(calculator_input_str[from_pos - 1])
+                       || calculator_input_str[from_pos - 1] == '(') {
                        snprintf(decimal_str, sizeof(decimal_str), "0%c",
                                 decimal_ch);
                        _calc_entry_text_insert(entry, decimal_str);
                        calculator_state = CALCULATOR_OPERAND_INPUT;
                        return;
-               } else {
-                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
                }
                return;
        } else {
@@ -709,7 +853,6 @@ static void _calc_btn_dot_clicked(Evas_Object * entry)
 
        str_num_len = strlen(str_num);
        if (str_num_len > 0 && str_num[str_num_len - 1] == decimal_ch) {
-               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
                return;
        }
 
@@ -723,13 +866,17 @@ static void _calc_btn_dot_clicked(Evas_Object * entry)
        }
 
        if (nPointCnt > 0) {
-               __calculator_wrong_format_create(CALC_MSG_ENTRY_LIMIT);
                return;
        }
-       snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
+       if (IS_OPERATOER(calculator_input_str[calculator_cursor_pos-1])
+               || calculator_input_str[calculator_cursor_pos-1] == '(') {
+               snprintf(decimal_str, sizeof(decimal_str), "0%c", decimal_ch);
+       } else {
+               snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
+       }
        _calc_entry_text_insert(entry, decimal_str);
        calculator_state = CALCULATOR_OPERAND_INPUT;
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return;
 }
 
@@ -743,7 +890,7 @@ static void _calc_btn_dot_clicked(Evas_Object * entry)
 */
 static void _calc_btn_backspace_clicked(Evas_Object * entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
 
        if (calculator_state == CALCULATOR_CALCULATED) {
                calculator_state = CALCULATOR_OPERATOR_INPUT;
@@ -752,15 +899,15 @@ static void _calc_btn_backspace_clicked(Evas_Object * entry)
                }
        }
        _calc_entry_backspace(entry);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 static int __calculator_delete_long_press(void *data)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        Evas_Object *entry = (Evas_Object *) data;
        _calc_btn_backspace_clicked(entry);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return 1;
 }
 
@@ -777,7 +924,7 @@ static void
 __calculator_control_normal_func_clicked(Evas_Object * entry,
                                         op_item_t * op_item)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
        strncpy(all_input, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
 
@@ -802,7 +949,8 @@ __calculator_control_normal_func_clicked(Evas_Object * entry,
                return;
 
        }
-    if(!strcmp(op_item->op_sym, "x") || !strcmp(op_item->op_sym, "/") || !strcmp(op_item->op_sym, "+")){
+    if(!strcmp(op_item->op_sym, "x")||!strcmp(op_item->op_sym, "/")
+               ||!strcmp(op_item->op_sym, "+")){
                if(!__calculator_string_digit_in(calculator_input_str)){ return; }
        }
        int nCntOp = calc_expr_get_operator_num(all_input);
@@ -823,7 +971,7 @@ __calculator_control_normal_func_clicked(Evas_Object * entry,
                        _calc_entry_text_insert(entry, op_item->op_sym);
                        calculator_state = CALCULATOR_OPERATOR_INPUT;
                } else if (((input_len > 1) && (before_cursor[input_len - 1] == '-') && (before_cursor[input_len - 2] == '('))  //(-
-                          || before_cursor[input_len - 1] == decimal_ch || before_cursor[input_len - 1] == '(')        // . or (
+                          || /*before_cursor[input_len - 1] == decimal_ch ||*/ before_cursor[input_len - 1] == '(')    // . or (
                {
 
                        __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
@@ -844,7 +992,8 @@ __calculator_control_normal_func_clicked(Evas_Object * entry,
                        calculator_state = CALCULATOR_OPERATOR_INPUT;
                        return;
                } else {
-                       if (!IS_DIGITAL(before_cursor[input_len - 1])) {
+                       if (!IS_DIGITAL(before_cursor[input_len - 1])
+                                       && (before_cursor[input_len - 1] != decimal_ch)) {
                                __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
                                return;
                        } else {
@@ -858,7 +1007,7 @@ __calculator_control_normal_func_clicked(Evas_Object * entry,
                _calc_entry_text_insert(entry, op_item->op_sym);
                calculator_state = CALCULATOR_OPERATOR_INPUT;
        }
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
@@ -871,7 +1020,7 @@ __calculator_control_normal_func_clicked(Evas_Object * entry,
 */
 static void __calculator_symbol_negative_clicked(Evas_Object * entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
 
        char result[MAX_RESULT_LENGTH] = { 0 };
 
@@ -900,7 +1049,6 @@ static void __calculator_symbol_negative_clicked(Evas_Object * entry)
        char expr[MAX_EXPRESSION_LENGTH] = { 0 };
        strncpy(expr, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
        int flag = 0;
-
        cursor -= 1;
        if (expr[cursor] == ')') {
                cursor -= 1;
@@ -944,41 +1092,49 @@ static void __calculator_symbol_negative_clicked(Evas_Object * entry)
        } else {
                __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
        }
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /* search the previous operator and value */
 static char * __calculator_search_prev_input(char *input_str)
 {
-       int i = strlen(input_str) - 1;
-       int rightbracket = 0;   
+       CALC_FUN_BEG();
+       int i = 0;
+       int bracket_number = 0;
        char *prev_input = NULL;
-       for ( ; i > 0; i--){
-               if (input_str[i] == ')') {
-                       rightbracket++;
-               } else if (input_str[i] == '(') {               
-                       rightbracket--;
+       for(; i< strlen(input_str); i++) {
+               if ('(' ==(input_str[i]) ){
+                       bracket_number++;
                }
-               if ((CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
-                       ||CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) && (rightbracket == 0)){
-                       prev_input = &input_str[i];                     
-                       return prev_input;
+               if( ')' == input_str[i]){
+                       bracket_number --;
+               }
+               if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
+                       || CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) {
+                       if ( !bracket_number){
+                               prev_input = &input_str[i];
+                               return prev_input;
+                       }
                }
        }
+       CALC_FUN_BEG();
        return prev_input;
 }
 
 /**
 * @describe
+* Deal the event when "=" clicked on the keyboard
 *
-*
-* @param        entry
-* @return       void
+* @param[in]   entry   The input entry
+* @return              void
 * @exception
 */
-static void __calculator_op_equal(Evas_Object * entry)
+static void __calculator_op_equal(Evas_Object *entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
        if (calculator_state == CALCULATOR_CALCULATED) {
                /*duplicate previous input operator and value*/
                char *p = __calculator_search_prev_input(calculator_input_str);
@@ -987,7 +1143,7 @@ static void __calculator_op_equal(Evas_Object * entry)
                }
                char prev_input[32] = { 0 };
                int len = g_strlcpy(prev_input, p, sizeof(prev_input));
-               if(len >= sizeof(prev_input)){
+               if (len >= sizeof(prev_input)) {
                        return;
                }
                char temp[32] = { 0 };
@@ -1008,6 +1164,7 @@ static void __calculator_op_equal(Evas_Object * entry)
        double result = 0;
        char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
        char result_buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_format[MAX_RESULT_LENGTH] = { 0 };
        int str_len = 0;
        char error_msg[MAX_ERROR_MESSAGE_LENGTH] = { 0 };
        calc_expr_close_parentheses(calculator_input_str);
@@ -1019,9 +1176,7 @@ static void __calculator_op_equal(Evas_Object * entry)
                return;
        }
 
-       PLOG("calculate :%s\n", str_buf);
        if (!calculator_calculate(str_buf, &result, error_msg)) {
-               PLOG("error : %s\n", error_msg);
                __calculator_wrong_format_create(error_msg);
                calculator_state = CALCULATOR_ERROR_OCCURED;
                return;
@@ -1033,20 +1188,23 @@ static void __calculator_op_equal(Evas_Object * entry)
 
                struct history_item item;
                memset(item.expression, 0, sizeof(item.expression));
-               memset(item.result, 0, sizeof(item.result));
+               memset(result_format, 0, sizeof(result_format));
                calc_expr_format_expression(calculator_input_str,
                                            item.expression);
-               calc_expr_format_expression(result_buf, item.result);
+               item.result = result;
+               calc_expr_format_expression(result_buf, result_format);
+               if (result_buf[0] == '-') {
+                       string_replace(result_format, "\xe2\x88\x92", "-");
+               }
 #ifdef SAVE_HISTORY
                calc_view_save_history(item);
 #endif
-
                /* show result */
                calculator_state = CALCULATOR_CALCULATED;
-               calc_view_show_result(item.result, ad);
+               calc_view_show_result(result_format, ad);
 
        }
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 /**
@@ -1059,7 +1217,7 @@ static void __calculator_op_equal(Evas_Object * entry)
 */
 static void __calculator_parenthesis_clicked(Evas_Object * entry)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
        snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
        if (calculator_state == CALCULATOR_CALCULATED) {
@@ -1124,7 +1282,7 @@ static void __calculator_parenthesis_clicked(Evas_Object * entry)
                        return;
                }
        }
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return;
 }
 
@@ -1141,7 +1299,7 @@ static void
 __calculator_control_functions_button_clicked(Evas_Object * entry,
                                              op_item_t * op_item)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
 
        char *str = NULL;
        function_t function = { 0 };
@@ -1233,41 +1391,44 @@ __calculator_control_functions_button_clicked(Evas_Object * entry,
                        edje_object_signal_emit(_EDJ(ad->edje), "show,input",
                                                "");
                        _calc_entry_clear(entry);
-                       _calc_entry_text_insert(entry, "p");
+                       _calc_entry_text_insert(entry, op_item->op_name);
                        break;
                }
-               if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
-                   && (before_cursor[before_len - 1] != '-')
-                   && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
-                   && (before_cursor[before_len - 1] != '^')
+               if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
+                   && (!IS_OPERATOER(before_cursor[before_len - 1]))
                    && (before_cursor[before_len - 1] != '(')
                    && (before_cursor[before_len - 1] != 'P')
                    && before_cursor[before_len - 1] != 'C') {
                        __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
                        break;
                }
-               _calc_entry_text_insert(entry, "p");
+               /* input digital after "p", the "x" opeartor will be added automatically */
+               if(IS_DIGITAL(before_cursor[before_len - 1])){
+                       _calc_entry_text_insert(entry, "x");
+               }
+               _calc_entry_text_insert(entry, op_item->op_name);
                break;
 
        case OP_E:
                if (calculator_state == CALCULATOR_CALCULATED) {
                        edje_object_signal_emit(_EDJ(ad->edje), "show,input",
                                                "");
-
                        _calc_entry_clear(entry);
                        _calc_entry_text_insert(entry, op_item->op_name);
                        break;
                }
-               if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
-                   && (before_cursor[before_len - 1] != '-')
-                   && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
-                   && (before_cursor[before_len - 1] != '^')
+               if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
+                   && (!IS_OPERATOER(before_cursor[before_len - 1]))
                    && (before_cursor[before_len - 1] != '(')
                    && (before_cursor[before_len - 1] != 'P')
                    && before_cursor[before_len - 1] != 'C') {
                        __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
                        break;
                }
+               /* input digital after "e", the "x" opeartor will be added automatically */
+               if(IS_DIGITAL(before_cursor[before_len - 1])){
+                       _calc_entry_text_insert(entry, "x");
+               }
                _calc_entry_text_insert(entry, op_item->op_name);
                break;
 
@@ -1343,7 +1504,7 @@ __calculator_control_functions_button_clicked(Evas_Object * entry,
                _calc_entry_text_insert(entry, op_item->op_name);
                break;
 
-       case OP_EX:             //e^
+       case OP_10X:            //10^
                if (calculator_state == CALCULATOR_CALCULATED) {
                        edje_object_signal_emit(_EDJ(ad->edje), "show,input",
                                                "");
@@ -1511,13 +1672,6 @@ __calculator_control_functions_button_clicked(Evas_Object * entry,
                        calculator_state = CALCULATOR_OPERATOR_INPUT;
                }
                break;
-/* @ attention
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
        case OP_1X:
                if (calculator_state == CALCULATOR_CALCULATED) {
                        edje_object_signal_emit(_EDJ(ad->edje), "show,input",
@@ -1555,13 +1709,6 @@ __calculator_control_functions_button_clicked(Evas_Object * entry,
                        //use_last_result = 1;
                        return;
                }
-/* @ attention
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
                if (input_len == 0) {
                        __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
                        break;
@@ -1609,7 +1756,7 @@ __calculator_control_functions_button_clicked(Evas_Object * entry,
                break;
        }
        calculator_state = CALCULATOR_SPECIAL_FUNCTION_INPUT;
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return;
 }
 
@@ -1626,7 +1773,7 @@ __calculator_control_functions_button_clicked(Evas_Object * entry,
 */
 static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
 
        int val = 0;
        if (evas_obj == edje_object_part_object_get(obj, "item_brack")) {
@@ -1687,8 +1834,8 @@ static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
                val = OP_LOG;
        } else if (evas_obj == edje_object_part_object_get(obj, "item_1x")) {
                val = OP_1X;
-       } else if (evas_obj == edje_object_part_object_get(obj, "item_ex")) {
-               val = OP_EX;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_10x")) {
+               val = OP_10X;
        } else if (evas_obj == edje_object_part_object_get(obj, "item_x2")) {
                val = OP_X2;
        } else if (evas_obj == edje_object_part_object_get(obj, "item_xy")) {
@@ -1700,9 +1847,69 @@ static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
        } else if (evas_obj == edje_object_part_object_get(obj, "item_e")) {
                val = OP_E;
        }
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
+       return val;
+}
+
+/////////////////////////// input text finish ////////////////////////////
+
+#ifdef __i386__
+/**
+* @describe
+*
+*
+* @param    evas_obj
+* @param    obj
+* @return    void
+* @exception
+*/
+static int _calculator_get_input_item_hd(const char *keyname, Evas_Object * obj)
+{
+       CALC_FUN_BEG();
+       int val = 0;
+       if (0 == strcmp(keyname, "KP_7")) {
+               val = OP_NUM_7;
+       } else if (0 == strcmp(keyname, "KP_8")) {
+               val = OP_NUM_8;
+       } else if (0 == strcmp(keyname, "KP_9")) {
+               val = OP_NUM_9;
+       } else if (0 == strcmp(keyname, "KP_4")) {
+               val = OP_NUM_4;
+       } else if (0 == strcmp(keyname, "KP_5")) {
+               val = OP_NUM_5;
+       } else if (0 == strcmp(keyname, "KP_6")) {
+               val = OP_NUM_6;
+       } else if (0 == strcmp(keyname, "KP_1")) {
+               val = OP_NUM_1;
+       } else if (0 == strcmp(keyname, "KP_2")) {
+               val = OP_NUM_2;
+       } else if (0 == strcmp(keyname, "KP_3")) {
+               val = OP_NUM_3;
+       } else if (0 == strcmp(keyname, "KP_0")) {
+               val = OP_NUM_0;
+       }else if (0 == strcmp(keyname, "KP_Decimal")) {
+               val = OP_DOT;
+       } else if (0 == strcmp(keyname, "Return")) {
+               val = OP_EQUAL;
+       } else if (0 == strcmp(keyname, "KP_Add")) {
+               val = OP_PLUS;
+       } else if (0 == strcmp(keyname, "KP_Subtract")) {
+               val = OP_MINUS;
+       } else if (0 == strcmp(keyname, "minus")) {
+               val = OP_MINUS;
+       } else if (0 == strcmp(keyname, "KP_Multiply")) {
+               val = OP_MULTIPLY;
+       } else if (0 == strcmp(keyname, "slash")) {
+               val = OP_DIVIDE;
+       } else if (0 == strcmp(keyname, "KP_Divide")) {
+               val = OP_DIVIDE;
+       }else if (0 == strcmp(keyname, "BackSpace")) {
+               val = OP_DELETE;
+       }
+       CALC_FUN_END();
        return val;
 }
+#endif
 
 /**
 * @description
@@ -1719,17 +1926,16 @@ static void
 _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj,
                   void *event_info)
 {
-       CONV_FUNC_IN();
-
+       CALC_FUN_BEG();
        int val = 0;
-       if (data && ad->popup == NULL) {
+       if (data) {
+
                Evas_Object *obj = (Evas_Object *) data;
                val = _calculator_get_input_item(evas_obj, obj);
                if (ad->wrong_timer) {
                        ecore_timer_del(ad->wrong_timer);
                        ad->wrong_timer = NULL;
                }
-               _calc_entry_text_set(ad->input_entry, calculator_input_str);
                switch (val) {
                case OP_DELETE:
                        _calc_btn_backspace_clicked(ad->input_entry);
@@ -1758,15 +1964,15 @@ _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj,
                                                                 &calc_op_item
                                                                 [val]);
                        break;
-               case OP_EQUAL:
-                       __calculator_op_equal(ad->input_entry);
-                       break;
                case OP_DOT:
                        _calc_btn_dot_clicked(ad->input_entry);
                        break;
                case OP_PARENTHESIS:
                        __calculator_parenthesis_clicked(ad->input_entry);
                        break;
+               case OP_EQUAL:
+                       __calculator_op_equal(ad->input_entry);
+                       break;
                case OP_NUM_0:
                case OP_NUM_1:
                case OP_NUM_2:
@@ -1800,7 +2006,7 @@ _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj,
                }
        }
 
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
 static void __calculator_wrong_format_delete(Evas_Object *in_entry)
@@ -1818,9 +2024,10 @@ static void __calculator_wrong_text_set(char * wrong_string)
        memset(buf, 0, sizeof(buf));
        snprintf(buf, sizeof(buf),
                 "<align=right><+ font_size=%d><color=#855B11FF>%s",
-                get_max_fontsize(), wrong_string);
+                cur_fontsize, wrong_string);
        elm_entry_entry_set(ad->input_entry, buf);
        elm_entry_cursor_end_set(ad->input_entry);
+       elm_object_focus_set(ad->input_entry, EINA_TRUE);
        calc_view_revise_input_scroller(ad);
 }
 
@@ -1840,7 +2047,7 @@ static void __calculator_wrong_format_create(char * wrong_string)
                ad->wrong_timer = NULL;
        }
        ad->wrong_timer =
-    ecore_timer_add(2,
+    ecore_timer_add(3,
                    (Ecore_Task_Cb)
                    __calculator_wrong_format_delete,
                    ad->input_entry);
@@ -1851,10 +2058,12 @@ static void
 __calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
                        void *event_info)
 {
+       CALC_FUN_BEG();
        if (ad->calc_timer) {
                ecore_timer_del(ad->calc_timer);
                ad->calc_timer = NULL;
        }
+       CALC_FUN_END();
 }
 
 /**
@@ -1864,8 +2073,9 @@ __calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
 * @param    keypad      the keypad
 * @return   void
 */
-static void _calc_view_keypad_cb_register(Evas_Object * keypad)
+void _calc_view_keypad_cb_register(Evas_Object * keypad)
 {
+       CALC_FUN_BEG();
        char *key_name[] = {
                "item_per", "item_sqr", "item_fac", "item_c", "item_div",
                    "item_mul", "item_del",
@@ -1873,7 +2083,7 @@ static void _calc_view_keypad_cb_register(Evas_Object * keypad)
                    "item_num9", "item_sub",
                "item_ln", "item_log", "item_1x", "item_num4", "item_num5",
                    "item_num6", "item_plus",
-               "item_ex", "item_x2", "item_xy", "item_num1", "item_num2",
+               "item_10x", "item_x2", "item_xy", "item_num1", "item_num2",
                    "item_num3", "item_brack",
                "item_abs", "item_pi", "item_e", "item_num0", "item_dot",
                    "item_neg", "item_eq",
@@ -1901,6 +2111,7 @@ static void _calc_view_keypad_cb_register(Evas_Object * keypad)
 
                }
        }
+       CALC_FUN_END();
 }
 
 /**
@@ -1923,6 +2134,7 @@ _calc_view_input_entry_mouseup_cb(void *data, Evas * e, Evas_Object * entry,
 static void
 _calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
 {
+       CALC_FUN_BEG();
        strncpy(internal_str, entry_str, buf_size - 1);
        /* remove result that behind '='(include '=') */
        char *enter = strchr(internal_str, '=');
@@ -1943,7 +2155,7 @@ _calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
                }
        }
        internal_str[i] = '\0';
-
+       CALC_FUN_END();
 }
 
 #ifdef __i386__
@@ -1951,20 +2163,51 @@ static void
 _calc_view_input_entry_keyup_cb(void *data, Evas * e, Evas_Object * entry,
                                void *event_info)
 {
-       calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for hardkey input     
+       CALC_FUN_BEG();
+       calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for hardkey input
+       int val = 0;
        if (data) {
+               Evas_Object *obj = (Evas_Object *) data;
                Evas_Event_Key_Up *evt = (Evas_Event_Key_Up *) event_info;
-               printf("keyname: %s\n", (char *)evt->keyname);
-               if ((0 == strcmp(evt->keyname, "XF86Phone"))||
-                       (0 == strcmp(evt->keyname, "XF86PowerOff"))|| 
-                       (0 == strcmp(evt->keyname, "XF86AudioRaiseVolume"))||
-                       (0 == strcmp(evt->keyname, "XF86AudioLowerVolume"))){
-                       return;
+               if (0 == strcmp(evt->key, "Return")) {
+                       //calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
+                       __calculator_op_equal(entry);
+
+               }
+               val = _calculator_get_input_item_hd(evt->key, obj);
+               switch (val) {
+               case OP_PLUS:
+               case OP_MINUS:
+               case OP_MULTIPLY:
+               case OP_DIVIDE:
+                       __calculator_control_normal_func_clicked(ad->input_entry, &calc_op_item[val]);
+                       break;
+               case OP_DOT:
+                       _calc_btn_dot_clicked(ad->input_entry);
+                       break;
+               case OP_NUM_0:
+               case OP_NUM_1:
+               case OP_NUM_2:
+               case OP_NUM_3:
+               case OP_NUM_4:
+               case OP_NUM_5:
+               case OP_NUM_6:
+               case OP_NUM_7:
+               case OP_NUM_8:
+               case OP_NUM_9:
+                       __calculator_control_panel_number_button_clicked(ad-> input_entry, &calc_op_item[val]);
+                       break;
+               case OP_DELETE:
+                       calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
+                       break;
+               default:
+                       break;
                }
-               _calc_entry_backspace(ad->input_entry);
        }
+       CALC_FUN_END();
 }
 #endif
+
 static bool
 _calc_view_input_entry_error_include(char *string)
 {
@@ -1980,19 +2223,22 @@ _calc_view_input_entry_error_include(char *string)
 
 /**
 * @description
-*   The callback of input entry when text changed.
+* The callback of input entry when text changed
 *
-* @param    data        the appdata
-* @param    [in]obj     the input entry
-* @param    event_info  unused
-* @return   void
+* @param[in]   data    the appdata
+* @param[in]   obj     the input entry
+* @param[in]   event_info      unused
+* @return      void
 */
 static void
-_calc_view_input_entry_changed_cb(void *data, Evas_Object * obj,
+_calc_view_input_entry_changed_cb(void *data, Evas_Object *obj,
                                  void *event_info)
 {
+       CALC_FUN_BEG();
+       if (data == NULL || obj == NULL) {
+               return;
+       }
        struct appdata *ad = (struct appdata *)data;
-       PLOG("Input entry test changed\n");     /* Don't remove the log. It can guard against recursion. */
        const char *str = (char *)elm_entry_entry_get(obj);
 
        if (paste_flag) {
@@ -2023,11 +2269,11 @@ _calc_view_input_entry_changed_cb(void *data, Evas_Object * obj,
                } else if (nCntOp >= MAX_OPERATOR_NUM) {
                        __calculator_wrong_format_create(CALC_MSG_MAX_OP);
                } else {
-                       if(char_in){
+                       if (char_in) {
                                strncpy(calculator_input_str, internal_expr,
                                        index);
                                calculator_cursor_pos = index;
-                       }else{
+                       } else {
                                strncpy(calculator_input_str, internal_expr,
                                        sizeof(calculator_input_str) - 1);
                                calculator_cursor_pos = cur_pos;
@@ -2035,19 +2281,28 @@ _calc_view_input_entry_changed_cb(void *data, Evas_Object * obj,
                        _calc_entry_text_set(ad->input_entry, calculator_input_str);
                }
 
+               if (entry_tmp) {
+                       free(entry_tmp);
+                       entry_tmp = NULL;
+               }
                if (entry_expr) {
                        free(entry_expr);
+                       entry_expr = NULL;
                }
-       }else{
+       } else {
                char *entry_expr_s = elm_entry_markup_to_utf8(str);
                char internal_expr_s[MAX_EXPRESSION_LENGTH] = { 0 };
                _calc_view_input_entry_to_str(entry_expr_s, internal_expr_s,
-                                                 MAX_EXPRESSION_LENGTH);
+                                             MAX_EXPRESSION_LENGTH);
                if(!_calc_view_input_entry_error_include(internal_expr_s)){
                        /*change calculator_input_str, after cut operation*/
                        strncpy(calculator_input_str, internal_expr_s,
                        MAX_EXPRESSION_LENGTH - 1);
                }
+               if (entry_expr_s) {
+                       free(entry_expr_s);
+                       entry_expr_s = NULL;
+               }
        }
        /*
         * Prevent pasting images into entry.
@@ -2074,33 +2329,19 @@ _calc_view_input_entry_changed_cb(void *data, Evas_Object * obj,
 
                calc_view_revise_input_scroller(ad);
        }
-
+       CALC_FUN_END();
 }
 
 static void
 _calc_view_input_entry_paste_cb(void *data, Evas_Object * obj, void *event_info)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        paste_flag = TRUE;
        strncpy(calculator_before_paste_str, calculator_input_str,
                MAX_EXPRESSION_LENGTH - 1);
-       printf("line = %d\n", __LINE__);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 }
 
-static void
-__conv_view_clear_clicked_cb(void *data, Evas_Object * obj, const char *emission, const char *source)
-{
-
-       CONV_FUNC_IN();
-
-       struct appdata *ad = (struct appdata *)data;
-       elm_entry_entry_set(ad->hist_area, "");
-       elm_entry_entry_set(ad->input_entry, "");
-       _calc_view_clear_histroy(ad->hist_area);
-
-       CONV_FUNC_OUT();
-}
 
 /**
 * @description
@@ -2113,17 +2354,17 @@ __conv_view_clear_clicked_cb(void *data, Evas_Object * obj, const char *emission
 static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
                                                  struct appdata *ad)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        Evas_Object *entry = elm_entry_add(ad->edje);
        elm_entry_single_line_set(entry, EINA_FALSE);
-       elm_entry_line_wrap_set(entry, ELM_WRAP_WORD);
        elm_entry_editable_set(entry, EINA_TRUE);
        elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
        elm_entry_entry_set(entry, "");
        elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_NO_IMAGE);
        elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
        elm_entry_cursor_end_set(entry);
-       elm_object_style_set(entry, "black");
+       elm_object_focus_set(entry, EINA_TRUE);
+    elm_object_style_set(entry, "black");
        evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND,
                                         EVAS_HINT_EXPAND);
        evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
@@ -2137,13 +2378,15 @@ static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
 #ifdef __i386__
        evas_object_event_callback_add(entry, EVAS_CALLBACK_KEY_UP,
                                       _calc_view_input_entry_keyup_cb, ad);
+       evas_object_smart_callback_del (entry, "changed",  _calc_view_input_entry_changed_cb);
 #endif
        evas_object_show(entry);
        limit_filter_data.max_char_count = 0;
        limit_filter_data.max_byte_count = 419 + 20;    //19*21+20//result:20
        elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size,
                                     &limit_filter_data);
-       CONV_FUNC_OUT();
+       elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
+       CALC_FUN_END();
        return entry;
 }
 
@@ -2158,7 +2401,7 @@ static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
 */
 static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        Evas_Object *scroller = elm_scroller_add(parent);
        elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
        evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
@@ -2167,22 +2410,50 @@ static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
                                        EVAS_HINT_FILL);
 
        evas_object_show(scroller);
-
-       CONV_FUNC_OUT();
-
+       CALC_FUN_END();
        return scroller;
 }
 
 /**
 * @description
-*   Create the main layout.
+* Create the background
+*
+* @param[in]   parent  background's parent
+* @return              when success return background, return NULL oppositely
+* @retval      layout  if success, return the background
+* @retval      NULL    if create failed or parent is null, return null
+* @exception
+*/
+static Evas_Object *__create_bg(Evas_Object *parent)
+{
+       CALC_FUN_BEG();
+       if (parent == NULL) {
+               return NULL;
+       }
+       Evas_Object *bg = elm_bg_add(parent);
+       if (bg == NULL) {
+               return NULL;
+       }
+       evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_win_resize_object_add(parent, bg);
+       evas_object_show(bg);
+       CALC_FUN_END();
+       return bg;
+}
+
+/**
+* @description
+* Create the main layout
 *
-* @param    parent          main layout's parent
-* @return   Evas_Object*    when success return a layout, return NULL oppositely.
+* @param[in]   parent  main layout's parent
+* @return              when success return a layout, return NULL oppositely
+* @retval      layout  if success, return the main layout
+* @retval      NULL    if create failed or parent is null, return null
+* @exception
 */
-static Evas_Object *_calc_view_create_layout_main(Evas_Object * parent)
+static Evas_Object *__calc_view_create_layout_main(Evas_Object *parent)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
 
        if (parent == NULL) {
                return NULL;
@@ -2193,21 +2464,84 @@ static Evas_Object *_calc_view_create_layout_main(Evas_Object * parent)
                return NULL;
        }
 
-       elm_layout_theme_set(layout, "standard", "window", "integration");
+       const char *profile = elm_config_profile_get();
+       if (!strcmp(profile, "mobile")) {
+               elm_layout_theme_set(layout, "layout", "application", "default");
+       } else if (!strcmp(profile, "desktop")) {
+               elm_layout_theme_set(layout, "layout", "application", "noindicator");
+       }
+
        evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
                                         EVAS_HINT_EXPAND);
        elm_win_resize_object_add(parent, layout);
 
-       edje_object_signal_emit(_EDJ(layout), "elm,state,show,content", "elm");
        edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator",
                                "elm");
        evas_object_show(layout);
 
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 
        return layout;
 }
 
+void _btn_clicked_cb(void *data, Evas_Object * obj, void *event_info)
+{
+       CALC_FUN_BEG();
+       Evas_Object *win_main = (Evas_Object *) data;
+       elm_win_lower(win_main);
+       CALC_FUN_END();
+}
+
+/**
+* @description
+*   Callback function of "Clear" Button on naviframe
+*
+* @param    data      the appdata
+* @param    obj
+* @param    event_info
+* @return   void
+
+*/
+static void
+__calc_view_clear_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       CALC_FUN_BEG();
+       struct appdata *ad = (struct appdata *)data;
+       elm_entry_entry_set(ad->hist_area, "");
+       elm_entry_entry_set(ad->input_entry, "");
+       _calc_view_clear_histroy(ad->hist_area);
+       CALC_FUN_END();
+}
+
+/**
+* @description
+*   Load the Naviframe.
+*
+* @param    ad      the appdata
+* @return   naviframe object
+
+*/
+static Evas_Object *__calc_view_create_navigation_layout(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       Evas_Object *nf = elm_naviframe_add(ad->layout);
+       Evas_Object *back_btn = elm_button_add(nf);
+       elm_object_style_set(back_btn, "naviframe/end_btn/default");
+       evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
+       ad->navi_it =
+           elm_naviframe_item_push(nf, NULL, back_btn, NULL, ad->edje, NULL);
+       elm_naviframe_item_title_visible_set(ad->navi_it, EINA_FALSE);
+       ad->tool_bar = elm_toolbar_add(nf);
+       elm_toolbar_shrink_mode_set(ad->tool_bar, ELM_TOOLBAR_SHRINK_EXPAND);
+       elm_object_item_part_content_set(ad->navi_it, "controlbar", ad->tool_bar);
+       ad->clear_btn = elm_toolbar_item_append(ad->tool_bar, NULL, "Clear History", __calc_view_clear_clicked_cb, ad);
+       ad->invalid_btn = elm_toolbar_item_append(ad->tool_bar, NULL, NULL, NULL, ad);
+       elm_object_item_disabled_set(ad->invalid_btn, EINA_TRUE);
+       evas_object_show(nf);
+       CALC_FUN_END();
+       return nf;
+}
+
 /**
 * @description
 *   Load the main view of calculator.
@@ -2218,13 +2552,15 @@ static Evas_Object *_calc_view_create_layout_main(Evas_Object * parent)
 */
 void calc_view_load(struct appdata *ad)
 {
-       CONV_FUNC_IN();
-
-       ad->layout = _calc_view_create_layout_main(ad->win);
-       ad->edje = load_edj(ad->win, LAYOUT_EDJ_NAME, GRP_MAIN);
+       CALC_FUN_BEG();
+       ad->bg = __create_bg(ad->win);
+       ad->layout = __calc_view_create_layout_main(ad->win);
+       ad->edje = load_edj(ad->layout, LAYOUT_EDJ_NAME, GRP_MAIN);
        evas_object_show(ad->edje);
        evas_object_name_set(ad->edje, "edje");
-       elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->edje);
+
+       ad->nf = __calc_view_create_navigation_layout(ad);
+       elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf);
 
        /* inititialize environment variable */
        locale = localeconv();
@@ -2236,6 +2572,7 @@ void calc_view_load(struct appdata *ad)
        if (len_seq == 2 || len_seq == 0) {
                separator_ch = 32;
        }
+
        /*init svi */
        svi_init(&ad->svi_handle);
 
@@ -2245,17 +2582,7 @@ void calc_view_load(struct appdata *ad)
        elm_object_content_set(ad->input_scroller, ad->input_entry);
        edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
                                 ad->input_scroller);
-       edje_object_signal_callback_add(_EDJ(ad->edje), "clicked", "",
-                                       __conv_view_clear_clicked_cb, ad);
-
-       /* pannels */
-       ad->por_pannel = load_edj(ad->edje, LAYOUT_EDJ_NAME, GRP_POR_PANNEL);
-       edje_object_part_swallow(_EDJ(ad->edje), "por_pannel/rect",
-                                ad->por_pannel);
-       edje_object_signal_emit(_EDJ(ad->edje), "portrait", "");
-       _calc_view_keypad_cb_register(_EDJ(ad->por_pannel));
-
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
 
 }
 
index c36f270..dfe13bd 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #include <math.h>              /* For math functions, cos(), sin(), etc. */
 #include <dlog.h>
@@ -26,6 +26,9 @@
 #include "calc-expression.h"
 #include "calculator_parser.h"
 
+#define  DECNUMDIGITS 34
+#include "decnumber/decNumber.h"
+
 #define CALCULATOR_MAX_FUNC_NUMBER                             16              /**<maximum num of function*/
 
 extern char decimal_ch;
@@ -42,7 +45,7 @@ static const function_t g_functions[CALCULATOR_MAX_FUNC_NUMBER] = {
         CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
        {"sqrt", "sqrt", 4, 'q', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
         CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
-       {"e^x", "e^", 2, 'E', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+       {"10^x", "10^", 3, 'T', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
         CALCULATOR_CALCULATE_PRIORITY_HIGHER, FALSE},
        {"x!", "!", 1, '!', FUNCTION_POSTFIX, OPERATOR_TYPE_UNARY,
         CALCULATOR_CALCULATE_PRIORITY_HIGHEST, FALSE},
@@ -97,14 +100,6 @@ __calculator_calculate_insert_node(GNode ** out_tree, GNode * to_insert,
        upper_node = *out_tree;
        node = upper_node;
 
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
-
        while (CALCULATOR_GET_NODE_DATA(upper_node)->node_calcu_priority >
               CALCULATOR_GET_NODE_DATA(to_insert)->node_calcu_priority) {
                if (G_NODE_IS_ROOT(upper_node)) {
@@ -145,13 +140,6 @@ __calculator_calculate_insert_node(GNode ** out_tree, GNode * to_insert,
                } else if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type ==
                           OPERATOR_TYPE_UNARY) {
                        GNode *tmp_node = NULL;
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
 
                        if (const_node) {
                                node_data =
@@ -218,13 +206,6 @@ __calculator_calculate_insert_node(GNode ** out_tree, GNode * to_insert,
                        g_node_insert(upper_node, -1, to_insert);
                        CALCULATOR_GET_NODE_DATA(upper_node)->children_num++;
                }
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
 
                else if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type == OPERATOR_TYPE_UNARY)     //upper_node must be equal to node equalized to *out_tree, for no functions' prority higher than unary operator
                {
@@ -381,7 +362,7 @@ static void __calculator_expression_tri_func_parenthesis(char *exp)
 static bool
 __calculator_calculate_formula_scan(char *string, int *end_idx, char *error_msg)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        gint i = 0;
        gchar *p = NULL;
 
@@ -408,7 +389,7 @@ __calculator_calculate_formula_scan(char *string, int *end_idx, char *error_msg)
                p++;
        }
        *end_idx = p - 1 - string;
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return TRUE;
 }
 
@@ -551,13 +532,12 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                                     char *start_pos, int end_idx,
                                     char *error_msg)
 {
-       CONV_FUNC_IN();
+       CALC_FUN_BEG();
        char *end_pos = start_pos + end_idx;
        gchar *p = NULL;
        gchar *q = NULL;
        gchar tmp[MAX_RESULT_LENGTH];
        gint i = 0;
-       gdouble factor = 0;
        calculator_state_t calculator_state = CALCULATOR_OPERAND_INPUT;
        calculator_node_data_t *node_data = NULL;
        GNode *tree = NULL;
@@ -573,13 +553,6 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
                return FALSE;
        }
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
 
        /* Scan from start to end of string */
        for (p = start_pos; p <= end_pos;) {
@@ -605,14 +578,12 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                        calculator_state = CALCULATOR_OPERATOR_INPUT;
                        if (i != 0)     //save the before operator,create a node.such as 345sin(),save 345
                        {
-                               factor = atof(tmp);
-                               memset(tmp, 0x00, sizeof(tmp));
                                i = 0;
 
                                node_data =
                                    g_malloc0(sizeof(calculator_node_data_t));
-                               node_data->tmp_result = factor;
-
+                               strcpy(node_data->tmp_result, tmp);
+                               memset(tmp, 0x00, sizeof(tmp));
                                node_data->negative_flag = 1;
                                node_data->negative_flag *= negative_sign;
                                new_node = g_node_new(node_data);
@@ -622,16 +593,14 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                                {
                                        if (((function.op_type ==
                                              OPERATOR_TYPE_BINARY)
-                                            && (function.function_char != '+')
+                                            /*&& (function.function_char != '+')*/
                                             && (function.function_char != '-'))
                                            ||
                                            ((function.op_type ==
                                              OPERATOR_TYPE_UNARY)
                                             && (function.category ==
                                                 FUNCTION_POSTFIX))) {
-                                               PLOG("Line:%d", __LINE__);
-                                               strcat(error_msg,
-                                                      _("Syntax error"));
+                                               strcat(error_msg,CALC_MSG_SYNTAX_ERROR);
                                                return FALSE;
                                        } else if (function.function_char ==
                                                   '-') {
@@ -640,13 +609,6 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                                        }
                                }
                        }
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
 
                        if (function.category == FUNCTION_CONSTANT)     //Pi, e
                        {
@@ -675,11 +637,7 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                                                    CALCULATOR_GET_NODE_DATA
                                                    (last_node)->
                                                    operator_type) {
-                                                       PLOG("Line:%d",
-                                                            __LINE__);
-                                                       strcat(error_msg,
-                                                              _
-                                                              ("Syntax error"));
+                                                       strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
                                                        return FALSE;
                                                }
                                                __calculator_calculate_insert_node
@@ -693,9 +651,10 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                                node_data =
                                    g_malloc0(sizeof(calculator_node_data_t));
                                if (function.function_char == 'p') {
-                                       node_data->tmp_result = PI;
+                                       strcpy(node_data->tmp_result, PI_STR);
                                } else if (function.function_char == 'e') {
-                                       node_data->tmp_result = EXPONENT;
+                                       strcpy(node_data->tmp_result,
+                                              EXPONENT_STR);
                                }
                                node_data->cur_operator =
                                    function.function_char;
@@ -767,13 +726,6 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                        p++;    /* Shift */
                }
 
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
                if (NULL == q) {
                        strcat(error_msg, CALC_MSG_SYNTAX_ERROR);       //add for "6((" ,then "="
                        return FALSE;
@@ -782,8 +734,8 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                        if (!isdigit(*p)
                            || (calculator_state ==
                                CALCULATOR_OPERAND_FRACTION_INPUT)) {
-                               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
-                               return FALSE;
+                               //strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                               //return FALSE;
                        } else {
                                calculator_state =
                                    CALCULATOR_OPERAND_FRACTION_INPUT;
@@ -798,22 +750,13 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                                        return FALSE;
                                }
                        }
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
-
                        //if ((new_node) && (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == PI || CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == EXPONENT))
                        if ((new_node)
                            &&
-                           (FLOAT_EQUAL
-                            (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result,
-                             PI)
-                            || FLOAT_EQUAL(CALCULATOR_GET_NODE_DATA(new_node)->
-                                           tmp_result, EXPONENT))) {
+                           (!strcmp
+                            (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, PI_STR)
+                            ||
+                            !strcmp(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, EXPONENT_STR))) {
                                node_data =
                                    g_malloc0(sizeof(calculator_node_data_t));
                                node_data->cur_operator = 'x';
@@ -834,22 +777,14 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                                last_node = tree;
                                new_node = NULL;
                        }
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
 
                        if (i != 0) {
-                               factor = atof(tmp);
-                               memset(tmp, 0x00, sizeof(tmp));
                                i = 0;
 
                                node_data =
                                    g_malloc0(sizeof(calculator_node_data_t));
-                               node_data->tmp_result = factor;
+                               strcpy(node_data->tmp_result, tmp);
+                               memset(tmp, 0x00, sizeof(tmp));
                                node_data->negative_flag = 1;
                                node_data->negative_flag *= negative_sign;
                                negative_sign = 1;
@@ -921,13 +856,6 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                                    negative_flag *= negative_sign;
                        }
                        negative_sign = 1;
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
 
                        if ((*p == '(') || (isdigit(*p))) {
                                node_data =
@@ -997,23 +925,16 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                        }
                }
        }
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
 
        if (i != 0)             //last digit number
        {
                //if ((new_node) && (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == PI || CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == EXPONENT))
                if ((new_node)
                    &&
-                   (FLOAT_EQUAL
-                    (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, PI)
-                    || FLOAT_EQUAL(CALCULATOR_GET_NODE_DATA(new_node)->
-                                   tmp_result, EXPONENT))) {
+                   (!strcmp
+                    (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, PI_STR)
+                    || !strcmp(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result,
+                               EXPONENT_STR))) {
                        node_data = g_malloc0(sizeof(calculator_node_data_t));
                        node_data->cur_operator = 'x';
                        node_data->negative_flag = 1;
@@ -1033,13 +954,11 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                        last_node = tree;
                        new_node = NULL;
                }
-
-               factor = atof(tmp);
-               memset(tmp, 0x00, sizeof(tmp));
                i = 0;
 
                node_data = g_malloc0(sizeof(calculator_node_data_t));
-               node_data->tmp_result = factor;
+               strcpy(node_data->tmp_result, tmp);
+               memset(tmp, 0x00, sizeof(tmp));
                node_data->negative_flag = 1;
                node_data->negative_flag *= negative_sign;
                negative_sign = 1;
@@ -1059,13 +978,6 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                        new_node = NULL;
                }
        }
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
 
        if (new_node != NULL) {
                CALCULATOR_GET_NODE_DATA(new_node)->negative_flag *=
@@ -1089,7 +1001,7 @@ __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
                new_node = NULL;
        }
        *out_tree = g_node_get_root(last_node);
-       CONV_FUNC_OUT();
+       CALC_FUN_END();
        return TRUE;
 }
 
@@ -1106,95 +1018,89 @@ static gboolean
 __calculator_calculate_exec_traverse_func(GNode * node, gpointer data)
 {
        gdouble operand0, operand1 = 0.0;
+       double tmp_ret = 0.0;
+       decNumber doperand0, doperand1, dresult;
+       decContext set;
+       char dec_result[DECNUMDIGITS + 14];
        char *error_msg = (char *)data;
-
-/*
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
-
+       char op0buf[MAX_RESULT_LENGTH] = { 0 };
+       char op1buf[MAX_RESULT_LENGTH] = { 0 };
        if (CALCULATOR_GET_NODE_DATA(node)->children_num !=
            CALCULATOR_GET_NODE_DATA(node)->operator_type) {
                strcat(error_msg, CALC_MSG_NUM_AFTER_OP);
                return TRUE;    //break the recursion
        }
 
-       operand0 =
-           CALCULATOR_GET_NODE_DATA(node->children)->tmp_result *
-           CALCULATOR_GET_NODE_DATA(node->children)->negative_flag;
-       CALCULATOR_GET_NODE_DATA(node->children)->negative_flag = 1;
+       decContextTestEndian(0);
+       decContextDefault(&set, DEC_INIT_BASE);
+       set.digits = DECNUMDIGITS;
+
+       if (CALCULATOR_GET_NODE_DATA(node->children)->negative_flag == -1) {
+               strcat(op0buf, "-");
+               CALCULATOR_GET_NODE_DATA(node->children)->negative_flag = 1;
+       }
+       strcat(op0buf, CALCULATOR_GET_NODE_DATA(node->children)->tmp_result);
+       operand0 = atof(op0buf);
+       decNumberFromString(&doperand0, op0buf, &set);
 
        if (CALCULATOR_GET_NODE_DATA(node)->operator_type ==
            OPERATOR_TYPE_BINARY) {
-               operand1 =
-                   CALCULATOR_GET_NODE_DATA(node->children->next)->tmp_result *
-                   CALCULATOR_GET_NODE_DATA(node->children->next)->
-                   negative_flag;
-               CALCULATOR_GET_NODE_DATA(node->children->next)->negative_flag =
-                   1;
+               if (CALCULATOR_GET_NODE_DATA
+                   (node->children->next)->negative_flag == -1) {
+                       strcat(op1buf, "-");
+                       CALCULATOR_GET_NODE_DATA(node->children->
+                                                next)->negative_flag = 1;
+               }
+               strcat(op1buf,
+                      CALCULATOR_GET_NODE_DATA(node->children->
+                                               next)->tmp_result);
+               operand1 = atof(op1buf);
+               decNumberFromString(&doperand1, op1buf, &set);
        }
-
-/* @ describe
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
        switch (CALCULATOR_GET_NODE_DATA(node)->cur_operator) {
        case '+':
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                   operand0 + operand1;
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
+               decNumberAdd(&dresult, &doperand0, &doperand1, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                break;
        case '-':
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                   operand0 - operand1;
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
+               decNumberSubtract(&dresult, &doperand0, &doperand1, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                break;
        case 'x':
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                   operand0 * operand1;
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
+               decNumberMultiply(&dresult, &doperand0, &doperand1, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                break;
        case '/':
                if (FLOAT_EQUAL(operand1, 0)) {
                        strcat(error_msg, CALC_MSG_DIVIDE_BY_ZERO);
                        return TRUE;    //break the recursion
                } else {
-                       CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                           operand0 / operand1;
-                       //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
+                       decNumberDivide(&dresult, &doperand0, &doperand1, &set);
+                       decNumberToString(&dresult, dec_result);
+                       strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result,
+                              dec_result);
                }
                break;
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
-
        case '^':
                if (operand0 < 0) {
                        gdouble power = 0.0;
                        power = floor(operand1);
                        if (!FLOAT_EQUAL(power, operand1))      //operand1 is not an integer
                        {
-                               strcat(error_msg, CALC_MSG_INVALID_XY);
                                return TRUE;
                        }
                }
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                   pow(operand0, operand1);
+               tmp_ret =pow(operand0, operand1);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
        case '!':
                if (operand0 < 0) {
@@ -1209,92 +1115,81 @@ __calculator_calculate_exec_traverse_func(GNode * node, gpointer data)
                if (strlen(error_msg) != 0) {
                        return TRUE;
                }
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                   __calculator_calculate_factorial(operand0, error_msg);
+               tmp_ret = __calculator_calculate_factorial(operand0, error_msg);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                if (strlen(error_msg) != 0) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
 
        case 'L':
                if (operand0 < 0) {
-                       strcat(error_msg, CALC_MSG_INVALID_LN);
                        return TRUE;
                } else if (FLOAT_EQUAL(operand0, 0)) {
-                       strcat(error_msg, CALC_MSG_INVALID_LN);
                        return TRUE;
                }
-
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result = log(operand0);
+               set.emax = 999999;
+               set.emin = -999999;
+               decNumberLn(&dresult, &doperand0, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
        case 'q':
                if (operand0 < 0) {
                        strcat(error_msg, CALC_MSG_INVALID_SQUARE);
                        return TRUE;
                }
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result = sqrt(operand0);
-               if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
-                       return TRUE;
-               }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
-               break;
-       case 'E':
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result = exp(operand0);
+               decNumberSquareRoot(&dresult, &doperand0, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
-
        case 's':
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                   sin(operand0 * RADIAN_FACTOR);
+               tmp_ret = sin(operand0 * RADIAN_FACTOR);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
        case 'c':
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                   cos(operand0 * RADIAN_FACTOR);
+               tmp_ret = cos(operand0 * RADIAN_FACTOR);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
        case 't':
                if (FLOAT_EQUAL(fmod(operand0, 180), 90) || FLOAT_EQUAL(fmod(operand0, 180), -90))      //revise by bfl
                {
-                       strcat(error_msg, CALC_MSG_INVALID_TAN);
                        return TRUE;
                }
-
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result =
-                   tan(operand0 * RADIAN_FACTOR);
+               tmp_ret = tan(operand0 * RADIAN_FACTOR);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
-/* @ attention
-     This is redundant comment.
-     Its only use is for Klocwork testing.
-     The comment rete should passed 25%.
-     But we have only one day to do this work.
-     So, sorry, I will delete this comment and add useful comment later.
-*/
-
        case 'l':
                if (operand0 < 0) {
                        strcat(error_msg, CALC_MSG_INVALID_LOG);
@@ -1303,46 +1198,46 @@ __calculator_calculate_exec_traverse_func(GNode * node, gpointer data)
                        strcat(error_msg, CALC_MSG_INVALID_LOG);
                        return TRUE;
                }
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result = log10(operand0);
+               set.emax = 999999;
+               set.emin = -999999;
+               decNumberLog10(&dresult, &doperand0, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
        case 'b':
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result = fabs(operand0);
+               tmp_ret = fabs(operand0);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
 
        case '2':
-               CALCULATOR_GET_NODE_DATA(node)->tmp_result = pow(2, operand0);
+               decNumberFromString(&doperand1, "2", &set);
+               decNumberPower(&dresult, &doperand1, &doperand0, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
                if (!__calculator_check_overflow
-                   (CALCULATOR_GET_NODE_DATA(node)->tmp_result, error_msg)) {
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
                        return TRUE;
                }
-               //calculator_calculate_truncate_result(&(CALCULATOR_GET_NODE_DATA(node)->tmp_result));
                break;
 
        default:
                break;
        }
-
-/* @ describe
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
-
-       CALCULATOR_GET_NODE_DATA(node)->tmp_result *=
+       /*CALCULATOR_GET_NODE_DATA(node)->tmp_result *=
            CALCULATOR_GET_NODE_DATA(node)->negative_flag;
-       CALCULATOR_GET_NODE_DATA(node)->negative_flag = 1;
+       CALCULATOR_GET_NODE_DATA(node)->negative_flag = 1;*/
 
        return FALSE;
 }
@@ -1367,18 +1262,10 @@ __calculator_calculate_exec(GNode * tree, double **result, char *error_msg)
                strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
                return FALSE;   //break the recursion
        } else if (depth == 1) {
-               **result = CALCULATOR_GET_NODE_DATA(tree)->tmp_result;
+               **result = atof(CALCULATOR_GET_NODE_DATA(tree)->tmp_result);
                **result *= CALCULATOR_GET_NODE_DATA(tree)->negative_flag;
                return TRUE;
        }
-
-/* @ describe
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
        g_node_traverse(tree,
                        G_POST_ORDER,
                        G_TRAVERSE_NON_LEAFS,
@@ -1389,7 +1276,7 @@ __calculator_calculate_exec(GNode * tree, double **result, char *error_msg)
        if (strlen(error_msg) > 0) {
                return FALSE;
        } else {
-               **result = CALCULATOR_GET_NODE_DATA(tree)->tmp_result;
+               **result = atof(CALCULATOR_GET_NODE_DATA(tree)->tmp_result);
        }
        return TRUE;
 }
@@ -1404,13 +1291,7 @@ __calculator_calculate_exec(GNode * tree, double **result, char *error_msg)
 */
 
 #if 0
-/* @ attention
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
+
 /*
 bool calculator_calculate_truncate_result(double* tmp_result)
 {
@@ -1466,13 +1347,6 @@ bool calculator_get_digits_number(char *szInput, int *pDigitCnt, int *pPointCnt)
        *pDigitCnt = 0;
        *pPointCnt = 0;
 
-/* @ describe
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
        if (nLen > 0) {
                for (nIndex = nLen - 1; nIndex >= 0; nIndex--) {
                        if (isdigit(szInput[nIndex])) {
@@ -1496,14 +1370,6 @@ bool calculator_get_digits_number(char *szInput, int *pDigitCnt, int *pPointCnt)
        return true;
 }
 
-/* @ describe
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
-
 /**
 * @describe
 *
@@ -1552,13 +1418,7 @@ bool calculator_expression_length_check(char *str, char *error_msg)
                                        nDigitCnt++;
                                } else {
                                        nPointCnt++;
-/* @ attention
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
+
 #if 0                          //YangQ
                                        /*
                                           if(nPointCnt > CALCULATORUI_MAX_INPUT_DECIMALS)
@@ -1572,16 +1432,8 @@ bool calculator_expression_length_check(char *str, char *error_msg)
                                }
                        }
                }
-/* @ describe
-    This is redundant comment.
-    Its only use is for Klocwork testing.
-    The comment rete should passed 25%.
-    But we have only one day to do this work.
-    So, sorry, I will delete this comment and add useful comment later.
-*/
                else if (c == decimal_ch) {
                        if (has_dot == 1) {
-                               strcat(error_msg, CALC_MSG_ENTRY_LIMIT);
                                return FALSE;
                        } else {
                                has_dot = 1;
@@ -1649,7 +1501,6 @@ bool calculator_calculate(gchar * string, gdouble * result, char *error_msg)
                } else {
                        LOGD("current tree is null\n");
                }
-               PLOG("error_msg:%s,line:%d\n", error_msg, __LINE__);
                return FALSE;
        }
        if (!__calculator_calculate_exec(tree, &result, error_msg)) {
diff --git a/src/decnumber/decContext.c b/src/decnumber/decContext.c
new file mode 100644 (file)
index 0000000..5ff92a7
--- /dev/null
@@ -0,0 +1,478 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Context module                                             */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2009.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for handling arithmetic         */
+/* context structures.                                                */
+/* ------------------------------------------------------------------ */
+
+#include <string.h>            // for strcmp
+#include <stdio.h>             // for printf if DECCHECK
+#include "decContext.h"                // context and base types
+#include "decNumberLocal.h"    // decNumber local types, etc.
+
+/* compile-time endian tester [assumes sizeof(Int)>1] */
+static const Int mfcone = 1;   // constant 1
+static const Flag *mfctop = (const Flag *)&mfcone;     // -> top byte
+#define LITEND *mfctop         // named flag; 1=little-endian
+
+/* ------------------------------------------------------------------ */
+/* round-for-reround digits                                           */
+/* ------------------------------------------------------------------ */
+const uByte DECSTICKYTAB[10] = { 1, 1, 2, 3, 4, 6, 6, 7, 8, 9 };       /* used if sticky */
+
+/* ------------------------------------------------------------------ */
+/* Powers of ten (powers[n]==10**n, 0<=n<=9)                          */
+/* ------------------------------------------------------------------ */
+const uInt DECPOWERS[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
+       10000000, 100000000, 1000000000
+};
+
+/* ------------------------------------------------------------------ */
+/* decContextClearStatus -- clear bits in current status              */
+/*                                                                    */
+/*  context is the context structure to be queried                    */
+/*  mask indicates the bits to be cleared (the status bit that        */
+/*    corresponds to each 1 bit in the mask is cleared)               */
+/*  returns context                                                   */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextClearStatus(decContext * context, uInt mask)
+{
+       context->status &= ~mask;
+       return context;
+}                              // decContextClearStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextDefault -- initialize a context structure                */
+/*                                                                    */
+/*  context is the structure to be initialized                        */
+/*  kind selects the required set of default values, one of:          */
+/*      DEC_INIT_BASE       -- select ANSI X3-274 defaults            */
+/*      DEC_INIT_DECIMAL32  -- select IEEE 754 defaults, 32-bit       */
+/*      DEC_INIT_DECIMAL64  -- select IEEE 754 defaults, 64-bit       */
+/*      DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit      */
+/*      For any other value a valid context is returned, but with     */
+/*      Invalid_operation set in the status field.                    */
+/*  returns a context structure with the appropriate initial values.  */
+/* ------------------------------------------------------------------ */
+decContext *decContextDefault(decContext * context, Int kind)
+{
+       // set defaults...
+       context->digits = 9;    // 9 digits
+       context->emax = DEC_MAX_EMAX;   // 9-digit exponents
+       context->emin = DEC_MIN_EMIN;   // .. balanced
+       context->round = DEC_ROUND_HALF_UP;     // 0.5 rises
+       context->traps = DEC_Errors;    // all but informational
+       context->status = 0;    // cleared
+       context->clamp = 0;     // no clamping
+#if DECSUBSET
+       context->extended = 0;  // cleared
+#endif
+       switch (kind) {
+       case DEC_INIT_BASE:
+               // [use defaults]
+               break;
+       case DEC_INIT_DECIMAL32:
+               context->digits = 7;    // digits
+               context->emax = 96;     // Emax
+               context->emin = -95;    // Emin
+               context->round = DEC_ROUND_HALF_EVEN;   // 0.5 to nearest even
+               context->traps = 0;     // no traps set
+               context->clamp = 1;     // clamp exponents
+#if DECSUBSET
+               context->extended = 1;  // set
+#endif
+               break;
+       case DEC_INIT_DECIMAL64:
+               context->digits = 16;   // digits
+               context->emax = 384;    // Emax
+               context->emin = -383;   // Emin
+               context->round = DEC_ROUND_HALF_EVEN;   // 0.5 to nearest even
+               context->traps = 0;     // no traps set
+               context->clamp = 1;     // clamp exponents
+#if DECSUBSET
+               context->extended = 1;  // set
+#endif
+               break;
+       case DEC_INIT_DECIMAL128:
+               context->digits = 34;   // digits
+               context->emax = 6144;   // Emax
+               context->emin = -6143;  // Emin
+               context->round = DEC_ROUND_HALF_EVEN;   // 0.5 to nearest even
+               context->traps = 0;     // no traps set
+               context->clamp = 1;     // clamp exponents
+#if DECSUBSET
+               context->extended = 1;  // set
+#endif
+               break;
+
+       default:                // invalid Kind
+               // use defaults, and ..
+               decContextSetStatus(context, DEC_Invalid_operation);    // trap
+       }
+
+       return context;
+}                              // decContextDefault
+
+/* ------------------------------------------------------------------ */
+/* decContextGetRounding -- return current rounding mode              */
+/*                                                                    */
+/*  context is the context structure to be queried                    */
+/*  returns the rounding mode                                         */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+enum rounding decContextGetRounding(decContext * context)
+{
+       return context->round;
+}                              // decContextGetRounding
+
+/* ------------------------------------------------------------------ */
+/* decContextGetStatus -- return current status                       */
+/*                                                                    */
+/*  context is the context structure to be queried                    */
+/*  returns status                                                    */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+uInt decContextGetStatus(decContext * context)
+{
+       return context->status;
+}                              // decContextGetStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextRestoreStatus -- restore bits in current status          */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  newstatus is the source for the bits to be restored               */
+/*  mask indicates the bits to be restored (the status bit that       */
+/*    corresponds to each 1 bit in the mask is set to the value of    */
+/*    the correspnding bit in newstatus)                              */
+/*  returns context                                                   */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextRestoreStatus(decContext * context,
+                                   uInt newstatus, uInt mask)
+{
+       context->status &= ~mask;       // clear the selected bits
+       context->status |= (mask & newstatus);  // or in the new bits
+       return context;
+}                              // decContextRestoreStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextSaveStatus -- save bits in current status                */
+/*                                                                    */
+/*  context is the context structure to be queried                    */
+/*  mask indicates the bits to be saved (the status bits that         */
+/*    correspond to each 1 bit in the mask are saved)                 */
+/*  returns the AND of the mask and the current status                */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+uInt decContextSaveStatus(decContext * context, uInt mask)
+{
+       return context->status & mask;
+}                              // decContextSaveStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextSetRounding -- set current rounding mode                 */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  newround is the value which will replace the current mode         */
+/*  returns context                                                   */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetRounding(decContext * context, enum rounding newround)
+{
+       context->round = newround;
+       return context;
+}                              // decContextSetRounding
+
+/* ------------------------------------------------------------------ */
+/* decContextSetStatus -- set status and raise trap if appropriate    */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  status  is the DEC_ exception code                                */
+/*  returns the context structure                                     */
+/*                                                                    */
+/* Control may never return from this routine, if there is a signal   */
+/* handler and it takes a long jump.                                  */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetStatus(decContext * context, uInt status)
+{
+       context->status |= status;
+       if (status & context->traps)
+               raise(SIGFPE);
+       return context;
+}                              // decContextSetStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextSetStatusFromString -- set status from a string + trap   */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  string is a string exactly equal to one that might be returned    */
+/*            by decContextStatusToString                             */
+/*                                                                    */
+/*  The status bit corresponding to the string is set, and a trap     */
+/*  is raised if appropriate.                                         */
+/*                                                                    */
+/*  returns the context structure, unless the string is equal to      */
+/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
+/*    returned.                                                       */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetStatusFromString(decContext * context,
+                                         const char *string)
+{
+       if (strcmp(string, DEC_Condition_CS) == 0)
+               return decContextSetStatus(context, DEC_Conversion_syntax);
+       if (strcmp(string, DEC_Condition_DZ) == 0)
+               return decContextSetStatus(context, DEC_Division_by_zero);
+       if (strcmp(string, DEC_Condition_DI) == 0)
+               return decContextSetStatus(context, DEC_Division_impossible);
+       if (strcmp(string, DEC_Condition_DU) == 0)
+               return decContextSetStatus(context, DEC_Division_undefined);
+       if (strcmp(string, DEC_Condition_IE) == 0)
+               return decContextSetStatus(context, DEC_Inexact);
+       if (strcmp(string, DEC_Condition_IS) == 0)
+               return decContextSetStatus(context, DEC_Insufficient_storage);
+       if (strcmp(string, DEC_Condition_IC) == 0)
+               return decContextSetStatus(context, DEC_Invalid_context);
+       if (strcmp(string, DEC_Condition_IO) == 0)
+               return decContextSetStatus(context, DEC_Invalid_operation);
+#if DECSUBSET
+       if (strcmp(string, DEC_Condition_LD) == 0)
+               return decContextSetStatus(context, DEC_Lost_digits);
+#endif
+       if (strcmp(string, DEC_Condition_OV) == 0)
+               return decContextSetStatus(context, DEC_Overflow);
+       if (strcmp(string, DEC_Condition_PA) == 0)
+               return decContextSetStatus(context, DEC_Clamped);
+       if (strcmp(string, DEC_Condition_RO) == 0)
+               return decContextSetStatus(context, DEC_Rounded);
+       if (strcmp(string, DEC_Condition_SU) == 0)
+               return decContextSetStatus(context, DEC_Subnormal);
+       if (strcmp(string, DEC_Condition_UN) == 0)
+               return decContextSetStatus(context, DEC_Underflow);
+       if (strcmp(string, DEC_Condition_ZE) == 0)
+               return context;
+       return NULL;            // Multiple status, or unknown
+}                              // decContextSetStatusFromString
+
+/* ------------------------------------------------------------------ */
+/* decContextSetStatusFromStringQuiet -- set status from a string     */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  string is a string exactly equal to one that might be returned    */
+/*            by decContextStatusToString                             */
+/*                                                                    */
+/*  The status bit corresponding to the string is set; no trap is     */
+/*  raised.                                                           */
+/*                                                                    */
+/*  returns the context structure, unless the string is equal to      */
+/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
+/*    returned.                                                       */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetStatusFromStringQuiet(decContext * context,
+                                              const char *string)
+{
+       if (strcmp(string, DEC_Condition_CS) == 0)
+               return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
+       if (strcmp(string, DEC_Condition_DZ) == 0)
+               return decContextSetStatusQuiet(context, DEC_Division_by_zero);
+       if (strcmp(string, DEC_Condition_DI) == 0)
+               return decContextSetStatusQuiet(context,
+                                               DEC_Division_impossible);
+       if (strcmp(string, DEC_Condition_DU) == 0)
+               return decContextSetStatusQuiet(context,
+                                               DEC_Division_undefined);
+       if (strcmp(string, DEC_Condition_IE) == 0)
+               return decContextSetStatusQuiet(context, DEC_Inexact);
+       if (strcmp(string, DEC_Condition_IS) == 0)
+               return decContextSetStatusQuiet(context,
+                                               DEC_Insufficient_storage);
+       if (strcmp(string, DEC_Condition_IC) == 0)
+               return decContextSetStatusQuiet(context, DEC_Invalid_context);
+       if (strcmp(string, DEC_Condition_IO) == 0)
+               return decContextSetStatusQuiet(context, DEC_Invalid_operation);
+#if DECSUBSET
+       if (strcmp(string, DEC_Condition_LD) == 0)
+               return decContextSetStatusQuiet(context, DEC_Lost_digits);
+#endif
+       if (strcmp(string, DEC_Condition_OV) == 0)
+               return decContextSetStatusQuiet(context, DEC_Overflow);
+       if (strcmp(string, DEC_Condition_PA) == 0)
+               return decContextSetStatusQuiet(context, DEC_Clamped);
+       if (strcmp(string, DEC_Condition_RO) == 0)
+               return decContextSetStatusQuiet(context, DEC_Rounded);
+       if (strcmp(string, DEC_Condition_SU) == 0)
+               return decContextSetStatusQuiet(context, DEC_Subnormal);
+       if (strcmp(string, DEC_Condition_UN) == 0)
+               return decContextSetStatusQuiet(context, DEC_Underflow);
+       if (strcmp(string, DEC_Condition_ZE) == 0)
+               return context;
+       return NULL;            // Multiple status, or unknown
+}                              // decContextSetStatusFromStringQuiet
+
+/* ------------------------------------------------------------------ */
+/* decContextSetStatusQuiet -- set status without trap                */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  status  is the DEC_ exception code                                */
+/*  returns the context structure                                     */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetStatusQuiet(decContext * context, uInt status)
+{
+       context->status |= status;
+       return context;
+}                              // decContextSetStatusQuiet
+
+/* ------------------------------------------------------------------ */
+/* decContextStatusToString -- convert status flags to a string       */
+/*                                                                    */
+/*  context is a context with valid status field                      */
+/*                                                                    */
+/*  returns a constant string describing the condition.  If multiple  */
+/*    (or no) flags are set, a generic constant message is returned.  */
+/* ------------------------------------------------------------------ */
+const char *decContextStatusToString(const decContext * context)
+{
+       Int status = context->status;
+
+       // test the five IEEE first, as some of the others are ambiguous when
+       // DECEXTFLAG=0
+       if (status == DEC_Invalid_operation)
+               return DEC_Condition_IO;
+       if (status == DEC_Division_by_zero)
+               return DEC_Condition_DZ;
+       if (status == DEC_Overflow)
+               return DEC_Condition_OV;
+       if (status == DEC_Underflow)
+               return DEC_Condition_UN;
+       if (status == DEC_Inexact)
+               return DEC_Condition_IE;
+
+       if (status == DEC_Division_impossible)
+               return DEC_Condition_DI;
+       if (status == DEC_Division_undefined)
+               return DEC_Condition_DU;
+       if (status == DEC_Rounded)
+               return DEC_Condition_RO;
+       if (status == DEC_Clamped)
+               return DEC_Condition_PA;
+       if (status == DEC_Subnormal)
+               return DEC_Condition_SU;
+       if (status == DEC_Conversion_syntax)
+               return DEC_Condition_CS;
+       if (status == DEC_Insufficient_storage)
+               return DEC_Condition_IS;
+       if (status == DEC_Invalid_context)
+               return DEC_Condition_IC;
+#if DECSUBSET
+       if (status == DEC_Lost_digits)
+               return DEC_Condition_LD;
+#endif
+       if (status == 0)
+               return DEC_Condition_ZE;
+       return DEC_Condition_MU;        // Multiple errors
+}                              // decContextStatusToString
+
+/* ------------------------------------------------------------------ */
+/* decContextTestEndian -- test whether DECLITEND is set correctly    */
+/*                                                                    */
+/*  quiet is 1 to suppress message; 0 otherwise                       */
+/*  returns 0 if DECLITEND is correct                                 */
+/*          1 if DECLITEND is incorrect and should be 1               */
+/*         -1 if DECLITEND is incorrect and should be 0               */
+/*                                                                    */
+/* A message is displayed if the return value is not 0 and quiet==0.  */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+Int decContextTestEndian(Flag quiet)
+{
+       Int res = 0;            // optimist
+       uInt dle = (uInt) DECLITEND;    // unsign
+       if (dle > 1)
+               dle = 1;        // ensure 0 or 1
+
+       if (LITEND != DECLITEND) {
+               if (!quiet) {   // always refer to this
+#if DECPRINT
+                       const char *adj;
+                       if (LITEND)
+                               adj = "little";
+                       else
+                               adj = "big";
+                       printf
+                           ("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
+                            DECLITEND, adj);
+#endif
+               }
+               res = (Int) LITEND - dle;
+       }
+       return res;
+}                              // decContextTestEndian
+
+/* ------------------------------------------------------------------ */
+/* decContextTestSavedStatus -- test bits in saved status             */
+/*                                                                    */
+/*  oldstatus is the status word to be tested                         */
+/*  mask indicates the bits to be tested (the oldstatus bits that     */
+/*    correspond to each 1 bit in the mask are tested)                */
+/*  returns 1 if any of the tested bits are 1, or 0 otherwise         */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+uInt decContextTestSavedStatus(uInt oldstatus, uInt mask)
+{
+       return (oldstatus & mask) != 0;
+}                              // decContextTestSavedStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextTestStatus -- test bits in current status                */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  mask indicates the bits to be tested (the status bits that        */
+/*    correspond to each 1 bit in the mask are tested)                */
+/*  returns 1 if any of the tested bits are 1, or 0 otherwise         */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+uInt decContextTestStatus(decContext * context, uInt mask)
+{
+       return (context->status & mask) != 0;
+}                              // decContextTestStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextZeroStatus -- clear all status bits                      */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  returns context                                                   */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextZeroStatus(decContext * context)
+{
+       context->status = 0;
+       return context;
+}                              // decContextZeroStatus
diff --git a/src/decnumber/decContext.h b/src/decnumber/decContext.h
new file mode 100644 (file)
index 0000000..2a8550a
--- /dev/null
@@ -0,0 +1,255 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Context module header                                      */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2010.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+/*                                                                    */
+/* Context variables must always have valid values:                   */
+/*                                                                    */
+/*  status   -- [any bits may be cleared, but not set, by user]       */
+/*  round    -- must be one of the enumerated rounding modes          */
+/*                                                                    */
+/* The following variables are implied for fixed size formats (i.e.,  */
+/* they are ignored) but should still be set correctly in case used   */
+/* with decNumber functions:                                          */
+/*                                                                    */
+/*  clamp    -- must be either 0 or 1                                 */
+/*  digits   -- must be in the range 1 through 999999999              */
+/*  emax     -- must be in the range 0 through 999999999              */
+/*  emin     -- must be in the range 0 through -999999999             */
+/*  extended -- must be either 0 or 1 [present only if DECSUBSET]     */
+/*  traps    -- only defined bits may be set                          */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+
+#if !defined(DECCONTEXT)
+#define DECCONTEXT
+#define DECCNAME     "decContext"      /* Short name */
+#define DECCFULLNAME "Decimal Context Descriptor"      /* Verbose name */
+#define DECCAUTHOR   "Mike Cowlishaw"  /* Who to blame */
+
+#if !defined(int32_t)
+#include <stdint.h>            /* C99 standard integers           */
+#endif
+#include <stdio.h>             /* for printf, etc.                */
+#include <signal.h>            /* for traps                       */
+
+  /* Extended flags setting -- set this to 0 to use only IEEE flags   */
+#if !defined(DECEXTFLAG)
+#define DECEXTFLAG 1           /* 1=enable extended flags         */
+#endif
+
+  /* Conditional code flag -- set this to 0 for best performance      */
+#if !defined(DECSUBSET)
+#define DECSUBSET  0           /* 1=enable subset arithmetic      */
+#endif
+
+  /* Context for operations, with associated constants                */
+enum rounding {
+       DEC_ROUND_CEILING,      /* round towards +infinity         */
+       DEC_ROUND_UP,           /* round away from 0               */
+       DEC_ROUND_HALF_UP,      /* 0.5 rounds up                   */
+       DEC_ROUND_HALF_EVEN,    /* 0.5 rounds to nearest even      */
+       DEC_ROUND_HALF_DOWN,    /* 0.5 rounds down                 */
+       DEC_ROUND_DOWN,         /* round towards 0 (truncate)      */
+       DEC_ROUND_FLOOR,        /* round towards -infinity         */
+       DEC_ROUND_05UP,         /* round for reround               */
+       DEC_ROUND_MAX           /* enum must be less than this     */
+};
+#define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
+
+typedef struct {
+       int32_t digits;         /* working precision               */
+       int32_t emax;           /* maximum positive exponent       */
+       int32_t emin;           /* minimum negative exponent       */
+       enum rounding round;    /* rounding mode                   */
+       uint32_t traps;         /* trap-enabler flags              */
+       uint32_t status;        /* status flags                    */
+       uint8_t clamp;          /* flag: apply IEEE exponent clamp */
+#if DECSUBSET
+       uint8_t extended;       /* flag: special-values allowed    */
+#endif
+} decContext;
+
+  /* Maxima and Minima for context settings                           */
+#define DEC_MAX_DIGITS 999999999
+#define DEC_MIN_DIGITS         1
+#define DEC_MAX_EMAX   999999999
+#define DEC_MIN_EMAX           0
+#define DEC_MAX_EMIN           0
+#define DEC_MIN_EMIN  -999999999
+#define DEC_MAX_MATH      999999       /* max emax, etc., for math funcs. */
+
+  /* Classifications for decimal numbers, aligned with 754 (note that */
+  /* 'normal' and 'subnormal' are meaningful only with a decContext   */
+  /* or a fixed size format).                                         */
+enum decClass {
+       DEC_CLASS_SNAN,
+       DEC_CLASS_QNAN,
+       DEC_CLASS_NEG_INF,
+       DEC_CLASS_NEG_NORMAL,
+       DEC_CLASS_NEG_SUBNORMAL,
+       DEC_CLASS_NEG_ZERO,
+       DEC_CLASS_POS_ZERO,
+       DEC_CLASS_POS_SUBNORMAL,
+       DEC_CLASS_POS_NORMAL,
+       DEC_CLASS_POS_INF
+};
+  /* Strings for the decClasses */
+#define DEC_ClassString_SN  "sNaN"
+#define DEC_ClassString_QN  "NaN"
+#define DEC_ClassString_NI  "-Infinity"
+#define DEC_ClassString_NN  "-Normal"
+#define DEC_ClassString_NS  "-Subnormal"
+#define DEC_ClassString_NZ  "-Zero"
+#define DEC_ClassString_PZ  "+Zero"
+#define DEC_ClassString_PS  "+Subnormal"
+#define DEC_ClassString_PN  "+Normal"
+#define DEC_ClassString_PI  "+Infinity"
+#define DEC_ClassString_UN  "Invalid"
+
+  /* Trap-enabler and Status flags (exceptional conditions), and      */
+  /* their names.  The top byte is reserved for internal use          */
+#if DECEXTFLAG
+    /* Extended flags */
+#define DEC_Conversion_syntax    0x00000001
+#define DEC_Division_by_zero     0x00000002
+#define DEC_Division_impossible  0x00000004
+#define DEC_Division_undefined   0x00000008
+#define DEC_Insufficient_storage 0x00000010    /* [when malloc fails]  */
+#define DEC_Inexact              0x00000020
+#define DEC_Invalid_context      0x00000040
+#define DEC_Invalid_operation    0x00000080
+#if DECSUBSET
+#define DEC_Lost_digits          0x00000100
+#endif
+#define DEC_Overflow             0x00000200
+#define DEC_Clamped              0x00000400
+#define DEC_Rounded              0x00000800
+#define DEC_Subnormal            0x00001000
+#define DEC_Underflow            0x00002000
+#else
+    /* IEEE flags only */
+#define DEC_Conversion_syntax    0x00000010
+#define DEC_Division_by_zero     0x00000002
+#define DEC_Division_impossible  0x00000010
+#define DEC_Division_undefined   0x00000010
+#define DEC_Insufficient_storage 0x00000010    /* [when malloc fails]  */
+#define DEC_Inexact              0x00000001
+#define DEC_Invalid_context      0x00000010
+#define DEC_Invalid_operation    0x00000010
+#if DECSUBSET
+#define DEC_Lost_digits          0x00000000
+#endif
+#define DEC_Overflow             0x00000008
+#define DEC_Clamped              0x00000000
+#define DEC_Rounded              0x00000000
+#define DEC_Subnormal            0x00000000
+#define DEC_Underflow            0x00000004
+#endif
+
+  /* IEEE 754 groupings for the flags                                 */
+  /* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal    */
+  /* are not in IEEE 754]                                             */
+#define DEC_IEEE_754_Division_by_zero  (DEC_Division_by_zero)
+#if DECSUBSET
+#define DEC_IEEE_754_Inexact           (DEC_Inexact | DEC_Lost_digits)
+#else
+#define DEC_IEEE_754_Inexact           (DEC_Inexact)
+#endif
+#define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax |     \
+                                          DEC_Division_impossible |   \
+                                          DEC_Division_undefined |    \
+                                          DEC_Insufficient_storage |  \
+                                          DEC_Invalid_context |       \
+                                          DEC_Invalid_operation)
+#define DEC_IEEE_754_Overflow          (DEC_Overflow)
+#define DEC_IEEE_754_Underflow         (DEC_Underflow)
+
+  /* flags which are normally errors (result is qNaN, infinite, or 0) */
+#define DEC_Errors (DEC_IEEE_754_Division_by_zero |                 \
+                      DEC_IEEE_754_Invalid_operation |                \
+                      DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)
+  /* flags which cause a result to become qNaN                        */
+#define DEC_NaNs    DEC_IEEE_754_Invalid_operation
+
+  /* flags which are normally for information only (finite results)   */
+#if DECSUBSET
+#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact    \
+                          | DEC_Lost_digits)
+#else
+#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
+#endif
+
+  /* IEEE 854 names (for compatibility with older decNumber versions) */
+#define DEC_IEEE_854_Division_by_zero  DEC_IEEE_754_Division_by_zero
+#define DEC_IEEE_854_Inexact           DEC_IEEE_754_Inexact
+#define DEC_IEEE_854_Invalid_operation DEC_IEEE_754_Invalid_operation
+#define DEC_IEEE_854_Overflow          DEC_IEEE_754_Overflow
+#define DEC_IEEE_854_Underflow         DEC_IEEE_754_Underflow
+
+  /* Name strings for the exceptional conditions                      */
+#define DEC_Condition_CS "Conversion syntax"
+#define DEC_Condition_DZ "Division by zero"
+#define DEC_Condition_DI "Division impossible"
+#define DEC_Condition_DU "Division undefined"
+#define DEC_Condition_IE "Inexact"
+#define DEC_Condition_IS "Insufficient storage"
+#define DEC_Condition_IC "Invalid context"
+#define DEC_Condition_IO "Invalid operation"
+#if DECSUBSET
+#define DEC_Condition_LD "Lost digits"
+#endif
+#define DEC_Condition_OV "Overflow"
+#define DEC_Condition_PA "Clamped"
+#define DEC_Condition_RO "Rounded"
+#define DEC_Condition_SU "Subnormal"
+#define DEC_Condition_UN "Underflow"
+#define DEC_Condition_ZE "No status"
+#define DEC_Condition_MU "Multiple status"
+#define DEC_Condition_Length 21        /* length of the longest string,   */
+                                  /* including terminator            */
+
+  /* Initialization descriptors, used by decContextDefault            */
+#define DEC_INIT_BASE         0
+#define DEC_INIT_DECIMAL32   32
+#define DEC_INIT_DECIMAL64   64
+#define DEC_INIT_DECIMAL128 128
+  /* Synonyms */
+#define DEC_INIT_DECSINGLE  DEC_INIT_DECIMAL32
+#define DEC_INIT_DECDOUBLE  DEC_INIT_DECIMAL64
+#define DEC_INIT_DECQUAD    DEC_INIT_DECIMAL128
+
+  /* decContext routines                                              */
+extern decContext *decContextClearStatus(decContext *, uint32_t);
+extern decContext *decContextDefault(decContext *, int32_t);
+extern enum rounding decContextGetRounding(decContext *);
+extern uint32_t decContextGetStatus(decContext *);
+extern decContext *decContextRestoreStatus(decContext *, uint32_t, uint32_t);
+extern uint32_t decContextSaveStatus(decContext *, uint32_t);
+extern decContext *decContextSetRounding(decContext *, enum rounding);
+extern decContext *decContextSetStatus(decContext *, uint32_t);
+extern decContext *decContextSetStatusFromString(decContext *, const char *);
+extern decContext *decContextSetStatusFromStringQuiet(decContext *,
+                                                     const char *);
+extern decContext *decContextSetStatusQuiet(decContext *, uint32_t);
+extern const char *decContextStatusToString(const decContext *);
+extern int32_t decContextTestEndian(uint8_t);
+extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
+extern uint32_t decContextTestStatus(decContext *, uint32_t);
+extern decContext *decContextZeroStatus(decContext *);
+
+#endif
diff --git a/src/decnumber/decNumber.c b/src/decnumber/decNumber.c
new file mode 100644 (file)
index 0000000..a769132
--- /dev/null
@@ -0,0 +1,8983 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Number arithmetic module                                   */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2009.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for arbitrary-precision General */
+/* Decimal Arithmetic as defined in the specification which may be    */
+/* found on the General Decimal Arithmetic pages.  It implements both */
+/* the full ('extended') arithmetic and the simpler ('subset')        */
+/* arithmetic.                                                        */
+/*                                                                    */
+/* Usage notes:                                                       */
+/*                                                                    */
+/* 1. This code is ANSI C89 except:                                   */
+/*                                                                    */
+/*    a) C99 line comments (double forward slash) are used.  (Most C  */
+/*       compilers accept these.  If yours does not, a simple script  */
+/*       can be used to convert them to ANSI C comments.)             */
+/*                                                                    */
+/*    b) Types from C99 stdint.h are used.  If you do not have this   */
+/*       header file, see the User's Guide section of the decNumber   */
+/*       documentation; this lists the necessary definitions.         */
+/*                                                                    */
+/*    c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and       */
+/*       uint64_t types may be used.  To avoid these, set DECUSE64=0  */
+/*       and DECDPUN<=4 (see documentation).                          */
+/*                                                                    */
+/*    The code also conforms to C99 restrictions; in particular,      */
+/*    strict aliasing rules are observed.                             */
+/*                                                                    */
+/* 2. The decNumber format which this library uses is optimized for   */
+/*    efficient processing of relatively short numbers; in particular */
+/*    it allows the use of fixed sized structures and minimizes copy  */
+/*    and move operations.  It does, however, support arbitrary       */
+/*    precision (up to 999,999,999 digits) and arbitrary exponent     */
+/*    range (Emax in the range 0 through 999,999,999 and Emin in the  */
+/*    range -999,999,999 through 0).  Mathematical functions (for     */
+/*    example decNumberExp) as identified below are restricted more   */
+/*    tightly: digits, emax, and -emin in the context must be <=      */
+/*    DEC_MAX_MATH (999999), and their operand(s) must be within      */
+/*    these bounds.                                                   */
+/*                                                                    */
+/* 3. Logical functions are further restricted; their operands must   */
+/*    be finite, positive, have an exponent of zero, and all digits   */
+/*    must be either 0 or 1.  The result will only contain digits     */
+/*    which are 0 or 1 (and will have exponent=0 and a sign of 0).    */
+/*                                                                    */
+/* 4. Operands to operator functions are never modified unless they   */
+/*    are also specified to be the result number (which is always     */
+/*    permitted).  Other than that case, operands must not overlap.   */
+/*                                                                    */
+/* 5. Error handling: the type of the error is ORed into the status   */
+/*    flags in the current context (decContext structure).  The       */
+/*    SIGFPE signal is then raised if the corresponding trap-enabler  */
+/*    flag in the decContext is set (is 1).                           */
+/*                                                                    */
+/*    It is the responsibility of the caller to clear the status      */
+/*    flags as required.                                              */
+/*                                                                    */
+/*    The result of any routine which returns a number will always    */
+/*    be a valid number (which may be a special value, such as an     */
+/*    Infinity or NaN).                                               */
+/*                                                                    */
+/* 6. The decNumber format is not an exchangeable concrete            */
+/*    representation as it comprises fields which may be machine-     */
+/*    dependent (packed or unpacked, or special length, for example). */
+/*    Canonical conversions to and from strings are provided; other   */
+/*    conversions are available in separate modules.                  */
+/*                                                                    */
+/* 7. Normally, input operands are assumed to be valid.  Set DECCHECK */
+/*    to 1 for extended operand checking (including NULL operands).   */
+/*    Results are undefined if a badly-formed structure (or a NULL    */
+/*    pointer to a structure) is provided, though with DECCHECK       */
+/*    enabled the operator routines are protected against exceptions. */
+/*    (Except if the result pointer is NULL, which is unrecoverable.) */
+/*                                                                    */
+/*    However, the routines will never cause exceptions if they are   */
+/*    given well-formed operands, even if the value of the operands   */
+/*    is inappropriate for the operation and DECCHECK is not set.     */
+/*    (Except for SIGFPE, as and where documented.)                   */
+/*                                                                    */
+/* 8. Subset arithmetic is available only if DECSUBSET is set to 1.   */
+/* ------------------------------------------------------------------ */
+/* Implementation notes for maintenance of this module:               */
+/*                                                                    */
+/* 1. Storage leak protection:  Routines which use malloc are not     */
+/*    permitted to use return for fastpath or error exits (i.e.,      */
+/*    they follow strict structured programming conventions).         */
+/*    Instead they have a do{}while(0); construct surrounding the     */
+/*    code which is protected -- break may be used to exit this.      */
+/*    Other routines can safely use the return statement inline.      */
+/*                                                                    */
+/*    Storage leak accounting can be enabled using DECALLOC.          */
+/*                                                                    */
+/* 2. All loops use the for(;;) construct.  Any do construct does     */
+/*    not loop; it is for allocation protection as just described.    */
+/*                                                                    */
+/* 3. Setting status in the context must always be the very last      */
+/*    action in a routine, as non-0 status may raise a trap and hence */
+/*    the call to set status may not return (if the handler uses long */
+/*    jump).  Therefore all cleanup must be done first.  In general,  */
+/*    to achieve this status is accumulated and is only applied just  */
+/*    before return by calling decContextSetStatus (via decStatus).   */
+/*                                                                    */
+/*    Routines which allocate storage cannot, in general, use the     */
+/*    'top level' routines which could cause a non-returning          */
+/*    transfer of control.  The decXxxxOp routines are safe (do not   */
+/*    call decStatus even if traps are set in the context) and should */
+/*    be used instead (they are also a little faster).                */
+/*                                                                    */
+/* 4. Exponent checking is minimized by allowing the exponent to      */
+/*    grow outside its limits during calculations, provided that      */
+/*    the decFinalize function is called later.  Multiplication and   */
+/*    division, and intermediate calculations in exponentiation,      */
+/*    require more careful checks because of the risk of 31-bit       */
+/*    overflow (the most negative valid exponent is -1999999997, for  */
+/*    a 999999999-digit number with adjusted exponent of -999999999). */
+/*                                                                    */
+/* 5. Rounding is deferred until finalization of results, with any    */
+/*    'off to the right' data being represented as a single digit     */
+/*    residue (in the range -1 through 9).  This avoids any double-   */
+/*    rounding when more than one shortening takes place (for         */
+/*    example, when a result is subnormal).                           */
+/*                                                                    */
+/* 6. The digits count is allowed to rise to a multiple of DECDPUN    */
+/*    during many operations, so whole Units are handled and exact    */
+/*    accounting of digits is not needed.  The correct digits value   */
+/*    is found by decGetDigits, which accounts for leading zeros.     */
+/*    This must be called before any rounding if the number of digits */
+/*    is not known exactly.                                           */
+/*                                                                    */
+/* 7. The multiply-by-reciprocal 'trick' is used for partitioning     */
+/*    numbers up to four digits, using appropriate constants.  This   */
+/*    is not useful for longer numbers because overflow of 32 bits    */
+/*    would lead to 4 multiplies, which is almost as expensive as     */
+/*    a divide (unless a floating-point or 64-bit multiply is         */
+/*    assumed to be available).                                       */
+/*                                                                    */
+/* 8. Unusual abbreviations that may be used in the commentary:       */
+/*      lhs -- left hand side (operand, of an operation)              */
+/*      lsd -- least significant digit (of coefficient)               */
+/*      lsu -- least significant Unit (of coefficient)                */
+/*      msd -- most significant digit (of coefficient)                */
+/*      msi -- most significant item (in an array)                    */
+/*      msu -- most significant Unit (of coefficient)                 */
+/*      rhs -- right hand side (operand, of an operation)             */
+/*      +ve -- positive                                               */
+/*      -ve -- negative                                               */
+/*      **  -- raise to the power                                     */
+/* ------------------------------------------------------------------ */
+
+#include <stdlib.h>            // for malloc, free, etc.
+#include <stdio.h>             // for printf [if needed]
+#include <string.h>            // for strcpy
+#include <ctype.h>             // for lower
+#include "decNumber.h"         // base number library
+#include "decNumberLocal.h"    // decNumber local types, etc.
+
+/* Constants */
+// Public lookup table used by the D2U macro
+const uByte d2utable[DECMAXD2U + 1] = D2UTABLE;
+
+#define DECVERB     1          // set to 1 for verbose DECCHECK
+#define powers      DECPOWERS  // old internal name
+
+// Local constants
+#define DIVIDE      0x80       // Divide operators
+#define REMAINDER   0x40       // ..
+#define DIVIDEINT   0x20       // ..
+#define REMNEAR     0x10       // ..
+#define COMPARE     0x01       // Compare operators
+#define COMPMAX     0x02       // ..
+#define COMPMIN     0x03       // ..
+#define COMPTOTAL   0x04       // ..
+#define COMPNAN     0x05       // .. [NaN processing]
+#define COMPSIG     0x06       // .. [signaling COMPARE]
+#define COMPMAXMAG  0x07       // ..
+#define COMPMINMAG  0x08       // ..
+
+#define DEC_sNaN     0x40000000        // local status: sNaN signal
+#define BADINT  (Int)0x80000000        // most-negative Int; error indicator
+// Next two indicate an integer >= 10**6, and its parity (bottom bit)
+#define BIGEVEN (Int)0x80000002
+#define BIGODD  (Int)0x80000003
+
+static Unit uarrone[1] = { 1 };        // Unit array of 1, used for incrementing
+
+/* Granularity-dependent code */
+#if DECDPUN<=4
+#define eInt  Int              // extended integer
+#define ueInt uInt             // unsigned extended integer
+  // Constant multipliers for divide-by-power-of five using reciprocal
+  // multiply, after removing powers of 2 by shifting, and final shift
+  // of 17 [we only need up to **4]
+static const uInt multies[] = { 131073, 26215, 5243, 1049, 210 };
+
+  // QUOT10 -- macro to return the quotient of unit u divided by 10**n
+#define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
+#else
+  // For DECDPUN>4 non-ANSI-89 64-bit types are needed.
+#if !DECUSE64
+#error decNumber.c: DECUSE64 must be 1 when DECDPUN>4
+#endif
+#define eInt  Long             // extended integer
+#define ueInt uLong            // unsigned extended integer
+#endif
+
+/* Local routines */
+static decNumber *decAddOp(decNumber *, const decNumber *, const decNumber *,
+                          decContext *, uByte, uInt *);
+static Flag decBiStr(const char *, const char *, const char *);
+static uInt decCheckMath(const decNumber *, decContext *, uInt *);
+static void decApplyRound(decNumber *, decContext *, Int, uInt *);
+static Int decCompare(const decNumber * lhs, const decNumber * rhs, Flag);
+static decNumber *decCompareOp(decNumber *, const decNumber *,
+                              const decNumber *, decContext *, Flag, uInt *);
+static void decCopyFit(decNumber *, const decNumber *, decContext *,
+                      Int *, uInt *);
+static decNumber *decDecap(decNumber *, Int);
+static decNumber *decDivideOp(decNumber *, const decNumber *,
+                             const decNumber *, decContext *, Flag, uInt *);
+static decNumber *decExpOp(decNumber *, const decNumber *,
+                          decContext *, uInt *);
+static void decFinalize(decNumber *, decContext *, Int *, uInt *);
+static Int decGetDigits(Unit *, Int);
+static Int decGetInt(const decNumber *);
+static decNumber *decLnOp(decNumber *, const decNumber *, decContext *, uInt *);
+static decNumber *decMultiplyOp(decNumber *, const decNumber *,
+                               const decNumber *, decContext *, uInt *);
+static decNumber *decNaNs(decNumber *, const decNumber *,
+                         const decNumber *, decContext *, uInt *);
+static decNumber *decQuantizeOp(decNumber *, const decNumber *,
+                               const decNumber *, decContext *, Flag, uInt *);
+static void decReverse(Unit *, Unit *);
+static void decSetCoeff(decNumber *, decContext *, const Unit *,
+                       Int, Int *, uInt *);
+static void decSetMaxValue(decNumber *, decContext *);
+static void decSetOverflow(decNumber *, decContext *, uInt *);
+static void decSetSubnormal(decNumber *, decContext *, Int *, uInt *);
+static Int decShiftToLeast(Unit *, Int, Int);
+static Int decShiftToMost(Unit *, Int, Int);
+static void decStatus(decNumber *, uInt, decContext *);
+static void decToString(const decNumber *, char[], Flag);
+static decNumber *decTrim(decNumber *, decContext *, Flag, Flag, Int *);
+static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
+                        Unit *, Int);
+static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+
+#if !DECSUBSET
+/* decFinish == decFinalize when no subset arithmetic needed */
+#define decFinish(a,b,c,d) decFinalize(a,b,c,d)
+#else
+static void decFinish(decNumber *, decContext *, Int *, uInt *);
+static decNumber *decRoundOperand(const decNumber *, decContext *, uInt *);
+#endif
+
+/* Local macros */
+// masked special-values bits
+#define SPECIALARG  (rhs->bits & DECSPECIAL)
+#define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)
+
+/* Diagnostic macros, etc. */
+#if DECALLOC
+// Handle malloc/free accounting.  If enabled, our accountable routines
+// are used; otherwise the code just goes straight to the system malloc
+// and free routines.
+#define malloc(a) decMalloc(a)
+#define free(a) decFree(a)
+#define DECFENCE 0x5a          // corruption detector
+// 'Our' malloc and free:
+static void *decMalloc(size_t);
+static void decFree(void *);
+uInt decAllocBytes = 0;                // count of bytes allocated
+// Note that DECALLOC code only checks for storage buffer overflow.
+// To check for memory leaks, the decAllocBytes variable must be
+// checked to be 0 at appropriate times (e.g., after the test
+// harness completes a set of tests).  This checking may be unreliable
+// if the testing is done in a multi-thread environment.
+#endif
+
+#if DECCHECK
+// Optional checking routines.  Enabling these means that decNumber
+// and decContext operands to operator routines are checked for
+// correctness.  This roughly doubles the execution time of the
+// fastest routines (and adds 600+ bytes), so should not normally be
+// used in 'production'.
+// decCheckInexact is used to check that inexact results have a full
+// complement of digits (where appropriate -- this is not the case
+// for Quantize, for example)
+#define DECUNRESU ((decNumber *)(void *)0xffffffff)
+#define DECUNUSED ((const decNumber *)(void *)0xffffffff)
+#define DECUNCONT ((decContext *)(void *)(0xffffffff))
+static Flag decCheckOperands(decNumber *, const decNumber *,
+                            const decNumber *, decContext *);
+static Flag decCheckNumber(const decNumber *);
+static void decCheckInexact(const decNumber *, decContext *);
+#endif
+
+#if DECTRACE || DECCHECK
+// Optional trace/debugging routines (may or may not be used)
+void decNumberShow(const decNumber *); // displays the components of a number
+static void decDumpAr(char, const Unit *, Int);
+#endif
+
+/* ================================================================== */
+/* Conversions                                                        */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* from-int32 -- conversion from Int or uInt                          */
+/*                                                                    */
+/*  dn is the decNumber to receive the integer                        */
+/*  in or uin is the integer to be converted                          */
+/*  returns dn                                                        */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberFromInt32(decNumber * dn, Int in)
+{
+       uInt unsig;
+       if (in >= 0)
+               unsig = in;
+       else {                  // negative (possibly BADINT)
+               if (in == BADINT)
+                       unsig = (uInt) 1073741824 *2;   // special case
+               else
+                       unsig = -in;    // invert
+       }
+       // in is now positive
+       decNumberFromUInt32(dn, unsig);
+       if (in < 0)
+               dn->bits = DECNEG;      // sign needed
+       return dn;
+}                              // decNumberFromInt32
+
+decNumber *decNumberFromUInt32(decNumber * dn, uInt uin)
+{
+       Unit *up;               // work pointer
+       decNumberZero(dn);      // clean
+       if (uin == 0)
+               return dn;      // [or decGetDigits bad call]
+       for (up = dn->lsu; uin > 0; up++) {
+               *up = (Unit) (uin % (DECDPUNMAX + 1));
+               uin = uin / (DECDPUNMAX + 1);
+       }
+       dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
+       return dn;
+}                              // decNumberFromUInt32
+
+/* ------------------------------------------------------------------ */
+/* to-int32 -- conversion to Int or uInt                              */
+/*                                                                    */
+/*  dn is the decNumber to convert                                    */
+/*  set is the context for reporting errors                           */
+/*  returns the converted decNumber, or 0 if Invalid is set           */
+/*                                                                    */
+/* Invalid is set if the decNumber does not have exponent==0 or if    */
+/* it is a NaN, Infinite, or out-of-range.                            */
+/* ------------------------------------------------------------------ */
+Int decNumberToInt32(const decNumber * dn, decContext * set)
+{
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set))
+               return 0;
+#endif
+
+       // special or too many digits, or bad exponent
+       if (dn->bits & DECSPECIAL || dn->digits > 10 || dn->exponent != 0) ;    // bad
+       else {                  // is a finite integer with 10 or fewer digits
+               Int d;          // work
+               const Unit *up; // ..
+               uInt hi = 0, lo;        // ..
+               up = dn->lsu;   // -> lsu
+               lo = *up;       // get 1 to 9 digits
+#if DECDPUN>1                  // split to higher
+               hi = lo / 10;
+               lo = lo % 10;
+#endif
+               up++;
+               // collect remaining Units, if any, into hi
+               for (d = DECDPUN; d < dn->digits; up++, d += DECDPUN)
+                       hi += *up * powers[d - 1];
+               // now low has the lsd, hi the remainder
+               if (hi > 214748364 || (hi == 214748364 && lo > 7)) {    // out of range?
+                       // most-negative is a reprieve
+                       if (dn->bits & DECNEG && hi == 214748364 && lo == 8)
+                               return 0x80000000;
+                       // bad -- drop through
+               } else {        // in-range always
+                       Int i = X10(hi) + lo;
+                       if (dn->bits & DECNEG)
+                               return -i;
+                       return i;
+               }
+       }                       // integer
+       decContextSetStatus(set, DEC_Invalid_operation);        // [may not return]
+       return 0;
+}                              // decNumberToInt32
+
+uInt decNumberToUInt32(const decNumber * dn, decContext * set)
+{
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set))
+               return 0;
+#endif
+       // special or too many digits, or bad exponent, or negative (<0)
+       if (dn->bits & DECSPECIAL || dn->digits > 10 || dn->exponent != 0 || (dn->bits & DECNEG && !ISZERO(dn))) ;      // bad
+       else {                  // is a finite integer with 10 or fewer digits
+               Int d;          // work
+               const Unit *up; // ..
+               uInt hi = 0, lo;        // ..
+               up = dn->lsu;   // -> lsu
+               lo = *up;       // get 1 to 9 digits
+#if DECDPUN>1                  // split to higher
+               hi = lo / 10;
+               lo = lo % 10;
+#endif
+               up++;
+               // collect remaining Units, if any, into hi
+               for (d = DECDPUN; d < dn->digits; up++, d += DECDPUN)
+                       hi += *up * powers[d - 1];
+
+               // now low has the lsd, hi the remainder
+               if (hi > 429496729 || (hi == 429496729 && lo > 5)) ;    // no reprieve possible
+               else
+                       return X10(hi) + lo;
+       }                       // integer
+       decContextSetStatus(set, DEC_Invalid_operation);        // [may not return]
+       return 0;
+}                              // decNumberToUInt32
+
+/* ------------------------------------------------------------------ */
+/* to-scientific-string -- conversion to numeric string               */
+/* to-engineering-string -- conversion to numeric string              */
+/*                                                                    */
+/*   decNumberToString(dn, string);                                   */
+/*   decNumberToEngString(dn, string);                                */
+/*                                                                    */
+/*  dn is the decNumber to convert                                    */
+/*  string is the string where the result will be laid out            */
+/*                                                                    */
+/*  string must be at least dn->digits+14 characters long             */
+/*                                                                    */
+/*  No error is possible, and no status can be set.                   */
+/* ------------------------------------------------------------------ */
+char *decNumberToString(const decNumber * dn, char *string)
+{
+       decToString(dn, string, 0);
+       return string;
+}                              // DecNumberToString
+
+char *decNumberToEngString(const decNumber * dn, char *string)
+{
+       decToString(dn, string, 1);
+       return string;
+}                              // DecNumberToEngString
+
+/* ------------------------------------------------------------------ */
+/* to-number -- conversion from numeric string                        */
+/*                                                                    */
+/* decNumberFromString -- convert string to decNumber                 */
+/*   dn        -- the number structure to fill                        */
+/*   chars[]   -- the string to convert ('\0' terminated)             */
+/*   set       -- the context used for processing any error,          */
+/*                determining the maximum precision available         */
+/*                (set.digits), determining the maximum and minimum   */
+/*                exponent (set.emax and set.emin), determining if    */
+/*                extended values are allowed, and checking the       */
+/*                rounding mode if overflow occurs or rounding is     */
+/*                needed.                                             */
+/*                                                                    */
+/* The length of the coefficient and the size of the exponent are     */
+/* checked by this routine, so the correct error (Underflow or        */
+/* Overflow) can be reported or rounding applied, as necessary.       */
+/*                                                                    */
+/* If bad syntax is detected, the result will be a quiet NaN.         */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberFromString(decNumber * dn, const char chars[],
+                              decContext * set)
+{
+       Int exponent = 0;       // working exponent [assume 0]
+       uByte bits = 0;         // working flags [assume +ve]
+       Unit *res;              // where result will be built
+       Unit resbuff[SD2U(DECBUFFER + 9)];      // local buffer in case need temporary
+       // [+9 allows for ln() constants]
+       Unit *allocres = NULL;  // -> allocated result, iff allocated
+       Int d = 0;              // count of digits found in decimal part
+       const char *dotchar = NULL;     // where dot was found
+       const char *cfirst = chars;     // -> first character of decimal part
+       const char *last = NULL;        // -> last digit of decimal part
+       const char *c;          // work
+       Unit *up;               // ..
+#if DECDPUN>1
+       Int cut, out;           // ..
+#endif
+       Int residue;            // rounding residue
+       uInt status = 0;        // error code
+
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
+               return decNumberZero(dn);
+#endif
+
+       do {                    // status & malloc protection
+               for (c = chars;; c++) { // -> input character
+                       if (*c >= '0' && *c <= '9') {   // test for Arabic digit
+                               last = c;
+                               d++;    // count of real digits
+                               continue;       // still in decimal part
+                       }
+                       if (*c == '.' && dotchar == NULL) {     // first '.'
+                               dotchar = c;    // record offset into decimal part
+                               if (c == cfirst)
+                                       cfirst++;       // first digit must follow
+                               continue;
+                       }
+                       if (c == chars) {       // first in string...
+                               if (*c == '-') {        // valid - sign
+                                       cfirst++;
+                                       bits = DECNEG;
+                                       continue;
+                               }
+                               if (*c == '+') {        // valid + sign
+                                       cfirst++;
+                                       continue;
+                               }
+                       }
+                       // *c is not a digit, or a valid +, -, or '.'
+                       break;
+               }               // c
+
+               if (last == NULL) {     // no digits yet
+                       status = DEC_Conversion_syntax; // assume the worst
+                       if (*c == '\0')
+                               break;  // and no more to come...
+#if DECSUBSET
+                       // if subset then infinities and NaNs are not allowed
+                       if (!set->extended)
+                               break;  // hopeless
+#endif
+                       // Infinities and NaNs are possible, here
+                       if (dotchar != NULL)
+                               break;  // .. unless had a dot
+                       decNumberZero(dn);      // be optimistic
+                       if (decBiStr(c, "infinity", "INFINITY")
+                           || decBiStr(c, "inf", "INF")) {
+                               dn->bits = bits | DECINF;
+                               status = 0;     // is OK
+                               break;  // all done
+                       }
+                       // a NaN expected
+                       // 2003.09.10 NaNs are now permitted to have a sign
+                       dn->bits = bits | DECNAN;       // assume simple NaN
+                       if (*c == 's' || *c == 'S') {   // looks like an sNaN
+                               c++;
+                               dn->bits = bits | DECSNAN;
+                       }
+                       if (*c != 'n' && *c != 'N')
+                               break;  // check caseless "NaN"
+                       c++;
+                       if (*c != 'a' && *c != 'A')
+                               break;  // ..
+                       c++;
+                       if (*c != 'n' && *c != 'N')
+                               break;  // ..
+                       c++;
+                       // now either nothing, or nnnn payload, expected
+                       // -> start of integer and skip leading 0s [including plain 0]
+                       for (cfirst = c; *cfirst == '0';)
+                               cfirst++;
+                       if (*cfirst == '\0') {  // "NaN" or "sNaN", maybe with all 0s
+                               status = 0;     // it's good
+                               break;  // ..
+                       }
+                       // something other than 0s; setup last and d as usual [no dots]
+                       for (c = cfirst;; c++, d++) {
+                               if (*c < '0' || *c > '9')
+                                       break;  // test for Arabic digit
+                               last = c;
+                       }
+                       if (*c != '\0')
+                               break;  // not all digits
+                       if (d > set->digits - 1) {
+                               // [NB: payload in a decNumber can be full length unless
+                               // clamped, in which case can only be digits-1]
+                               if (set->clamp)
+                                       break;
+                               if (d > set->digits)
+                                       break;
+                       }       // too many digits?
+                       // good; drop through to convert the integer to coefficient
+                       status = 0;     // syntax is OK
+                       bits = dn->bits;        // for copy-back
+               }               // last==NULL
+
+               else if (*c != '\0') {  // more to process...
+                       // had some digits; exponent is only valid sequence now
+                       Flag nege;      // 1=negative exponent
+                       const char *firstexp;   // -> first significant exponent digit
+                       status = DEC_Conversion_syntax; // assume the worst
+                       if (*c != 'e' && *c != 'E')
+                               break;
+                       /* Found 'e' or 'E' -- now process explicit exponent */
+                       // 1998.07.11: sign no longer required
+                       nege = 0;
+                       c++;    // to (possible) sign
+                       if (*c == '-') {
+                               nege = 1;
+                               c++;
+                       } else if (*c == '+')
+                               c++;
+                       if (*c == '\0')
+                               break;
+
+                       for (; *c == '0' && *(c + 1) != '\0';)
+                               c++;    // strip insignificant zeros
+                       firstexp = c;   // save exponent digit place
+                       for (;; c++) {
+                               if (*c < '0' || *c > '9')
+                                       break;  // not a digit
+                               exponent =
+                                   X10(exponent) + (Int) * c - (Int) '0';
+                       }       // c
+                       // if not now on a '\0', *c must not be a digit
+                       if (*c != '\0')
+                               break;
+
+                       // (this next test must be after the syntax checks)
+                       // if it was too long the exponent may have wrapped, so check
+                       // carefully and set it to a certain overflow if wrap possible
+                       if (c >= firstexp + 9 + 1) {
+                               if (c > firstexp + 9 + 1 || *firstexp > '1')
+                                       exponent = DECNUMMAXE * 2;
+                               // [up to 1999999999 is OK, for example 1E-1000000998]
+                       }
+                       if (nege)
+                               exponent = -exponent;   // was negative
+                       status = 0;     // is OK
+               }               // stuff after digits
+
+               // Here when whole string has been inspected; syntax is good
+               // cfirst->first digit (never dot), last->last digit (ditto)
+
+               // strip leading zeros/dot [leave final 0 if all 0's]
+               if (*cfirst == '0') {   // [cfirst has stepped over .]
+                       for (c = cfirst; c < last; c++, cfirst++) {
+                               if (*c == '.')
+                                       continue;       // ignore dots
+                               if (*c != '0')
+                                       break;  // non-zero found
+                               d--;    // 0 stripped
+                       }       // c
+#if DECSUBSET
+                       // make a rapid exit for easy zeros if !extended
+                       if (*cfirst == '0' && !set->extended) {
+                               decNumberZero(dn);      // clean result
+                               break;  // [could be return]
+                       }
+#endif
+               }               // at least one leading 0
+
+               // Handle decimal point...
+               if (dotchar != NULL && dotchar < last)  // non-trailing '.' found?
+                       exponent -= (last - dotchar);   // adjust exponent
+               // [we can now ignore the .]
+
+               // OK, the digits string is good.  Assemble in the decNumber, or in
+               // a temporary units array if rounding is needed
+               if (d <= set->digits)
+                       res = dn->lsu;  // fits into supplied decNumber
+               else {          // rounding needed
+                       Int needbytes = D2U(d) * sizeof(Unit);  // bytes needed
+                       res = resbuff;  // assume use local buffer
+                       if (needbytes > (Int) sizeof(resbuff)) {        // too big for local
+                               allocres = (Unit *) malloc(needbytes);
+                               if (allocres == NULL) {
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               res = allocres;
+                       }
+               }
+               // res now -> number lsu, buffer, or allocated storage for Unit array
+
+               // Place the coefficient into the selected Unit array
+               // [this is often 70% of the cost of this function when DECDPUN>1]
+#if DECDPUN>1
+               out = 0;        // accumulator
+               up = res + D2U(d) - 1;  // -> msu
+               cut = d - (up - res) * DECDPUN; // digits in top unit
+               for (c = cfirst;; c++) {        // along the digits
+                       if (*c == '.')
+                               continue;       // ignore '.' [don't decrement cut]
+                       out = X10(out) + (Int) * c - (Int) '0';
+                       if (c == last)
+                               break;  // done [never get to trailing '.']
+                       cut--;
+                       if (cut > 0)
+                               continue;       // more for this unit
+                       *up = (Unit) out;       // write unit
+                       up--;   // prepare for unit below..
+                       cut = DECDPUN;  // ..
+                       out = 0;        // ..
+               }               // c
+               *up = (Unit) out;       // write lsu
+
+#else
+               // DECDPUN==1
+               up = res;       // -> lsu
+               for (c = last; c >= cfirst; c--) {      // over each character, from least
+                       if (*c == '.')
+                               continue;       // ignore . [don't step up]
+                       *up = (Unit) ((Int) * c - (Int) '0');
+                       up++;
+               }               // c
+#endif
+
+               dn->bits = bits;
+               dn->exponent = exponent;
+               dn->digits = d;
+
+               // if not in number (too long) shorten into the number
+               if (d > set->digits) {
+                       residue = 0;
+                       decSetCoeff(dn, set, res, d, &residue, &status);
+                       // always check for overflow or subnormal and round as needed
+                       decFinalize(dn, set, &residue, &status);
+               } else {        // no rounding, but may still have overflow or subnormal
+                       // [these tests are just for performance; finalize repeats them]
+                       if ((dn->exponent - 1 < set->emin - dn->digits)
+                           || (dn->exponent - 1 > set->emax - set->digits)) {
+                               residue = 0;
+                               decFinalize(dn, set, &residue, &status);
+                       }
+               }
+               // decNumberShow(dn);
+       } while (0);            // [for break]
+
+       if (allocres != NULL)
+               free(allocres); // drop any storage used
+       if (status != 0)
+               decStatus(dn, status, set);
+       return dn;
+}                              /* decNumberFromString */
+
+/* ================================================================== */
+/* Operators                                                          */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* decNumberAbs -- absolute value operator                            */
+/*                                                                    */
+/*   This computes C = abs(A)                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* See also decNumberCopyAbs for a quiet bitwise version of this.     */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* This has the same effect as decNumberPlus unless A is negative,    */
+/* in which case it has the same effect as decNumberMinus.            */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberAbs(decNumber * res, const decNumber * rhs,
+                       decContext * set)
+{
+       decNumber dzero;        // for 0
+       uInt status = 0;        // accumulator
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       decNumberZero(&dzero);  // set 0
+       dzero.exponent = rhs->exponent; // [no coefficient expansion]
+       decAddOp(res, &dzero, rhs, set, (uByte) (rhs->bits & DECNEG), &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberAbs
+
+/* ------------------------------------------------------------------ */
+/* decNumberAdd -- add two Numbers                                    */
+/*                                                                    */
+/*   This computes C = A + B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* This just calls the routine shared with Subtract                   */
+decNumber *decNumberAdd(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decAddOp(res, lhs, rhs, set, 0, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberAdd
+
+/* ------------------------------------------------------------------ */
+/* decNumberAnd -- AND two Numbers, digitwise                         */
+/*                                                                    */
+/*   This computes C = A & B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X&X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context (used for result length and error report)     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Logical function restrictions apply (see above); a NaN is          */
+/* returned with Invalid_operation if a restriction is violated.      */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberAnd(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       const Unit *ua, *ub;    // -> operands
+       const Unit *msua, *msub;        // -> operand msus
+       Unit *uc, *msuc;        // -> result and its msu
+       Int msudigs;            // digits in res msu
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       if (lhs->exponent != 0 || decNumberIsSpecial(lhs)
+           || decNumberIsNegative(lhs)
+           || rhs->exponent != 0 || decNumberIsSpecial(rhs)
+           || decNumberIsNegative(rhs)) {
+               decStatus(res, DEC_Invalid_operation, set);
+               return res;
+       }
+       // operands are valid
+       ua = lhs->lsu;          // bottom-up
+       ub = rhs->lsu;          // ..
+       uc = res->lsu;          // ..
+       msua = ua + D2U(lhs->digits) - 1;       // -> msu of lhs
+       msub = ub + D2U(rhs->digits) - 1;       // -> msu of rhs
+       msuc = uc + D2U(set->digits) - 1;       // -> msu of result
+       msudigs = MSUDIGITS(set->digits);       // [faster than remainder]
+       for (; uc <= msuc; ua++, ub++, uc++) {  // Unit loop
+               Unit a, b;      // extract units
+               if (ua > msua)
+                       a = 0;
+               else
+                       a = *ua;
+               if (ub > msub)
+                       b = 0;
+               else
+                       b = *ub;
+               *uc = 0;        // can now write back
+               if (a | b) {    // maybe 1 bits to examine
+                       Int i, j;
+                       *uc = 0;        // can now write back
+                       // This loop could be unrolled and/or use BIN2BCD tables
+                       for (i = 0; i < DECDPUN; i++) {
+                               if (a & b & 1)
+                                       *uc = *uc + (Unit) powers[i];   // effect AND
+                               j = a % 10;
+                               a = a / 10;
+                               j |= b % 10;
+                               b = b / 10;
+                               if (j > 1) {
+                                       decStatus(res, DEC_Invalid_operation,
+                                                 set);
+                                       return res;
+                               }
+                               if (uc == msuc && i == msudigs - 1)
+                                       break;  // just did final digit
+                       }       // each digit
+               }               // both OK
+       }                       // each unit
+       // [here uc-1 is the msu of the result]
+       res->digits = decGetDigits(res->lsu, uc - res->lsu);
+       res->exponent = 0;      // integer
+       res->bits = 0;          // sign=0
+       return res;             // [no status to set]
+}                              // decNumberAnd
+
+/* ------------------------------------------------------------------ */
+/* decNumberCompare -- compare two Numbers                            */
+/*                                                                    */
+/*   This computes C = A ? B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for one digit (or NaN).                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCompare(decNumber * res, const decNumber * lhs,
+                           const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPARE, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberCompare
+
+/* ------------------------------------------------------------------ */
+/* decNumberCompareSignal -- compare, signalling on all NaNs          */
+/*                                                                    */
+/*   This computes C = A ? B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for one digit (or NaN).                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCompareSignal(decNumber * res, const decNumber * lhs,
+                                 const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberCompareSignal
+
+/* ------------------------------------------------------------------ */
+/* decNumberCompareTotal -- compare two Numbers, using total ordering */
+/*                                                                    */
+/*   This computes C = A ? B, under total ordering                    */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for one digit; the result will always be one of  */
+/* -1, 0, or 1.                                                       */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCompareTotal(decNumber * res, const decNumber * lhs,
+                                const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberCompareTotal
+
+/* ------------------------------------------------------------------ */
+/* decNumberCompareTotalMag -- compare, total ordering of magnitudes  */
+/*                                                                    */
+/*   This computes C = |A| ? |B|, under total ordering                */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for one digit; the result will always be one of  */
+/* -1, 0, or 1.                                                       */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCompareTotalMag(decNumber * res, const decNumber * lhs,
+                                   const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       uInt needbytes;         // for space calculations
+       decNumber bufa[D2N(DECBUFFER + 1)];     // +1 in case DECBUFFER=0
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber bufb[D2N(DECBUFFER + 1)];
+       decNumber *allocbufb = NULL;    // -> allocated bufb, iff allocated
+       decNumber *a, *b;       // temporary pointers
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+               // if either is negative, take a copy and absolute
+               if (decNumberIsNegative(lhs)) { // lhs<0
+                       a = bufa;
+                       needbytes =
+                           sizeof(decNumber) + (D2U(lhs->digits) -
+                                                1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufa)) { // need malloc space
+                               allocbufa = (decNumber *) malloc(needbytes);
+                               if (allocbufa == NULL) {        // hopeless -- abandon
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               a = allocbufa;  // use the allocated space
+                       }
+                       decNumberCopy(a, lhs);  // copy content
+                       a->bits &= ~DECNEG;     // .. and clear the sign
+                       lhs = a;        // use copy from here on
+               }
+               if (decNumberIsNegative(rhs)) { // rhs<0
+                       b = bufb;
+                       needbytes =
+                           sizeof(decNumber) + (D2U(rhs->digits) -
+                                                1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufb)) { // need malloc space
+                               allocbufb = (decNumber *) malloc(needbytes);
+                               if (allocbufb == NULL) {        // hopeless -- abandon
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               b = allocbufb;  // use the allocated space
+                       }
+                       decNumberCopy(b, rhs);  // copy content
+                       b->bits &= ~DECNEG;     // .. and clear the sign
+                       rhs = b;        // use copy from here on
+               }
+               decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
+       } while (0);            // end protected
+
+       if (allocbufa != NULL)
+               free(allocbufa);        // drop any storage used
+       if (allocbufb != NULL)
+               free(allocbufb);        // ..
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberCompareTotalMag
+
+/* ------------------------------------------------------------------ */
+/* decNumberDivide -- divide one number by another                    */
+/*                                                                    */
+/*   This computes C = A / B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberDivide(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberDivide
+
+/* ------------------------------------------------------------------ */
+/* decNumberDivideInteger -- divide and return integer quotient       */
+/*                                                                    */
+/*   This computes C = A # B, where # is the integer divide operator  */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X#X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberDivideInteger(decNumber * res, const decNumber * lhs,
+                                 const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberDivideInteger
+
+/* ------------------------------------------------------------------ */
+/* decNumberExp -- exponentiation                                     */
+/*                                                                    */
+/*   This computes C = exp(A)                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* Finite results will always be full precision and Inexact, except   */
+/* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
+/*                                                                    */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+/* This is a wrapper for decExpOp which can handle the slightly wider */
+/* (double) range needed by Ln (which has to be able to calculate     */
+/* exp(-a) where a can be the tiniest number (Ntiny).                 */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberExp(decNumber * res, const decNumber * rhs,
+                       decContext * set)
+{
+       uInt status = 0;        // accumulator
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // Check restrictions; these restrictions ensure that if h=8 (see
+       // decExpOp) then the result will either overflow or underflow to 0.
+       // Other math functions restrict the input range, too, for inverses.
+       // If not violated then carry out the operation.
+       if (!decCheckMath(rhs, set, &status))
+               do {            // protect allocation
+#if DECSUBSET
+                       if (!set->extended) {
+                               // reduce operand and set lostDigits status, as needed
+                               if (rhs->digits > set->digits) {
+                                       allocrhs =
+                                           decRoundOperand(rhs, set, &status);
+                                       if (allocrhs == NULL)
+                                               break;
+                                       rhs = allocrhs;
+                               }
+                       }
+#endif
+                       decExpOp(res, rhs, set, &status);
+               } while (0);    // end protected
+
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // drop any storage used
+#endif
+       // apply significant status
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberExp
+
+/* ------------------------------------------------------------------ */
+/* decNumberFMA -- fused multiply add                                 */
+/*                                                                    */
+/*   This computes D = (A * B) + C with only one rounding             */
+/*                                                                    */
+/*   res is D, the result.  D may be A or B or C (e.g., X=FMA(X,X,X)) */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   fhs is C [far hand side]                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberFMA(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, const decNumber * fhs,
+                       decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decContext dcmul;       // context for the multiplication
+       uInt needbytes;         // for space calculations
+       decNumber bufa[D2N(DECBUFFER * 2 + 1)];
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *acc;         // accumulator pointer
+       decNumber dzero;        // work
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+       if (decCheckOperands(res, fhs, DECUNUSED, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {   // [undefined if subset]
+                       status |= DEC_Invalid_operation;
+                       break;
+               }
+#endif
+               // Check math restrictions [these ensure no overflow or underflow]
+               if ((!decNumberIsSpecial(lhs)
+                    && decCheckMath(lhs, set, &status))
+                   || (!decNumberIsSpecial(rhs)
+                       && decCheckMath(rhs, set, &status))
+                   || (!decNumberIsSpecial(fhs)
+                       && decCheckMath(fhs, set, &status)))
+                       break;
+               // set up context for multiply
+               dcmul = *set;
+               dcmul.digits = lhs->digits + rhs->digits;       // just enough
+               // [The above may be an over-estimate for subset arithmetic, but that's OK]
+               dcmul.emax = DEC_MAX_EMAX;      // effectively unbounded ..
+               dcmul.emin = DEC_MIN_EMIN;      // [thanks to Math restrictions]
+               // set up decNumber space to receive the result of the multiply
+               acc = bufa;     // may fit
+               needbytes =
+                   sizeof(decNumber) + (D2U(dcmul.digits) - 1) * sizeof(Unit);
+               if (needbytes > sizeof(bufa)) { // need malloc space
+                       allocbufa = (decNumber *) malloc(needbytes);
+                       if (allocbufa == NULL) {        // hopeless -- abandon
+                               status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       acc = allocbufa;        // use the allocated space
+               }
+               // multiply with extended range and necessary precision
+               //printf("emin=%ld\n", dcmul.emin);
+               decMultiplyOp(acc, lhs, rhs, &dcmul, &status);
+               // Only Invalid operation (from sNaN or Inf * 0) is possible in
+               // status; if either is seen than ignore fhs (in case it is
+               // another sNaN) and set acc to NaN unless we had an sNaN
+               // [decMultiplyOp leaves that to caller]
+               // Note sNaN has to go through addOp to shorten payload if
+               // necessary
+               if ((status & DEC_Invalid_operation) != 0) {
+                       if (!(status & DEC_sNaN)) {     // but be true invalid
+                               decNumberZero(res);     // acc not yet set
+                               res->bits = DECNAN;
+                               break;
+                       }
+                       decNumberZero(&dzero);  // make 0 (any non-NaN would do)
+                       fhs = &dzero;   // use that
+               }
+#if DECCHECK
+               else {          // multiply was OK
+                       if (status != 0)
+                               printf("Status=%08lx after FMA multiply\n",
+                                      (LI) status);
+               }
+#endif
+               // add the third operand and result -> res, and all is done
+               decAddOp(res, acc, fhs, set, 0, &status);
+       } while (0);            // end protected
+
+       if (allocbufa != NULL)
+               free(allocbufa);        // drop any storage used
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberFMA
+
+/* ------------------------------------------------------------------ */
+/* decNumberInvert -- invert a Number, digitwise                      */
+/*                                                                    */
+/*   This computes C = ~A                                             */
+/*                                                                    */
+/*   res is C, the result.  C may be A (e.g., X=~X)                   */
+/*   rhs is A                                                         */
+/*   set is the context (used for result length and error report)     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Logical function restrictions apply (see above); a NaN is          */
+/* returned with Invalid_operation if a restriction is violated.      */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberInvert(decNumber * res, const decNumber * rhs,
+                          decContext * set)
+{
+       const Unit *ua, *msua;  // -> operand and its msu
+       Unit *uc, *msuc;        // -> result and its msu
+       Int msudigs;            // digits in res msu
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       if (rhs->exponent != 0 || decNumberIsSpecial(rhs)
+           || decNumberIsNegative(rhs)) {
+               decStatus(res, DEC_Invalid_operation, set);
+               return res;
+       }
+       // operand is valid
+       ua = rhs->lsu;          // bottom-up
+       uc = res->lsu;          // ..
+       msua = ua + D2U(rhs->digits) - 1;       // -> msu of rhs
+       msuc = uc + D2U(set->digits) - 1;       // -> msu of result
+       msudigs = MSUDIGITS(set->digits);       // [faster than remainder]
+       for (; uc <= msuc; ua++, uc++) {        // Unit loop
+               Unit a;         // extract unit
+               Int i, j;       // work
+               if (ua > msua)
+                       a = 0;
+               else
+                       a = *ua;
+               *uc = 0;        // can now write back
+               // always need to examine all bits in rhs
+               // This loop could be unrolled and/or use BIN2BCD tables
+               for (i = 0; i < DECDPUN; i++) {
+                       if ((~a) & 1)
+                               *uc = *uc + (Unit) powers[i];   // effect INVERT
+                       j = a % 10;
+                       a = a / 10;
+                       if (j > 1) {
+                               decStatus(res, DEC_Invalid_operation, set);
+                               return res;
+                       }
+                       if (uc == msuc && i == msudigs - 1)
+                               break;  // just did final digit
+               }               // each digit
+       }                       // each unit
+       // [here uc-1 is the msu of the result]
+       res->digits = decGetDigits(res->lsu, uc - res->lsu);
+       res->exponent = 0;      // integer
+       res->bits = 0;          // sign=0
+       return res;             // [no status to set]
+}                              // decNumberInvert
+
+/* ------------------------------------------------------------------ */
+/* decNumberLn -- natural logarithm                                   */
+/*                                                                    */
+/*   This computes C = ln(A)                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Notable cases:                                                     */
+/*   A<0 -> Invalid                                                   */
+/*   A=0 -> -Infinity (Exact)                                         */
+/*   A=+Infinity -> +Infinity (Exact)                                 */
+/*   A=1 exactly -> 0 (Exact)                                         */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+/* This is a wrapper for decLnOp which can handle the slightly wider  */
+/* (+11) range needed by Ln, Log10, etc. (which may have to be able   */
+/* to calculate at p+e+2).                                            */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberLn(decNumber * res, const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // Check restrictions; this is a math function; if not violated
+       // then carry out the operation.
+       if (!decCheckMath(rhs, set, &status))
+               do {            // protect allocation
+#if DECSUBSET
+                       if (!set->extended) {
+                               // reduce operand and set lostDigits status, as needed
+                               if (rhs->digits > set->digits) {
+                                       allocrhs =
+                                           decRoundOperand(rhs, set, &status);
+                                       if (allocrhs == NULL)
+                                               break;
+                                       rhs = allocrhs;
+                               }
+                               // special check in subset for rhs=0
+                               if (ISZERO(rhs)) {      // +/- zeros -> error
+                                       status |= DEC_Invalid_operation;
+                                       break;
+                               }
+                       }       // extended=0
+#endif
+                       decLnOp(res, rhs, set, &status);
+               } while (0);    // end protected
+
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // drop any storage used
+#endif
+       // apply significant status
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberLn
+
+/* ------------------------------------------------------------------ */
+/* decNumberLogB - get adjusted exponent, by 754 rules                */
+/*                                                                    */
+/*   This computes C = adjustedexponent(A)                            */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context, used only for digits and status              */
+/*                                                                    */
+/* For an unrounded result, digits may need to be 10 (A might have    */
+/* 10**9 digits and an exponent of +999999999, or one digit and an    */
+/* exponent of -1999999999).                                          */
+/*                                                                    */
+/* This returns the adjusted exponent of A after (in theory) padding  */
+/* with zeros on the right to set->digits digits while keeping the    */
+/* same value.  The exponent is not limited by emin/emax.             */
+/*                                                                    */
+/* Notable cases:                                                     */
+/*   A<0 -> Use |A|                                                   */
+/*   A=0 -> -Infinity (Division by zero)                              */
+/*   A=Infinite -> +Infinity (Exact)                                  */
+/*   A=1 exactly -> 0 (Exact)                                         */
+/*   NaNs are propagated as usual                                     */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberLogB(decNumber * res, const decNumber * rhs,
+                        decContext * set)
+{
+       uInt status = 0;        // accumulator
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // NaNs as usual; Infinities return +Infinity; 0->oops
+       if (decNumberIsNaN(rhs))
+               decNaNs(res, rhs, NULL, set, &status);
+       else if (decNumberIsInfinite(rhs))
+               decNumberCopyAbs(res, rhs);
+       else if (decNumberIsZero(rhs)) {
+               decNumberZero(res);     // prepare for Infinity
+               res->bits = DECNEG | DECINF;    // -Infinity
+               status |= DEC_Division_by_zero; // as per 754
+       } else {                // finite non-zero
+               Int ae = rhs->exponent + rhs->digits - 1;       // adjusted exponent
+               if (set->digits >= 10)
+                       decNumberFromInt32(res, ae);    // lay it out
+               else {
+                       decNumber buft[D2N(10)];        // temporary number
+                       decNumber *t = buft;    // ..
+                       decNumberFromInt32(t, ae);      // lay it out
+                       decNumberPlus(res, t, set);     // round as necessary
+               }
+       }
+
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberLogB
+
+/* ------------------------------------------------------------------ */
+/* decNumberLog10 -- logarithm in base 10                             */
+/*                                                                    */
+/*   This computes C = log10(A)                                       */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Notable cases:                                                     */
+/*   A<0 -> Invalid                                                   */
+/*   A=0 -> -Infinity (Exact)                                         */
+/*   A=+Infinity -> +Infinity (Exact)                                 */
+/*   A=10**n (if n is an integer) -> n (Exact)                        */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+/* This calculates ln(A)/ln(10) using appropriate precision.  For     */
+/* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the      */
+/* requested digits and t is the number of digits in the exponent     */
+/* (maximum 6).  For ln(10) it is p + 3; this is often handled by the */
+/* fastpath in decLnOp.  The final division is done to the requested  */
+/* precision.                                                         */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberLog10(decNumber * res, const decNumber * rhs,
+                         decContext * set)
+{
+       uInt status = 0, ignore = 0;    // status accumulators
+       uInt needbytes;         // for space calculations
+       Int p;                  // working precision
+       Int t;                  // digits in exponent of A
+
+       // buffers for a and b working decimals
+       // (adjustment calculator, same size)
+       decNumber bufa[D2N(DECBUFFER + 2)];
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *a = bufa;    // temporary a
+       decNumber bufb[D2N(DECBUFFER + 2)];
+       decNumber *allocbufb = NULL;    // -> allocated bufb, iff allocated
+       decNumber *b = bufb;    // temporary b
+       decNumber bufw[D2N(10)];        // working 2-10 digit number
+       decNumber *w = bufw;    // ..
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+
+       decContext aset;        // working context
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // Check restrictions; this is a math function; if not violated
+       // then carry out the operation.
+       if (!decCheckMath(rhs, set, &status))
+               do {            // protect malloc
+#if DECSUBSET
+                       if (!set->extended) {
+                               // reduce operand and set lostDigits status, as needed
+                               if (rhs->digits > set->digits) {
+                                       allocrhs =
+                                           decRoundOperand(rhs, set, &status);
+                                       if (allocrhs == NULL)
+                                               break;
+                                       rhs = allocrhs;
+                               }
+                               // special check in subset for rhs=0
+                               if (ISZERO(rhs)) {      // +/- zeros -> error
+                                       status |= DEC_Invalid_operation;
+                                       break;
+                               }
+                       }       // extended=0
+#endif
+
+                       decContextDefault(&aset, DEC_INIT_DECIMAL64);   // clean context
+
+                       // handle exact powers of 10; only check if +ve finite
+                       if (!(rhs->bits & (DECNEG | DECSPECIAL))
+                           && !ISZERO(rhs)) {
+                               Int residue = 0;        // (no residue)
+                               uInt copystat = 0;      // clean status
+
+                               // round to a single digit...
+                               aset.digits = 1;
+                               decCopyFit(w, rhs, &aset, &residue, &copystat); // copy & shorten
+                               // if exact and the digit is 1, rhs is a power of 10
+                               if (!(copystat & DEC_Inexact) && w->lsu[0] == 1) {
+                                       // the exponent, conveniently, is the power of 10; making
+                                       // this the result needs a little care as it might not fit,
+                                       // so first convert it into the working number, and then move
+                                       // to res
+                                       decNumberFromInt32(w, w->exponent);
+                                       residue = 0;
+                                       decCopyFit(res, w, set, &residue, &status);     // copy & round
+                                       decFinish(res, set, &residue, &status); // cleanup/set flags
+                                       break;
+                               }       // not a power of 10
+                       }       // not a candidate for exact
+
+                       // simplify the information-content calculation to use 'total
+                       // number of digits in a, including exponent' as compared to the
+                       // requested digits, as increasing this will only rarely cost an
+                       // iteration in ln(a) anyway
+                       t = 6;  // it can never be >6
+
+                       // allocate space when needed...
+                       p = (rhs->digits + t >
+                            set->digits ? rhs->digits + t : set->digits) + 3;
+                       needbytes =
+                           sizeof(decNumber) + (D2U(p) - 1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufa)) { // need malloc space
+                               allocbufa = (decNumber *) malloc(needbytes);
+                               if (allocbufa == NULL) {        // hopeless -- abandon
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               a = allocbufa;  // use the allocated space
+                       }
+                       aset.digits = p;        // as calculated
+                       aset.emax = DEC_MAX_MATH;       // usual bounds
+                       aset.emin = -DEC_MAX_MATH;      // ..
+                       aset.clamp = 0; // and no concrete format
+                       decLnOp(a, rhs, &aset, &status);        // a=ln(rhs)
+
+                       // skip the division if the result so far is infinite, NaN, or
+                       // zero, or there was an error; note NaN from sNaN needs copy
+                       if (status & DEC_NaNs && !(status & DEC_sNaN))
+                               break;
+                       if (a->bits & DECSPECIAL || ISZERO(a)) {
+                               decNumberCopy(res, a);  // [will fit]
+                               break;
+                       }
+                       // for ln(10) an extra 3 digits of precision are needed
+                       p = set->digits + 3;
+                       needbytes =
+                           sizeof(decNumber) + (D2U(p) - 1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufb)) { // need malloc space
+                               allocbufb = (decNumber *) malloc(needbytes);
+                               if (allocbufb == NULL) {        // hopeless -- abandon
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               b = allocbufb;  // use the allocated space
+                       }
+                       decNumberZero(w);       // set up 10...
+#if DECDPUN==1
+                       w->lsu[1] = 1;
+                       w->lsu[0] = 0;  // ..
+#else
+                       w->lsu[0] = 10; // ..
+#endif
+                       w->digits = 2;  // ..
+
+                       aset.digits = p;
+                       decLnOp(b, w, &aset, &ignore);  // b=ln(10)
+
+                       aset.digits = set->digits;      // for final divide
+                       decDivideOp(res, a, b, &aset, DIVIDE, &status); // into result
+               } while (0);    // [for break]
+
+       if (allocbufa != NULL)
+               free(allocbufa);        // drop any storage used
+       if (allocbufb != NULL)
+               free(allocbufb);        // ..
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+#endif
+       // apply significant status
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberLog10
+
+/* ------------------------------------------------------------------ */
+/* decNumberMax -- compare two Numbers and return the maximum         */
+/*                                                                    */
+/*   This computes C = A ? B, returning the maximum by 754 rules      */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMax(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMax
+
+/* ------------------------------------------------------------------ */
+/* decNumberMaxMag -- compare and return the maximum by magnitude     */
+/*                                                                    */
+/*   This computes C = A ? B, returning the maximum by 754 rules      */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMaxMag(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMaxMag
+
+/* ------------------------------------------------------------------ */
+/* decNumberMin -- compare two Numbers and return the minimum         */
+/*                                                                    */
+/*   This computes C = A ? B, returning the minimum by 754 rules      */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMin(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMin
+
+/* ------------------------------------------------------------------ */
+/* decNumberMinMag -- compare and return the minimum by magnitude     */
+/*                                                                    */
+/*   This computes C = A ? B, returning the minimum by 754 rules      */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMinMag(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMinMag
+
+/* ------------------------------------------------------------------ */
+/* decNumberMinus -- prefix minus operator                            */
+/*                                                                    */
+/*   This computes C = 0 - A                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* See also decNumberCopyNegate for a quiet bitwise version of this.  */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* Simply use AddOp for the subtract, which will do the necessary.    */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMinus(decNumber * res, const decNumber * rhs,
+                         decContext * set)
+{
+       decNumber dzero;
+       uInt status = 0;        // accumulator
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       decNumberZero(&dzero);  // make 0
+       dzero.exponent = rhs->exponent; // [no coefficient expansion]
+       decAddOp(res, &dzero, rhs, set, DECNEG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMinus
+
+/* ------------------------------------------------------------------ */
+/* decNumberNextMinus -- next towards -Infinity                       */
+/*                                                                    */
+/*   This computes C = A - infinitesimal, rounded towards -Infinity   */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* This is a generalization of 754 NextDown.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberNextMinus(decNumber * res, const decNumber * rhs,
+                             decContext * set)
+{
+       decNumber dtiny;        // constant
+       decContext workset = *set;      // work
+       uInt status = 0;        // accumulator
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // +Infinity is the special case
+       if ((rhs->bits & (DECINF | DECNEG)) == DECINF) {
+               decSetMaxValue(res, set);       // is +ve
+               // there is no status to set
+               return res;
+       }
+       decNumberZero(&dtiny);  // start with 0
+       dtiny.lsu[0] = 1;       // make number that is ..
+       dtiny.exponent = DEC_MIN_EMIN - 1;      // .. smaller than tiniest
+       workset.round = DEC_ROUND_FLOOR;
+       decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
+       status &= DEC_Invalid_operation | DEC_sNaN;     // only sNaN Invalid please
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberNextMinus
+
+/* ------------------------------------------------------------------ */
+/* decNumberNextPlus -- next towards +Infinity                        */
+/*                                                                    */
+/*   This computes C = A + infinitesimal, rounded towards +Infinity   */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* This is a generalization of 754 NextUp.                            */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberNextPlus(decNumber * res, const decNumber * rhs,
+                            decContext * set)
+{
+       decNumber dtiny;        // constant
+       decContext workset = *set;      // work
+       uInt status = 0;        // accumulator
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // -Infinity is the special case
+       if ((rhs->bits & (DECINF | DECNEG)) == (DECINF | DECNEG)) {
+               decSetMaxValue(res, set);
+               res->bits = DECNEG;     // negative
+               // there is no status to set
+               return res;
+       }
+       decNumberZero(&dtiny);  // start with 0
+       dtiny.lsu[0] = 1;       // make number that is ..
+       dtiny.exponent = DEC_MIN_EMIN - 1;      // .. smaller than tiniest
+       workset.round = DEC_ROUND_CEILING;
+       decAddOp(res, rhs, &dtiny, &workset, 0, &status);
+       status &= DEC_Invalid_operation | DEC_sNaN;     // only sNaN Invalid please
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberNextPlus
+
+/* ------------------------------------------------------------------ */
+/* decNumberNextToward -- next towards rhs                            */
+/*                                                                    */
+/*   This computes C = A +/- infinitesimal, rounded towards           */
+/*   +/-Infinity in the direction of B, as per 754-1985 nextafter     */
+/*   modified during revision but dropped from 754-2008.              */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B.                          */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* This is a generalization of 754-1985 NextAfter.                    */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberNextToward(decNumber * res, const decNumber * lhs,
+                              const decNumber * rhs, decContext * set)
+{
+       decNumber dtiny;        // constant
+       decContext workset = *set;      // work
+       Int result;             // ..
+       uInt status = 0;        // accumulator
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
+               decNaNs(res, lhs, rhs, set, &status);
+       } else {                // Is numeric, so no chance of sNaN Invalid, etc.
+               result = decCompare(lhs, rhs, 0);       // sign matters
+               if (result == BADINT)
+                       status |= DEC_Insufficient_storage;     // rare
+               else {          // valid compare
+                       if (result == 0)
+                               decNumberCopySign(res, lhs, rhs);       // easy
+                       else {  // differ: need NextPlus or NextMinus
+                               uByte sub;      // add or subtract
+                               if (result < 0) {       // lhs<rhs, do nextplus
+                                       // -Infinity is the special case
+                                       if ((lhs->bits & (DECINF | DECNEG)) ==
+                                           (DECINF | DECNEG)) {
+                                               decSetMaxValue(res, set);
+                                               res->bits = DECNEG;     // negative
+                                               return res;     // there is no status to set
+                                       }
+                                       workset.round = DEC_ROUND_CEILING;
+                                       sub = 0;        // add, please
+                               }       // plus
+                               else {  // lhs>rhs, do nextminus
+                                       // +Infinity is the special case
+                                       if ((lhs->bits & (DECINF | DECNEG)) ==
+                                           DECINF) {
+                                               decSetMaxValue(res, set);
+                                               return res;     // there is no status to set
+                                       }
+                                       workset.round = DEC_ROUND_FLOOR;
+                                       sub = DECNEG;   // subtract, please
+                               }       // minus
+                               decNumberZero(&dtiny);  // start with 0
+                               dtiny.lsu[0] = 1;       // make number that is ..
+                               dtiny.exponent = DEC_MIN_EMIN - 1;      // .. smaller than tiniest
+                               decAddOp(res, lhs, &dtiny, &workset, sub, &status);     // + or -
+                               // turn off exceptions if the result is a normal number
+                               // (including Nmin), otherwise let all status through
+                               if (decNumberIsNormal(res, set))
+                                       status = 0;
+                       }       // unequal
+               }               // compare OK
+       }                       // numeric
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberNextToward
+
+/* ------------------------------------------------------------------ */
+/* decNumberOr -- OR two Numbers, digitwise                           */
+/*                                                                    */
+/*   This computes C = A | B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X|X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context (used for result length and error report)     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Logical function restrictions apply (see above); a NaN is          */
+/* returned with Invalid_operation if a restriction is violated.      */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberOr(decNumber * res, const decNumber * lhs,
+                      const decNumber * rhs, decContext * set)
+{
+       const Unit *ua, *ub;    // -> operands
+       const Unit *msua, *msub;        // -> operand msus
+       Unit *uc, *msuc;        // -> result and its msu
+       Int msudigs;            // digits in res msu
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       if (lhs->exponent != 0 || decNumberIsSpecial(lhs)
+           || decNumberIsNegative(lhs)
+           || rhs->exponent != 0 || decNumberIsSpecial(rhs)
+           || decNumberIsNegative(rhs)) {
+               decStatus(res, DEC_Invalid_operation, set);
+               return res;
+       }
+       // operands are valid
+       ua = lhs->lsu;          // bottom-up
+       ub = rhs->lsu;          // ..
+       uc = res->lsu;          // ..
+       msua = ua + D2U(lhs->digits) - 1;       // -> msu of lhs
+       msub = ub + D2U(rhs->digits) - 1;       // -> msu of rhs
+       msuc = uc + D2U(set->digits) - 1;       // -> msu of result
+       msudigs = MSUDIGITS(set->digits);       // [faster than remainder]
+       for (; uc <= msuc; ua++, ub++, uc++) {  // Unit loop
+               Unit a, b;      // extract units
+               if (ua > msua)
+                       a = 0;
+               else
+                       a = *ua;
+               if (ub > msub)
+                       b = 0;
+               else
+                       b = *ub;
+               *uc = 0;        // can now write back
+               if (a | b) {    // maybe 1 bits to examine
+                       Int i, j;
+                       // This loop could be unrolled and/or use BIN2BCD tables
+                       for (i = 0; i < DECDPUN; i++) {
+                               if ((a | b) & 1)
+                                       *uc = *uc + (Unit) powers[i];   // effect OR
+                               j = a % 10;
+                               a = a / 10;
+                               j |= b % 10;
+                               b = b / 10;
+                               if (j > 1) {
+                                       decStatus(res, DEC_Invalid_operation,
+                                                 set);
+                                       return res;
+                               }
+                               if (uc == msuc && i == msudigs - 1)
+                                       break;  // just did final digit
+                       }       // each digit
+               }               // non-zero
+       }                       // each unit
+       // [here uc-1 is the msu of the result]
+       res->digits = decGetDigits(res->lsu, uc - res->lsu);
+       res->exponent = 0;      // integer
+       res->bits = 0;          // sign=0
+       return res;             // [no status to set]
+}                              // decNumberOr
+
+/* ------------------------------------------------------------------ */
+/* decNumberPlus -- prefix plus operator                              */
+/*                                                                    */
+/*   This computes C = 0 + A                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* See also decNumberCopy for a quiet bitwise version of this.        */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* This simply uses AddOp; Add will take fast path after preparing A. */
+/* Performance is a concern here, as this routine is often used to    */
+/* check operands and apply rounding and overflow/underflow testing.  */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberPlus(decNumber * res, const decNumber * rhs,
+                        decContext * set)
+{
+       decNumber dzero;
+       uInt status = 0;        // accumulator
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       decNumberZero(&dzero);  // make 0
+       dzero.exponent = rhs->exponent; // [no coefficient expansion]
+       decAddOp(res, &dzero, rhs, set, 0, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberPlus
+
+/* ------------------------------------------------------------------ */
+/* decNumberMultiply -- multiply two Numbers                          */
+/*                                                                    */
+/*   This computes C = A x B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMultiply(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decMultiplyOp(res, lhs, rhs, set, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMultiply
+
+/* ------------------------------------------------------------------ */
+/* decNumberPower -- raise a number to a power                        */
+/*                                                                    */
+/*   This computes C = A ** B                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X**X)        */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* However, if 1999999997<=B<=999999999 and B is an integer then the  */
+/* restrictions on A and the context are relaxed to the usual bounds, */
+/* for compatibility with the earlier (integer power only) version    */
+/* of this function.                                                  */
+/*                                                                    */
+/* When B is an integer, the result may be exact, even if rounded.    */
+/*                                                                    */
+/* The final result is rounded according to the context; it will      */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberPower(decNumber * res, const decNumber * lhs,
+                         const decNumber * rhs, decContext * set)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       decNumber *allocdac = NULL;     // -> allocated acc buffer, iff used
+       decNumber *allocinv = NULL;     // -> allocated 1/x buffer, iff used
+       Int reqdigits = set->digits;    // requested DIGITS
+       Int n;                  // rhs in binary
+       Flag rhsint = 0;        // 1 if rhs is an integer
+       Flag useint = 0;        // 1 if can use integer calculation
+       Flag isoddint = 0;      // 1 if rhs is an integer and odd
+       Int i;                  // work
+#if DECSUBSET
+       Int dropped;            // ..
+#endif
+       uInt needbytes;         // buffer size needed
+       Flag seenbit;           // seen a bit while powering
+       Int residue = 0;        // rounding residue
+       uInt status = 0;        // accumulators
+       uByte bits = 0;         // result sign if errors
+       decContext aset;        // working context
+       decNumber dnOne;        // work value 1...
+       // local accumulator buffer [a decNumber, with digits+elength+1 digits]
+       decNumber dacbuff[D2N(DECBUFFER + 9)];
+       decNumber *dac = dacbuff;       // -> result accumulator
+       // same again for possible 1/lhs calculation
+       decNumber invbuff[D2N(DECBUFFER + 9)];
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {   // reduce operands and set status, as needed
+                       if (lhs->digits > reqdigits) {
+                               alloclhs = decRoundOperand(lhs, set, &status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > reqdigits) {
+                               allocrhs = decRoundOperand(rhs, set, &status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // handle NaNs and rhs Infinity (lhs infinity is harder)
+               if (SPECIALARGS) {
+                       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {       // NaNs
+                               decNaNs(res, lhs, rhs, set, &status);
+                               break;
+                       }
+                       if (decNumberIsInfinite(rhs)) { // rhs Infinity
+                               Flag rhsneg = rhs->bits & DECNEG;       // save rhs sign
+                               if (decNumberIsNegative(lhs)    // lhs<0
+                                   && !decNumberIsZero(lhs))   // ..
+                                       status |= DEC_Invalid_operation;
+                               else {  // lhs >=0
+                                       decNumberZero(&dnOne);  // set up 1
+                                       dnOne.lsu[0] = 1;
+                                       decNumberCompare(dac, lhs, &dnOne, set);        // lhs ? 1
+                                       decNumberZero(res);     // prepare for 0/1/Infinity
+                                       if (decNumberIsNegative(dac)) { // lhs<1
+                                               if (rhsneg)
+                                                       res->bits |= DECINF;    // +Infinity [else is +0]
+                                       } else if (dac->lsu[0] == 0) {  // lhs=1
+                                               // 1**Infinity is inexact, so return fully-padded 1.0000
+                                               Int shift = set->digits - 1;
+                                               *res->lsu = 1;  // was 0, make int 1
+                                               res->digits =
+                                                   decShiftToMost(res->lsu, 1,
+                                                                  shift);
+                                               res->exponent = -shift; // make 1.0000...
+                                               status |= DEC_Inexact | DEC_Rounded;    // deemed inexact
+                                       } else {        // lhs>1
+                                               if (!rhsneg)
+                                                       res->bits |= DECINF;    // +Infinity [else is +0]
+                                       }
+                               }       // lhs>=0
+                               break;
+                       }
+                       // [lhs infinity drops through]
+               }               // specials
+
+               // Original rhs may be an integer that fits and is in range
+               n = decGetInt(rhs);
+               if (n != BADINT) {      // it is an integer
+                       rhsint = 1;     // record the fact for 1**n
+                       isoddint = (Flag) n & 1;        // [works even if big]
+                       if (n != BIGEVEN && n != BIGODD)        // can use integer path?
+                               useint = 1;     // looks good
+               }
+
+               if (decNumberIsNegative(lhs)    // -x ..
+                   && isoddint)
+                       bits = DECNEG;  // .. to an odd power
+
+               // handle LHS infinity
+               if (decNumberIsInfinite(lhs)) { // [NaNs already handled]
+                       uByte rbits = rhs->bits;        // save
+                       decNumberZero(res);     // prepare
+                       if (n == 0)
+                               *res->lsu = 1;  // [-]Inf**0 => 1
+                       else {
+                               // -Inf**nonint -> error
+                               if (!rhsint && decNumberIsNegative(lhs)) {
+                                       status |= DEC_Invalid_operation;        // -Inf**nonint is error
+                                       break;
+                               }
+                               if (!(rbits & DECNEG))
+                                       bits |= DECINF; // was not a **-n
+                               // [otherwise will be 0 or -0]
+                               res->bits = bits;
+                       }
+                       break;
+               }
+               // similarly handle LHS zero
+               if (decNumberIsZero(lhs)) {
+                       if (n == 0) {   // 0**0 => Error
+#if DECSUBSET
+                               if (!set->extended) {   // [unless subset]
+                                       decNumberZero(res);
+                                       *res->lsu = 1;  // return 1
+                                       break;
+                               }
+#endif
+                               status |= DEC_Invalid_operation;
+                       } else {        // 0**x
+                               uByte rbits = rhs->bits;        // save
+                               if (rbits & DECNEG) {   // was a 0**(-n)
+#if DECSUBSET
+                                       if (!set->extended) {   // [bad if subset]
+                                               status |= DEC_Invalid_operation;
+                                               break;
+                                       }
+#endif
+                                       bits |= DECINF;
+                               }
+                               decNumberZero(res);     // prepare
+                               // [otherwise will be 0 or -0]
+                               res->bits = bits;
+                       }
+                       break;
+               }
+               // here both lhs and rhs are finite; rhs==0 is handled in the
+               // integer path.  Next handle the non-integer cases
+               if (!useint) {  // non-integral rhs
+                       // any -ve lhs is bad, as is either operand or context out of
+                       // bounds
+                       if (decNumberIsNegative(lhs)) {
+                               status |= DEC_Invalid_operation;
+                               break;
+                       }
+                       if (decCheckMath(lhs, set, &status)
+                           || decCheckMath(rhs, set, &status))
+                               break;  // variable status
+
+                       decContextDefault(&aset, DEC_INIT_DECIMAL64);   // clean context
+                       aset.emax = DEC_MAX_MATH;       // usual bounds
+                       aset.emin = -DEC_MAX_MATH;      // ..
+                       aset.clamp = 0; // and no concrete format
+
+                       // calculate the result using exp(ln(lhs)*rhs), which can
+                       // all be done into the accumulator, dac.  The precision needed
+                       // is enough to contain the full information in the lhs (which
+                       // is the total digits, including exponent), or the requested
+                       // precision, if larger, + 4; 6 is used for the exponent
+                       // maximum length, and this is also used when it is shorter
+                       // than the requested digits as it greatly reduces the >0.5 ulp
+                       // cases at little cost (because Ln doubles digits each
+                       // iteration so a few extra digits rarely causes an extra
+                       // iteration)
+                       aset.digits = MAXI(lhs->digits, set->digits) + 6 + 4;
+               }               // non-integer rhs
+
+               else {          // rhs is in-range integer
+                       if (n == 0) {   // x**0 = 1
+                               // (0**0 was handled above)
+                               decNumberZero(res);     // result=1
+                               *res->lsu = 1;  // ..
+                               break;
+                       }
+                       // rhs is a non-zero integer
+                       if (n < 0)
+                               n = -n; // use abs(n)
+
+                       aset = *set;    // clone the context
+                       aset.round = DEC_ROUND_HALF_EVEN;       // internally use balanced
+                       // calculate the working DIGITS
+                       aset.digits =
+                           reqdigits + (rhs->digits + rhs->exponent) + 2;
+#if DECSUBSET
+                       if (!set->extended)
+                               aset.digits--;  // use classic precision
+#endif
+                       // it's an error if this is more than can be handled
+                       if (aset.digits > DECNUMMAXP) {
+                               status |= DEC_Invalid_operation;
+                               break;
+                       }
+               }               // integer path
+
+               // aset.digits is the count of digits for the accumulator needed
+               // if accumulator is too long for local storage, then allocate
+               needbytes =
+                   sizeof(decNumber) + (D2U(aset.digits) - 1) * sizeof(Unit);
+               // [needbytes also used below if 1/lhs needed]
+               if (needbytes > sizeof(dacbuff)) {
+                       allocdac = (decNumber *) malloc(needbytes);
+                       if (allocdac == NULL) { // hopeless -- abandon
+                               status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       dac = allocdac; // use the allocated space
+               }
+               // here, aset is set up and accumulator is ready for use
+
+               if (!useint) {  // non-integral rhs
+                       // x ** y; special-case x=1 here as it will otherwise always
+                       // reduce to integer 1; decLnOp has a fastpath which detects
+                       // the case of x=1
+                       decLnOp(dac, lhs, &aset, &status);      // dac=ln(lhs)
+                       // [no error possible, as lhs 0 already handled]
+                       if (ISZERO(dac)) {      // x==1, 1.0, etc.
+                               // need to return fully-padded 1.0000 etc., but rhsint->1
+                               *dac->lsu = 1;  // was 0, make int 1
+                               if (!rhsint) {  // add padding
+                                       Int shift = set->digits - 1;
+                                       dac->digits =
+                                           decShiftToMost(dac->lsu, 1, shift);
+                                       dac->exponent = -shift; // make 1.0000...
+                                       status |= DEC_Inexact | DEC_Rounded;    // deemed inexact
+                               }
+                       } else {
+                               decMultiplyOp(dac, dac, rhs, &aset, &status);   // dac=dac*rhs
+                               decExpOp(dac, dac, &aset, &status);     // dac=exp(dac)
+                       }
+                       // and drop through for final rounding
+               }               // non-integer rhs
+
+               else {          // carry on with integer
+                       decNumberZero(dac);     // acc=1
+                       *dac->lsu = 1;  // ..
+
+                       // if a negative power the constant 1 is needed, and if not subset
+                       // invert the lhs now rather than inverting the result later
+                       if (decNumberIsNegative(rhs)) { // was a **-n [hence digits>0]
+                               decNumber *inv = invbuff;       // asssume use fixed buffer
+                               decNumberCopy(&dnOne, dac);     // dnOne=1;  [needed now or later]
+#if DECSUBSET
+                               if (set->extended) {    // need to calculate 1/lhs
+#endif
+                                       // divide lhs into 1, putting result in dac [dac=1/dac]
+                                       decDivideOp(dac, &dnOne, lhs, &aset,
+                                                   DIVIDE, &status);
+                                       // now locate or allocate space for the inverted lhs
+                                       if (needbytes > sizeof(invbuff)) {
+                                               allocinv = (decNumber *)
+                                                   malloc(needbytes);
+                                               if (allocinv == NULL) { // hopeless -- abandon
+                                                       status |=
+                                                           DEC_Insufficient_storage;
+                                                       break;
+                                               }
+                                               inv = allocinv; // use the allocated space
+                                       }
+                                       // [inv now points to big-enough buffer or allocated storage]
+                                       decNumberCopy(inv, dac);        // copy the 1/lhs
+                                       decNumberCopy(dac, &dnOne);     // restore acc=1
+                                       lhs = inv;      // .. and go forward with new lhs
+#if DECSUBSET
+                               }
+#endif
+                       }
+                       // Raise-to-the-power loop...
+                       seenbit = 0;    // set once a 1-bit is encountered
+                       for (i = 1;; i++) {     // for each bit [top bit ignored]
+                               // abandon if had overflow or terminal underflow
+                               if (status & (DEC_Overflow | DEC_Underflow)) {  // interesting?
+                                       if (status & DEC_Overflow
+                                           || ISZERO(dac))
+                                               break;
+                               }
+                               // [the following two lines revealed an optimizer bug in a C++
+                               // compiler, with symptom: 5**3 -> 25, when n=n+n was used]
+                               n = n << 1;     // move next bit to testable position
+                               if (n < 0) {    // top bit is set
+                                       seenbit = 1;    // OK, significant bit seen
+                                       decMultiplyOp(dac, dac, lhs, &aset, &status);   // dac=dac*x
+                               }
+                               if (i == 31)
+                                       break;  // that was the last bit
+                               if (!seenbit)
+                                       continue;       // no need to square 1
+                               decMultiplyOp(dac, dac, dac, &aset, &status);   // dac=dac*dac [square]
+                       }       /*i */// 32 bits
+
+                       // complete internal overflow or underflow processing
+                       if (status & (DEC_Overflow | DEC_Underflow)) {
+#if DECSUBSET
+                               // If subset, and power was negative, reverse the kind of -erflow
+                               // [1/x not yet done]
+                               if (!set->extended && decNumberIsNegative(rhs)) {
+                                       if (status & DEC_Overflow)
+                                               status ^=
+                                                   DEC_Overflow | DEC_Underflow
+                                                   | DEC_Subnormal;
+                                       else {  // trickier -- Underflow may or may not be set
+                                               status &= ~(DEC_Underflow | DEC_Subnormal);     // [one or both]
+                                               status |= DEC_Overflow;
+                                       }
+                               }
+#endif
+                               dac->bits = (dac->bits & ~DECNEG) | bits;       // force correct sign
+                               // round subnormals [to set.digits rather than aset.digits]
+                               // or set overflow result similarly as required
+                               decFinalize(dac, set, &residue, &status);
+                               decNumberCopy(res, dac);        // copy to result (is now OK length)
+                               break;
+                       }
+#if DECSUBSET
+                       if (!set->extended &&   // subset math
+                           decNumberIsNegative(rhs)) { // was a **-n [hence digits>0]
+                               // so divide result into 1 [dac=1/dac]
+                               decDivideOp(dac, &dnOne, dac, &aset, DIVIDE,
+                                           &status);
+                       }
+#endif
+               }               // rhs integer path
+
+               // reduce result to the requested length and copy to result
+               decCopyFit(res, dac, set, &residue, &status);
+               decFinish(res, set, &residue, &status); // final cleanup
+#if DECSUBSET
+               if (!set->extended)
+                       decTrim(res, set, 0, 1, &dropped);      // trailing zeros
+#endif
+       } while (0);            // end protected
+
+       if (allocdac != NULL)
+               free(allocdac); // drop any storage used
+       if (allocinv != NULL)
+               free(allocinv); // ..
+#if DECSUBSET
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+#endif
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberPower
+
+/* ------------------------------------------------------------------ */
+/* decNumberQuantize -- force exponent to requested value             */
+/*                                                                    */
+/*   This computes C = op(A, B), where op adjusts the coefficient     */
+/*   of C (by rounding or shifting) such that the exponent (-scale)   */
+/*   of C has exponent of B.  The numerical value of C will equal A,  */
+/*   except for the effects of any rounding that occurred.            */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B                           */
+/*   lhs is A, the number to adjust                                   */
+/*   rhs is B, the number with exponent to match                      */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Unless there is an error or the result is infinite, the exponent   */
+/* after the operation is guaranteed to be equal to that of B.        */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberQuantize(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decQuantizeOp(res, lhs, rhs, set, 1, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberQuantize
+
+/* ------------------------------------------------------------------ */
+/* decNumberReduce -- remove trailing zeros                           */
+/*                                                                    */
+/*   This computes C = 0 + A, and normalizes the result               */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+// Previously known as Normalize
+decNumber *decNumberNormalize(decNumber * res, const decNumber * rhs,
+                             decContext * set)
+{
+       return decNumberReduce(res, rhs, set);
+}                              // decNumberNormalize
+
+decNumber *decNumberReduce(decNumber * res, const decNumber * rhs,
+                          decContext * set)
+{
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+       uInt status = 0;        // as usual
+       Int residue = 0;        // as usual
+       Int dropped;            // work
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operand and set lostDigits status, as needed
+                       if (rhs->digits > set->digits) {
+                               allocrhs = decRoundOperand(rhs, set, &status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // Infinities copy through; NaNs need usual treatment
+               if (decNumberIsNaN(rhs)) {
+                       decNaNs(res, rhs, NULL, set, &status);
+                       break;
+               }
+               // reduce result to the requested length and copy to result
+               decCopyFit(res, rhs, set, &residue, &status);   // copy & round
+               decFinish(res, set, &residue, &status); // cleanup/set flags
+               decTrim(res, set, 1, 0, &dropped);      // normalize in place
+               // [may clamp]
+       } while (0);            // end protected
+
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+#endif
+       if (status != 0)
+               decStatus(res, status, set);    // then report status
+       return res;
+}                              // decNumberReduce
+
+/* ------------------------------------------------------------------ */
+/* decNumberRescale -- force exponent to requested value              */
+/*                                                                    */
+/*   This computes C = op(A, B), where op adjusts the coefficient     */
+/*   of C (by rounding or shifting) such that the exponent (-scale)   */
+/*   of C has the value B.  The numerical value of C will equal A,    */
+/*   except for the effects of any rounding that occurred.            */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B                           */
+/*   lhs is A, the number to adjust                                   */
+/*   rhs is B, the requested exponent                                 */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Unless there is an error or the result is infinite, the exponent   */
+/* after the operation is guaranteed to be equal to B.                */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberRescale(decNumber * res, const decNumber * lhs,
+                           const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decQuantizeOp(res, lhs, rhs, set, 0, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberRescale
+
+/* ------------------------------------------------------------------ */
+/* decNumberRemainder -- divide and return remainder                  */
+/*                                                                    */
+/*   This computes C = A % B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberRemainder(decNumber * res, const decNumber * lhs,
+                             const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberRemainder
+
+/* ------------------------------------------------------------------ */
+/* decNumberRemainderNear -- divide and return remainder from nearest */
+/*                                                                    */
+/*   This computes C = A % B, where % is the IEEE remainder operator  */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberRemainderNear(decNumber * res, const decNumber * lhs,
+                                 const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberRemainderNear
+
+/* ------------------------------------------------------------------ */
+/* decNumberRotate -- rotate the coefficient of a Number left/right   */
+/*                                                                    */
+/*   This computes C = A rot B  (in base ten and rotating set->digits */
+/*   digits).                                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=XrotX)       */
+/*   lhs is A                                                         */
+/*   rhs is B, the number of digits to rotate (-ve to right)          */
+/*   set is the context                                               */
+/*                                                                    */
+/* The digits of the coefficient of A are rotated to the left (if B   */
+/* is positive) or to the right (if B is negative) without adjusting  */
+/* the exponent or the sign of A.  If lhs->digits is less than        */
+/* set->digits the coefficient is padded with zeros on the left       */
+/* before the rotate.  Any leading zeros in the result are removed    */
+/* as usual.                                                          */
+/*                                                                    */
+/* B must be an integer (q=0) and in the range -set->digits through   */
+/* +set->digits.                                                      */
+/* C must have space for set->digits digits.                          */
+/* NaNs are propagated as usual.  Infinities are unaffected (but      */
+/* B must be valid).  No status is set unless B is invalid or an      */
+/* operand is an sNaN.                                                */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberRotate(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       Int rotate;             // rhs as an Int
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       // NaNs propagate as normal
+       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
+               decNaNs(res, lhs, rhs, set, &status);
+       // rhs must be an integer
+       else if (decNumberIsInfinite(rhs) || rhs->exponent != 0)
+               status = DEC_Invalid_operation;
+       else {                  // both numeric, rhs is an integer
+               rotate = decGetInt(rhs);        // [cannot fail]
+               if (rotate == BADINT    // something bad ..
+                   || rotate == BIGODD || rotate == BIGEVEN    // .. very big ..
+                   || abs(rotate) > set->digits)       // .. or out of range
+                       status = DEC_Invalid_operation;
+               else {          // rhs is OK
+                       decNumberCopy(res, lhs);
+                       // convert -ve rotate to equivalent positive rotation
+                       if (rotate < 0)
+                               rotate = set->digits + rotate;
+                       if (rotate != 0 && rotate != set->digits        // zero or full rotation
+                           && !decNumberIsInfinite(res)) {     // lhs was infinite
+                               // left-rotate to do; 0 < rotate < set->digits
+                               uInt units, shift;      // work
+                               uInt msudigits; // digits in result msu
+                               Unit *msu = res->lsu + D2U(res->digits) - 1;    // current msu
+                               Unit *msumax = res->lsu + D2U(set->digits) - 1; // rotation msu
+                               for (msu++; msu <= msumax; msu++)
+                                       *msu = 0;       // ensure high units=0
+                               res->digits = set->digits;      // now full-length
+                               msudigits = MSUDIGITS(res->digits);     // actual digits in msu
+
+                               // rotation here is done in-place, in three steps
+                               // 1. shift all to least up to one unit to unit-align final
+                               //    lsd [any digits shifted out are rotated to the left,
+                               //    abutted to the original msd (which may require split)]
+                               //
+                               //    [if there are no whole units left to rotate, the
+                               //    rotation is now complete]
+                               //
+                               // 2. shift to least, from below the split point only, so that
+                               //    the final msd is in the right place in its Unit [any
+                               //    digits shifted out will fit exactly in the current msu,
+                               //    left aligned, no split required]
+                               //
+                               // 3. rotate all the units by reversing left part, right
+                               //    part, and then whole
+                               //
+                               // example: rotate right 8 digits (2 units + 2), DECDPUN=3.
+                               //
+                               //   start: 00a bcd efg hij klm npq
+                               //
+                               //      1a  000 0ab cde fgh|ijk lmn [pq saved]
+                               //      1b  00p qab cde fgh|ijk lmn
+                               //
+                               //      2a  00p qab cde fgh|00i jkl [mn saved]
+                               //      2b  mnp qab cde fgh|00i jkl
+                               //
+                               //      3a  fgh cde qab mnp|00i jkl
+                               //      3b  fgh cde qab mnp|jkl 00i
+                               //      3c  00i jkl mnp qab cde fgh
+
+                               // Step 1: amount to shift is the partial right-rotate count
+                               rotate = set->digits - rotate;  // make it right-rotate
+                               units = rotate / DECDPUN;       // whole units to rotate
+                               shift = rotate % DECDPUN;       // left-over digits count
+                               if (shift > 0) {        // not an exact number of units
+                                       uInt save = res->lsu[0] % powers[shift];        // save low digit(s)
+                                       decShiftToLeast(res->lsu,
+                                                       D2U(res->digits),
+                                                       shift);
+                                       if (shift > msudigits) {        // msumax-1 needs >0 digits
+                                               uInt rem = save % powers[shift - msudigits];    // split save
+                                               *msumax = (Unit) (save / powers[shift - msudigits]);    // and insert
+                                               *(msumax - 1) = *(msumax - 1)
+                                                   + (Unit) (rem * powers[DECDPUN - (shift - msudigits)]);     // ..
+                                       } else {        // all fits in msumax
+                                               *msumax = *msumax + (Unit) (save * powers[msudigits - shift]);  // [maybe *1]
+                                       }
+                               }       // digits shift needed
+
+                               // If whole units to rotate...
+                               if (units > 0) {        // some to do
+                                       // Step 2: the units to touch are the whole ones in rotate,
+                                       //   if any, and the shift is DECDPUN-msudigits (which may be
+                                       //   0, again)
+                                       shift = DECDPUN - msudigits;
+                                       if (shift > 0) {        // not an exact number of units
+                                               uInt save = res->lsu[0] % powers[shift];        // save low digit(s)
+                                               decShiftToLeast(res->lsu, units,
+                                                               shift);
+                                               *msumax =
+                                                   *msumax +
+                                                   (Unit) (save *
+                                                           powers[msudigits]);
+                                       }       // partial shift needed
+
+                                       // Step 3: rotate the units array using triple reverse
+                                       // (reversing is easy and fast)
+                                       decReverse(res->lsu + units, msumax);   // left part
+                                       decReverse(res->lsu, res->lsu + units - 1);     // right part
+                                       decReverse(res->lsu, msumax);   // whole
+                               }       // whole units to rotate
+                               // the rotation may have left an undetermined number of zeros
+                               // on the left, so true length needs to be calculated
+                               res->digits =
+                                   decGetDigits(res->lsu,
+                                                msumax - res->lsu + 1);
+                       }       // rotate needed
+               }               // rhs OK
+       }                       // numerics
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberRotate
+
+/* ------------------------------------------------------------------ */
+/* decNumberSameQuantum -- test for equal exponents                   */
+/*                                                                    */
+/*   res is the result number, which will contain either 0 or 1       */
+/*   lhs is a number to test                                          */
+/*   rhs is the second (usually a pattern)                            */
+/*                                                                    */
+/* No errors are possible and no context is needed.                   */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberSameQuantum(decNumber * res, const decNumber * lhs,
+                               const decNumber * rhs)
+{
+       Unit ret = 0;           // return value
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, DECUNCONT))
+               return res;
+#endif
+
+       if (SPECIALARGS) {
+               if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs))
+                       ret = 1;
+               else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs))
+                       ret = 1;
+               // [anything else with a special gives 0]
+       } else if (lhs->exponent == rhs->exponent)
+               ret = 1;
+
+       decNumberZero(res);     // OK to overwrite an operand now
+       *res->lsu = ret;
+       return res;
+}                              // decNumberSameQuantum
+
+/* ------------------------------------------------------------------ */
+/* decNumberScaleB -- multiply by a power of 10                       */
+/*                                                                    */
+/* This computes C = A x 10**B where B is an integer (q=0) with       */
+/* maximum magnitude 2*(emax+digits)                                  */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B                           */
+/*   lhs is A, the number to adjust                                   */
+/*   rhs is B, the requested power of ten to use                      */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* The result may underflow or overflow.                              */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberScaleB(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       Int reqexp;             // requested exponent change [B]
+       uInt status = 0;        // accumulator
+       Int residue;            // work
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       // Handle special values except lhs infinite
+       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
+               decNaNs(res, lhs, rhs, set, &status);
+       // rhs must be an integer
+       else if (decNumberIsInfinite(rhs) || rhs->exponent != 0)
+               status = DEC_Invalid_operation;
+       else {
+               // lhs is a number; rhs is a finite with q==0
+               reqexp = decGetInt(rhs);        // [cannot fail]
+               // maximum range is larger than getInt can handle, so this is
+               // more restrictive than the specification
+               if (reqexp == BADINT    // something bad ..
+                   || reqexp == BIGODD || reqexp == BIGEVEN    // it was huge
+                   || (abs(reqexp) + 1) / 2 > (set->digits + set->emax))       // .. or out of range
+                       status = DEC_Invalid_operation;
+               else {          // rhs is OK
+                       decNumberCopy(res, lhs);        // all done if infinite lhs
+                       if (!decNumberIsInfinite(res)) {        // prepare to scale
+                               Int exp = res->exponent;        // save for overflow test
+                               res->exponent += reqexp;        // adjust the exponent
+                               if (((exp ^ reqexp) >= 0)       // same sign ...
+                                   && ((exp ^ res->exponent) < 0)) {   // .. but result had different
+                                       // the calculation overflowed, so force right treatment
+                                       if (exp < 0)
+                                               res->exponent =
+                                                   DEC_MIN_EMIN -
+                                                   DEC_MAX_DIGITS;
+                                       else
+                                               res->exponent =
+                                                   DEC_MAX_EMAX + 1;
+                               }
+                               residue = 0;
+                               decFinalize(res, set, &residue, &status);       // final check
+                       }       // finite LHS
+               }               // rhs OK
+       }                       // rhs finite
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberScaleB
+
+/* ------------------------------------------------------------------ */
+/* decNumberShift -- shift the coefficient of a Number left or right  */
+/*                                                                    */
+/*   This computes C = A << B or C = A >> -B  (in base ten).          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X<<X)        */
+/*   lhs is A                                                         */
+/*   rhs is B, the number of digits to shift (-ve to right)           */
+/*   set is the context                                               */
+/*                                                                    */
+/* The digits of the coefficient of A are shifted to the left (if B   */
+/* is positive) or to the right (if B is negative) without adjusting  */
+/* the exponent or the sign of A.                                     */
+/*                                                                    */
+/* B must be an integer (q=0) and in the range -set->digits through   */
+/* +set->digits.                                                      */
+/* C must have space for set->digits digits.                          */
+/* NaNs are propagated as usual.  Infinities are unaffected (but      */
+/* B must be valid).  No status is set unless B is invalid or an      */
+/* operand is an sNaN.                                                */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberShift(decNumber * res, const decNumber * lhs,
+                         const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       Int shift;              // rhs as an Int
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       // NaNs propagate as normal
+       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
+               decNaNs(res, lhs, rhs, set, &status);
+       // rhs must be an integer
+       else if (decNumberIsInfinite(rhs) || rhs->exponent != 0)
+               status = DEC_Invalid_operation;
+       else {                  // both numeric, rhs is an integer
+               shift = decGetInt(rhs); // [cannot fail]
+               if (shift == BADINT     // something bad ..
+                   || shift == BIGODD || shift == BIGEVEN      // .. very big ..
+                   || abs(shift) > set->digits)        // .. or out of range
+                       status = DEC_Invalid_operation;
+               else {          // rhs is OK
+                       decNumberCopy(res, lhs);
+                       if (shift != 0 && !decNumberIsInfinite(res)) {  // something to do
+                               if (shift > 0) {        // to left
+                                       if (shift == set->digits) {     // removing all
+                                               *res->lsu = 0;  // so place 0
+                                               res->digits = 1;        // ..
+                                       } else {        //
+                                               // first remove leading digits if necessary
+                                               if (res->digits + shift >
+                                                   set->digits) {
+                                                       decDecap(res,
+                                                                res->digits +
+                                                                shift -
+                                                                set->digits);
+                                                       // that updated res->digits; may have gone to 1 (for a
+                                                       // single digit or for zero
+                                               }
+                                               if (res->digits > 1 || *res->lsu)       // if non-zero..
+                                                       res->digits =
+                                                           decShiftToMost
+                                                           (res->lsu,
+                                                            res->digits,
+                                                            shift);
+                                       }       // partial left
+                               }       // left
+                               else {  // to right
+                                       if (-shift >= res->digits) {    // discarding all
+                                               *res->lsu = 0;  // so place 0
+                                               res->digits = 1;        // ..
+                                       } else {
+                                               decShiftToLeast(res->lsu,
+                                                               D2U
+                                                               (res->digits),
+                                                               -shift);
+                                               res->digits -= (-shift);
+                                       }
+                               }       // to right
+                       }       // non-0 non-Inf shift
+               }               // rhs OK
+       }                       // numerics
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberShift
+
+/* ------------------------------------------------------------------ */
+/* decNumberSquareRoot -- square root operator                        */
+/*                                                                    */
+/*   This computes C = squareroot(A)                                  */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* This uses the following varying-precision algorithm in:            */
+/*                                                                    */
+/*   Properly Rounded Variable Precision Square Root, T. E. Hull and  */
+/*   A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */
+/*   pp229-237, ACM, September 1985.                                  */
+/*                                                                    */
+/* The square-root is calculated using Newton's method, after which   */
+/* a check is made to ensure the result is correctly rounded.         */
+/*                                                                    */
+/* % [Reformatted original Numerical Turing source code follows.]     */
+/* function sqrt(x : real) : real                                     */
+/* % sqrt(x) returns the properly rounded approximation to the square */
+/* % root of x, in the precision of the calling environment, or it    */
+/* % fails if x < 0.                                                  */
+/* % t e hull and a abrham, august, 1984                              */
+/* if x <= 0 then                                                     */
+/*   if x < 0 then                                                    */
+/*     assert false                                                   */
+/*   else                                                             */
+/*     result 0                                                       */
+/*   end if                                                           */
+/* end if                                                             */
+/* var f := setexp(x, 0)  % fraction part of x   [0.1 <= x < 1]       */
+/* var e := getexp(x)     % exponent part of x                        */
+/* var approx : real                                                  */
+/* if e mod 2 = 0  then                                               */
+/*   approx := .259 + .819 * f   % approx to root of f                */
+/* else                                                               */
+/*   f := f/l0                   % adjustments                        */
+/*   e := e + 1                  %   for odd                          */
+/*   approx := .0819 + 2.59 * f  %   exponent                         */
+/* end if                                                             */
+/*                                                                    */
+/* var p:= 3                                                          */
+/* const maxp := currentprecision + 2                                 */
+/* loop                                                               */
+/*   p := min(2*p - 2, maxp)     % p = 4,6,10, . . . , maxp           */
+/*   precision p                                                      */
+/*   approx := .5 * (approx + f/approx)                               */
+/*   exit when p = maxp                                               */
+/* end loop                                                           */
+/*                                                                    */
+/* % approx is now within 1 ulp of the properly rounded square root   */
+/* % of f; to ensure proper rounding, compare squares of (approx -    */
+/* % l/2 ulp) and (approx + l/2 ulp) with f.                          */
+/* p := currentprecision                                              */
+/* begin                                                              */
+/*   precision p + 2                                                  */
+/*   const approxsubhalf := approx - setexp(.5, -p)                   */
+/*   if mulru(approxsubhalf, approxsubhalf) > f then                  */
+/*     approx := approx - setexp(.l, -p + 1)                          */
+/*   else                                                             */
+/*     const approxaddhalf := approx + setexp(.5, -p)                 */
+/*     if mulrd(approxaddhalf, approxaddhalf) < f then                */
+/*       approx := approx + setexp(.l, -p + 1)                        */
+/*     end if                                                         */
+/*   end if                                                           */
+/* end                                                                */
+/* result setexp(approx, e div 2)  % fix exponent                     */
+/* end sqrt                                                           */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberSquareRoot(decNumber * res, const decNumber * rhs,
+                              decContext * set)
+{
+       decContext workset, approxset;  // work contexts
+       decNumber dzero;        // used for constant zero
+       Int maxp;               // largest working precision
+       Int workp;              // working precision
+       Int residue = 0;        // rounding residue
+       uInt status = 0, ignore = 0;    // status accumulators
+       uInt rstatus;           // ..
+       Int exp;                // working exponent
+       Int ideal;              // ideal (preferred) exponent
+       Int needbytes;          // work
+       Int dropped;            // ..
+
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+       // buffer for f [needs +1 in case DECBUFFER 0]
+       decNumber buff[D2N(DECBUFFER + 1)];
+       // buffer for a [needs +2 to match likely maxp]
+       decNumber bufa[D2N(DECBUFFER + 2)];
+       // buffer for temporary, b [must be same size as a]
+       decNumber bufb[D2N(DECBUFFER + 2)];
+       decNumber *allocbuff = NULL;    // -> allocated buff, iff allocated
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *allocbufb = NULL;    // -> allocated bufb, iff allocated
+       decNumber *f = buff;    // reduced fraction
+       decNumber *a = bufa;    // approximation to result
+       decNumber *b = bufb;    // intermediate result
+       // buffer for temporary variable, up to 3 digits
+       decNumber buft[D2N(3)];
+       decNumber *t = buft;    // up-to-3-digit constant or work
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operand and set lostDigits status, as needed
+                       if (rhs->digits > set->digits) {
+                               allocrhs = decRoundOperand(rhs, set, &status);
+                               if (allocrhs == NULL)
+                                       break;
+                               // [Note: 'f' allocation below could reuse this buffer if
+                               // used, but as this is rare they are kept separate for clarity.]
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // handle infinities and NaNs
+               if (SPECIALARG) {
+                       if (decNumberIsInfinite(rhs)) { // an infinity
+                               if (decNumberIsNegative(rhs))
+                                       status |= DEC_Invalid_operation;
+                               else
+                                       decNumberCopy(res, rhs);        // +Infinity
+                       } else
+                               decNaNs(res, rhs, NULL, set, &status);  // a NaN
+                       break;
+               }
+               // calculate the ideal (preferred) exponent [floor(exp/2)]
+               // [It would be nicer to write: ideal=rhs->exponent>>1, but this
+               // generates a compiler warning.  Generated code is the same.]
+               ideal = (rhs->exponent & ~1) / 2;       // target
+
+               // handle zeros
+               if (ISZERO(rhs)) {
+                       decNumberCopy(res, rhs);        // could be 0 or -0
+                       res->exponent = ideal;  // use the ideal [safe]
+                       // use decFinish to clamp any out-of-range exponent, etc.
+                       decFinish(res, set, &residue, &status);
+                       break;
+               }
+               // any other -x is an oops
+               if (decNumberIsNegative(rhs)) {
+                       status |= DEC_Invalid_operation;
+                       break;
+               }
+               // space is needed for three working variables
+               //   f -- the same precision as the RHS, reduced to 0.01->0.99...
+               //   a -- Hull's approximation -- precision, when assigned, is
+               //        currentprecision+1 or the input argument precision,
+               //        whichever is larger (+2 for use as temporary)
+               //   b -- intermediate temporary result (same size as a)
+               // if any is too long for local storage, then allocate
+               workp = MAXI(set->digits + 1, rhs->digits);     // actual rounding precision
+               workp = MAXI(workp, 7); // at least 7 for low cases
+               maxp = workp + 2;       // largest working precision
+
+               needbytes =
+                   sizeof(decNumber) + (D2U(rhs->digits) - 1) * sizeof(Unit);
+               if (needbytes > (Int) sizeof(buff)) {
+                       allocbuff = (decNumber *) malloc(needbytes);
+                       if (allocbuff == NULL) {        // hopeless -- abandon
+                               status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       f = allocbuff;  // use the allocated space
+               }
+               // a and b both need to be able to hold a maxp-length number
+               needbytes = sizeof(decNumber) + (D2U(maxp) - 1) * sizeof(Unit);
+               if (needbytes > (Int) sizeof(bufa)) {   // [same applies to b]
+                       allocbufa = (decNumber *) malloc(needbytes);
+                       allocbufb = (decNumber *) malloc(needbytes);
+                       if (allocbufa == NULL || allocbufb == NULL) {   // hopeless
+                               status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       a = allocbufa;  // use the allocated spaces
+                       b = allocbufb;  // ..
+               }
+               // copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1
+               decNumberCopy(f, rhs);
+               exp = f->exponent + f->digits;  // adjusted to Hull rules
+               f->exponent = -(f->digits);     // to range
+
+               // set up working context
+               decContextDefault(&workset, DEC_INIT_DECIMAL64);
+               workset.emax = DEC_MAX_EMAX;
+               workset.emin = DEC_MIN_EMIN;
+
+               // [Until further notice, no error is possible and status bits
+               // (Rounded, etc.) should be ignored, not accumulated.]
+
+               // Calculate initial approximation, and allow for odd exponent
+               workset.digits = workp; // p for initial calculation
+               t->bits = 0;
+               t->digits = 3;
+               a->bits = 0;
+               a->digits = 3;
+               if ((exp & 1) == 0) {   // even exponent
+                       // Set t=0.259, a=0.819
+                       t->exponent = -3;
+                       a->exponent = -3;
+#if DECDPUN>=3
+                       t->lsu[0] = 259;
+                       a->lsu[0] = 819;
+#elif DECDPUN==2
+                       t->lsu[0] = 59;
+                       t->lsu[1] = 2;
+                       a->lsu[0] = 19;
+                       a->lsu[1] = 8;
+#else
+                       t->lsu[0] = 9;
+                       t->lsu[1] = 5;
+                       t->lsu[2] = 2;
+                       a->lsu[0] = 9;
+                       a->lsu[1] = 1;
+                       a->lsu[2] = 8;
+#endif
+               } else {        // odd exponent
+                       // Set t=0.0819, a=2.59
+                       f->exponent--;  // f=f/10
+                       exp++;  // e=e+1
+                       t->exponent = -4;
+                       a->exponent = -2;
+#if DECDPUN>=3
+                       t->lsu[0] = 819;
+                       a->lsu[0] = 259;
+#elif DECDPUN==2
+                       t->lsu[0] = 19;
+                       t->lsu[1] = 8;
+                       a->lsu[0] = 59;
+                       a->lsu[1] = 2;
+#else
+                       t->lsu[0] = 9;
+                       t->lsu[1] = 1;
+                       t->lsu[2] = 8;
+                       a->lsu[0] = 9;
+                       a->lsu[1] = 5;
+                       a->lsu[2] = 2;
+#endif
+               }
+
+               decMultiplyOp(a, a, f, &workset, &ignore);      // a=a*f
+               decAddOp(a, a, t, &workset, 0, &ignore);        // ..+t
+               // [a is now the initial approximation for sqrt(f), calculated with
+               // currentprecision, which is also a's precision.]
+
+               // the main calculation loop
+               decNumberZero(&dzero);  // make 0
+               decNumberZero(t);       // set t = 0.5
+               t->lsu[0] = 5;  // ..
+               t->exponent = -1;       // ..
+               workset.digits = 3;     // initial p
+               for (; workset.digits < maxp;) {
+                       // set p to min(2*p - 2, maxp)  [hence 3; or: 4, 6, 10, ... , maxp]
+                       workset.digits = MINI(workset.digits * 2 - 2, maxp);
+                       // a = 0.5 * (a + f/a)
+                       // [calculated at p then rounded to currentprecision]
+                       decDivideOp(b, f, a, &workset, DIVIDE, &ignore);        // b=f/a
+                       decAddOp(b, b, a, &workset, 0, &ignore);        // b=b+a
+                       decMultiplyOp(a, b, t, &workset, &ignore);      // a=b*0.5
+               }               // loop
+
+               // Here, 0.1 <= a < 1 [Hull], and a has maxp digits
+               // now reduce to length, etc.; this needs to be done with a
+               // having the correct exponent so as to handle subnormals
+               // correctly
+               approxset = *set;       // get emin, emax, etc.
+               approxset.round = DEC_ROUND_HALF_EVEN;
+               a->exponent += exp / 2; // set correct exponent
+               rstatus = 0;    // clear status
+               residue = 0;    // .. and accumulator
+               decCopyFit(a, a, &approxset, &residue, &rstatus);       // reduce (if needed)
+               decFinish(a, &approxset, &residue, &rstatus);   // clean and finalize
+
+               // Overflow was possible if the input exponent was out-of-range,
+               // in which case quit
+               if (rstatus & DEC_Overflow) {
+                       status = rstatus;       // use the status as-is
+                       decNumberCopy(res, a);  // copy to result
+                       break;
+               }
+               // Preserve status except Inexact/Rounded
+               status |= (rstatus & ~(DEC_Rounded | DEC_Inexact));
+
+               // Carry out the Hull correction
+               a->exponent -= exp / 2; // back to 0.1->1
+
+               // a is now at final precision and within 1 ulp of the properly
+               // rounded square root of f; to ensure proper rounding, compare
+               // squares of (a - l/2 ulp) and (a + l/2 ulp) with f.
+               // Here workset.digits=maxp and t=0.5, and a->digits determines
+               // the ulp
+               workset.digits--;       // maxp-1 is OK now
+               t->exponent = -a->digits - 1;   // make 0.5 ulp
+               decAddOp(b, a, t, &workset, DECNEG, &ignore);   // b = a - 0.5 ulp
+               workset.round = DEC_ROUND_UP;
+               decMultiplyOp(b, b, b, &workset, &ignore);      // b = mulru(b, b)
+               decCompareOp(b, f, b, &workset, COMPARE, &ignore);      // b ? f, reversed
+               if (decNumberIsNegative(b)) {   // f < b [i.e., b > f]
+                       // this is the more common adjustment, though both are rare
+                       t->exponent++;  // make 1.0 ulp
+                       t->lsu[0] = 1;  // ..
+                       decAddOp(a, a, t, &workset, DECNEG, &ignore);   // a = a - 1 ulp
+                       // assign to approx [round to length]
+                       approxset.emin -= exp / 2;      // adjust to match a
+                       approxset.emax -= exp / 2;
+                       decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+               } else {
+                       decAddOp(b, a, t, &workset, 0, &ignore);        // b = a + 0.5 ulp
+                       workset.round = DEC_ROUND_DOWN;
+                       decMultiplyOp(b, b, b, &workset, &ignore);      // b = mulrd(b, b)
+                       decCompareOp(b, b, f, &workset, COMPARE, &ignore);      // b ? f
+                       if (decNumberIsNegative(b)) {   // b < f
+                               t->exponent++;  // make 1.0 ulp
+                               t->lsu[0] = 1;  // ..
+                               decAddOp(a, a, t, &workset, 0, &ignore);        // a = a + 1 ulp
+                               // assign to approx [round to length]
+                               approxset.emin -= exp / 2;      // adjust to match a
+                               approxset.emax -= exp / 2;
+                               decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+                       }
+               }
+               // [no errors are possible in the above, and rounding/inexact during
+               // estimation are irrelevant, so status was not accumulated]
+
+               // Here, 0.1 <= a < 1  (still), so adjust back
+               a->exponent += exp / 2; // set correct exponent
+
+               // count droppable zeros [after any subnormal rounding] by
+               // trimming a copy
+               decNumberCopy(b, a);
+               decTrim(b, set, 1, 1, &dropped);        // [drops trailing zeros]
+
+               // Set Inexact and Rounded.  The answer can only be exact if
+               // it is short enough so that squaring it could fit in workp
+               // digits, so this is the only (relatively rare) condition that
+               // a careful check is needed
+               if (b->digits * 2 - 1 > workp) {        // cannot fit
+                       status |= DEC_Inexact | DEC_Rounded;
+               } else {        // could be exact/unrounded
+                       uInt mstatus = 0;       // local status
+                       decMultiplyOp(b, b, b, &workset, &mstatus);     // try the multiply
+                       if (mstatus & DEC_Overflow) {   // result just won't fit
+                               status |= DEC_Inexact | DEC_Rounded;
+                       } else {        // plausible
+                               decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus);   // b ? rhs
+                               if (!ISZERO(t))
+                                       status |= DEC_Inexact | DEC_Rounded;    // not equal
+                               else {  // is Exact
+                                       // here, dropped is the count of trailing zeros in 'a'
+                                       // use closest exponent to ideal...
+                                       Int todrop = ideal - a->exponent;       // most that can be dropped
+                                       if (todrop < 0)
+                                               status |= DEC_Rounded;  // ideally would add 0s
+                                       else {  // unrounded
+                                               // there are some to drop, but emax may not allow all
+                                               Int maxexp =
+                                                   set->emax - set->digits + 1;
+                                               Int maxdrop =
+                                                   maxexp - a->exponent;
+                                               if (todrop > maxdrop && set->clamp) {   // apply clamping
+                                                       todrop = maxdrop;
+                                                       status |= DEC_Clamped;
+                                               }
+                                               if (dropped < todrop) { // clamp to those available
+                                                       todrop = dropped;
+                                                       status |= DEC_Clamped;
+                                               }
+                                               if (todrop > 0) {       // have some to drop
+                                                       decShiftToLeast(a->lsu,
+                                                                       D2U
+                                                                       (a->digits),
+                                                                       todrop);
+                                                       a->exponent += todrop;  // maintain numerical value
+                                                       a->digits -= todrop;    // new length
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // double-check Underflow, as perhaps the result could not have
+               // been subnormal (initial argument too big), or it is now Exact
+               if (status & DEC_Underflow) {
+                       Int ae = rhs->exponent + rhs->digits - 1;       // adjusted exponent
+                       // check if truly subnormal
+#if DECEXTFLAG                 // DEC_Subnormal too
+                       if (ae >= set->emin * 2)
+                               status &= ~(DEC_Subnormal | DEC_Underflow);
+#else
+                       if (ae >= set->emin * 2)
+                               status &= ~DEC_Underflow;
+#endif
+                       // check if truly inexact
+                       if (!(status & DEC_Inexact))
+                               status &= ~DEC_Underflow;
+               }
+
+               decNumberCopy(res, a);  // a is now the result
+       } while (0);            // end protected
+
+       if (allocbuff != NULL)
+               free(allocbuff);        // drop any storage used
+       if (allocbufa != NULL)
+               free(allocbufa);        // ..
+       if (allocbufb != NULL)
+               free(allocbufb);        // ..
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+#endif
+       if (status != 0)
+               decStatus(res, status, set);    // then report status
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberSquareRoot
+
+/* ------------------------------------------------------------------ */
+/* decNumberSubtract -- subtract two Numbers                          */
+/*                                                                    */
+/*   This computes C = A - B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X-X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberSubtract(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+
+       decAddOp(res, lhs, rhs, set, DECNEG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberSubtract
+
+/* ------------------------------------------------------------------ */
+/* decNumberToIntegralExact -- round-to-integral-value with InExact   */
+/* decNumberToIntegralValue -- round-to-integral-value                */
+/*                                                                    */
+/*   res is the result                                                */
+/*   rhs is input number                                              */
+/*   set is the context                                               */
+/*                                                                    */
+/* res must have space for any value of rhs.                          */
+/*                                                                    */
+/* This implements the IEEE special operators and therefore treats    */
+/* special values as valid.  For finite numbers it returns            */
+/* rescale(rhs, 0) if rhs->exponent is <0.                            */
+/* Otherwise the result is rhs (so no error is possible, except for   */
+/* sNaN).                                                             */
+/*                                                                    */
+/* The context is used for rounding mode and status after sNaN, but   */
+/* the digits setting is ignored.  The Exact version will signal      */
+/* Inexact if the result differs numerically from rhs; the other      */
+/* never signals Inexact.                                             */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberToIntegralExact(decNumber * res, const decNumber * rhs,
+                                   decContext * set)
+{
+       decNumber dn;
+       decContext workset;     // working context
+       uInt status = 0;        // accumulator
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // handle infinities and NaNs
+       if (SPECIALARG) {
+               if (decNumberIsInfinite(rhs))
+                       decNumberCopy(res, rhs);        // an Infinity
+               else
+                       decNaNs(res, rhs, NULL, set, &status);  // a NaN
+       } else {                // finite
+               // have a finite number; no error possible (res must be big enough)
+               if (rhs->exponent >= 0)
+                       return decNumberCopy(res, rhs);
+               // that was easy, but if negative exponent there is work to do...
+               workset = *set; // clone rounding, etc.
+               workset.digits = rhs->digits;   // no length rounding
+               workset.traps = 0;      // no traps
+               decNumberZero(&dn);     // make a number with exponent 0
+               decNumberQuantize(res, rhs, &dn, &workset);
+               status |= workset.status;
+       }
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberToIntegralExact
+
+decNumber *decNumberToIntegralValue(decNumber * res, const decNumber * rhs,
+                                   decContext * set)
+{
+       decContext workset = *set;      // working context
+       workset.traps = 0;      // no traps
+       decNumberToIntegralExact(res, rhs, &workset);
+       // this never affects set, except for sNaNs; NaN will have been set
+       // or propagated already, so no need to call decStatus
+       set->status |= workset.status & DEC_Invalid_operation;
+       return res;
+}                              // decNumberToIntegralValue
+
+/* ------------------------------------------------------------------ */
+/* decNumberXor -- XOR two Numbers, digitwise                         */
+/*                                                                    */
+/*   This computes C = A ^ B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X^X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context (used for result length and error report)     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Logical function restrictions apply (see above); a NaN is          */
+/* returned with Invalid_operation if a restriction is violated.      */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberXor(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       const Unit *ua, *ub;    // -> operands
+       const Unit *msua, *msub;        // -> operand msus
+       Unit *uc, *msuc;        // -> result and its msu
+       Int msudigs;            // digits in res msu
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       if (lhs->exponent != 0 || decNumberIsSpecial(lhs)
+           || decNumberIsNegative(lhs)
+           || rhs->exponent != 0 || decNumberIsSpecial(rhs)
+           || decNumberIsNegative(rhs)) {
+               decStatus(res, DEC_Invalid_operation, set);
+               return res;
+       }
+       // operands are valid
+       ua = lhs->lsu;          // bottom-up
+       ub = rhs->lsu;          // ..
+       uc = res->lsu;          // ..
+       msua = ua + D2U(lhs->digits) - 1;       // -> msu of lhs
+       msub = ub + D2U(rhs->digits) - 1;       // -> msu of rhs
+       msuc = uc + D2U(set->digits) - 1;       // -> msu of result
+       msudigs = MSUDIGITS(set->digits);       // [faster than remainder]
+       for (; uc <= msuc; ua++, ub++, uc++) {  // Unit loop
+               Unit a, b;      // extract units
+               if (ua > msua)
+                       a = 0;
+               else
+                       a = *ua;
+               if (ub > msub)
+                       b = 0;
+               else
+                       b = *ub;
+               *uc = 0;        // can now write back
+               if (a | b) {    // maybe 1 bits to examine
+                       Int i, j;
+                       // This loop could be unrolled and/or use BIN2BCD tables
+                       for (i = 0; i < DECDPUN; i++) {
+                               if ((a ^ b) & 1)
+                                       *uc = *uc + (Unit) powers[i];   // effect XOR
+                               j = a % 10;
+                               a = a / 10;
+                               j |= b % 10;
+                               b = b / 10;
+                               if (j > 1) {
+                                       decStatus(res, DEC_Invalid_operation,
+                                                 set);
+                                       return res;
+                               }
+                               if (uc == msuc && i == msudigs - 1)
+                                       break;  // just did final digit
+                       }       // each digit
+               }               // non-zero
+       }                       // each unit
+       // [here uc-1 is the msu of the result]
+       res->digits = decGetDigits(res->lsu, uc - res->lsu);
+       res->exponent = 0;      // integer
+       res->bits = 0;          // sign=0
+       return res;             // [no status to set]
+}                              // decNumberXor
+
+/* ================================================================== */
+/* Utility routines                                                   */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* decNumberClass -- return the decClass of a decNumber               */
+/*   dn -- the decNumber to test                                      */
+/*   set -- the context to use for Emin                               */
+/*   returns the decClass enum                                        */
+/* ------------------------------------------------------------------ */
+enum decClass decNumberClass(const decNumber * dn, decContext * set)
+{
+       if (decNumberIsSpecial(dn)) {
+               if (decNumberIsQNaN(dn))
+                       return DEC_CLASS_QNAN;
+               if (decNumberIsSNaN(dn))
+                       return DEC_CLASS_SNAN;
+               // must be an infinity
+               if (decNumberIsNegative(dn))
+                       return DEC_CLASS_NEG_INF;
+               return DEC_CLASS_POS_INF;
+       }
+       // is finite
+       if (decNumberIsNormal(dn, set)) {       // most common
+               if (decNumberIsNegative(dn))
+                       return DEC_CLASS_NEG_NORMAL;
+               return DEC_CLASS_POS_NORMAL;
+       }
+       // is subnormal or zero
+       if (decNumberIsZero(dn)) {      // most common
+               if (decNumberIsNegative(dn))
+                       return DEC_CLASS_NEG_ZERO;
+               return DEC_CLASS_POS_ZERO;
+       }
+       if (decNumberIsNegative(dn))
+               return DEC_CLASS_NEG_SUBNORMAL;
+       return DEC_CLASS_POS_SUBNORMAL;
+}                              // decNumberClass
+
+/* ------------------------------------------------------------------ */
+/* decNumberClassToString -- convert decClass to a string             */
+/*                                                                    */
+/*  eclass is a valid decClass                                        */
+/*  returns a constant string describing the class (max 13+1 chars)   */
+/* ------------------------------------------------------------------ */
+const char *decNumberClassToString(enum decClass eclass)
+{
+       if (eclass == DEC_CLASS_POS_NORMAL)
+               return DEC_ClassString_PN;
+       if (eclass == DEC_CLASS_NEG_NORMAL)
+               return DEC_ClassString_NN;
+       if (eclass == DEC_CLASS_POS_ZERO)
+               return DEC_ClassString_PZ;
+       if (eclass == DEC_CLASS_NEG_ZERO)
+               return DEC_ClassString_NZ;
+       if (eclass == DEC_CLASS_POS_SUBNORMAL)
+               return DEC_ClassString_PS;
+       if (eclass == DEC_CLASS_NEG_SUBNORMAL)
+               return DEC_ClassString_NS;
+       if (eclass == DEC_CLASS_POS_INF)
+               return DEC_ClassString_PI;
+       if (eclass == DEC_CLASS_NEG_INF)
+               return DEC_ClassString_NI;
+       if (eclass == DEC_CLASS_QNAN)
+               return DEC_ClassString_QN;
+       if (eclass == DEC_CLASS_SNAN)
+               return DEC_ClassString_SN;
+       return DEC_ClassString_UN;      // Unknown
+}                              // decNumberClassToString
+
+/* ------------------------------------------------------------------ */
+/* decNumberCopy -- copy a number                                     */
+/*                                                                    */
+/*   dest is the target decNumber                                     */
+/*   src  is the source decNumber                                     */
+/*   returns dest                                                     */
+/*                                                                    */
+/* (dest==src is allowed and is a no-op)                              */
+/* All fields are updated as required.  This is a utility operation,  */
+/* so special values are unchanged and no error is possible.          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCopy(decNumber * dest, const decNumber * src)
+{
+
+#if DECCHECK
+       if (src == NULL)
+               return decNumberZero(dest);
+#endif
+
+       if (dest == src)
+               return dest;    // no copy required
+
+       // Use explicit assignments here as structure assignment could copy
+       // more than just the lsu (for small DECDPUN).  This would not affect
+       // the value of the results, but could disturb test harness spill
+       // checking.
+       dest->bits = src->bits;
+       dest->exponent = src->exponent;
+       dest->digits = src->digits;
+       dest->lsu[0] = src->lsu[0];
+       if (src->digits > DECDPUN) {    // more Units to come
+               const Unit *smsup, *s;  // work
+               Unit *d;        // ..
+               // memcpy for the remaining Units would be safe as they cannot
+               // overlap.  However, this explicit loop is faster in short cases.
+               d = dest->lsu + 1;      // -> first destination
+               smsup = src->lsu + D2U(src->digits);    // -> source msu+1
+               for (s = src->lsu + 1; s < smsup; s++, d++)
+                       *d = *s;
+       }
+       return dest;
+}                              // decNumberCopy
+
+/* ------------------------------------------------------------------ */
+/* decNumberCopyAbs -- quiet absolute value operator                  */
+/*                                                                    */
+/*   This sets C = abs(A)                                             */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* No exception or error can occur; this is a quiet bitwise operation.*/
+/* See also decNumberAbs for a checking version of this.              */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCopyAbs(decNumber * res, const decNumber * rhs)
+{
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT))
+               return res;
+#endif
+       decNumberCopy(res, rhs);
+       res->bits &= ~DECNEG;   // turn off sign
+       return res;
+}                              // decNumberCopyAbs
+
+/* ------------------------------------------------------------------ */
+/* decNumberCopyNegate -- quiet negate value operator                 */
+/*                                                                    */
+/*   This sets C = negate(A)                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* No exception or error can occur; this is a quiet bitwise operation.*/
+/* See also decNumberMinus for a checking version of this.            */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCopyNegate(decNumber * res, const decNumber * rhs)
+{
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT))
+               return res;
+#endif
+       decNumberCopy(res, rhs);
+       res->bits ^= DECNEG;    // invert the sign
+       return res;
+}                              // decNumberCopyNegate
+
+/* ------------------------------------------------------------------ */
+/* decNumberCopySign -- quiet copy and set sign operator              */
+/*                                                                    */
+/*   This sets C = A with the sign of B                               */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* No exception or error can occur; this is a quiet bitwise operation.*/
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCopySign(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs)
+{
+       uByte sign;             // rhs sign
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT))
+               return res;
+#endif
+       sign = rhs->bits & DECNEG;      // save sign bit
+       decNumberCopy(res, lhs);
+       res->bits &= ~DECNEG;   // clear the sign
+       res->bits |= sign;      // set from rhs
+       return res;
+}                              // decNumberCopySign
+
+/* ------------------------------------------------------------------ */
+/* decNumberGetBCD -- get the coefficient in BCD8                     */
+/*   dn is the source decNumber                                       */
+/*   bcd is the uInt array that will receive dn->digits BCD bytes,    */
+/*     most-significant at offset 0                                   */
+/*   returns bcd                                                      */
+/*                                                                    */
+/* bcd must have at least dn->digits bytes.  No error is possible; if */
+/* dn is a NaN or Infinite, digits must be 1 and the coefficient 0.   */
+/* ------------------------------------------------------------------ */
+uByte *decNumberGetBCD(const decNumber * dn, uByte * bcd)
+{
+       uByte *ub = bcd + dn->digits - 1;       // -> lsd
+       const Unit *up = dn->lsu;       // Unit pointer, -> lsu
+
+#if DECDPUN==1                 // trivial simple copy
+       for (; ub >= bcd; ub--, up++)
+               *ub = *up;
+#else                          // chopping needed
+       uInt u = *up;           // work
+       uInt cut = DECDPUN;     // downcounter through unit
+       for (; ub >= bcd; ub--) {
+               *ub = (uByte) (u % 10); // [*6554 trick inhibits, here]
+               u = u / 10;
+               cut--;
+               if (cut > 0)
+                       continue;       // more in this unit
+               up++;
+               u = *up;
+               cut = DECDPUN;
+       }
+#endif
+       return bcd;
+}                              // decNumberGetBCD
+
+/* ------------------------------------------------------------------ */
+/* decNumberSetBCD -- set (replace) the coefficient from BCD8         */
+/*   dn is the target decNumber                                       */
+/*   bcd is the uInt array that will source n BCD bytes, most-        */
+/*     significant at offset 0                                        */
+/*   n is the number of digits in the source BCD array (bcd)          */
+/*   returns dn                                                       */
+/*                                                                    */
+/* dn must have space for at least n digits.  No error is possible;   */
+/* if dn is a NaN, or Infinite, or is to become a zero, n must be 1   */
+/* and bcd[0] zero.                                                   */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberSetBCD(decNumber * dn, const uByte * bcd, uInt n)
+{
+       Unit *up = dn->lsu + D2U(dn->digits) - 1;       // -> msu [target pointer]
+       const uByte *ub = bcd;  // -> source msd
+
+#if DECDPUN==1                 // trivial simple copy
+       for (; ub < bcd + n; ub++, up--)
+               *up = *ub;
+#else                          // some assembly needed
+       // calculate how many digits in msu, and hence first cut
+       Int cut = MSUDIGITS(n); // [faster than remainder]
+       for (; up >= dn->lsu; up--) {   // each Unit from msu
+               *up = 0;        // will take <=DECDPUN digits
+               for (; cut > 0; ub++, cut--)
+                       *up = X10(*up) + *ub;
+               cut = DECDPUN;  // next Unit has all digits
+       }
+#endif
+       dn->digits = n;         // set digit count
+       return dn;
+}                              // decNumberSetBCD
+
+/* ------------------------------------------------------------------ */
+/* decNumberIsNormal -- test normality of a decNumber                 */
+/*   dn is the decNumber to test                                      */
+/*   set is the context to use for Emin                               */
+/*   returns 1 if |dn| is finite and >=Nmin, 0 otherwise              */
+/* ------------------------------------------------------------------ */
+Int decNumberIsNormal(const decNumber * dn, decContext * set)
+{
+       Int ae;                 // adjusted exponent
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set))
+               return 0;
+#endif
+
+       if (decNumberIsSpecial(dn))
+               return 0;       // not finite
+       if (decNumberIsZero(dn))
+               return 0;       // not non-zero
+
+       ae = dn->exponent + dn->digits - 1;     // adjusted exponent
+       if (ae < set->emin)
+               return 0;       // is subnormal
+       return 1;
+}                              // decNumberIsNormal
+
+/* ------------------------------------------------------------------ */
+/* decNumberIsSubnormal -- test subnormality of a decNumber           */
+/*   dn is the decNumber to test                                      */
+/*   set is the context to use for Emin                               */
+/*   returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise    */
+/* ------------------------------------------------------------------ */
+Int decNumberIsSubnormal(const decNumber * dn, decContext * set)
+{
+       Int ae;                 // adjusted exponent
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set))
+               return 0;
+#endif
+
+       if (decNumberIsSpecial(dn))
+               return 0;       // not finite
+       if (decNumberIsZero(dn))
+               return 0;       // not non-zero
+
+       ae = dn->exponent + dn->digits - 1;     // adjusted exponent
+       if (ae < set->emin)
+               return 1;       // is subnormal
+       return 0;
+}                              // decNumberIsSubnormal
+
+/* ------------------------------------------------------------------ */
+/* decNumberTrim -- remove insignificant zeros                        */
+/*                                                                    */
+/*   dn is the number to trim                                         */
+/*   returns dn                                                       */
+/*                                                                    */
+/* All fields are updated as required.  This is a utility operation,  */
+/* so special values are unchanged and no error is possible.  The     */
+/* zeros are removed unconditionally.                                 */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberTrim(decNumber * dn)
+{
+       Int dropped;            // work
+       decContext set;         // ..
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT))
+               return dn;
+#endif
+       decContextDefault(&set, DEC_INIT_BASE); // clamp=0
+       return decTrim(dn, &set, 0, 1, &dropped);
+}                              // decNumberTrim
+
+/* ------------------------------------------------------------------ */
+/* decNumberVersion -- return the name and version of this module     */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+const char *decNumberVersion(void)
+{
+       return DECVERSION;
+}                              // decNumberVersion
+
+/* ------------------------------------------------------------------ */
+/* decNumberZero -- set a number to 0                                 */
+/*                                                                    */
+/*   dn is the number to set, with space for one digit                */
+/*   returns dn                                                       */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+// Memset is not used as it is much slower in some environments.
+decNumber *decNumberZero(decNumber * dn)
+{
+
+#if DECCHECK
+       if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT))
+               return dn;
+#endif
+
+       dn->bits = 0;
+       dn->exponent = 0;
+       dn->digits = 1;
+       dn->lsu[0] = 0;
+       return dn;
+}                              // decNumberZero
+
+/* ================================================================== */
+/* Local routines                                                     */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* decToString -- lay out a number into a string                      */
+/*                                                                    */
+/*   dn     is the number to lay out                                  */
+/*   string is where to lay out the number                            */
+/*   eng    is 1 if Engineering, 0 if Scientific                      */
+/*                                                                    */
+/* string must be at least dn->digits+14 characters long              */
+/* No error is possible.                                              */
+/*                                                                    */
+/* Note that this routine can generate a -0 or 0.000.  These are      */
+/* never generated in subset to-number or arithmetic, but can occur   */
+/* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234).              */
+/* ------------------------------------------------------------------ */
+// If DECCHECK is enabled the string "?" is returned if a number is
+// invalid.
+static void decToString(const decNumber * dn, char *string, Flag eng)
+{
+       Int exp = dn->exponent; // local copy
+       Int e;                  // E-part value
+       Int pre;                // digits before the '.'
+       Int cut;                // for counting digits in a Unit
+       char *c = string;       // work [output pointer]
+       const Unit *up = dn->lsu + D2U(dn->digits) - 1; // -> msu [input pointer]
+       uInt u, pow;            // work
+
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
+               strcpy(string, "?");
+               return;
+       }
+#endif
+
+       if (decNumberIsNegative(dn)) {  // Negatives get a minus
+               *c = '-';
+               c++;
+       }
+       if (dn->bits & DECSPECIAL) {    // Is a special value
+               if (decNumberIsInfinite(dn)) {
+                       strcpy(c, "Inf");
+                       strcpy(c + 3, "inity");
+                       return;
+               }
+               // a NaN
+               if (dn->bits & DECSNAN) {       // signalling NaN
+                       *c = 's';
+                       c++;
+               }
+               strcpy(c, "NaN");
+               c += 3;         // step past
+               // if not a clean non-zero coefficient, that's all there is in a
+               // NaN string
+               if (exp != 0 || (*dn->lsu == 0 && dn->digits == 1))
+                       return;
+               // [drop through to add integer]
+       }
+       // calculate how many digits in msu, and hence first cut
+       cut = MSUDIGITS(dn->digits);    // [faster than remainder]
+       cut--;                  // power of ten for digit
+
+       if (exp == 0) {         // simple integer [common fastpath]
+               for (; up >= dn->lsu; up--) {   // each Unit from msu
+                       u = *up;        // contains DECDPUN digits to lay out
+                       for (; cut >= 0; c++, cut--)
+                               TODIGIT(u, cut, c, pow);
+                       cut = DECDPUN - 1;      // next Unit has all digits
+               }
+               *c = '\0';      // terminate the string
+               return;
+       }
+
+       /* non-0 exponent -- assume plain form */
+       pre = dn->digits + exp; // digits before '.'
+       e = 0;                  // no E
+       if ((exp > 0) || (pre < -5)) {  // need exponential form
+               e = exp + dn->digits - 1;       // calculate E value
+               pre = 1;        // assume one digit before '.'
+               if (eng && (e != 0)) {  // engineering: may need to adjust
+                       Int adj;        // adjustment
+                       // The C remainder operator is undefined for negative numbers, so
+                       // a positive remainder calculation must be used here
+                       if (e < 0) {
+                               adj = (-e) % 3;
+                               if (adj != 0)
+                                       adj = 3 - adj;
+                       } else {        // e>0
+                               adj = e % 3;
+                       }
+                       e = e - adj;
+                       // if dealing with zero still produce an exponent which is a
+                       // multiple of three, as expected, but there will only be the
+                       // one zero before the E, still.  Otherwise note the padding.
+                       if (!ISZERO(dn))
+                               pre += adj;
+                       else {  // is zero
+                               if (adj != 0) { // 0.00Esnn needed
+                                       e = e + 3;
+                                       pre = -(2 - adj);
+                               }
+                       }       // zero
+               }               // eng
+       }                       // need exponent
+
+       /* lay out the digits of the coefficient, adding 0s and . as needed */
+       u = *up;
+       if (pre > 0) {          // xxx.xxx or xx00 (engineering) form
+               Int n = pre;
+               for (; pre > 0; pre--, c++, cut--) {
+                       if (cut < 0) {  // need new Unit
+                               if (up == dn->lsu)
+                                       break;  // out of input digits (pre>digits)
+                               up--;
+                               cut = DECDPUN - 1;
+                               u = *up;
+                       }
+                       TODIGIT(u, cut, c, pow);
+               }
+               if (n < dn->digits) {   // more to come, after '.'
+                       *c = '.';
+                       c++;
+                       for (;; c++, cut--) {
+                               if (cut < 0) {  // need new Unit
+                                       if (up == dn->lsu)
+                                               break;  // out of input digits
+                                       up--;
+                                       cut = DECDPUN - 1;
+                                       u = *up;
+                               }
+                               TODIGIT(u, cut, c, pow);
+                       }
+               } else
+                       for (; pre > 0; pre--, c++)
+                               *c = '0';       // 0 padding (for engineering) needed
+       } else {                // 0.xxx or 0.000xxx form
+               *c = '0';
+               c++;
+               *c = '.';
+               c++;
+               for (; pre < 0; pre++, c++)
+                       *c = '0';       // add any 0's after '.'
+               for (;; c++, cut--) {
+                       if (cut < 0) {  // need new Unit
+                               if (up == dn->lsu)
+                                       break;  // out of input digits
+                               up--;
+                               cut = DECDPUN - 1;
+                               u = *up;
+                       }
+                       TODIGIT(u, cut, c, pow);
+               }
+       }
+
+       /* Finally add the E-part, if needed.  It will never be 0, has a
+          base maximum and minimum of +999999999 through -999999999, but
+          could range down to -1999999998 for anormal numbers */
+       if (e != 0) {
+               Flag had = 0;   // 1=had non-zero
+               *c = 'E';
+               c++;
+               *c = '+';
+               c++;            // assume positive
+               u = e;          // ..
+               if (e < 0) {
+                       *(c - 1) = '-'; // oops, need -
+                       u = -e; // uInt, please
+               }
+               // lay out the exponent [_itoa or equivalent is not ANSI C]
+               for (cut = 9; cut >= 0; cut--) {
+                       TODIGIT(u, cut, c, pow);
+                       if (*c == '0' && !had)
+                               continue;       // skip leading zeros
+                       had = 1;        // had non-0
+                       c++;    // step for next
+               }               // cut
+       }
+       *c = '\0';              // terminate the string (all paths)
+       return;
+}                              // decToString
+
+/* ------------------------------------------------------------------ */
+/* decAddOp -- add/subtract operation                                 */
+/*                                                                    */
+/*   This computes C = A + B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*   negate is DECNEG if rhs should be negated, or 0 otherwise        */
+/*   status accumulates status for the caller                         */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* Inexact in status must be 0 for correct Exact zero sign in result  */
+/* ------------------------------------------------------------------ */
+/* If possible, the coefficient is calculated directly into C.        */
+/* However, if:                                                       */
+/*   -- a digits+1 calculation is needed because the numbers are      */
+/*      unaligned and span more than set->digits digits               */
+/*   -- a carry to digits+1 digits looks possible                     */
+/*   -- C is the same as A or B, and the result would destructively   */
+/*      overlap the A or B coefficient                                */
+/* then the result must be calculated into a temporary buffer.  In    */
+/* this case a local (stack) buffer is used if possible, and only if  */
+/* too long for that does malloc become the final resort.             */
+/*                                                                    */
+/* Misalignment is handled as follows:                                */
+/*   Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp.    */
+/*   BPad: Apply the padding by a combination of shifting (whole      */
+/*         units) and multiplication (part units).                    */
+/*                                                                    */
+/* Addition, especially x=x+1, is speed-critical.                     */
+/* The static buffer is larger than might be expected to allow for    */
+/* calls from higher-level funtions (notable exp).                    */
+/* ------------------------------------------------------------------ */
+static decNumber *decAddOp(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set,
+                          uByte negate, uInt * status)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       Int rhsshift;           // working shift (in Units)
+       Int maxdigits;          // longest logical length
+       Int mult;               // multiplier
+       Int residue;            // rounding accumulator
+       uByte bits;             // result bits
+       Flag diffsign;          // non-0 if arguments have different sign
+       Unit *acc;              // accumulator for result
+       Unit accbuff[SD2U(DECBUFFER * 2 + 20)]; // local buffer [*2+20 reduces many
+       // allocations when called from
+       // other operations, notable exp]
+       Unit *allocacc = NULL;  // -> allocated acc buffer, iff allocated
+       Int reqdigits = set->digits;    // local copy; requested DIGITS
+       Int padding;            // work
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > reqdigits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > reqdigits) {
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // note whether signs differ [used all paths]
+               diffsign = (Flag) ((lhs->bits ^ rhs->bits ^ negate) & DECNEG);
+
+               // handle infinities and NaNs
+               if (SPECIALARGS) {      // a special bit set
+                       if (SPECIALARGS & (DECSNAN | DECNAN))   // a NaN
+                               decNaNs(res, lhs, rhs, set, status);
+                       else {  // one or two infinities
+                               if (decNumberIsInfinite(lhs)) { // LHS is infinity
+                                       // two infinities with different signs is invalid
+                                       if (decNumberIsInfinite(rhs)
+                                           && diffsign) {
+                                               *status |=
+                                                   DEC_Invalid_operation;
+                                               break;
+                                       }
+                                       bits = lhs->bits & DECNEG;      // get sign from LHS
+                               } else
+                                       bits = (rhs->bits ^ negate) & DECNEG;   // RHS must be Infinity
+                               bits |= DECINF;
+                               decNumberZero(res);
+                               res->bits = bits;       // set +/- infinity
+                       }       // an infinity
+                       break;
+               }
+               // Quick exit for add 0s; return the non-0, modified as need be
+               if (ISZERO(lhs)) {
+                       Int adjust;     // work
+                       Int lexp = lhs->exponent;       // save in case LHS==RES
+                       bits = lhs->bits;       // ..
+                       residue = 0;    // clear accumulator
+                       decCopyFit(res, rhs, set, &residue, status);    // copy (as needed)
+                       res->bits ^= negate;    // flip if rhs was negated
+#if DECSUBSET
+                       if (set->extended) {    // exponents on zeros count
+#endif
+                               // exponent will be the lower of the two
+                               adjust = lexp - res->exponent;  // adjustment needed [if -ve]
+                               if (ISZERO(res)) {      // both 0: special IEEE 754 rules
+                                       if (adjust < 0)
+                                               res->exponent = lexp;   // set exponent
+                                       // 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0
+                                       if (diffsign) {
+                                               if (set->round !=
+                                                   DEC_ROUND_FLOOR)
+                                                       res->bits = 0;
+                                               else
+                                                       res->bits = DECNEG;     // preserve 0 sign
+                                       }
+                               } else {        // non-0 res
+                                       if (adjust < 0) {       // 0-padding needed
+                                               if ((res->digits - adjust) >
+                                                   set->digits) {
+                                                       adjust = res->digits - set->digits;     // to fit exactly
+                                                       *status |= DEC_Rounded; // [but exact]
+                                               }
+                                               res->digits =
+                                                   decShiftToMost(res->lsu,
+                                                                  res->digits,
+                                                                  -adjust);
+                                               res->exponent += adjust;        // set the exponent.
+                                       }
+                               }       // non-0 res
+#if DECSUBSET
+                       }       // extended
+#endif
+                       decFinish(res, set, &residue, status);  // clean and finalize
+                       break;
+               }
+
+               if (ISZERO(rhs)) {      // [lhs is non-zero]
+                       Int adjust;     // work
+                       Int rexp = rhs->exponent;       // save in case RHS==RES
+                       bits = rhs->bits;       // be clean
+                       residue = 0;    // clear accumulator
+                       decCopyFit(res, lhs, set, &residue, status);    // copy (as needed)
+#if DECSUBSET
+                       if (set->extended) {    // exponents on zeros count
+#endif
+                               // exponent will be the lower of the two
+                               // [0-0 case handled above]
+                               adjust = rexp - res->exponent;  // adjustment needed [if -ve]
+                               if (adjust < 0) {       // 0-padding needed
+                                       if ((res->digits - adjust) >
+                                           set->digits) {
+                                               adjust = res->digits - set->digits;     // to fit exactly
+                                               *status |= DEC_Rounded; // [but exact]
+                                       }
+                                       res->digits =
+                                           decShiftToMost(res->lsu,
+                                                          res->digits,
+                                                          -adjust);
+                                       res->exponent += adjust;        // set the exponent.
+                               }
+#if DECSUBSET
+                       }       // extended
+#endif
+                       decFinish(res, set, &residue, status);  // clean and finalize
+                       break;
+               }
+               // [NB: both fastpath and mainpath code below assume these cases
+               // (notably 0-0) have already been handled]
+
+               // calculate the padding needed to align the operands
+               padding = rhs->exponent - lhs->exponent;
+
+               // Fastpath cases where the numbers are aligned and normal, the RHS
+               // is all in one unit, no operand rounding is needed, and no carry,
+               // lengthening, or borrow is needed
+               if (padding == 0 && rhs->digits <= DECDPUN && rhs->exponent >= set->emin        // [some normals drop through]
+                   && rhs->exponent <= set->emax - set->digits + 1     // [could clamp]
+                   && rhs->digits <= reqdigits && lhs->digits <= reqdigits) {
+                       Int partial = *lhs->lsu;
+                       if (!diffsign) {        // adding
+                               partial += *rhs->lsu;
+                               if ((partial <= DECDPUNMAX)     // result fits in unit
+                                   && (lhs->digits >= DECDPUN ||       // .. and no digits-count change
+                                       partial < (Int) powers[lhs->digits])) { // ..
+                                       if (res != lhs)
+                                               decNumberCopy(res, lhs);        // not in place
+                                       *res->lsu = (Unit) partial;     // [copy could have overwritten RHS]
+                                       break;
+                               }
+                               // else drop out for careful add
+                       } else {        // signs differ
+                               partial -= *rhs->lsu;
+                               if (partial > 0) {      // no borrow needed, and non-0 result
+                                       if (res != lhs)
+                                               decNumberCopy(res, lhs);        // not in place
+                                       *res->lsu = (Unit) partial;
+                                       // this could have reduced digits [but result>0]
+                                       res->digits =
+                                           decGetDigits(res->lsu,
+                                                        D2U(res->digits));
+                                       break;
+                               }
+                               // else drop out for careful subtract
+                       }
+               }
+               // Now align (pad) the lhs or rhs so they can be added or
+               // subtracted, as necessary.  If one number is much larger than
+               // the other (that is, if in plain form there is a least one
+               // digit between the lowest digit of one and the highest of the
+               // other) padding with up to DIGITS-1 trailing zeros may be
+               // needed; then apply rounding (as exotic rounding modes may be
+               // affected by the residue).
+               rhsshift = 0;   // rhs shift to left (padding) in Units
+               bits = lhs->bits;       // assume sign is that of LHS
+               mult = 1;       // likely multiplier
+
+               // [if padding==0 the operands are aligned; no padding is needed]
+               if (padding != 0) {
+                       // some padding needed; always pad the RHS, as any required
+                       // padding can then be effected by a simple combination of
+                       // shifts and a multiply
+                       Flag swapped = 0;
+                       if (padding < 0) {      // LHS needs the padding
+                               const decNumber *t;
+                               padding = -padding;     // will be +ve
+                               bits = (uByte) (rhs->bits ^ negate);    // assumed sign is now that of RHS
+                               t = lhs;
+                               lhs = rhs;
+                               rhs = t;
+                               swapped = 1;
+                       }
+                       // If, after pad, rhs would be longer than lhs by digits+1 or
+                       // more then lhs cannot affect the answer, except as a residue,
+                       // so only need to pad up to a length of DIGITS+1.
+                       if (rhs->digits + padding > lhs->digits + reqdigits + 1) {
+                               // The RHS is sufficient
+                               // for residue use the relative sign indication...
+                               Int shift = reqdigits - rhs->digits;    // left shift needed
+                               residue = 1;    // residue for rounding
+                               if (diffsign)
+                                       residue = -residue;     // signs differ
+                               // copy, shortening if necessary
+                               decCopyFit(res, rhs, set, &residue, status);
+                               // if it was already shorter, then need to pad with zeros
+                               if (shift > 0) {
+                                       res->digits =
+                                           decShiftToMost(res->lsu,
+                                                          res->digits, shift);
+                                       res->exponent -= shift; // adjust the exponent.
+                               }
+                               // flip the result sign if unswapped and rhs was negated
+                               if (!swapped)
+                                       res->bits ^= negate;
+                               decFinish(res, set, &residue, status);  // done
+                               break;
+                       }
+                       // LHS digits may affect result
+                       rhsshift = D2U(padding + 1) - 1;        // this much by Unit shift ..
+                       mult = powers[padding - (rhsshift * DECDPUN)];  // .. this by multiplication
+               }               // padding needed
+
+               if (diffsign)
+                       mult = -mult;   // signs differ
+
+               // determine the longer operand
+               maxdigits = rhs->digits + padding;      // virtual length of RHS
+               if (lhs->digits > maxdigits)
+                       maxdigits = lhs->digits;
+
+               // Decide on the result buffer to use; if possible place directly
+               // into result.
+               acc = res->lsu; // assume add direct to result
+               // If destructive overlap, or the number is too long, or a carry or
+               // borrow to DIGITS+1 might be possible, a buffer must be used.
+               // [Might be worth more sophisticated tests when maxdigits==reqdigits]
+               if ((maxdigits >= reqdigits)    // is, or could be, too large
+                   || (res == rhs && rhsshift > 0)) {  // destructive overlap
+                       // buffer needed, choose it; units for maxdigits digits will be
+                       // needed, +1 Unit for carry or borrow
+                       Int need = D2U(maxdigits) + 1;
+                       acc = accbuff;  // assume use local buffer
+                       if (need * sizeof(Unit) > sizeof(accbuff)) {
+                               // printf("malloc add %ld %ld\n", need, sizeof(accbuff));
+                               allocacc = (Unit *) malloc(need * sizeof(Unit));
+                               if (allocacc == NULL) { // hopeless -- abandon
+                                       *status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               acc = allocacc;
+                       }
+               }
+
+               res->bits = (uByte) (bits & DECNEG);    // it's now safe to overwrite..
+               res->exponent = lhs->exponent;  // .. operands (even if aliased)
+
+#if DECTRACE
+               decDumpAr('A', lhs->lsu, D2U(lhs->digits));
+               decDumpAr('B', rhs->lsu, D2U(rhs->digits));
+               printf("  :h: %ld %ld\n", rhsshift, mult);
+#endif
+
+               // add [A+B*m] or subtract [A+B*(-m)]
+               res->digits = decUnitAddSub(lhs->lsu, D2U(lhs->digits),
+                                           rhs->lsu, D2U(rhs->digits),
+                                           rhsshift, acc, mult)
+                   * DECDPUN;  // [units -> digits]
+               if (res->digits < 0) {  // borrowed...
+                       res->digits = -res->digits;
+                       res->bits ^= DECNEG;    // flip the sign
+               }
+#if DECTRACE
+               decDumpAr('+', acc, D2U(res->digits));
+#endif
+
+               // If a buffer was used the result must be copied back, possibly
+               // shortening.  (If no buffer was used then the result must have
+               // fit, so can't need rounding and residue must be 0.)
+               residue = 0;    // clear accumulator
+               if (acc != res->lsu) {
+#if DECSUBSET
+                       if (set->extended) {    // round from first significant digit
+#endif
+                               // remove leading zeros that were added due to rounding up to
+                               // integral Units -- before the test for rounding.
+                               if (res->digits > reqdigits)
+                                       res->digits =
+                                           decGetDigits(acc, D2U(res->digits));
+                               decSetCoeff(res, set, acc, res->digits,
+                                           &residue, status);
+#if DECSUBSET
+                       } else {        // subset arithmetic rounds from original significant digit
+                               // May have an underestimate.  This only occurs when both
+                               // numbers fit in DECDPUN digits and are padding with a
+                               // negative multiple (-10, -100...) and the top digit(s) become
+                               // 0.  (This only matters when using X3.274 rules where the
+                               // leading zero could be included in the rounding.)
+                               if (res->digits < maxdigits) {
+                                       *(acc + D2U(res->digits)) = 0;  // ensure leading 0 is there
+                                       res->digits = maxdigits;
+                               } else {
+                                       // remove leading zeros that added due to rounding up to
+                                       // integral Units (but only those in excess of the original
+                                       // maxdigits length, unless extended) before test for rounding.
+                                       if (res->digits > reqdigits) {
+                                               res->digits =
+                                                   decGetDigits(acc,
+                                                                D2U
+                                                                (res->digits));
+                                               if (res->digits < maxdigits)
+                                                       res->digits = maxdigits;
+                                       }
+                               }
+                               decSetCoeff(res, set, acc, res->digits,
+                                           &residue, status);
+                               // Now apply rounding if needed before removing leading zeros.
+                               // This is safe because subnormals are not a possibility
+                               if (residue != 0) {
+                                       decApplyRound(res, set, residue,
+                                                     status);
+                                       residue = 0;    // did what needed to be done
+                               }
+                       }       // subset
+#endif
+               }               // used buffer
+
+               // strip leading zeros [these were left on in case of subset subtract]
+               res->digits = decGetDigits(res->lsu, D2U(res->digits));
+
+               // apply checks and rounding
+               decFinish(res, set, &residue, status);
+
+               // "When the sum of two operands with opposite signs is exactly
+               // zero, the sign of that sum shall be '+' in all rounding modes
+               // except round toward -Infinity, in which mode that sign shall be
+               // '-'."  [Subset zeros also never have '-', set by decFinish.]
+               if (ISZERO(res) && diffsign
+#if DECSUBSET
+                   && set->extended
+#endif
+                   && (*status & DEC_Inexact) == 0) {
+                       if (set->round == DEC_ROUND_FLOOR)
+                               res->bits |= DECNEG;    // sign -
+                       else
+                               res->bits &= ~DECNEG;   // sign +
+               }
+       } while (0);            // end protected
+
+       if (allocacc != NULL)
+               free(allocacc); // drop any storage used
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+       return res;
+}                              // decAddOp
+
+/* ------------------------------------------------------------------ */
+/* decDivideOp -- division operation                                  */
+/*                                                                    */
+/*  This routine performs the calculations for all four division      */
+/*  operators (divide, divideInteger, remainder, remainderNear).      */
+/*                                                                    */
+/*  C=A op B                                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*   op  is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively.    */
+/*   status is the usual accumulator                                  */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+/*   The underlying algorithm of this routine is the same as in the   */
+/*   1981 S/370 implementation, that is, non-restoring long division  */
+/*   with bi-unit (rather than bi-digit) estimation for each unit     */
+/*   multiplier.  In this pseudocode overview, complications for the  */
+/*   Remainder operators and division residues for exact rounding are */
+/*   omitted for clarity.                                             */
+/*                                                                    */
+/*     Prepare operands and handle special values                     */
+/*     Test for x/0 and then 0/x                                      */
+/*     Exp =Exp1 - Exp2                                               */
+/*     Exp =Exp +len(var1) -len(var2)                                 */
+/*     Sign=Sign1 * Sign2                                             */
+/*     Pad accumulator (Var1) to double-length with 0's (pad1)        */
+/*     Pad Var2 to same length as Var1                                */
+/*     msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round  */
+/*     have=0                                                         */
+/*     Do until (have=digits+1 OR residue=0)                          */
+/*       if exp<0 then if integer divide/residue then leave           */
+/*       this_unit=0                                                  */
+/*       Do forever                                                   */
+/*          compare numbers                                           */
+/*          if <0 then leave inner_loop                               */
+/*          if =0 then (* quick exit without subtract *) do           */
+/*             this_unit=this_unit+1; output this_unit                */
+/*             leave outer_loop; end                                  */
+/*          Compare lengths of numbers (mantissae):                   */
+/*          If same then tops2=msu2pair -- {units 1&2 of var2}        */
+/*                  else tops2=msu2plus -- {0, unit 1 of var2}        */
+/*          tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */
+/*          mult=tops1/tops2  -- Good and safe guess at divisor       */
+/*          if mult=0 then mult=1                                     */
+/*          this_unit=this_unit+mult                                  */
+/*          subtract                                                  */
+/*          end inner_loop                                            */
+/*        if have\=0 | this_unit\=0 then do                           */
+/*          output this_unit                                          */
+/*          have=have+1; end                                          */
+/*        var2=var2/10                                                */
+/*        exp=exp-1                                                   */
+/*        end outer_loop                                              */
+/*     exp=exp+1   -- set the proper exponent                         */
+/*     if have=0 then generate answer=0                               */
+/*     Return (Result is defined by Var1)                             */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+/* Two working buffers are needed during the division; one (digits+   */
+/* 1) to accumulate the result, and the other (up to 2*digits+1) for  */
+/* long subtractions.  These are acc and var1 respectively.           */
+/* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/
+/* The static buffers may be larger than might be expected to allow   */
+/* for calls from higher-level funtions (notable exp).                */
+/* ------------------------------------------------------------------ */
+static decNumber *decDivideOp(decNumber * res,
+                             const decNumber * lhs, const decNumber * rhs,
+                             decContext * set, Flag op, uInt * status)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       Unit accbuff[SD2U(DECBUFFER + DECDPUN + 10)];   // local buffer
+       Unit *acc = accbuff;    // -> accumulator array for result
+       Unit *allocacc = NULL;  // -> allocated buffer, iff allocated
+       Unit *accnext;          // -> where next digit will go
+       Int acclength;          // length of acc needed [Units]
+       Int accunits;           // count of units accumulated
+       Int accdigits;          // count of digits accumulated
+
+       Unit varbuff[SD2U(DECBUFFER * 2 + DECDPUN)];    // buffer for var1
+       Unit *var1 = varbuff;   // -> var1 array for long subtraction
+       Unit *varalloc = NULL;  // -> allocated buffer, iff used
+       Unit *msu1;             // -> msu of var1
+
+       const Unit *var2;       // -> var2 array
+       const Unit *msu2;       // -> msu of var2
+       Int msu2plus;           // msu2 plus one [does not vary]
+       eInt msu2pair;          // msu2 pair plus one [does not vary]
+
+       Int var1units, var2units;       // actual lengths
+       Int var2ulen;           // logical length (units)
+       Int var1initpad = 0;    // var1 initial padding (digits)
+       Int maxdigits;          // longest LHS or required acc length
+       Int mult;               // multiplier for subtraction
+       Unit thisunit;          // current unit being accumulated
+       Int residue;            // for rounding
+       Int reqdigits = set->digits;    // requested DIGITS
+       Int exponent;           // working exponent
+       Int maxexponent = 0;    // DIVIDE maximum exponent if unrounded
+       uByte bits;             // working sign
+       Unit *target;           // work
+       const Unit *source;     // ..
+       uInt const *pow;        // ..
+       Int shift, cut;         // ..
+#if DECSUBSET
+       Int dropped;            // work
+#endif
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > reqdigits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > reqdigits) {
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               bits = (lhs->bits ^ rhs->bits) & DECNEG;        // assumed sign for divisions
+
+               // handle infinities and NaNs
+               if (SPECIALARGS) {      // a special bit set
+                       if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
+                               decNaNs(res, lhs, rhs, set, status);
+                               break;
+                       }
+                       // one or two infinities
+                       if (decNumberIsInfinite(lhs)) { // LHS (dividend) is infinite
+                               if (decNumberIsInfinite(rhs) || // two infinities are invalid ..
+                                   op & (REMAINDER | REMNEAR)) {       // as is remainder of infinity
+                                       *status |= DEC_Invalid_operation;
+                                       break;
+                               }
+                               // [Note that infinity/0 raises no exceptions]
+                               decNumberZero(res);
+                               res->bits = bits | DECINF;      // set +/- infinity
+                               break;
+                       } else {        // RHS (divisor) is infinite
+                               residue = 0;
+                               if (op & (REMAINDER | REMNEAR)) {
+                                       // result is [finished clone of] lhs
+                                       decCopyFit(res, lhs, set, &residue,
+                                                  status);
+                               } else {        // a division
+                                       decNumberZero(res);
+                                       res->bits = bits;       // set +/- zero
+                                       // for DIVIDEINT the exponent is always 0.  For DIVIDE, result
+                                       // is a 0 with infinitely negative exponent, clamped to minimum
+                                       if (op & DIVIDE) {
+                                               res->exponent =
+                                                   set->emin - set->digits + 1;
+                                               *status |= DEC_Clamped;
+                                       }
+                               }
+                               decFinish(res, set, &residue, status);
+                               break;
+                       }
+               }
+               // handle 0 rhs (x/0)
+               if (ISZERO(rhs)) {      // x/0 is always exceptional
+                       if (ISZERO(lhs)) {
+                               decNumberZero(res);     // [after lhs test]
+                               *status |= DEC_Division_undefined;      // 0/0 will become NaN
+                       } else {
+                               decNumberZero(res);
+                               if (op & (REMAINDER | REMNEAR))
+                                       *status |= DEC_Invalid_operation;
+                               else {
+                                       *status |= DEC_Division_by_zero;        // x/0
+                                       res->bits = bits | DECINF;      // .. is +/- Infinity
+                               }
+                       }
+                       break;
+               }
+               // handle 0 lhs (0/x)
+               if (ISZERO(lhs)) {      // 0/x [x!=0]
+#if DECSUBSET
+                       if (!set->extended)
+                               decNumberZero(res);
+                       else {
+#endif
+                               if (op & DIVIDE) {
+                                       residue = 0;
+                                       exponent = lhs->exponent - rhs->exponent;       // ideal exponent
+                                       decNumberCopy(res, lhs);        // [zeros always fit]
+                                       res->bits = bits;       // sign as computed
+                                       res->exponent = exponent;       // exponent, too
+                                       decFinalize(res, set, &residue, status);        // check exponent
+                               } else if (op & DIVIDEINT) {
+                                       decNumberZero(res);     // integer 0
+                                       res->bits = bits;       // sign as computed
+                               } else {        // a remainder
+                                       exponent = rhs->exponent;       // [save in case overwrite]
+                                       decNumberCopy(res, lhs);        // [zeros always fit]
+                                       if (exponent < res->exponent)
+                                               res->exponent = exponent;       // use lower
+                               }
+#if DECSUBSET
+                       }
+#endif
+                       break;
+               }
+               // Precalculate exponent.  This starts off adjusted (and hence fits
+               // in 31 bits) and becomes the usual unadjusted exponent as the
+               // division proceeds.  The order of evaluation is important, here,
+               // to avoid wrap.
+               exponent =
+                   (lhs->exponent + lhs->digits) - (rhs->exponent +
+                                                    rhs->digits);
+
+               // If the working exponent is -ve, then some quick exits are
+               // possible because the quotient is known to be <1
+               // [for REMNEAR, it needs to be < -1, as -0.5 could need work]
+               if (exponent < 0 && !(op == DIVIDE)) {
+                       if (op & DIVIDEINT) {
+                               decNumberZero(res);     // integer part is 0
+#if DECSUBSET
+                               if (set->extended)
+#endif
+                                       res->bits = bits;       // set +/- zero
+                               break;
+                       }
+                       // fastpath remainders so long as the lhs has the smaller
+                       // (or equal) exponent
+                       if (lhs->exponent <= rhs->exponent) {
+                               if (op & REMAINDER || exponent < -1) {
+                                       // It is REMAINDER or safe REMNEAR; result is [finished
+                                       // clone of] lhs  (r = x - 0*y)
+                                       residue = 0;
+                                       decCopyFit(res, lhs, set, &residue,
+                                                  status);
+                                       decFinish(res, set, &residue, status);
+                                       break;
+                               }
+                               // [unsafe REMNEAR drops through]
+                       }
+               }               // fastpaths
+
+               /* Long (slow) division is needed; roll up the sleeves... */
+
+               // The accumulator will hold the quotient of the division.
+               // If it needs to be too long for stack storage, then allocate.
+               acclength = D2U(reqdigits + DECDPUN);   // in Units
+               if (acclength * sizeof(Unit) > sizeof(accbuff)) {
+                       // printf("malloc dvacc %ld units\n", acclength);
+                       allocacc = (Unit *) malloc(acclength * sizeof(Unit));
+                       if (allocacc == NULL) { // hopeless -- abandon
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       acc = allocacc; // use the allocated space
+               }
+               // var1 is the padded LHS ready for subtractions.
+               // If it needs to be too long for stack storage, then allocate.
+               // The maximum units needed for var1 (long subtraction) is:
+               // Enough for
+               //     (rhs->digits+reqdigits-1) -- to allow full slide to right
+               // or  (lhs->digits)             -- to allow for long lhs
+               // whichever is larger
+               //   +1                -- for rounding of slide to right
+               //   +1                -- for leading 0s
+               //   +1                -- for pre-adjust if a remainder or DIVIDEINT
+               // [Note: unused units do not participate in decUnitAddSub data]
+               maxdigits = rhs->digits + reqdigits - 1;
+               if (lhs->digits > maxdigits)
+                       maxdigits = lhs->digits;
+               var1units = D2U(maxdigits) + 2;
+               // allocate a guard unit above msu1 for REMAINDERNEAR
+               if (!(op & DIVIDE))
+                       var1units++;
+               if ((var1units + 1) * sizeof(Unit) > sizeof(varbuff)) {
+                       // printf("malloc dvvar %ld units\n", var1units+1);
+                       varalloc =
+                           (Unit *) malloc((var1units + 1) * sizeof(Unit));
+                       if (varalloc == NULL) { // hopeless -- abandon
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       var1 = varalloc;        // use the allocated space
+               }
+               // Extend the lhs and rhs to full long subtraction length.  The lhs
+               // is truly extended into the var1 buffer, with 0 padding, so a
+               // subtract in place is always possible.  The rhs (var2) has
+               // virtual padding (implemented by decUnitAddSub).
+               // One guard unit was allocated above msu1 for rem=rem+rem in
+               // REMAINDERNEAR.
+               msu1 = var1 + var1units - 1;    // msu of var1
+               source = lhs->lsu + D2U(lhs->digits) - 1;       // msu of input array
+               for (target = msu1; source >= lhs->lsu; source--, target--)
+                       *target = *source;
+               for (; target >= var1; target--)
+                       *target = 0;
+
+               // rhs (var2) is left-aligned with var1 at the start
+               var2ulen = var1units;   // rhs logical length (units)
+               var2units = D2U(rhs->digits);   // rhs actual length (units)
+               var2 = rhs->lsu;        // -> rhs array
+               msu2 = var2 + var2units - 1;    // -> msu of var2 [never changes]
+               // now set up the variables which will be used for estimating the
+               // multiplication factor.  If these variables are not exact, add
+               // 1 to make sure that the multiplier is never overestimated.
+               msu2plus = *msu2;       // it's value ..
+               if (var2units > 1)
+                       msu2plus++;     // .. +1 if any more
+               msu2pair = (eInt) * msu2 * (DECDPUNMAX + 1);    // top two pair ..
+               if (var2units > 1) {    // .. [else treat 2nd as 0]
+                       msu2pair += *(msu2 - 1);        // ..
+                       if (var2units > 2)
+                               msu2pair++;     // .. +1 if any more
+               }
+               // The calculation is working in units, which may have leading zeros,
+               // but the exponent was calculated on the assumption that they are
+               // both left-aligned.  Adjust the exponent to compensate: add the
+               // number of leading zeros in var1 msu and subtract those in var2 msu.
+               // [This is actually done by counting the digits and negating, as
+               // lead1=DECDPUN-digits1, and similarly for lead2.]
+               for (pow = &powers[1]; *msu1 >= *pow; pow++)
+                       exponent--;
+               for (pow = &powers[1]; *msu2 >= *pow; pow++)
+                       exponent++;
+
+               // Now, if doing an integer divide or remainder, ensure that
+               // the result will be Unit-aligned.  To do this, shift the var1
+               // accumulator towards least if need be.  (It's much easier to
+               // do this now than to reassemble the residue afterwards, if
+               // doing a remainder.)  Also ensure the exponent is not negative.
+               if (!(op & DIVIDE)) {
+                       Unit *u;        // work
+                       // save the initial 'false' padding of var1, in digits
+                       var1initpad = (var1units - D2U(lhs->digits)) * DECDPUN;
+                       // Determine the shift to do.
+                       if (exponent < 0)
+                               cut = -exponent;
+                       else
+                               cut = DECDPUN - exponent % DECDPUN;
+                       decShiftToLeast(var1, var1units, cut);
+                       exponent += cut;        // maintain numerical value
+                       var1initpad -= cut;     // .. and reduce padding
+                       // clean any most-significant units which were just emptied
+                       for (u = msu1; cut >= DECDPUN; cut -= DECDPUN, u--)
+                               *u = 0;
+               }               // align
+               else {          // is DIVIDE
+                       maxexponent = lhs->exponent - rhs->exponent;    // save
+                       // optimization: if the first iteration will just produce 0,
+                       // preadjust to skip it [valid for DIVIDE only]
+                       if (*msu1 < *msu2) {
+                               var2ulen--;     // shift down
+                               exponent -= DECDPUN;    // update the exponent
+                       }
+               }
+
+               // ---- start the long-division loops ------------------------------
+               accunits = 0;   // no units accumulated yet
+               accdigits = 0;  // .. or digits
+               accnext = acc + acclength - 1;  // -> msu of acc [NB: allows digits+1]
+               for (;;) {      // outer forever loop
+                       thisunit = 0;   // current unit assumed 0
+                       // find the next unit
+                       for (;;) {      // inner forever loop
+                               // strip leading zero units [from either pre-adjust or from
+                               // subtract last time around].  Leave at least one unit.
+                               for (; *msu1 == 0 && msu1 > var1; msu1--)
+                                       var1units--;
+
+                               if (var1units < var2ulen)
+                                       break;  // var1 too low for subtract
+                               if (var1units == var2ulen) {    // unit-by-unit compare needed
+                                       // compare the two numbers, from msu
+                                       const Unit *pv1, *pv2;
+                                       Unit v2;        // units to compare
+                                       pv2 = msu2;     // -> msu
+                                       for (pv1 = msu1;; pv1--, pv2--) {
+                                               // v1=*pv1 -- always OK
+                                               v2 = 0; // assume in padding
+                                               if (pv2 >= var2)
+                                                       v2 = *pv2;      // in range
+                                               if (*pv1 != v2)
+                                                       break;  // no longer the same
+                                               if (pv1 == var1)
+                                                       break;  // done; leave pv1 as is
+                                       }
+                                       // here when all inspected or a difference seen
+                                       if (*pv1 < v2)
+                                               break;  // var1 too low to subtract
+                                       if (*pv1 == v2) {       // var1 == var2
+                                               // reach here if var1 and var2 are identical; subtraction
+                                               // would increase digit by one, and the residue will be 0 so
+                                               // the calculation is done; leave the loop with residue=0.
+                                               thisunit++;     // as though subtracted
+                                               *var1 = 0;      // set var1 to 0
+                                               var1units = 1;  // ..
+                                               break;  // from inner
+                                       }       // var1 == var2
+                                       // *pv1>v2.  Prepare for real subtraction; the lengths are equal
+                                       // Estimate the multiplier (there's always a msu1-1)...
+                                       // Bring in two units of var2 to provide a good estimate.
+                                       mult =
+                                           (Int) (((eInt) * msu1 *
+                                                   (DECDPUNMAX + 1) + *(msu1 -
+                                                                        1)) /
+                                                  msu2pair);
+                               }       // lengths the same
+                               else {  // var1units > var2ulen, so subtraction is safe
+                                       // The var2 msu is one unit towards the lsu of the var1 msu,
+                                       // so only one unit for var2 can be used.
+                                       mult =
+                                           (Int) (((eInt) * msu1 *
+                                                   (DECDPUNMAX + 1) + *(msu1 -
+                                                                        1)) /
+                                                  msu2plus);
+                               }
+                               if (mult == 0)
+                                       mult = 1;       // must always be at least 1
+                               // subtraction needed; var1 is > var2
+                               thisunit = (Unit) (thisunit + mult);    // accumulate
+                               // subtract var1-var2, into var1; only the overlap needs
+                               // processing, as this is an in-place calculation
+                               shift = var2ulen - var2units;
+#if DECTRACE
+                               decDumpAr('1', &var1[shift], var1units - shift);
+                               decDumpAr('2', var2, var2units);
+                               printf("m=%ld\n", -mult);
+#endif
+                               decUnitAddSub(&var1[shift], var1units - shift,
+                                             var2, var2units, 0,
+                                             &var1[shift], -mult);
+#if DECTRACE
+                               decDumpAr('#', &var1[shift], var1units - shift);
+#endif
+                               // var1 now probably has leading zeros; these are removed at the
+                               // top of the inner loop.
+                       }       // inner loop
+
+                       // The next unit has been calculated in full; unless it's a
+                       // leading zero, add to acc
+                       if (accunits != 0 || thisunit != 0) {   // is first or non-zero
+                               *accnext = thisunit;    // store in accumulator
+                               // account exactly for the new digits
+                               if (accunits == 0) {
+                                       accdigits++;    // at least one
+                                       for (pow = &powers[1]; thisunit >= *pow;
+                                            pow++)
+                                               accdigits++;
+                               } else
+                                       accdigits += DECDPUN;
+                               accunits++;     // update count
+                               accnext--;      // ready for next
+                               if (accdigits > reqdigits)
+                                       break;  // have enough digits
+                       }
+                       // if the residue is zero, the operation is done (unless divide
+                       // or divideInteger and still not enough digits yet)
+                       if (*var1 == 0 && var1units == 1) {     // residue is 0
+                               if (op & (REMAINDER | REMNEAR))
+                                       break;
+                               if ((op & DIVIDE) && (exponent <= maxexponent))
+                                       break;
+                               // [drop through if divideInteger]
+                       }
+                       // also done enough if calculating remainder or integer
+                       // divide and just did the last ('units') unit
+                       if (exponent == 0 && !(op & DIVIDE))
+                               break;
+
+                       // to get here, var1 is less than var2, so divide var2 by the per-
+                       // Unit power of ten and go for the next digit
+                       var2ulen--;     // shift down
+                       exponent -= DECDPUN;    // update the exponent
+               }               // outer loop
+
+               // ---- division is complete ---------------------------------------
+               // here: acc      has at least reqdigits+1 of good results (or fewer
+               //                if early stop), starting at accnext+1 (its lsu)
+               //       var1     has any residue at the stopping point
+               //       accunits is the number of digits collected in acc
+               if (accunits == 0) {    // acc is 0
+                       accunits = 1;   // show have a unit ..
+                       accdigits = 1;  // ..
+                       *accnext = 0;   // .. whose value is 0
+               } else
+                       accnext++;      // back to last placed
+               // accnext now -> lowest unit of result
+
+               residue = 0;    // assume no residue
+               if (op & DIVIDE) {
+                       // record the presence of any residue, for rounding
+                       if (*var1 != 0 || var1units > 1)
+                               residue = 1;
+                       else {  // no residue
+                               // Had an exact division; clean up spurious trailing 0s.
+                               // There will be at most DECDPUN-1, from the final multiply,
+                               // and then only if the result is non-0 (and even) and the
+                               // exponent is 'loose'.
+#if DECDPUN>1
+                               Unit lsu = *accnext;
+                               if (!(lsu & 0x01) && (lsu != 0)) {
+                                       // count the trailing zeros
+                                       Int drop = 0;
+                                       for (;; drop++) {       // [will terminate because lsu!=0]
+                                               if (exponent >= maxexponent)
+                                                       break;  // don't chop real 0s
+#if DECDPUN<=4
+                                               if ((lsu - QUOT10(lsu, drop + 1)
+                                                    * powers[drop + 1]) != 0)
+                                                       break;  // found non-0 digit
+#else
+                                               if (lsu % powers[drop + 1] != 0)
+                                                       break;  // found non-0 digit
+#endif
+                                               exponent++;
+                                       }
+                                       if (drop > 0) {
+                                               accunits =
+                                                   decShiftToLeast(accnext,
+                                                                   accunits,
+                                                                   drop);
+                                               accdigits =
+                                                   decGetDigits(accnext,
+                                                                accunits);
+                                               accunits = D2U(accdigits);
+                                               // [exponent was adjusted in the loop]
+                                       }
+                               }       // neither odd nor 0
+#endif
+                       }       // exact divide
+               }               // divide
+               else {          /* op!=DIVIDE */
+
+                       // check for coefficient overflow
+                       if (accdigits + exponent > reqdigits) {
+                               *status |= DEC_Division_impossible;
+                               break;
+                       }
+                       if (op & (REMAINDER | REMNEAR)) {
+                               // [Here, the exponent will be 0, because var1 was adjusted
+                               // appropriately.]
+                               Int postshift;  // work
+                               Flag wasodd = 0;        // integer was odd
+                               Unit *quotlsu;  // for save
+                               Int quotdigits; // ..
+
+                               bits = lhs->bits;       // remainder sign is always as lhs
+
+                               // Fastpath when residue is truly 0 is worthwhile [and
+                               // simplifies the code below]
+                               if (*var1 == 0 && var1units == 1) {     // residue is 0
+                                       Int exp = lhs->exponent;        // save min(exponents)
+                                       if (rhs->exponent < exp)
+                                               exp = rhs->exponent;
+                                       decNumberZero(res);     // 0 coefficient
+#if DECSUBSET
+                                       if (set->extended)
+#endif
+                                               res->exponent = exp;    // .. with proper exponent
+                                       res->bits = (uByte) (bits & DECNEG);    // [cleaned]
+                                       decFinish(res, set, &residue, status);  // might clamp
+                                       break;
+                               }
+                               // note if the quotient was odd
+                               if (*accnext & 0x01)
+                                       wasodd = 1;     // acc is odd
+                               quotlsu = accnext;      // save in case need to reinspect
+                               quotdigits = accdigits; // ..
+
+                               // treat the residue, in var1, as the value to return, via acc
+                               // calculate the unused zero digits.  This is the smaller of:
+                               //   var1 initial padding (saved above)
+                               //   var2 residual padding, which happens to be given by:
+                               postshift =
+                                   var1initpad + exponent - lhs->exponent +
+                                   rhs->exponent;
+                               // [the 'exponent' term accounts for the shifts during divide]
+                               if (var1initpad < postshift)
+                                       postshift = var1initpad;
+
+                               // shift var1 the requested amount, and adjust its digits
+                               var1units =
+                                   decShiftToLeast(var1, var1units, postshift);
+                               accnext = var1;
+                               accdigits = decGetDigits(var1, var1units);
+                               accunits = D2U(accdigits);
+
+                               exponent = lhs->exponent;       // exponent is smaller of lhs & rhs
+                               if (rhs->exponent < exponent)
+                                       exponent = rhs->exponent;
+
+                               // Now correct the result if doing remainderNear; if it
+                               // (looking just at coefficients) is > rhs/2, or == rhs/2 and
+                               // the integer was odd then the result should be rem-rhs.
+                               if (op & REMNEAR) {
+                                       Int compare, tarunits;  // work
+                                       Unit *up;       // ..
+                                       // calculate remainder*2 into the var1 buffer (which has
+                                       // 'headroom' of an extra unit and hence enough space)
+                                       // [a dedicated 'double' loop would be faster, here]
+                                       tarunits =
+                                           decUnitAddSub(accnext, accunits,
+                                                         accnext, accunits, 0,
+                                                         accnext, 1);
+                                       // decDumpAr('r', accnext, tarunits);
+
+                                       // Here, accnext (var1) holds tarunits Units with twice the
+                                       // remainder's coefficient, which must now be compared to the
+                                       // RHS.  The remainder's exponent may be smaller than the RHS's.
+                                       compare =
+                                           decUnitCompare(accnext, tarunits,
+                                                          rhs->lsu,
+                                                          D2U(rhs->digits),
+                                                          rhs->exponent -
+                                                          exponent);
+                                       if (compare == BADINT) {        // deep trouble
+                                               *status |=
+                                                   DEC_Insufficient_storage;
+                                               break;
+                                       }
+                                       // now restore the remainder by dividing by two; the lsu
+                                       // is known to be even.
+                                       for (up = accnext;
+                                            up < accnext + tarunits; up++) {
+                                               Int half;       // half to add to lower unit
+                                               half = *up & 0x01;
+                                               *up /= 2;       // [shift]
+                                               if (!half)
+                                                       continue;
+                                               *(up - 1) +=
+                                                   (DECDPUNMAX + 1) / 2;
+                                       }
+                                       // [accunits still describes the original remainder length]
+
+                                       if (compare > 0 || (compare == 0 && wasodd)) {  // adjustment needed
+                                               Int exp, expunits, exprem;      // work
+                                               // This is effectively causing round-up of the quotient,
+                                               // so if it was the rare case where it was full and all
+                                               // nines, it would overflow and hence division-impossible
+                                               // should be raised
+                                               Flag allnines = 0;      // 1 if quotient all nines
+                                               if (quotdigits == reqdigits) {  // could be borderline
+                                                       for (up = quotlsu;;
+                                                            up++) {
+                                                               if (quotdigits >
+                                                                   DECDPUN) {
+                                                                       if (*up
+                                                                           !=
+                                                                           DECDPUNMAX)
+                                                                               break;  // non-nines
+                                                               } else {        // this is the last Unit
+                                                                       if (*up
+                                                                           ==
+                                                                           powers
+                                                                           [quotdigits]
+                                                                           - 1)
+                                                                               allnines
+                                                                                   =
+                                                                                   1;
+                                                                       break;
+                                                               }
+                                                               quotdigits -= DECDPUN;  // checked those digits
+                                                       }       // up
+                                               }       // borderline check
+                                               if (allnines) {
+                                                       *status |=
+                                                           DEC_Division_impossible;
+                                                       break;
+                                               }
+                                               // rem-rhs is needed; the sign will invert.  Again, var1
+                                               // can safely be used for the working Units array.
+                                               exp = rhs->exponent - exponent; // RHS padding needed
+                                               // Calculate units and remainder from exponent.
+                                               expunits = exp / DECDPUN;
+                                               exprem = exp % DECDPUN;
+                                               // subtract [A+B*(-m)]; the result will always be negative
+                                               accunits =
+                                                   -decUnitAddSub(accnext,
+                                                                  accunits,
+                                                                  rhs->lsu,
+                                                                  D2U
+                                                                  (rhs->digits),
+                                                                  expunits,
+                                                                  accnext,
+                                                                  -(Int)
+                                                                  powers
+                                                                  [exprem]);
+                                               accdigits = decGetDigits(accnext, accunits);    // count digits exactly
+                                               accunits = D2U(accdigits);      // and recalculate the units for copy
+                                               // [exponent is as for original remainder]
+                                               bits ^= DECNEG; // flip the sign
+                                       }
+                               }       // REMNEAR
+                       }       // REMAINDER or REMNEAR
+               }               // not DIVIDE
+
+               // Set exponent and bits
+               res->exponent = exponent;
+               res->bits = (uByte) (bits & DECNEG);    // [cleaned]
+
+               // Now the coefficient.
+               decSetCoeff(res, set, accnext, accdigits, &residue, status);
+
+               decFinish(res, set, &residue, status);  // final cleanup
+
+#if DECSUBSET
+               // If a divide then strip trailing zeros if subset [after round]
+               if (!set->extended && (op == DIVIDE))
+                       decTrim(res, set, 0, 1, &dropped);
+#endif
+       } while (0);            // end protected
+
+       if (varalloc != NULL)
+               free(varalloc); // drop any storage used
+       if (allocacc != NULL)
+               free(allocacc); // ..
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+       return res;
+}                              // decDivideOp
+
+/* ------------------------------------------------------------------ */
+/* decMultiplyOp -- multiplication operation                          */
+/*                                                                    */
+/*  This routine performs the multiplication C=A x B.                 */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X*X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*   status is the usual accumulator                                  */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+/* 'Classic' multiplication is used rather than Karatsuba, as the     */
+/* latter would give only a minor improvement for the short numbers   */
+/* expected to be handled most (and uses much more memory).           */
+/*                                                                    */
+/* There are two major paths here: the general-purpose ('old code')   */
+/* path which handles all DECDPUN values, and a fastpath version      */
+/* which is used if 64-bit ints are available, DECDPUN<=4, and more   */
+/* than two calls to decUnitAddSub would be made.                     */
+/*                                                                    */
+/* The fastpath version lumps units together into 8-digit or 9-digit  */
+/* chunks, and also uses a lazy carry strategy to minimise expensive  */
+/* 64-bit divisions.  The chunks are then broken apart again into     */
+/* units for continuing processing.  Despite this overhead, the       */
+/* fastpath can speed up some 16-digit operations by 10x (and much    */
+/* more for higher-precision calculations).                           */
+/*                                                                    */
+/* A buffer always has to be used for the accumulator; in the         */
+/* fastpath, buffers are also always needed for the chunked copies of */
+/* of the operand coefficients.                                       */
+/* Static buffers are larger than needed just for multiply, to allow  */
+/* for calls from other operations (notably exp).                     */
+/* ------------------------------------------------------------------ */
+#define FASTMUL (DECUSE64 && DECDPUN<5)
+static decNumber *decMultiplyOp(decNumber * res, const decNumber * lhs,
+                               const decNumber * rhs, decContext * set,
+                               uInt * status)
+{
+       Int accunits;           // Units of accumulator in use
+       Int exponent;           // work
+       Int residue = 0;        // rounding residue
+       uByte bits;             // result sign
+       Unit *acc;              // -> accumulator Unit array
+       Int needbytes;          // size calculator
+       void *allocacc = NULL;  // -> allocated accumulator, iff allocated
+       Unit accbuff[SD2U(DECBUFFER * 4 + 1)];  // buffer (+1 for DECBUFFER==0,
+       // *4 for calls from other operations)
+       const Unit *mer, *mermsup;      // work
+       Int madlength;          // Units in multiplicand
+       Int shift;              // Units to shift multiplicand by
+
+#if FASTMUL
+       // if DECDPUN is 1 or 3 work in base 10**9, otherwise
+       // (DECDPUN is 2 or 4) then work in base 10**8
+#if DECDPUN & 1                        // odd
+#define FASTBASE 1000000000    // base
+#define FASTDIGS          9    // digits in base
+#define FASTLAZY         18    // carry resolution point [1->18]
+#else
+#define FASTBASE  100000000
+#define FASTDIGS          8
+#define FASTLAZY       1844    // carry resolution point [1->1844]
+#endif
+       // three buffers are used, two for chunked copies of the operands
+       // (base 10**8 or base 10**9) and one base 2**64 accumulator with
+       // lazy carry evaluation
+       uInt zlhibuff[(DECBUFFER * 2 + 1) / 8 + 1];     // buffer (+1 for DECBUFFER==0)
+       uInt *zlhi = zlhibuff;  // -> lhs array
+       uInt *alloclhi = NULL;  // -> allocated buffer, iff allocated
+       uInt zrhibuff[(DECBUFFER * 2 + 1) / 8 + 1];     // buffer (+1 for DECBUFFER==0)
+       uInt *zrhi = zrhibuff;  // -> rhs array
+       uInt *allocrhi = NULL;  // -> allocated buffer, iff allocated
+       uLong zaccbuff[(DECBUFFER * 2 + 1) / 4 + 2];    // buffer (+1 for DECBUFFER==0)
+       // [allocacc is shared for both paths, as only one will run]
+       uLong *zacc = zaccbuff; // -> accumulator array for exact result
+#if DECDPUN==1
+       Int zoff;               // accumulator offset
+#endif
+       uInt *lip, *rip;        // item pointers
+       uInt *lmsi, *rmsi;      // most significant items
+       Int ilhs, irhs, iacc;   // item counts in the arrays
+       Int lazy;               // lazy carry counter
+       uLong lcarry;           // uLong carry
+       uInt carry;             // carry (NB not uLong)
+       Int count;              // work
+       const Unit *cup;        // ..
+       Unit *up;               // ..
+       uLong *lp;              // ..
+       Int p;                  // ..
+#endif
+
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // -> allocated buffer, iff allocated
+       decNumber *allocrhs = NULL;     // -> allocated buffer, iff allocated
+#endif
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       // precalculate result sign
+       bits = (uByte) ((lhs->bits ^ rhs->bits) & DECNEG);
+
+       // handle infinities and NaNs
+       if (SPECIALARGS) {      // a special bit set
+               if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
+                       decNaNs(res, lhs, rhs, set, status);
+                       return res;
+               }
+               // one or two infinities; Infinity * 0 is invalid
+               if (((lhs->bits & DECINF) == 0 && ISZERO(lhs))
+                   || ((rhs->bits & DECINF) == 0 && ISZERO(rhs))) {
+                       *status |= DEC_Invalid_operation;
+                       return res;
+               }
+               decNumberZero(res);
+               res->bits = bits | DECINF;      // infinity
+               return res;
+       }
+       // For best speed, as in DMSRCN [the original Rexx numerics
+       // module], use the shorter number as the multiplier (rhs) and
+       // the longer as the multiplicand (lhs) to minimise the number of
+       // adds (partial products)
+       if (lhs->digits < rhs->digits) {        // swap...
+               const decNumber *hold = lhs;
+               lhs = rhs;
+               rhs = hold;
+       }
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > set->digits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > set->digits) {
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+#if FASTMUL                    // fastpath can be used
+               // use the fast path if there are enough digits in the shorter
+               // operand to make the setup and takedown worthwhile
+#define NEEDTWO (DECDPUN*2)    // within two decUnitAddSub calls
+               if (rhs->digits > NEEDTWO) {    // use fastpath...
+                       // calculate the number of elements in each array
+                       ilhs = (lhs->digits + FASTDIGS - 1) / FASTDIGS; // [ceiling]
+                       irhs = (rhs->digits + FASTDIGS - 1) / FASTDIGS; // ..
+                       iacc = ilhs + irhs;
+
+                       // allocate buffers if required, as usual
+                       needbytes = ilhs * sizeof(uInt);
+                       if (needbytes > (Int) sizeof(zlhibuff)) {
+                               alloclhi = (uInt *) malloc(needbytes);
+                               zlhi = alloclhi;
+                       }
+                       needbytes = irhs * sizeof(uInt);
+                       if (needbytes > (Int) sizeof(zrhibuff)) {
+                               allocrhi = (uInt *) malloc(needbytes);
+                               zrhi = allocrhi;
+                       }
+                       // Allocating the accumulator space needs a special case when
+                       // DECDPUN=1 because when converting the accumulator to Units
+                       // after the multiplication each 8-byte item becomes 9 1-byte
+                       // units.  Therefore iacc extra bytes are needed at the front
+                       // (rounded up to a multiple of 8 bytes), and the uLong
+                       // accumulator starts offset the appropriate number of units
+                       // to the right to avoid overwrite during the unchunking.
+                       needbytes = iacc * sizeof(uLong);
+#if DECDPUN==1
+                       zoff = (iacc + 7) / 8;  // items to offset by
+                       needbytes += zoff * 8;
+#endif
+                       if (needbytes > (Int) sizeof(zaccbuff)) {
+                               allocacc = (uLong *) malloc(needbytes);
+                               zacc = (uLong *) allocacc;
+                       }
+                       if (zlhi == NULL || zrhi == NULL || zacc == NULL) {
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+
+                       acc = (Unit *) zacc;    // -> target Unit array
+#if DECDPUN==1
+                       zacc += zoff;   // start uLong accumulator to right
+#endif
+
+                       // assemble the chunked copies of the left and right sides
+                       for (count = lhs->digits, cup = lhs->lsu, lip = zlhi;
+                            count > 0; lip++)
+                               for (p = 0, *lip = 0; p < FASTDIGS && count > 0;
+                                    p += DECDPUN, cup++, count -= DECDPUN)
+                                       *lip += *cup * powers[p];
+                       lmsi = lip - 1; // save -> msi
+                       for (count = rhs->digits, cup = rhs->lsu, rip = zrhi;
+                            count > 0; rip++)
+                               for (p = 0, *rip = 0; p < FASTDIGS && count > 0;
+                                    p += DECDPUN, cup++, count -= DECDPUN)
+                                       *rip += *cup * powers[p];
+                       rmsi = rip - 1; // save -> msi
+
+                       // zero the accumulator
+                       for (lp = zacc; lp < zacc + iacc; lp++)
+                               *lp = 0;
+
+                       /* Start the multiplication */
+                       // Resolving carries can dominate the cost of accumulating the
+                       // partial products, so this is only done when necessary.
+                       // Each uLong item in the accumulator can hold values up to
+                       // 2**64-1, and each partial product can be as large as
+                       // (10**FASTDIGS-1)**2.  When FASTDIGS=9, this can be added to
+                       // itself 18.4 times in a uLong without overflowing, so during
+                       // the main calculation resolution is carried out every 18th
+                       // add -- every 162 digits.  Similarly, when FASTDIGS=8, the
+                       // partial products can be added to themselves 1844.6 times in
+                       // a uLong without overflowing, so intermediate carry
+                       // resolution occurs only every 14752 digits.  Hence for common
+                       // short numbers usually only the one final carry resolution
+                       // occurs.
+                       // (The count is set via FASTLAZY to simplify experiments to
+                       // measure the value of this approach: a 35% improvement on a
+                       // [34x34] multiply.)
+                       lazy = FASTLAZY;        // carry delay count
+                       for (rip = zrhi; rip <= rmsi; rip++) {  // over each item in rhs
+                               lp = zacc + (rip - zrhi);       // where to add the lhs
+                               for (lip = zlhi; lip <= lmsi; lip++, lp++) {    // over each item in lhs
+                                       *lp += (uLong) (*lip) * (*rip); // [this should in-line]
+                               }       // lip loop
+                               lazy--;
+                               if (lazy > 0 && rip != rmsi)
+                                       continue;
+                               lazy = FASTLAZY;        // reset delay count
+                               // spin up the accumulator resolving overflows
+                               for (lp = zacc; lp < zacc + iacc; lp++) {
+                                       if (*lp < FASTBASE)
+                                               continue;       // it fits
+                                       lcarry = *lp / FASTBASE;        // top part [slow divide]
+                                       // lcarry can exceed 2**32-1, so check again; this check
+                                       // and occasional extra divide (slow) is well worth it, as
+                                       // it allows FASTLAZY to be increased to 18 rather than 4
+                                       // in the FASTDIGS=9 case
+                                       if (lcarry < FASTBASE)
+                                               carry = (uInt) lcarry;  // [usual]
+                                       else {  // two-place carry [fairly rare]
+                                               uInt carry2 = (uInt) (lcarry / FASTBASE);       // top top part
+                                               *(lp + 2) += carry2;    // add to item+2
+                                               *lp -= ((uLong) FASTBASE * FASTBASE * carry2);  // [slow]
+                                               carry = (uInt) (lcarry - ((uLong) FASTBASE * carry2));  // [inline]
+                                       }
+                                       *(lp + 1) += carry;     // add to item above [inline]
+                                       *lp -= ((uLong) FASTBASE * carry);      // [inline]
+                               }       // carry resolution
+                       }       // rip loop
+
+                       // The multiplication is complete; time to convert back into
+                       // units.  This can be done in-place in the accumulator and in
+                       // 32-bit operations, because carries were resolved after the
+                       // final add.  This needs N-1 divides and multiplies for
+                       // each item in the accumulator (which will become up to N
+                       // units, where 2<=N<=9).
+                       for (lp = zacc, up = acc; lp < zacc + iacc; lp++) {
+                               uInt item = (uInt) * lp;        // decapitate to uInt
+                               for (p = 0; p < FASTDIGS - DECDPUN;
+                                    p += DECDPUN, up++) {
+                                       uInt part = item / (DECDPUNMAX + 1);
+                                       *up =
+                                           (Unit) (item -
+                                                   (part * (DECDPUNMAX + 1)));
+                                       item = part;
+                               }       // p
+                               *up = (Unit) item;
+                               up++;   // [final needs no division]
+                       }       // lp
+                       accunits = up - acc;    // count of units
+               } else {        // here to use units directly, without chunking ['old code']
+#endif
+
+                       // if accumulator will be too long for local storage, then allocate
+                       acc = accbuff;  // -> assume buffer for accumulator
+                       needbytes =
+                           (D2U(lhs->digits) +
+                            D2U(rhs->digits)) * sizeof(Unit);
+                       if (needbytes > (Int) sizeof(accbuff)) {
+                               allocacc = (Unit *) malloc(needbytes);
+                               if (allocacc == NULL) {
+                                       *status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               acc = (Unit *) allocacc;        // use the allocated space
+                       }
+
+                       /* Now the main long multiplication loop */
+                       // Unlike the equivalent in the IBM Java implementation, there
+                       // is no advantage in calculating from msu to lsu.  So, do it
+                       // by the book, as it were.
+                       // Each iteration calculates ACC=ACC+MULTAND*MULT
+                       accunits = 1;   // accumulator starts at '0'
+                       *acc = 0;       // .. (lsu=0)
+                       shift = 0;      // no multiplicand shift at first
+                       madlength = D2U(lhs->digits);   // this won't change
+                       mermsup = rhs->lsu + D2U(rhs->digits);  // -> msu+1 of multiplier
+
+                       for (mer = rhs->lsu; mer < mermsup; mer++) {
+                               // Here, *mer is the next Unit in the multiplier to use
+                               // If non-zero [optimization] add it...
+                               if (*mer != 0)
+                                       accunits =
+                                           decUnitAddSub(&acc[shift],
+                                                         accunits - shift,
+                                                         lhs->lsu, madlength,
+                                                         0, &acc[shift], *mer)
+                                           + shift;
+                               else {  // extend acc with a 0; it will be used shortly
+                                       *(acc + accunits) = 0;  // [this avoids length of <=0 later]
+                                       accunits++;
+                               }
+                               // multiply multiplicand by 10**DECDPUN for next Unit to left
+                               shift++;        // add this for 'logical length'
+                       }       // n
+#if FASTMUL
+               }               // unchunked units
+#endif
+               // common end-path
+#if DECTRACE
+               decDumpAr('*', acc, accunits);  // Show exact result
+#endif
+
+               // acc now contains the exact result of the multiplication,
+               // possibly with a leading zero unit; build the decNumber from
+               // it, noting if any residue
+               res->bits = bits;       // set sign
+               res->digits = decGetDigits(acc, accunits);      // count digits exactly
+
+               // There can be a 31-bit wrap in calculating the exponent.
+               // This can only happen if both input exponents are negative and
+               // both their magnitudes are large.  If there was a wrap, set a
+               // safe very negative exponent, from which decFinalize() will
+               // raise a hard underflow shortly.
+               exponent = lhs->exponent + rhs->exponent;       // calculate exponent
+               if (lhs->exponent < 0 && rhs->exponent < 0 && exponent > 0)
+                       exponent = -2 * DECNUMMAXE;     // force underflow
+               res->exponent = exponent;       // OK to overwrite now
+
+               // Set the coefficient.  If any rounding, residue records
+               decSetCoeff(res, set, acc, res->digits, &residue, status);
+               decFinish(res, set, &residue, status);  // final cleanup
+       } while (0);            // end protected
+
+       if (allocacc != NULL)
+               free(allocacc); // drop any storage used
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+#if FASTMUL
+       if (allocrhi != NULL)
+               free(allocrhi); // ..
+       if (alloclhi != NULL)
+               free(alloclhi); // ..
+#endif
+       return res;
+}                              // decMultiplyOp
+
+/* ------------------------------------------------------------------ */
+/* decExpOp -- effect exponentiation                                  */
+/*                                                                    */
+/*   This computes C = exp(A)                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits. status is updated but    */
+/* not set.                                                           */
+/*                                                                    */
+/* Restrictions:                                                      */
+/*                                                                    */
+/*   digits, emax, and -emin in the context must be less than         */
+/*   2*DEC_MAX_MATH (1999998), and the rhs must be within these       */
+/*   bounds or a zero.  This is an internal routine, so these         */
+/*   restrictions are contractual and not enforced.                   */
+/*                                                                    */
+/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/*                                                                    */
+/* Finite results will always be full precision and Inexact, except   */
+/* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
+/* ------------------------------------------------------------------ */
+/* This approach used here is similar to the algorithm described in   */
+/*                                                                    */
+/*   Variable Precision Exponential Function, T. E. Hull and          */
+/*   A. Abrham, ACM Transactions on Mathematical Software, Vol 12 #2, */
+/*   pp79-91, ACM, June 1986.                                         */
+/*                                                                    */
+/* with the main difference being that the iterations in the series   */
+/* evaluation are terminated dynamically (which does not require the  */
+/* extra variable-precision variables which are expensive in this     */
+/* context).                                                          */
+/*                                                                    */
+/* The error analysis in Hull & Abrham's paper applies except for the */
+/* round-off error accumulation during the series evaluation.  This   */
+/* code does not precalculate the number of iterations and so cannot  */
+/* use Horner's scheme.  Instead, the accumulation is done at double- */
+/* precision, which ensures that the additions of the terms are exact */
+/* and do not accumulate round-off (and any round-off errors in the   */
+/* terms themselves move 'to the right' faster than they can          */
+/* accumulate).  This code also extends the calculation by allowing,  */
+/* in the spirit of other decNumber operators, the input to be more   */
+/* precise than the result (the precision used is based on the more   */
+/* precise of the input or requested result).                         */
+/*                                                                    */
+/* Implementation notes:                                              */
+/*                                                                    */
+/* 1. This is separated out as decExpOp so it can be called from      */
+/*    other Mathematical functions (notably Ln) with a wider range    */
+/*    than normal.  In particular, it can handle the slightly wider   */
+/*    (double) range needed by Ln (which has to be able to calculate  */
+/*    exp(-x) where x can be the tiniest number (Ntiny).              */
+/*                                                                    */
+/* 2. Normalizing x to be <=0.1 (instead of <=1) reduces loop         */
+/*    iterations by appoximately a third with additional (although    */
+/*    diminishing) returns as the range is reduced to even smaller    */
+/*    fractions.  However, h (the power of 10 used to correct the     */
+/*    result at the end, see below) must be kept <=8 as otherwise     */
+/*    the final result cannot be computed.  Hence the leverage is a   */
+/*    sliding value (8-h), where potentially the range is reduced     */
+/*    more for smaller values.                                        */
+/*                                                                    */
+/*    The leverage that can be applied in this way is severely        */
+/*    limited by the cost of the raise-to-the power at the end,       */
+/*    which dominates when the number of iterations is small (less    */
+/*    than ten) or when rhs is short.  As an example, the adjustment  */
+/*    x**10,000,000 needs 31 multiplications, all but one full-width. */
+/*                                                                    */
+/* 3. The restrictions (especially precision) could be raised with    */
+/*    care, but the full decNumber range seems very hard within the   */
+/*    32-bit limits.                                                  */
+/*                                                                    */
+/* 4. The working precisions for the static buffers are twice the     */
+/*    obvious size to allow for calls from decNumberPower.            */
+/* ------------------------------------------------------------------ */
+decNumber *decExpOp(decNumber * res, const decNumber * rhs,
+                   decContext * set, uInt * status)
+{
+       uInt ignore = 0;        // working status
+       Int h;                  // adjusted exponent for 0.xxxx
+       Int p;                  // working precision
+       Int residue;            // rounding residue
+       uInt needbytes;         // for space calculations
+       const decNumber *x = rhs;       // (may point to safe copy later)
+       decContext aset, tset, dset;    // working contexts
+       Int comp;               // work
+
+       // the argument is often copied to normalize it, so (unusually) it
+       // is treated like other buffers, using DECBUFFER, +1 in case
+       // DECBUFFER is 0
+       decNumber bufr[D2N(DECBUFFER * 2 + 1)];
+       decNumber *allocrhs = NULL;     // non-NULL if rhs buffer allocated
+
+       // the working precision will be no more than set->digits+8+1
+       // so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER
+       // is 0 (and twice that for the accumulator)
+
+       // buffer for t, term (working precision plus)
+       decNumber buft[D2N(DECBUFFER * 2 + 9 + 1)];
+       decNumber *allocbuft = NULL;    // -> allocated buft, iff allocated
+       decNumber *t = buft;    // term
+       // buffer for a, accumulator (working precision * 2), at least 9
+       decNumber bufa[D2N(DECBUFFER * 4 + 18 + 1)];
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *a = bufa;    // accumulator
+       // decNumber for the divisor term; this needs at most 9 digits
+       // and so can be fixed size [16 so can use standard context]
+       decNumber bufd[D2N(16)];
+       decNumber *d = bufd;    // divisor
+       decNumber numone;       // constant 1
+
+#if DECCHECK
+       Int iterations = 0;     // for later sanity check
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+               if (SPECIALARG) {       // handle infinities and NaNs
+                       if (decNumberIsInfinite(rhs)) { // an infinity
+                               if (decNumberIsNegative(rhs))   // -Infinity -> +0
+                                       decNumberZero(res);
+                               else
+                                       decNumberCopy(res, rhs);        // +Infinity -> self
+                       } else
+                               decNaNs(res, rhs, NULL, set, status);   // a NaN
+                       break;
+               }
+
+               if (ISZERO(rhs)) {      // zeros -> exact 1
+                       decNumberZero(res);     // make clean 1
+                       *res->lsu = 1;  // ..
+                       break;
+               }               // [no status to set]
+
+               // e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path
+               // positive and negative tiny cases which will result in inexact
+               // 1.  This also allows the later add-accumulate to always be
+               // exact (because its length will never be more than twice the
+               // working precision).
+               // The comparator (tiny) needs just one digit, so use the
+               // decNumber d for it (reused as the divisor, etc., below); its
+               // exponent is such that if x is positive it will have
+               // set->digits-1 zeros between the decimal point and the digit,
+               // which is 4, and if x is negative one more zero there as the
+               // more precise result will be of the form 0.9999999 rather than
+               // 1.0000001.  Hence, tiny will be 0.0000004  if digits=7 and x>0
+               // or 0.00000004 if digits=7 and x<0.  If RHS not larger than
+               // this then the result will be 1.000000
+               decNumberZero(d);       // clean
+               *d->lsu = 4;    // set 4 ..
+               d->exponent = -set->digits;     // * 10**(-d)
+               if (decNumberIsNegative(rhs))
+                       d->exponent--;  // negative case
+               comp = decCompare(d, rhs, 1);   // signless compare
+               if (comp == BADINT) {
+                       *status |= DEC_Insufficient_storage;
+                       break;
+               }
+               if (comp >= 0) {        // rhs < d
+                       Int shift = set->digits - 1;
+                       decNumberZero(res);     // set 1
+                       *res->lsu = 1;  // ..
+                       res->digits = decShiftToMost(res->lsu, 1, shift);
+                       res->exponent = -shift; // make 1.0000...
+                       *status |= DEC_Inexact | DEC_Rounded;   // .. inexactly
+                       break;
+               }               // tiny
+
+               // set up the context to be used for calculating a, as this is
+               // used on both paths below
+               decContextDefault(&aset, DEC_INIT_DECIMAL64);
+               // accumulator bounds are as requested (could underflow)
+               aset.emax = set->emax;  // usual bounds
+               aset.emin = set->emin;  // ..
+               aset.clamp = 0; // and no concrete format
+
+               // calculate the adjusted (Hull & Abrham) exponent (where the
+               // decimal point is just to the left of the coefficient msd)
+               h = rhs->exponent + rhs->digits;
+               // if h>8 then 10**h cannot be calculated safely; however, when
+               // h=8 then exp(|rhs|) will be at least exp(1E+7) which is at
+               // least 6.59E+4342944, so (due to the restriction on Emax/Emin)
+               // overflow (or underflow to 0) is guaranteed -- so this case can
+               // be handled by simply forcing the appropriate excess
+               if (h > 8) {    // overflow/underflow
+                       // set up here so Power call below will over or underflow to
+                       // zero; set accumulator to either 2 or 0.02
+                       // [stack buffer for a is always big enough for this]
+                       decNumberZero(a);
+                       *a->lsu = 2;    // not 1 but < exp(1)
+                       if (decNumberIsNegative(rhs))
+                               a->exponent = -2;       // make 0.02
+                       h = 8;  // clamp so 10**h computable
+                       p = 9;  // set a working precision
+               } else {        // h<=8
+                       Int maxlever = (rhs->digits > 8 ? 1 : 0);
+                       // [could/should increase this for precisions >40 or so, too]
+
+                       // if h is 8, cannot normalize to a lower upper limit because
+                       // the final result will not be computable (see notes above),
+                       // but leverage can be applied whenever h is less than 8.
+                       // Apply as much as possible, up to a MAXLEVER digits, which
+                       // sets the tradeoff against the cost of the later a**(10**h).
+                       // As h is increased, the working precision below also
+                       // increases to compensate for the "constant digits at the
+                       // front" effect.
+                       Int lever = MINI(8 - h, maxlever);      // leverage attainable
+                       Int use = -rhs->digits - lever; // exponent to use for RHS
+                       h += lever;     // apply leverage selected
+                       if (h < 0) {    // clamp
+                               use += h;       // [may end up subnormal]
+                               h = 0;
+                       }
+                       // Take a copy of RHS if it needs normalization (true whenever x>=1)
+                       if (rhs->exponent != use) {
+                               decNumber *newrhs = bufr;       // assume will fit on stack
+                               needbytes =
+                                   sizeof(decNumber) + (D2U(rhs->digits) -
+                                                        1) * sizeof(Unit);
+                               if (needbytes > sizeof(bufr)) { // need malloc space
+                                       allocrhs =
+                                           (decNumber *) malloc(needbytes);
+                                       if (allocrhs == NULL) { // hopeless -- abandon
+                                               *status |=
+                                                   DEC_Insufficient_storage;
+                                               break;
+                                       }
+                                       newrhs = allocrhs;      // use the allocated space
+                               }
+                               decNumberCopy(newrhs, rhs);     // copy to safe space
+                               newrhs->exponent = use; // normalize; now <1
+                               x = newrhs;     // ready for use
+                               // decNumberShow(x);
+                       }
+                       // Now use the usual power series to evaluate exp(x).  The
+                       // series starts as 1 + x + x^2/2 ... so prime ready for the
+                       // third term by setting the term variable t=x, the accumulator
+                       // a=1, and the divisor d=2.
+
+                       // First determine the working precision.  From Hull & Abrham
+                       // this is set->digits+h+2.  However, if x is 'over-precise' we
+                       // need to allow for all its digits to potentially participate
+                       // (consider an x where all the excess digits are 9s) so in
+                       // this case use x->digits+h+2
+                       p = MAXI(x->digits, set->digits) + h + 2;       // [h<=8]
+
+                       // a and t are variable precision, and depend on p, so space
+                       // must be allocated for them if necessary
+
+                       // the accumulator needs to be able to hold 2p digits so that
+                       // the additions on the second and subsequent iterations are
+                       // sufficiently exact.
+                       needbytes =
+                           sizeof(decNumber) + (D2U(p * 2) - 1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufa)) { // need malloc space
+                               allocbufa = (decNumber *) malloc(needbytes);
+                               if (allocbufa == NULL) {        // hopeless -- abandon
+                                       *status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               a = allocbufa;  // use the allocated space
+                       }
+                       // the term needs to be able to hold p digits (which is
+                       // guaranteed to be larger than x->digits, so the initial copy
+                       // is safe); it may also be used for the raise-to-power
+                       // calculation below, which needs an extra two digits
+                       needbytes =
+                           sizeof(decNumber) + (D2U(p + 2) - 1) * sizeof(Unit);
+                       if (needbytes > sizeof(buft)) { // need malloc space
+                               allocbuft = (decNumber *) malloc(needbytes);
+                               if (allocbuft == NULL) {        // hopeless -- abandon
+                                       *status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               t = allocbuft;  // use the allocated space
+                       }
+
+                       decNumberCopy(t, x);    // term=x
+                       decNumberZero(a);
+                       *a->lsu = 1;    // accumulator=1
+                       decNumberZero(d);
+                       *d->lsu = 2;    // divisor=2
+                       decNumberZero(&numone);
+                       *numone.lsu = 1;        // constant 1 for increment
+
+                       // set up the contexts for calculating a, t, and d
+                       decContextDefault(&tset, DEC_INIT_DECIMAL64);
+                       dset = tset;
+                       // accumulator bounds are set above, set precision now
+                       aset.digits = p * 2;    // double
+                       // term bounds avoid any underflow or overflow
+                       tset.digits = p;
+                       tset.emin = DEC_MIN_EMIN;       // [emax is plenty]
+                       // [dset.digits=16, etc., are sufficient]
+
+                       // finally ready to roll
+                       for (;;) {
+#if DECCHECK
+                               iterations++;
+#endif
+                               // only the status from the accumulation is interesting
+                               // [but it should remain unchanged after first add]
+                               decAddOp(a, a, t, &aset, 0, status);    // a=a+t
+                               decMultiplyOp(t, t, x, &tset, &ignore); // t=t*x
+                               decDivideOp(t, t, d, &tset, DIVIDE, &ignore);   // t=t/d
+                               // the iteration ends when the term cannot affect the result,
+                               // if rounded to p digits, which is when its value is smaller
+                               // than the accumulator by p+1 digits.  There must also be
+                               // full precision in a.
+                               if (((a->digits + a->exponent) >=
+                                    (t->digits + t->exponent + p + 1))
+                                   && (a->digits >= p))
+                                       break;
+                               decAddOp(d, d, &numone, &dset, 0, &ignore);     // d=d+1
+                       }       // iterate
+
+#if DECCHECK
+                       // just a sanity check; comment out test to show always
+                       if (iterations > p + 3)
+                               printf
+                                   ("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
+                                    (LI) iterations, (LI) * status, (LI) p,
+                                    (LI) x->digits);
+#endif
+               }               // h<=8
+
+               // apply postconditioning: a=a**(10**h) -- this is calculated
+               // at a slightly higher precision than Hull & Abrham suggest
+               if (h > 0) {
+                       Int seenbit = 0;        // set once a 1-bit is seen
+                       Int i;  // counter
+                       Int n = powers[h];      // always positive
+                       aset.digits = p + 2;    // sufficient precision
+                       // avoid the overhead and many extra digits of decNumberPower
+                       // as all that is needed is the short 'multipliers' loop; here
+                       // accumulate the answer into t
+                       decNumberZero(t);
+                       *t->lsu = 1;    // acc=1
+                       for (i = 1;; i++) {     // for each bit [top bit ignored]
+                               // abandon if have had overflow or terminal underflow
+                               if (*status & (DEC_Overflow | DEC_Underflow)) { // interesting?
+                                       if (*status & DEC_Overflow || ISZERO(t))
+                                               break;
+                               }
+                               n = n << 1;     // move next bit to testable position
+                               if (n < 0) {    // top bit is set
+                                       seenbit = 1;    // OK, have a significant bit
+                                       decMultiplyOp(t, t, a, &aset, status);  // acc=acc*x
+                               }
+                               if (i == 31)
+                                       break;  // that was the last bit
+                               if (!seenbit)
+                                       continue;       // no need to square 1
+                               decMultiplyOp(t, t, t, &aset, status);  // acc=acc*acc [square]
+                       }       /*i */// 32 bits
+                       // decNumberShow(t);
+                       a = t;  // and carry on using t instead of a
+               }
+               // Copy and round the result to res
+               residue = 1;    // indicate dirt to right ..
+               if (ISZERO(a))
+                       residue = 0;    // .. unless underflowed to 0
+               aset.digits = set->digits;      // [use default rounding]
+               decCopyFit(res, a, &aset, &residue, status);    // copy & shorten
+               decFinish(res, set, &residue, status);  // cleanup/set flags
+       } while (0);            // end protected
+
+       if (allocrhs != NULL)
+               free(allocrhs); // drop any storage used
+       if (allocbufa != NULL)
+               free(allocbufa);        // ..
+       if (allocbuft != NULL)
+               free(allocbuft);        // ..
+       // [status is handled by caller]
+       return res;
+}                              // decExpOp
+
+/* ------------------------------------------------------------------ */
+/* Initial-estimate natural logarithm table                           */
+/*                                                                    */
+/*   LNnn -- 90-entry 16-bit table for values from .10 through .99.   */
+/*           The result is a 4-digit encode of the coefficient (c=the */
+/*           top 14 bits encoding 0-9999) and a 2-digit encode of the */
+/*           exponent (e=the bottom 2 bits encoding 0-3)              */
+/*                                                                    */
+/*           The resulting value is given by:                         */
+/*                                                                    */
+/*             v = -c * 10**(-e-3)                                    */
+/*                                                                    */
+/*           where e and c are extracted from entry k = LNnn[x-10]    */
+/*           where x is truncated (NB) into the range 10 through 99,  */
+/*           and then c = k>>2 and e = k&3.                           */
+/* ------------------------------------------------------------------ */
+const uShort LNnn[90] = { 9016, 8652, 8316, 8008, 7724, 7456, 7208,
+       6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312,
+       5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032,
+       39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
+       29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
+       22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
+       15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
+       10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801,
+       5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
+       10130, 6046, 20055
+};
+
+/* ------------------------------------------------------------------ */
+/* decLnOp -- effect natural logarithm                                */
+/*                                                                    */
+/*   This computes C = ln(A)                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Notable cases:                                                     */
+/*   A<0 -> Invalid                                                   */
+/*   A=0 -> -Infinity (Exact)                                         */
+/*   A=+Infinity -> +Infinity (Exact)                                 */
+/*   A=1 exactly -> 0 (Exact)                                         */
+/*                                                                    */
+/* Restrictions (as for Exp):                                         */
+/*                                                                    */
+/*   digits, emax, and -emin in the context must be less than         */
+/*   DEC_MAX_MATH+11 (1000010), and the rhs must be within these      */
+/*   bounds or a zero.  This is an internal routine, so these         */
+/*   restrictions are contractual and not enforced.                   */
+/*                                                                    */
+/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+/* The result is calculated using Newton's method, with each          */
+/* iteration calculating a' = a + x * exp(-a) - 1.  See, for example, */
+/* Epperson 1989.                                                     */
+/*                                                                    */
+/* The iteration ends when the adjustment x*exp(-a)-1 is tiny enough. */
+/* This has to be calculated at the sum of the precision of x and the */
+/* working precision.                                                 */
+/*                                                                    */
+/* Implementation notes:                                              */
+/*                                                                    */
+/* 1. This is separated out as decLnOp so it can be called from       */
+/*    other Mathematical functions (e.g., Log 10) with a wider range  */
+/*    than normal.  In particular, it can handle the slightly wider   */
+/*    (+9+2) range needed by a power function.                        */
+/*                                                                    */
+/* 2. The speed of this function is about 10x slower than exp, as     */
+/*    it typically needs 4-6 iterations for short numbers, and the    */
+/*    extra precision needed adds a squaring effect, twice.           */
+/*                                                                    */
+/* 3. Fastpaths are included for ln(10) and ln(2), up to length 40,   */
+/*    as these are common requests.  ln(10) is used by log10(x).      */
+/*                                                                    */
+/* 4. An iteration might be saved by widening the LNnn table, and     */
+/*    would certainly save at least one if it were made ten times     */
+/*    bigger, too (for truncated fractions 0.100 through 0.999).      */
+/*    However, for most practical evaluations, at least four or five  */
+/*    iterations will be neede -- so this would only speed up by      */
+/*    20-25% and that probably does not justify increasing the table  */
+/*    size.                                                           */
+/*                                                                    */
+/* 5. The static buffers are larger than might be expected to allow   */
+/*    for calls from decNumberPower.                                  */
+/* ------------------------------------------------------------------ */
+decNumber *decLnOp(decNumber * res, const decNumber * rhs,
+                  decContext * set, uInt * status)
+{
+       uInt ignore = 0;        // working status accumulator
+       uInt needbytes;         // for space calculations
+       Int residue;            // rounding residue
+       Int r;                  // rhs=f*10**r [see below]
+       Int p;                  // working precision
+       Int pp;                 // precision for iteration
+       Int t;                  // work
+
+       // buffers for a (accumulator, typically precision+2) and b
+       // (adjustment calculator, same size)
+       decNumber bufa[D2N(DECBUFFER + 12)];
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *a = bufa;    // accumulator/work
+       decNumber bufb[D2N(DECBUFFER * 2 + 2)];
+       decNumber *allocbufb = NULL;    // -> allocated bufa, iff allocated
+       decNumber *b = bufb;    // adjustment/work
+
+       decNumber numone;       // constant 1
+       decNumber cmp;          // work
+       decContext aset, bset;  // working contexts
+
+#if DECCHECK
+       Int iterations = 0;     // for later sanity check
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+               if (SPECIALARG) {       // handle infinities and NaNs
+                       if (decNumberIsInfinite(rhs)) { // an infinity
+                               if (decNumberIsNegative(rhs))   // -Infinity -> error
+                                       *status |= DEC_Invalid_operation;
+                               else
+                                       decNumberCopy(res, rhs);        // +Infinity -> self
+                       } else
+                               decNaNs(res, rhs, NULL, set, status);   // a NaN
+                       break;
+               }
+
+               if (ISZERO(rhs)) {      // +/- zeros -> -Infinity
+                       decNumberZero(res);     // make clean
+                       res->bits = DECINF | DECNEG;    // set - infinity
+                       break;
+               }               // [no status to set]
+
+               // Non-zero negatives are bad...
+               if (decNumberIsNegative(rhs)) { // -x -> error
+                       *status |= DEC_Invalid_operation;
+                       break;
+               }
+               // Here, rhs is positive, finite, and in range
+
+               // lookaside fastpath code for ln(2) and ln(10) at common lengths
+               if (rhs->exponent == 0 && set->digits <= 40) {
+#if DECDPUN==1
+                       if (rhs->lsu[0] == 0 && rhs->lsu[1] == 1 && rhs->digits == 2) { // ln(10)
+#else
+                       if (rhs->lsu[0] == 10 && rhs->digits == 2) {    // ln(10)
+#endif
+                               aset = *set;
+                               aset.round = DEC_ROUND_HALF_EVEN;
+#define LN10 "2.302585092994045684017991454684364207601"
+                               decNumberFromString(res, LN10, &aset);
+                               *status |= (DEC_Inexact | DEC_Rounded); // is inexact
+                               break;
+                       }
+                       if (rhs->lsu[0] == 2 && rhs->digits == 1) {     // ln(2)
+                               aset = *set;
+                               aset.round = DEC_ROUND_HALF_EVEN;
+#define LN2 "0.6931471805599453094172321214581765680755"
+                               decNumberFromString(res, LN2, &aset);
+                               *status |= (DEC_Inexact | DEC_Rounded);
+                               break;
+                       }
+               }               // integer and short
+
+               // Determine the working precision.  This is normally the
+               // requested precision + 2, with a minimum of 9.  However, if
+               // the rhs is 'over-precise' then allow for all its digits to
+               // potentially participate (consider an rhs where all the excess
+               // digits are 9s) so in this case use rhs->digits+2.
+               p = MAXI(rhs->digits, MAXI(set->digits, 7)) + 2;
+
+               // Allocate space for the accumulator and the high-precision
+               // adjustment calculator, if necessary.  The accumulator must
+               // be able to hold p digits, and the adjustment up to
+               // rhs->digits+p digits.  They are also made big enough for 16
+               // digits so that they can be used for calculating the initial
+               // estimate.
+               needbytes =
+                   sizeof(decNumber) + (D2U(MAXI(p, 16)) - 1) * sizeof(Unit);
+               if (needbytes > sizeof(bufa)) { // need malloc space
+                       allocbufa = (decNumber *) malloc(needbytes);
+                       if (allocbufa == NULL) {        // hopeless -- abandon
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       a = allocbufa;  // use the allocated space
+               }
+               pp = p + rhs->digits;
+               needbytes =
+                   sizeof(decNumber) + (D2U(MAXI(pp, 16)) - 1) * sizeof(Unit);
+               if (needbytes > sizeof(bufb)) { // need malloc space
+                       allocbufb = (decNumber *) malloc(needbytes);
+                       if (allocbufb == NULL) {        // hopeless -- abandon
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       b = allocbufb;  // use the allocated space
+               }
+               // Prepare an initial estimate in acc. Calculate this by
+               // considering the coefficient of x to be a normalized fraction,
+               // f, with the decimal point at far left and multiplied by
+               // 10**r.  Then, rhs=f*10**r and 0.1<=f<1, and
+               //   ln(x) = ln(f) + ln(10)*r
+               // Get the initial estimate for ln(f) from a small lookup
+               // table (see above) indexed by the first two digits of f,
+               // truncated.
+
+               decContextDefault(&aset, DEC_INIT_DECIMAL64);   // 16-digit extended
+               r = rhs->exponent + rhs->digits;        // 'normalised' exponent
+               decNumberFromInt32(a, r);       // a=r
+               decNumberFromInt32(b, 2302585); // b=ln(10) (2.302585)
+               b->exponent = -6;       //  ..
+               decMultiplyOp(a, a, b, &aset, &ignore); // a=a*b
+               // now get top two digits of rhs into b by simple truncate and
+               // force to integer
+               residue = 0;    // (no residue)
+               aset.digits = 2;
+               aset.round = DEC_ROUND_DOWN;
+               decCopyFit(b, rhs, &aset, &residue, &ignore);   // copy & shorten
+               b->exponent = 0;        // make integer
+               t = decGetInt(b);       // [cannot fail]
+               if (t < 10)
+                       t = X10(t);     // adjust single-digit b
+               t = LNnn[t - 10];       // look up ln(b)
+               decNumberFromInt32(b, t >> 2);  // b=ln(b) coefficient
+               b->exponent = -(t & 3) - 3;     // set exponent
+               b->bits = DECNEG;       // ln(0.10)->ln(0.99) always -ve
+               aset.digits = 16;
+               aset.round = DEC_ROUND_HALF_EVEN;       // restore
+               decAddOp(a, a, b, &aset, 0, &ignore);   // acc=a+b
+               // the initial estimate is now in a, with up to 4 digits correct.
+               // When rhs is at or near Nmax the estimate will be low, so we
+               // will approach it from below, avoiding overflow when calling exp.
+
+               decNumberZero(&numone);
+               *numone.lsu = 1;        // constant 1 for adjustment
+
+               // accumulator bounds are as requested (could underflow, but
+               // cannot overflow)
+               aset.emax = set->emax;
+               aset.emin = set->emin;
+               aset.clamp = 0; // no concrete format
+               // set up a context to be used for the multiply and subtract
+               bset = aset;
+               bset.emax = DEC_MAX_MATH * 2;   // use double bounds for the
+               bset.emin = -DEC_MAX_MATH * 2;  // adjustment calculation
+               // [see decExpOp call below]
+               // for each iteration double the number of digits to calculate,
+               // up to a maximum of p
+               pp = 9;         // initial precision
+               // [initially 9 as then the sequence starts 7+2, 16+2, and
+               // 34+2, which is ideal for standard-sized numbers]
+               aset.digits = pp;       // working context
+               bset.digits = pp + rhs->digits; // wider context
+               for (;;) {      // iterate
+#if DECCHECK
+                       iterations++;
+                       if (iterations > 24)
+                               break;  // consider 9 * 2**24
+#endif
+                       // calculate the adjustment (exp(-a)*x-1) into b.  This is a
+                       // catastrophic subtraction but it really is the difference
+                       // from 1 that is of interest.
+                       // Use the internal entry point to Exp as it allows the double
+                       // range for calculating exp(-a) when a is the tiniest subnormal.
+                       a->bits ^= DECNEG;      // make -a
+                       decExpOp(b, a, &bset, &ignore); // b=exp(-a)
+                       a->bits ^= DECNEG;      // restore sign of a
+                       // now multiply by rhs and subtract 1, at the wider precision
+                       decMultiplyOp(b, b, rhs, &bset, &ignore);       // b=b*rhs
+                       decAddOp(b, b, &numone, &bset, DECNEG, &ignore);        // b=b-1
+
+                       // the iteration ends when the adjustment cannot affect the
+                       // result by >=0.5 ulp (at the requested digits), which
+                       // is when its value is smaller than the accumulator by
+                       // set->digits+1 digits (or it is zero) -- this is a looser
+                       // requirement than for Exp because all that happens to the
+                       // accumulator after this is the final rounding (but note that
+                       // there must also be full precision in a, or a=0).
+
+                       if (decNumberIsZero(b) ||
+                           (a->digits + a->exponent) >=
+                           (b->digits + b->exponent + set->digits + 1)) {
+                               if (a->digits == p)
+                                       break;
+                               if (decNumberIsZero(a)) {
+                                       decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore);      // rhs=1 ?
+                                       if (cmp.lsu[0] == 0)
+                                               a->exponent = 0;        // yes, exact 0
+                                       else
+                                               *status |= (DEC_Inexact | DEC_Rounded); // no, inexact
+                                       break;
+                               }
+                               // force padding if adjustment has gone to 0 before full length
+                               if (decNumberIsZero(b))
+                                       b->exponent = a->exponent - p;
+                       }
+                       // not done yet ...
+                       decAddOp(a, a, b, &aset, 0, &ignore);   // a=a+b for next estimate
+                       if (pp == p)
+                               continue;       // precision is at maximum
+                       // lengthen the next calculation
+                       pp = pp * 2;    // double precision
+                       if (pp > p)
+                               pp = p; // clamp to maximum
+                       aset.digits = pp;       // working context
+                       bset.digits = pp + rhs->digits; // wider context
+               }               // Newton's iteration
+
+#if DECCHECK
+               // just a sanity check; remove the test to show always
+               if (iterations > 24)
+                       printf
+                           ("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
+                            (LI) iterations, (LI) * status, (LI) p,
+                            (LI) rhs->digits);
+#endif
+
+               // Copy and round the result to res
+               residue = 1;    // indicate dirt to right
+               if (ISZERO(a))
+                       residue = 0;    // .. unless underflowed to 0
+               aset.digits = set->digits;      // [use default rounding]
+               decCopyFit(res, a, &aset, &residue, status);    // copy & shorten
+               decFinish(res, set, &residue, status);  // cleanup/set flags
+       } while (0);            // end protected
+
+       if (allocbufa != NULL)
+               free(allocbufa);        // drop any storage used
+       if (allocbufb != NULL)
+               free(allocbufb);        // ..
+       // [status is handled by caller]
+       return res;
+}                              // decLnOp
+
+/* ------------------------------------------------------------------ */
+/* decQuantizeOp  -- force exponent to requested value                */
+/*                                                                    */
+/*   This computes C = op(A, B), where op adjusts the coefficient     */
+/*   of C (by rounding or shifting) such that the exponent (-scale)   */
+/*   of C has the value B or matches the exponent of B.               */
+/*   The numerical value of C will equal A, except for the effects of */
+/*   any rounding that occurred.                                      */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B                           */
+/*   lhs is A, the number to adjust                                   */
+/*   rhs is B, the requested exponent                                 */
+/*   set is the context                                               */
+/*   quant is 1 for quantize or 0 for rescale                         */
+/*   status is the status accumulator (this can be called without     */
+/*          risk of control loss)                                     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Unless there is an error or the result is infinite, the exponent   */
+/* after the operation is guaranteed to be that requested.            */
+/* ------------------------------------------------------------------ */
+static decNumber *decQuantizeOp(decNumber * res, const decNumber * lhs,
+                               const decNumber * rhs, decContext * set,
+                               Flag quant, uInt * status)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       const decNumber *inrhs = rhs;   // save original rhs
+       Int reqdigits = set->digits;    // requested DIGITS
+       Int reqexp;             // requested exponent [-scale]
+       Int residue = 0;        // rounding residue
+       Int etiny = set->emin - (reqdigits - 1);
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > reqdigits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > reqdigits) {  // [this only checks lostDigits]
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // Handle special values
+               if (SPECIALARGS) {
+                       // NaNs get usual processing
+                       if (SPECIALARGS & (DECSNAN | DECNAN))
+                               decNaNs(res, lhs, rhs, set, status);
+                       // one infinity but not both is bad
+                       else if ((lhs->bits ^ rhs->bits) & DECINF)
+                               *status |= DEC_Invalid_operation;
+                       // both infinity: return lhs
+                       else
+                               decNumberCopy(res, lhs);        // [nop if in place]
+                       break;
+               }
+               // set requested exponent
+               if (quant)
+                       reqexp = inrhs->exponent;       // quantize -- match exponents
+               else {          // rescale -- use value of rhs
+                       // Original rhs must be an integer that fits and is in range,
+                       // which could be from -1999999997 to +999999999, thanks to
+                       // subnormals
+                       reqexp = decGetInt(inrhs);      // [cannot fail]
+               }
+
+#if DECSUBSET
+               if (!set->extended)
+                       etiny = set->emin;      // no subnormals
+#endif
+
+               if (reqexp == BADINT    // bad (rescale only) or ..
+                   || reqexp == BIGODD || reqexp == BIGEVEN    // very big (ditto) or ..
+                   || (reqexp < etiny) // < lowest
+                   || (reqexp > set->emax)) {  // > emax
+                       *status |= DEC_Invalid_operation;
+                       break;
+               }
+               // the RHS has been processed, so it can be overwritten now if necessary
+               if (ISZERO(lhs)) {      // zero coefficient unchanged
+                       decNumberCopy(res, lhs);        // [nop if in place]
+                       res->exponent = reqexp; // .. just set exponent
+#if DECSUBSET
+                       if (!set->extended)
+                               res->bits = 0;  // subset specification; no -0
+#endif
+               } else {        // non-zero lhs
+                       Int adjust = reqexp - lhs->exponent;    // digit adjustment needed
+                       // if adjusted coefficient will definitely not fit, give up now
+                       if ((lhs->digits - adjust) > reqdigits) {
+                               *status |= DEC_Invalid_operation;
+                               break;
+                       }
+
+                       if (adjust > 0) {       // increasing exponent
+                               // this will decrease the length of the coefficient by adjust
+                               // digits, and must round as it does so
+                               decContext workset;     // work
+                               workset = *set; // clone rounding, etc.
+                               workset.digits = lhs->digits - adjust;  // set requested length
+                               // [note that the latter can be <1, here]
+                               decCopyFit(res, lhs, &workset, &residue, status);       // fit to result
+                               decApplyRound(res, &workset, residue, status);  // .. and round
+                               residue = 0;    // [used]
+                               // If just rounded a 999s case, exponent will be off by one;
+                               // adjust back (after checking space), if so.
+                               if (res->exponent > reqexp) {
+                                       // re-check needed, e.g., for quantize(0.9999, 0.001) under
+                                       // set->digits==3
+                                       if (res->digits == reqdigits) { // cannot shift by 1
+                                               *status &= ~(DEC_Inexact | DEC_Rounded);        // [clean these]
+                                               *status |=
+                                                   DEC_Invalid_operation;
+                                               break;
+                                       }
+                                       res->digits = decShiftToMost(res->lsu, res->digits, 1); // shift
+                                       res->exponent--;        // (re)adjust the exponent.
+                               }
+#if DECSUBSET
+                               if (ISZERO(res) && !set->extended)
+                                       res->bits = 0;  // subset; no -0
+#endif
+                       }       // increase
+                       else {  /* adjust<=0 */
+                               // decreasing or = exponent
+                               // this will increase the length of the coefficient by -adjust
+                               // digits, by adding zero or more trailing zeros; this is
+                               // already checked for fit, above
+                               decNumberCopy(res, lhs);        // [it will fit]
+                               // if padding needed (adjust<0), add it now...
+                               if (adjust < 0) {
+                                       res->digits =
+                                           decShiftToMost(res->lsu,
+                                                          res->digits,
+                                                          -adjust);
+                                       res->exponent += adjust;        // adjust the exponent
+                               }
+                       }       // decrease
+               }               // non-zero
+
+               // Check for overflow [do not use Finalize in this case, as an
+               // overflow here is a "don't fit" situation]
+               if (res->exponent > set->emax - res->digits + 1) {      // too big
+                       *status |= DEC_Invalid_operation;
+                       break;
+               } else {
+                       decFinalize(res, set, &residue, status);        // set subnormal flags
+                       *status &= ~DEC_Underflow;      // suppress Underflow [as per 754]
+               }
+       } while (0);            // end protected
+
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // drop any storage used
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+       return res;
+}                              // decQuantizeOp
+
+/* ------------------------------------------------------------------ */
+/* decCompareOp -- compare, min, or max two Numbers                   */
+/*                                                                    */
+/*   This computes C = A ? B and carries out one of four operations:  */
+/*     COMPARE    -- returns the signum (as a number) giving the      */
+/*                   result of a comparison unless one or both        */
+/*                   operands is a NaN (in which case a NaN results)  */
+/*     COMPSIG    -- as COMPARE except that a quiet NaN raises        */
+/*                   Invalid operation.                               */
+/*     COMPMAX    -- returns the larger of the operands, using the    */
+/*                   754 maxnum operation                             */
+/*     COMPMAXMAG -- ditto, comparing absolute values                 */
+/*     COMPMIN    -- the 754 minnum operation                         */
+/*     COMPMINMAG -- ditto, comparing absolute values                 */
+/*     COMTOTAL   -- returns the signum (as a number) giving the      */
+/*                   result of a comparison using 754 total ordering  */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*   op  is the operation flag                                        */
+/*   status is the usual accumulator                                  */
+/*                                                                    */
+/* C must have space for one digit for COMPARE or set->digits for     */
+/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG.                       */
+/* ------------------------------------------------------------------ */
+/* The emphasis here is on speed for common cases, and avoiding       */
+/* coefficient comparison if possible.                                */
+/* ------------------------------------------------------------------ */
+decNumber *decCompareOp(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set,
+                       Flag op, uInt * status)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       Int result = 0;         // default result value
+       uByte merged;           // work
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > set->digits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL) {
+                                       result = BADINT;
+                                       break;
+                               }
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > set->digits) {
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL) {
+                                       result = BADINT;
+                                       break;
+                               }
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // If total ordering then handle differing signs 'up front'
+               if (op == COMPTOTAL) {  // total ordering
+                       if (decNumberIsNegative(lhs) &
+                           !decNumberIsNegative(rhs)) {
+                               result = -1;
+                               break;
+                       }
+                       if (!decNumberIsNegative(lhs) &
+                           decNumberIsNegative(rhs)) {
+                               result = +1;
+                               break;
+                       }
+               }
+               // handle NaNs specially; let infinities drop through
+               // This assumes sNaN (even just one) leads to NaN.
+               merged = (lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
+               if (merged) {   // a NaN bit set
+                       if (op == COMPARE) ;    // result will be NaN
+                       else if (op == COMPSIG) // treat qNaN as sNaN
+                               *status |= DEC_Invalid_operation | DEC_sNaN;
+                       else if (op == COMPTOTAL) {     // total ordering, always finite
+                               // signs are known to be the same; compute the ordering here
+                               // as if the signs are both positive, then invert for negatives
+                               if (!decNumberIsNaN(lhs))
+                                       result = -1;
+                               else if (!decNumberIsNaN(rhs))
+                                       result = +1;
+                               // here if both NaNs
+                               else if (decNumberIsSNaN(lhs)
+                                        && decNumberIsQNaN(rhs))
+                                       result = -1;
+                               else if (decNumberIsQNaN(lhs)
+                                        && decNumberIsSNaN(rhs))
+                                       result = +1;
+                               else {  // both NaN or both sNaN
+                                       // now it just depends on the payload
+                                       result =
+                                           decUnitCompare(lhs->lsu,
+                                                          D2U(lhs->digits),
+                                                          rhs->lsu,
+                                                          D2U(rhs->digits), 0);
+                                       // [Error not possible, as these are 'aligned']
+                               }       // both same NaNs
+                               if (decNumberIsNegative(lhs))
+                                       result = -result;
+                               break;
+                       }       // total order
+
+                       else if (merged & DECSNAN) ;    // sNaN -> qNaN
+                       else {  // here if MIN or MAX and one or two quiet NaNs
+                               // min or max -- 754 rules ignore single NaN
+                               if (!decNumberIsNaN(lhs)
+                                   || !decNumberIsNaN(rhs)) {
+                                       // just one NaN; force choice to be the non-NaN operand
+                                       op = COMPMAX;
+                                       if (lhs->bits & DECNAN)
+                                               result = -1;    // pick rhs
+                                       else
+                                               result = +1;    // pick lhs
+                                       break;
+                               }
+                       }       // max or min
+                       op = COMPNAN;   // use special path
+                       decNaNs(res, lhs, rhs, set, status);    // propagate NaN
+                       break;
+               }
+               // have numbers
+               if (op == COMPMAXMAG || op == COMPMINMAG)
+                       result = decCompare(lhs, rhs, 1);
+               else
+                       result = decCompare(lhs, rhs, 0);       // sign matters
+       } while (0);            // end protected
+
+       if (result == BADINT)
+               *status |= DEC_Insufficient_storage;    // rare
+       else {
+               if (op == COMPARE || op == COMPSIG || op == COMPTOTAL) {        // returning signum
+                       if (op == COMPTOTAL && result == 0) {
+                               // operands are numerically equal or same NaN (and same sign,
+                               // tested first); if identical, leave result 0
+                               if (lhs->exponent != rhs->exponent) {
+                                       if (lhs->exponent < rhs->exponent)
+                                               result = -1;
+                                       else
+                                               result = +1;
+                                       if (decNumberIsNegative(lhs))
+                                               result = -result;
+                               }       // lexp!=rexp
+                       }       // total-order by exponent
+                       decNumberZero(res);     // [always a valid result]
+                       if (result != 0) {      // must be -1 or +1
+                               *res->lsu = 1;
+                               if (result < 0)
+                                       res->bits = DECNEG;
+                       }
+               } else if (op == COMPNAN) ;     // special, drop through
+               else {          // MAX or MIN, non-NaN result
+                       Int residue = 0;        // rounding accumulator
+                       // choose the operand for the result
+                       const decNumber *choice;
+                       if (result == 0) {      // operands are numerically equal
+                               // choose according to sign then exponent (see 754)
+                               uByte slhs = (lhs->bits & DECNEG);
+                               uByte srhs = (rhs->bits & DECNEG);
+#if DECSUBSET
+                               if (!set->extended) {   // subset: force left-hand
+                                       op = COMPMAX;
+                                       result = +1;
+                               } else
+#endif
+                               if (slhs != srhs) {     // signs differ
+                                       if (slhs)
+                                               result = -1;    // rhs is max
+                                       else
+                                               result = +1;    // lhs is max
+                               } else if (slhs && srhs) {      // both negative
+                                       if (lhs->exponent < rhs->exponent)
+                                               result = +1;
+                                       else
+                                               result = -1;
+                                       // [if equal, use lhs, technically identical]
+                               } else {        // both positive
+                                       if (lhs->exponent > rhs->exponent)
+                                               result = +1;
+                                       else
+                                               result = -1;
+                                       // [ditto]
+                               }
+                       }       // numerically equal
+                       // here result will be non-0; reverse if looking for MIN
+                       if (op == COMPMIN || op == COMPMINMAG)
+                               result = -result;
+                       choice = (result > 0 ? lhs : rhs);      // choose
+                       // copy chosen to result, rounding if need be
+                       decCopyFit(res, choice, set, &residue, status);
+                       decFinish(res, set, &residue, status);
+               }
+       }
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // free any storage used
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+       return res;
+}                              // decCompareOp
+
+/* ------------------------------------------------------------------ */
+/* decCompare -- compare two decNumbers by numerical value            */
+/*                                                                    */
+/*  This routine compares A ? B without altering them.                */
+/*                                                                    */
+/*  Arg1 is A, a decNumber which is not a NaN                         */
+/*  Arg2 is B, a decNumber which is not a NaN                         */
+/*  Arg3 is 1 for a sign-independent compare, 0 otherwise             */
+/*                                                                    */
+/*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
+/*  (the only possible failure is an allocation error)                */
+/* ------------------------------------------------------------------ */
+static Int decCompare(const decNumber * lhs, const decNumber * rhs, Flag abs)
+{
+       Int result;             // result value
+       Int sigr;               // rhs signum
+       Int compare;            // work
+
+       result = 1;             // assume signum(lhs)
+       if (ISZERO(lhs))
+               result = 0;
+       if (abs) {
+               if (ISZERO(rhs))
+                       return result;  // LHS wins or both 0
+               // RHS is non-zero
+               if (result == 0)
+                       return -1;      // LHS is 0; RHS wins
+               // [here, both non-zero, result=1]
+       } else {                // signs matter
+               if (result && decNumberIsNegative(lhs))
+                       result = -1;
+               sigr = 1;       // compute signum(rhs)
+               if (ISZERO(rhs))
+                       sigr = 0;
+               else if (decNumberIsNegative(rhs))
+                       sigr = -1;
+               if (result > sigr)
+                       return +1;      // L > R, return 1
+               if (result < sigr)
+                       return -1;      // L < R, return -1
+               if (result == 0)
+                       return 0;       // both 0
+       }
+
+       // signums are the same; both are non-zero
+       if ((lhs->bits | rhs->bits) & DECINF) { // one or more infinities
+               if (decNumberIsInfinite(rhs)) {
+                       if (decNumberIsInfinite(lhs))
+                               result = 0;     // both infinite
+                       else
+                               result = -result;       // only rhs infinite
+               }
+               return result;
+       }
+       // must compare the coefficients, allowing for exponents
+       if (lhs->exponent > rhs->exponent) {    // LHS exponent larger
+               // swap sides, and sign
+               const decNumber *temp = lhs;
+               lhs = rhs;
+               rhs = temp;
+               result = -result;
+       }
+       compare = decUnitCompare(lhs->lsu, D2U(lhs->digits),
+                                rhs->lsu, D2U(rhs->digits),
+                                rhs->exponent - lhs->exponent);
+       if (compare != BADINT)
+               compare *= result;      // comparison succeeded
+       return compare;
+}                              // decCompare
+
+/* ------------------------------------------------------------------ */
+/* decUnitCompare -- compare two >=0 integers in Unit arrays          */
+/*                                                                    */
+/*  This routine compares A ? B*10**E where A and B are unit arrays   */
+/*  A is a plain integer                                              */
+/*  B has an exponent of E (which must be non-negative)               */
+/*                                                                    */
+/*  Arg1 is A first Unit (lsu)                                        */
+/*  Arg2 is A length in Units                                         */
+/*  Arg3 is B first Unit (lsu)                                        */
+/*  Arg4 is B length in Units                                         */
+/*  Arg5 is E (0 if the units are aligned)                            */
+/*                                                                    */
+/*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
+/*  (the only possible failure is an allocation error, which can      */
+/*  only occur if E!=0)                                               */
+/* ------------------------------------------------------------------ */
+static Int decUnitCompare(const Unit * a, Int alength,
+                         const Unit * b, Int blength, Int exp)
+{
+       Unit *acc;              // accumulator for result
+       Unit accbuff[SD2U(DECBUFFER * 2 + 1)];  // local buffer
+       Unit *allocacc = NULL;  // -> allocated acc buffer, iff allocated
+       Int accunits, need;     // units in use or needed for acc
+       const Unit *l, *r, *u;  // work
+       Int expunits, exprem, result;   // ..
+
+       if (exp == 0) {         // aligned; fastpath
+               if (alength > blength)
+                       return 1;
+               if (alength < blength)
+                       return -1;
+               // same number of units in both -- need unit-by-unit compare
+               l = a + alength - 1;
+               r = b + alength - 1;
+               for (; l >= a; l--, r--) {
+                       if (*l > *r)
+                               return 1;
+                       if (*l < *r)
+                               return -1;
+               }
+               return 0;       // all units match
+       }                       // aligned
+
+       // Unaligned.  If one is >1 unit longer than the other, padded
+       // approximately, then can return easily
+       if (alength > blength + (Int) D2U(exp))
+               return 1;
+       if (alength + 1 < blength + (Int) D2U(exp))
+               return -1;
+
+       // Need to do a real subtract.  For this, a result buffer is needed
+       // even though only the sign is of interest.  Its length needs
+       // to be the larger of alength and padded blength, +2
+       need = blength + D2U(exp);      // maximum real length of B
+       if (need < alength)
+               need = alength;
+       need += 2;
+       acc = accbuff;          // assume use local buffer
+       if (need * sizeof(Unit) > sizeof(accbuff)) {
+               allocacc = (Unit *) malloc(need * sizeof(Unit));
+               if (allocacc == NULL)
+                       return BADINT;  // hopeless -- abandon
+               acc = allocacc;
+       }
+       // Calculate units and remainder from exponent.
+       expunits = exp / DECDPUN;
+       exprem = exp % DECDPUN;
+       // subtract [A+B*(-m)]
+       accunits = decUnitAddSub(a, alength, b, blength, expunits, acc,
+                                -(Int) powers[exprem]);
+       // [UnitAddSub result may have leading zeros, even on zero]
+       if (accunits < 0)
+               result = -1;    // negative result
+       else {                  // non-negative result
+               // check units of the result before freeing any storage
+               for (u = acc; u < acc + accunits - 1 && *u == 0;)
+                       u++;
+               result = (*u == 0 ? 0 : +1);
+       }
+       // clean up and return the result
+       if (allocacc != NULL)
+               free(allocacc); // drop any storage used
+       return result;
+}                              // decUnitCompare
+
+/* ------------------------------------------------------------------ */
+/* decUnitAddSub -- add or subtract two >=0 integers in Unit arrays   */
+/*                                                                    */
+/*  This routine performs the calculation:                            */
+/*                                                                    */
+/*  C=A+(B*M)                                                         */
+/*                                                                    */
+/*  Where M is in the range -DECDPUNMAX through +DECDPUNMAX.          */
+/*                                                                    */
+/*  A may be shorter or longer than B.                                */
+/*                                                                    */
+/*  Leading zeros are not removed after a calculation.  The result is */
+/*  either the same length as the longer of A and B (adding any       */
+/*  shift), or one Unit longer than that (if a Unit carry occurred).  */
+/*                                                                    */
+/*  A and B content are not altered unless C is also A or B.          */
+/*  C may be the same array as A or B, but only if no zero padding is */
+/*  requested (that is, C may be B only if bshift==0).                */
+/*  C is filled from the lsu; only those units necessary to complete  */
+/*  the calculation are referenced.                                   */
+/*                                                                    */
+/*  Arg1 is A first Unit (lsu)                                        */
+/*  Arg2 is A length in Units                                         */
+/*  Arg3 is B first Unit (lsu)                                        */
+/*  Arg4 is B length in Units                                         */
+/*  Arg5 is B shift in Units  (>=0; pads with 0 units if positive)    */
+/*  Arg6 is C first Unit (lsu)                                        */
+/*  Arg7 is M, the multiplier                                         */
+/*                                                                    */
+/*  returns the count of Units written to C, which will be non-zero   */
+/*  and negated if the result is negative.  That is, the sign of the  */
+/*  returned Int is the sign of the result (positive for zero) and    */
+/*  the absolute value of the Int is the count of Units.              */
+/*                                                                    */
+/*  It is the caller's responsibility to make sure that C size is     */
+/*  safe, allowing space if necessary for a one-Unit carry.           */
+/*                                                                    */
+/*  This routine is severely performance-critical; *any* change here  */
+/*  must be measured (timed) to assure no performance degradation.    */
+/*  In particular, trickery here tends to be counter-productive, as   */
+/*  increased complexity of code hurts register optimizations on      */
+/*  register-poor architectures.  Avoiding divisions is nearly        */
+/*  always a Good Idea, however.                                      */
+/*                                                                    */
+/* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark  */
+/* (IBM Warwick, UK) for some of the ideas used in this routine.      */
+/* ------------------------------------------------------------------ */
+static Int decUnitAddSub(const Unit * a, Int alength,
+                        const Unit * b, Int blength, Int bshift,
+                        Unit * c, Int m)
+{
+       const Unit *alsu = a;   // A lsu [need to remember it]
+       Unit *clsu = c;         // C ditto
+       Unit *minC;             // low water mark for C
+       Unit *maxC;             // high water mark for C
+       eInt carry = 0;         // carry integer (could be Long)
+       Int add;                // work
+#if DECDPUN<=4                 // myriadal, millenary, etc.
+       Int est;                // estimated quotient
+#endif
+
+#if DECTRACE
+       if (alength < 1 || blength < 1)
+               printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength,
+                      blength, m);
+#endif
+
+       maxC = c + alength;     // A is usually the longer
+       minC = c + blength;     // .. and B the shorter
+       if (bshift != 0) {      // B is shifted; low As copy across
+               minC += bshift;
+               // if in place [common], skip copy unless there's a gap [rare]
+               if (a == c && bshift <= alength) {
+                       c += bshift;
+                       a += bshift;
+               } else
+                       for (; c < clsu + bshift; a++, c++) {   // copy needed
+                               if (a < alsu + alength)
+                                       *c = *a;
+                               else
+                                       *c = 0;
+                       }
+       }
+       if (minC > maxC) {      // swap
+               Unit *hold = minC;
+               minC = maxC;
+               maxC = hold;
+       }
+       // For speed, do the addition as two loops; the first where both A
+       // and B contribute, and the second (if necessary) where only one or
+       // other of the numbers contribute.
+       // Carry handling is the same (i.e., duplicated) in each case.
+       for (; c < minC; c++) {
+               carry += *a;
+               a++;
+               carry += ((eInt) * b) * m;      // [special-casing m=1/-1
+               b++;            // here is not a win]
+               // here carry is new Unit of digits; it could be +ve or -ve
+               if ((ueInt) carry <= DECDPUNMAX) {      // fastpath 0-DECDPUNMAX
+                       *c = (Unit) carry;
+                       carry = 0;
+                       continue;
+               }
+#if DECDPUN==4                 // use divide-by-multiply
+               if (carry >= 0) {
+                       est = (((ueInt) carry >> 11) * 53687) >> 18;
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                       carry = est;    // likely quotient [89%]
+                       if (*c < DECDPUNMAX + 1)
+                               continue;       // estimate was correct
+                       carry++;
+                       *c -= DECDPUNMAX + 1;
+                       continue;
+               }
+               // negative case
+               carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+               est = (((ueInt) carry >> 11) * 53687) >> 18;
+               *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+               carry = est - (DECDPUNMAX + 1); // correctly negative
+               if (*c < DECDPUNMAX + 1)
+                       continue;       // was OK
+               carry++;
+               *c -= DECDPUNMAX + 1;
+#elif DECDPUN==3
+               if (carry >= 0) {
+                       est = (((ueInt) carry >> 3) * 16777) >> 21;
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                       carry = est;    // likely quotient [99%]
+                       if (*c < DECDPUNMAX + 1)
+                               continue;       // estimate was correct
+                       carry++;
+                       *c -= DECDPUNMAX + 1;
+                       continue;
+               }
+               // negative case
+               carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+               est = (((ueInt) carry >> 3) * 16777) >> 21;
+               *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+               carry = est - (DECDPUNMAX + 1); // correctly negative
+               if (*c < DECDPUNMAX + 1)
+                       continue;       // was OK
+               carry++;
+               *c -= DECDPUNMAX + 1;
+#elif DECDPUN<=2
+               // Can use QUOT10 as carry <= 4 digits
+               if (carry >= 0) {
+                       est = QUOT10(carry, DECDPUN);
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                       carry = est;    // quotient
+                       continue;
+               }
+               // negative case
+               carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+               est = QUOT10(carry, DECDPUN);
+               *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+               carry = est - (DECDPUNMAX + 1); // correctly negative
+#else
+               // remainder operator is undefined if negative, so must test
+               if ((ueInt) carry < (DECDPUNMAX + 1) * 2) {     // fastpath carry +1
+                       *c = (Unit) (carry - (DECDPUNMAX + 1)); // [helps additions]
+                       carry = 1;
+                       continue;
+               }
+               if (carry >= 0) {
+                       *c = (Unit) (carry % (DECDPUNMAX + 1));
+                       carry = carry / (DECDPUNMAX + 1);
+                       continue;
+               }
+               // negative case
+               carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+               *c = (Unit) (carry % (DECDPUNMAX + 1));
+               carry = carry / (DECDPUNMAX + 1) - (DECDPUNMAX + 1);
+#endif
+       }                       // c
+
+       // now may have one or other to complete
+       // [pretest to avoid loop setup/shutdown]
+       if (c < maxC)
+               for (; c < maxC; c++) {
+                       if (a < alsu + alength) {       // still in A
+                               carry += *a;
+                               a++;
+                       } else {        // inside B
+                               carry += ((eInt) * b) * m;
+                               b++;
+                       }
+                       // here carry is new Unit of digits; it could be +ve or -ve and
+                       // magnitude up to DECDPUNMAX squared
+                       if ((ueInt) carry <= DECDPUNMAX) {      // fastpath 0-DECDPUNMAX
+                               *c = (Unit) carry;
+                               carry = 0;
+                               continue;
+                       }
+                       // result for this unit is negative or >DECDPUNMAX
+#if DECDPUN==4                 // use divide-by-multiply
+                       if (carry >= 0) {
+                               est = (((ueInt) carry >> 11) * 53687) >> 18;
+                               *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                               carry = est;    // likely quotient [79.7%]
+                               if (*c < DECDPUNMAX + 1)
+                                       continue;       // estimate was correct
+                               carry++;
+                               *c -= DECDPUNMAX + 1;
+                               continue;
+                       }
+                       // negative case
+                       carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+                       est = (((ueInt) carry >> 11) * 53687) >> 18;
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+                       carry = est - (DECDPUNMAX + 1); // correctly negative
+                       if (*c < DECDPUNMAX + 1)
+                               continue;       // was OK
+                       carry++;
+                       *c -= DECDPUNMAX + 1;
+#elif DECDPUN==3
+                       if (carry >= 0) {
+                               est = (((ueInt) carry >> 3) * 16777) >> 21;
+                               *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                               carry = est;    // likely quotient [99%]
+                               if (*c < DECDPUNMAX + 1)
+                                       continue;       // estimate was correct
+                               carry++;
+                               *c -= DECDPUNMAX + 1;
+                               continue;
+                       }
+                       // negative case
+                       carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+                       est = (((ueInt) carry >> 3) * 16777) >> 21;
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+                       carry = est - (DECDPUNMAX + 1); // correctly negative
+                       if (*c < DECDPUNMAX + 1)
+                               continue;       // was OK
+                       carry++;
+                       *c -= DECDPUNMAX + 1;
+#elif DECDPUN<=2
+                       if (carry >= 0) {
+                               est = QUOT10(carry, DECDPUN);
+                               *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                               carry = est;    // quotient
+                               continue;
+                       }
+                       // negative case
+                       carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+                       est = QUOT10(carry, DECDPUN);
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+                       carry = est - (DECDPUNMAX + 1); // correctly negative
+#else
+                       if ((ueInt) carry < (DECDPUNMAX + 1) * 2) {     // fastpath carry 1
+                               *c = (Unit) (carry - (DECDPUNMAX + 1));
+                               carry = 1;
+                               continue;
+                       }
+                       // remainder operator is undefined if negative, so must test
+                       if (carry >= 0) {
+                               *c = (Unit) (carry % (DECDPUNMAX + 1));
+                               carry = carry / (DECDPUNMAX + 1);
+                               continue;
+                       }
+                       // negative case
+                       carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+                       *c = (Unit) (carry % (DECDPUNMAX + 1));
+                       carry = carry / (DECDPUNMAX + 1) - (DECDPUNMAX + 1);
+#endif
+               }               // c
+
+       // OK, all A and B processed; might still have carry or borrow
+       // return number of Units in the result, negated if a borrow
+       if (carry == 0)
+               return c - clsu;        // no carry, so no more to do
+       if (carry > 0) {        // positive carry
+               *c = (Unit) carry;      // place as new unit
+               c++;            // ..
+               return c - clsu;
+       }
+       // -ve carry: it's a borrow; complement needed
+       add = 1;                // temporary carry...
+       for (c = clsu; c < maxC; c++) {
+               add = DECDPUNMAX + add - *c;
+               if (add <= DECDPUNMAX) {
+                       *c = (Unit) add;
+                       add = 0;
+               } else {
+                       *c = 0;
+                       add = 1;
+               }
+       }
+       // add an extra unit iff it would be non-zero
+#if DECTRACE
+       printf("UAS borrow: add %ld, carry %ld\n", add, carry);
+#endif
+       if ((add - carry - 1) != 0) {
+               *c = (Unit) (add - carry - 1);
+               c++;            // interesting, include it
+       }
+       return clsu - c;        // -ve result indicates borrowed
+}                              // decUnitAddSub
+
+/* ------------------------------------------------------------------ */
+/* decTrim -- trim trailing zeros or normalize                        */
+/*                                                                    */
+/*   dn is the number to trim or normalize                            */
+/*   set is the context to use to check for clamp                     */
+/*   all is 1 to remove all trailing zeros, 0 for just fraction ones  */
+/*   noclamp is 1 to unconditional (unclamped) trim                   */
+/*   dropped returns the number of discarded trailing zeros           */
+/*   returns dn                                                       */
+/*                                                                    */
+/* If clamp is set in the context then the number of zeros trimmed    */
+/* may be limited if the exponent is high.                            */
+/* All fields are updated as required.  This is a utility operation,  */
+/* so special values are unchanged and no error is possible.          */
+/* ------------------------------------------------------------------ */
+static decNumber *decTrim(decNumber * dn, decContext * set, Flag all,
+                         Flag noclamp, Int * dropped)
+{
+       Int d, exp;             // work
+       uInt cut;               // ..
+       Unit *up;               // -> current Unit
+
+#if DECCHECK
+       if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT))
+               return dn;
+#endif
+
+       *dropped = 0;           // assume no zeros dropped
+       if ((dn->bits & DECSPECIAL)     // fast exit if special ..
+           || (*dn->lsu & 0x01))
+               return dn;      // .. or odd
+       if (ISZERO(dn)) {       // .. or 0
+               dn->exponent = 0;       // (sign is preserved)
+               return dn;
+       }
+       // have a finite number which is even
+       exp = dn->exponent;
+       cut = 1;                // digit (1-DECDPUN) in Unit
+       up = dn->lsu;           // -> current Unit
+       for (d = 0; d < dn->digits - 1; d++) {  // [don't strip the final digit]
+               // slice by powers
+#if DECDPUN<=4
+               uInt quot = QUOT10(*up, cut);
+               if ((*up - quot * powers[cut]) != 0)
+                       break;  // found non-0 digit
+#else
+               if (*up % powers[cut] != 0)
+                       break;  // found non-0 digit
+#endif
+               // have a trailing 0
+               if (!all) {     // trimming
+                       // [if exp>0 then all trailing 0s are significant for trim]
+                       if (exp <= 0) { // if digit might be significant
+                               if (exp == 0)
+                                       break;  // then quit
+                               exp++;  // next digit might be significant
+                       }
+               }
+               cut++;          // next power
+               if (cut > DECDPUN) {    // need new Unit
+                       up++;
+                       cut = 1;
+               }
+       }                       // d
+       if (d == 0)
+               return dn;      // none to drop
+
+       // may need to limit drop if clamping
+       if (set->clamp && !noclamp) {
+               Int maxd = set->emax - set->digits + 1 - dn->exponent;
+               if (maxd <= 0)
+                       return dn;      // nothing possible
+               if (d > maxd)
+                       d = maxd;
+       }
+       // effect the drop
+       decShiftToLeast(dn->lsu, D2U(dn->digits), d);
+       dn->exponent += d;      // maintain numerical value
+       dn->digits -= d;        // new length
+       *dropped = d;           // report the count
+       return dn;
+}                              // decTrim
+
+/* ------------------------------------------------------------------ */
+/* decReverse -- reverse a Unit array in place                        */
+/*                                                                    */
+/*   ulo    is the start of the array                                 */
+/*   uhi    is the end of the array (highest Unit to include)         */
+/*                                                                    */
+/* The units ulo through uhi are reversed in place (if the number     */
+/* of units is odd, the middle one is untouched).  Note that the      */
+/* digit(s) in each unit are unaffected.                              */
+/* ------------------------------------------------------------------ */
+static void decReverse(Unit * ulo, Unit * uhi)
+{
+       Unit temp;
+       for (; ulo < uhi; ulo++, uhi--) {
+               temp = *ulo;
+               *ulo = *uhi;
+               *uhi = temp;
+       }
+       return;
+}                              // decReverse
+
+/* ------------------------------------------------------------------ */
+/* decShiftToMost -- shift digits in array towards most significant   */
+/*                                                                    */
+/*   uar    is the array                                              */
+/*   digits is the count of digits in use in the array                */
+/*   shift  is the number of zeros to pad with (least significant);   */
+/*     it must be zero or positive                                    */
+/*                                                                    */
+/*   returns the new length of the integer in the array, in digits    */
+/*                                                                    */
+/* No overflow is permitted (that is, the uar array must be known to  */
+/* be large enough to hold the result, after shifting).               */
+/* ------------------------------------------------------------------ */
+static Int decShiftToMost(Unit * uar, Int digits, Int shift)
+{
+       Unit *target, *source, *first;  // work
+       Int cut;                // odd 0's to add
+       uInt next;              // work
+
+       if (shift == 0)
+               return digits;  // [fastpath] nothing to do
+       if ((digits + shift) <= DECDPUN) {      // [fastpath] single-unit case
+               *uar = (Unit) (*uar * powers[shift]);
+               return digits + shift;
+       }
+
+       next = 0;               // all paths
+       source = uar + D2U(digits) - 1; // where msu comes from
+       target = source + D2U(shift);   // where upper part of first cut goes
+       cut = DECDPUN - MSUDIGITS(shift);       // where to slice
+       if (cut == 0) {         // unit-boundary case
+               for (; source >= uar; source--, target--)
+                       *target = *source;
+       } else {
+               first = uar + D2U(digits + shift) - 1;  // where msu of source will end up
+               for (; source >= uar; source--, target--) {
+                       // split the source Unit and accumulate remainder for next
+#if DECDPUN<=4
+                       uInt quot = QUOT10(*source, cut);
+                       uInt rem = *source - quot * powers[cut];
+                       next += quot;
+#else
+                       uInt rem = *source % powers[cut];
+                       next += *source / powers[cut];
+#endif
+                       if (target <= first)
+                               *target = (Unit) next;  // write to target iff valid
+                       next = rem * powers[DECDPUN - cut];     // save remainder for next Unit
+               }
+       }                       // shift-move
+
+       // propagate any partial unit to one below and clear the rest
+       for (; target >= uar; target--) {
+               *target = (Unit) next;
+               next = 0;
+       }
+       return digits + shift;
+}                              // decShiftToMost
+
+/* ------------------------------------------------------------------ */
+/* decShiftToLeast -- shift digits in array towards least significant */
+/*                                                                    */
+/*   uar   is the array                                               */
+/*   units is length of the array, in units                           */
+/*   shift is the number of digits to remove from the lsu end; it     */
+/*     must be zero or positive and <= than units*DECDPUN.            */
+/*                                                                    */
+/*   returns the new length of the integer in the array, in units     */
+/*                                                                    */
+/* Removed digits are discarded (lost).  Units not required to hold   */
+/* the final result are unchanged.                                    */
+/* ------------------------------------------------------------------ */
+static Int decShiftToLeast(Unit * uar, Int units, Int shift)
+{
+       Unit *target, *up;      // work
+       Int cut, count;         // work
+       Int quot, rem;          // for division
+
+       if (shift == 0)
+               return units;   // [fastpath] nothing to do
+       if (shift == units * DECDPUN) { // [fastpath] little to do
+               *uar = 0;       // all digits cleared gives zero
+               return 1;       // leaves just the one
+       }
+
+       target = uar;           // both paths
+       cut = MSUDIGITS(shift);
+       if (cut == DECDPUN) {   // unit-boundary case; easy
+               up = uar + D2U(shift);
+               for (; up < uar + units; target++, up++)
+                       *target = *up;
+               return target - uar;
+       }
+       // messier
+       up = uar + D2U(shift - cut);    // source; correct to whole Units
+       count = units * DECDPUN - shift;        // the maximum new length
+#if DECDPUN<=4
+       quot = QUOT10(*up, cut);
+#else
+       quot = *up / powers[cut];
+#endif
+       for (;; target++) {
+               *target = (Unit) quot;
+               count -= (DECDPUN - cut);
+               if (count <= 0)
+                       break;
+               up++;
+               quot = *up;
+#if DECDPUN<=4
+               quot = QUOT10(quot, cut);
+               rem = *up - quot * powers[cut];
+#else
+               rem = quot % powers[cut];
+               quot = quot / powers[cut];
+#endif
+               *target = (Unit) (*target + rem * powers[DECDPUN - cut]);
+               count -= cut;
+               if (count <= 0)
+                       break;
+       }
+       return target - uar + 1;
+}                              // decShiftToLeast
+
+#if DECSUBSET
+/* ------------------------------------------------------------------ */
+/* decRoundOperand -- round an operand  [used for subset only]        */
+/*                                                                    */
+/*   dn is the number to round (dn->digits is > set->digits)          */
+/*   set is the relevant context                                      */
+/*   status is the status accumulator                                 */
+/*                                                                    */
+/*   returns an allocated decNumber with the rounded result.          */
+/*                                                                    */
+/* lostDigits and other status may be set by this.                    */
+/*                                                                    */
+/* Since the input is an operand, it must not be modified.            */
+/* Instead, return an allocated decNumber, rounded as required.       */
+/* It is the caller's responsibility to free the allocated storage.   */
+/*                                                                    */
+/* If no storage is available then the result cannot be used, so NULL */
+/* is returned.                                                       */
+/* ------------------------------------------------------------------ */
+static decNumber *decRoundOperand(const decNumber * dn, decContext * set,
+                                 uInt * status)
+{
+       decNumber *res;         // result structure
+       uInt newstatus = 0;     // status from round
+       Int residue = 0;        // rounding accumulator
+
+       // Allocate storage for the returned decNumber, big enough for the
+       // length specified by the context
+       res = (decNumber *) malloc(sizeof(decNumber)
+                                  + (D2U(set->digits) - 1) * sizeof(Unit));
+       if (res == NULL) {
+               *status |= DEC_Insufficient_storage;
+               return NULL;
+       }
+       decCopyFit(res, dn, set, &residue, &newstatus);
+       decApplyRound(res, set, residue, &newstatus);
+
+       // If that set Inexact then "lost digits" is raised...
+       if (newstatus & DEC_Inexact)
+               newstatus |= DEC_Lost_digits;
+       *status |= newstatus;
+       return res;
+}                              // decRoundOperand
+#endif
+
+/* ------------------------------------------------------------------ */
+/* decCopyFit -- copy a number, truncating the coefficient if needed  */
+/*                                                                    */
+/*   dest is the target decNumber                                     */
+/*   src  is the source decNumber                                     */
+/*   set is the context [used for length (digits) and rounding mode]  */
+/*   residue is the residue accumulator                               */
+/*   status contains the current status to be updated                 */
+/*                                                                    */
+/* (dest==src is allowed and will be a no-op if fits)                 */
+/* All fields are updated as required.                                */
+/* ------------------------------------------------------------------ */
+static void decCopyFit(decNumber * dest, const decNumber * src,
+                      decContext * set, Int * residue, uInt * status)
+{
+       dest->bits = src->bits;
+       dest->exponent = src->exponent;
+       decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
+}                              // decCopyFit
+
+/* ------------------------------------------------------------------ */
+/* decSetCoeff -- set the coefficient of a number                     */
+/*                                                                    */
+/*   dn    is the number whose coefficient array is to be set.        */
+/*         It must have space for set->digits digits                  */
+/*   set   is the context [for size]                                  */
+/*   lsu   -> lsu of the source coefficient [may be dn->lsu]          */
+/*   len   is digits in the source coefficient [may be dn->digits]    */
+/*   residue is the residue accumulator.  This has values as in       */
+/*         decApplyRound, and will be unchanged unless the            */
+/*         target size is less than len.  In this case, the           */
+/*         coefficient is truncated and the residue is updated to     */
+/*         reflect the previous residue and the dropped digits.       */
+/*   status is the status accumulator, as usual                       */
+/*                                                                    */
+/* The coefficient may already be in the number, or it can be an      */
+/* external intermediate array.  If it is in the number, lsu must ==  */
+/* dn->lsu and len must == dn->digits.                                */
+/*                                                                    */
+/* Note that the coefficient length (len) may be < set->digits, and   */
+/* in this case this merely copies the coefficient (or is a no-op     */
+/* if dn->lsu==lsu).                                                  */
+/*                                                                    */
+/* Note also that (only internally, from decQuantizeOp and            */
+/* decSetSubnormal) the value of set->digits may be less than one,    */
+/* indicating a round to left.  This routine handles that case        */
+/* correctly; caller ensures space.                                   */
+/*                                                                    */
+/* dn->digits, dn->lsu (and as required), and dn->exponent are        */
+/* updated as necessary.   dn->bits (sign) is unchanged.              */
+/*                                                                    */
+/* DEC_Rounded status is set if any digits are discarded.             */
+/* DEC_Inexact status is set if any non-zero digits are discarded, or */
+/*                       incoming residue was non-0 (implies rounded) */
+/* ------------------------------------------------------------------ */
+// mapping array: maps 0-9 to canonical residues, so that a residue
+// can be adjusted in the range [-1, +1] and achieve correct rounding
+//                             0  1  2  3  4  5  6  7  8  9
+static const uByte resmap[10] = { 0, 3, 3, 3, 3, 5, 7, 7, 7, 7 };
+
+static void decSetCoeff(decNumber * dn, decContext * set, const Unit * lsu,
+                       Int len, Int * residue, uInt * status)
+{
+       Int discard;            // number of digits to discard
+       uInt cut;               // cut point in Unit
+       const Unit *up;         // work
+       Unit *target;           // ..
+       Int count;              // ..
+#if DECDPUN<=4
+       uInt temp;              // ..
+#endif
+
+       discard = len - set->digits;    // digits to discard
+       if (discard <= 0) {     // no digits are being discarded
+               if (dn->lsu != lsu) {   // copy needed
+                       // copy the coefficient array to the result number; no shift needed
+                       count = len;    // avoids D2U
+                       up = lsu;
+                       for (target = dn->lsu; count > 0;
+                            target++, up++, count -= DECDPUN)
+                               *target = *up;
+                       dn->digits = len;       // set the new length
+               }
+               // dn->exponent and residue are unchanged, record any inexactitude
+               if (*residue != 0)
+                       *status |= (DEC_Inexact | DEC_Rounded);
+               return;
+       }
+       // some digits must be discarded ...
+       dn->exponent += discard;        // maintain numerical value
+       *status |= DEC_Rounded; // accumulate Rounded status
+       if (*residue > 1)
+               *residue = 1;   // previous residue now to right, so reduce
+
+       if (discard > len) {    // everything, +1, is being discarded
+               // guard digit is 0
+               // residue is all the number [NB could be all 0s]
+               if (*residue <= 0) {    // not already positive
+                       count = len;    // avoids D2U
+                       for (up = lsu; count > 0; up++, count -= DECDPUN)
+                               if (*up != 0) { // found non-0
+                                       *residue = 1;
+                                       break;  // no need to check any others
+                               }
+               }
+               if (*residue != 0)
+                       *status |= DEC_Inexact; // record inexactitude
+               *dn->lsu = 0;   // coefficient will now be 0
+               dn->digits = 1; // ..
+               return;
+       }                       // total discard
+
+       // partial discard [most common case]
+       // here, at least the first (most significant) discarded digit exists
+
+       // spin up the number, noting residue during the spin, until get to
+       // the Unit with the first discarded digit.  When reach it, extract
+       // it and remember its position
+       count = 0;
+       for (up = lsu;; up++) {
+               count += DECDPUN;
+               if (count >= discard)
+                       break;  // full ones all checked
+               if (*up != 0)
+                       *residue = 1;
+       }                       // up
+
+       // here up -> Unit with first discarded digit
+       cut = discard - (count - DECDPUN) - 1;
+       if (cut == DECDPUN - 1) {       // unit-boundary case (fast)
+               Unit half = (Unit) powers[DECDPUN] >> 1;
+               // set residue directly
+               if (*up >= half) {
+                       if (*up > half)
+                               *residue = 7;
+                       else
+                               *residue += 5;  // add sticky bit
+               } else {        // <half
+                       if (*up != 0)
+                               *residue = 3;   // [else is 0, leave as sticky bit]
+               }
+               if (set->digits <= 0) { // special for Quantize/Subnormal :-(
+                       *dn->lsu = 0;   // .. result is 0
+                       dn->digits = 1; // ..
+               } else {        // shift to least
+                       count = set->digits;    // now digits to end up with
+                       dn->digits = count;     // set the new length
+                       up++;   // move to next
+                       // on unit boundary, so shift-down copy loop is simple
+                       for (target = dn->lsu; count > 0;
+                            target++, up++, count -= DECDPUN)
+                               *target = *up;
+               }
+       }                       // unit-boundary case
+
+       else {                  // discard digit is in low digit(s), and not top digit
+               uInt discard1;  // first discarded digit
+               uInt quot, rem; // for divisions
+               if (cut == 0)
+                       quot = *up;     // is at bottom of unit
+               else {          /* cut>0 */
+                       // it's not at bottom of unit
+#if DECDPUN<=4
+                       quot = QUOT10(*up, cut);
+                       rem = *up - quot * powers[cut];
+#else
+                       rem = *up % powers[cut];
+                       quot = *up / powers[cut];
+#endif
+                       if (rem != 0)
+                               *residue = 1;
+               }
+               // discard digit is now at bottom of quot
+#if DECDPUN<=4
+               temp = (quot * 6554) >> 16;     // fast /10
+               // Vowels algorithm here not a win (9 instructions)
+               discard1 = quot - X10(temp);
+               quot = temp;
+#else
+               discard1 = quot % 10;
+               quot = quot / 10;
+#endif
+               // here, discard1 is the guard digit, and residue is everything
+               // else [use mapping array to accumulate residue safely]
+               *residue += resmap[discard1];
+               cut++;          // update cut
+               // here: up -> Unit of the array with bottom digit
+               //       cut is the division point for each Unit
+               //       quot holds the uncut high-order digits for the current unit
+               if (set->digits <= 0) { // special for Quantize/Subnormal :-(
+                       *dn->lsu = 0;   // .. result is 0
+                       dn->digits = 1; // ..
+               } else {        // shift to least needed
+                       count = set->digits;    // now digits to end up with
+                       dn->digits = count;     // set the new length
+                       // shift-copy the coefficient array to the result number
+                       for (target = dn->lsu;; target++) {
+                               *target = (Unit) quot;
+                               count -= (DECDPUN - cut);
+                               if (count <= 0)
+                                       break;
+                               up++;
+                               quot = *up;
+#if DECDPUN<=4
+                               quot = QUOT10(quot, cut);
+                               rem = *up - quot * powers[cut];
+#else
+                               rem = quot % powers[cut];
+                               quot = quot / powers[cut];
+#endif
+                               *target =
+                                   (Unit) (*target +
+                                           rem * powers[DECDPUN - cut]);
+                               count -= cut;
+                               if (count <= 0)
+                                       break;
+                       }       // shift-copy loop
+               }               // shift to least
+       }                       // not unit boundary
+
+       if (*residue != 0)
+               *status |= DEC_Inexact; // record inexactitude
+       return;
+}                              // decSetCoeff
+
+/* ------------------------------------------------------------------ */
+/* decApplyRound -- apply pending rounding to a number                */
+/*                                                                    */
+/*   dn    is the number, with space for set->digits digits           */
+/*   set   is the context [for size and rounding mode]                */
+/*   residue indicates pending rounding, being any accumulated        */
+/*         guard and sticky information.  It may be:                  */
+/*         6-9: rounding digit is >5                                  */
+/*         5:   rounding digit is exactly half-way                    */
+/*         1-4: rounding digit is <5 and >0                           */
+/*         0:   the coefficient is exact                              */
+/*        -1:   as 1, but the hidden digits are subtractive, that     */
+/*              is, of the opposite sign to dn.  In this case the     */
+/*              coefficient must be non-0.  This case occurs when     */
+/*              subtracting a small number (which can be reduced to   */
+/*              a sticky bit); see decAddOp.                          */
+/*   status is the status accumulator, as usual                       */
+/*                                                                    */
+/* This routine applies rounding while keeping the length of the      */
+/* coefficient constant.  The exponent and status are unchanged       */
+/* except if:                                                         */
+/*                                                                    */
+/*   -- the coefficient was increased and is all nines (in which      */
+/*      case Overflow could occur, and is handled directly here so    */
+/*      the caller does not need to re-test for overflow)             */
+/*                                                                    */
+/*   -- the coefficient was decreased and becomes all nines (in which */
+/*      case Underflow could occur, and is also handled directly).    */
+/*                                                                    */
+/* All fields in dn are updated as required.                          */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+static void decApplyRound(decNumber * dn, decContext * set, Int residue,
+                         uInt * status)
+{
+       Int bump;               // 1 if coefficient needs to be incremented
+       // -1 if coefficient needs to be decremented
+
+       if (residue == 0)
+               return;         // nothing to apply
+
+       bump = 0;               // assume a smooth ride
+
+       // now decide whether, and how, to round, depending on mode
+       switch (set->round) {
+       case DEC_ROUND_05UP:{   // round zero or five up (for reround)
+                       // This is the same as DEC_ROUND_DOWN unless there is a
+                       // positive residue and the lsd of dn is 0 or 5, in which case
+                       // it is bumped; when residue is <0, the number is therefore
+                       // bumped down unless the final digit was 1 or 6 (in which
+                       // case it is bumped down and then up -- a no-op)
+                       Int lsd5 = *dn->lsu % 5;        // get lsd and quintate
+                       if (residue < 0 && lsd5 != 1)
+                               bump = -1;
+                       else if (residue > 0 && lsd5 == 0)
+                               bump = 1;
+                       // [bump==1 could be applied directly; use common path for clarity]
+                       break;
+               }               // r-05
+
+       case DEC_ROUND_DOWN:{
+                       // no change, except if negative residue
+                       if (residue < 0)
+                               bump = -1;
+                       break;
+               }               // r-d
+
+       case DEC_ROUND_HALF_DOWN:{
+                       if (residue > 5)
+                               bump = 1;
+                       break;
+               }               // r-h-d
+
+       case DEC_ROUND_HALF_EVEN:{
+                       if (residue > 5)
+                               bump = 1;       // >0.5 goes up
+                       else if (residue == 5) {        // exactly 0.5000...
+                               // 0.5 goes up iff [new] lsd is odd
+                               if (*dn->lsu & 0x01)
+                                       bump = 1;
+                       }
+                       break;
+               }               // r-h-e
+
+       case DEC_ROUND_HALF_UP:{
+                       if (residue >= 5)
+                               bump = 1;
+                       break;
+               }               // r-h-u
+
+       case DEC_ROUND_UP:{
+                       if (residue > 0)
+                               bump = 1;
+                       break;
+               }               // r-u
+
+       case DEC_ROUND_CEILING:{
+                       // same as _UP for positive numbers, and as _DOWN for negatives
+                       // [negative residue cannot occur on 0]
+                       if (decNumberIsNegative(dn)) {
+                               if (residue < 0)
+                                       bump = -1;
+                       } else {
+                               if (residue > 0)
+                                       bump = 1;
+                       }
+                       break;
+               }               // r-c
+
+       case DEC_ROUND_FLOOR:{
+                       // same as _UP for negative numbers, and as _DOWN for positive
+                       // [negative residue cannot occur on 0]
+                       if (!decNumberIsNegative(dn)) {
+                               if (residue < 0)
+                                       bump = -1;
+                       } else {
+                               if (residue > 0)
+                                       bump = 1;
+                       }
+                       break;
+               }               // r-f
+
+       default:{               // e.g., DEC_ROUND_MAX
+                       *status |= DEC_Invalid_context;
+#if DECTRACE || (DECCHECK && DECVERB)
+                       printf("Unknown rounding mode: %d\n", set->round);
+#endif
+                       break;
+               }
+       }                       // switch
+
+       // now bump the number, up or down, if need be
+       if (bump == 0)
+               return;         // no action required
+
+       // Simply use decUnitAddSub unless bumping up and the number is
+       // all nines.  In this special case set to 100... explicitly
+       // and adjust the exponent by one (as otherwise could overflow
+       // the array)
+       // Similarly handle all-nines result if bumping down.
+       if (bump > 0) {
+               Unit *up;       // work
+               uInt count = dn->digits;        // digits to be checked
+               for (up = dn->lsu;; up++) {
+                       if (count <= DECDPUN) {
+                               // this is the last Unit (the msu)
+                               if (*up != powers[count] - 1)
+                                       break;  // not still 9s
+                               // here if it, too, is all nines
+                               *up = (Unit) powers[count - 1]; // here 999 -> 100 etc.
+                               for (up = up - 1; up >= dn->lsu; up--)
+                                       *up = 0;        // others all to 0
+                               dn->exponent++; // and bump exponent
+                               // [which, very rarely, could cause Overflow...]
+                               if ((dn->exponent + dn->digits) > set->emax + 1) {
+                                       decSetOverflow(dn, set, status);
+                               }
+                               return; // done
+                       }
+                       // a full unit to check, with more to come
+                       if (*up != DECDPUNMAX)
+                               break;  // not still 9s
+                       count -= DECDPUN;
+               }               // up
+       }                       // bump>0
+       else {                  // -1
+               // here checking for a pre-bump of 1000... (leading 1, all
+               // other digits zero)
+               Unit *up, *sup; // work
+               uInt count = dn->digits;        // digits to be checked
+               for (up = dn->lsu;; up++) {
+                       if (count <= DECDPUN) {
+                               // this is the last Unit (the msu)
+                               if (*up != powers[count - 1])
+                                       break;  // not 100..
+                               // here if have the 1000... case
+                               sup = up;       // save msu pointer
+                               *up = (Unit) powers[count] - 1; // here 100 in msu -> 999
+                               // others all to all-nines, too
+                               for (up = up - 1; up >= dn->lsu; up--)
+                                       *up = (Unit) powers[DECDPUN] - 1;
+                               dn->exponent--; // and bump exponent
+
+                               // iff the number was at the subnormal boundary (exponent=etiny)
+                               // then the exponent is now out of range, so it will in fact get
+                               // clamped to etiny and the final 9 dropped.
+                               // printf(">> emin=%d exp=%d sdig=%d\n", set->emin,
+                               //        dn->exponent, set->digits);
+                               if (dn->exponent + 1 ==
+                                   set->emin - set->digits + 1) {
+                                       if (count == 1 && dn->digits == 1)
+                                               *sup = 0;       // here 9 -> 0[.9]
+                                       else {
+                                               *sup = (Unit) powers[count - 1] - 1;    // here 999.. in msu -> 99..
+                                               dn->digits--;
+                                       }
+                                       dn->exponent++;
+                                       *status |=
+                                           DEC_Underflow | DEC_Subnormal |
+                                           DEC_Inexact | DEC_Rounded;
+                               }
+                               return; // done
+                       }
+                       // a full unit to check, with more to come
+                       if (*up != 0)
+                               break;  // not still 0s
+                       count -= DECDPUN;
+               }               // up
+
+       }                       // bump<0
+
+       // Actual bump needed.  Do it.
+       decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
+}                              // decApplyRound
+
+#if DECSUBSET
+/* ------------------------------------------------------------------ */
+/* decFinish -- finish processing a number                            */
+/*                                                                    */
+/*   dn is the number                                                 */
+/*   set is the context                                               */
+/*   residue is the rounding accumulator (as in decApplyRound)        */
+/*   status is the accumulator                                        */
+/*                                                                    */
+/* This finishes off the current number by:                           */
+/*    1. If not extended:                                             */
+/*       a. Converting a zero result to clean '0'                     */
+/*       b. Reducing positive exponents to 0, if would fit in digits  */
+/*    2. Checking for overflow and subnormals (always)                */
+/* Note this is just Finalize when no subset arithmetic.              */
+/* All fields are updated as required.                                */
+/* ------------------------------------------------------------------ */
+static void decFinish(decNumber * dn, decContext * set, Int * residue,
+                     uInt * status)
+{
+       if (!set->extended) {
+               if ISZERO
+                       (dn) {  // value is zero
+                       dn->exponent = 0;       // clean exponent ..
+                       dn->bits = 0;   // .. and sign
+                       return; // no error possible
+                       }
+               if (dn->exponent >= 0) {        // non-negative exponent
+                       // >0; reduce to integer if possible
+                       if (set->digits >= (dn->exponent + dn->digits)) {
+                               dn->digits =
+                                   decShiftToMost(dn->lsu, dn->digits,
+                                                  dn->exponent);
+                               dn->exponent = 0;
+                       }
+               }
+       }                       // !extended
+
+       decFinalize(dn, set, residue, status);
+}                              // decFinish
+#endif
+
+/* ------------------------------------------------------------------ */
+/* decFinalize -- final check, clamp, and round of a number           */
+/*                                                                    */
+/*   dn is the number                                                 */
+/*   set is the context                                               */
+/*   residue is the rounding accumulator (as in decApplyRound)        */
+/*   status is the status accumulator                                 */
+/*                                                                    */
+/* This finishes off the current number by checking for subnormal     */
+/* results, applying any pending rounding, checking for overflow,     */
+/* and applying any clamping.                                         */
+/* Underflow and overflow conditions are raised as appropriate.       */
+/* All fields are updated as required.                                */
+/* ------------------------------------------------------------------ */
+static void decFinalize(decNumber * dn, decContext * set, Int * residue,
+                       uInt * status)
+{
+       Int shift;              // shift needed if clamping
+       Int tinyexp = set->emin - dn->digits + 1;       // precalculate subnormal boundary
+
+       // Must be careful, here, when checking the exponent as the
+       // adjusted exponent could overflow 31 bits [because it may already
+       // be up to twice the expected].
+
+       // First test for subnormal.  This must be done before any final
+       // round as the result could be rounded to Nmin or 0.
+       if (dn->exponent <= tinyexp) {  // prefilter
+               Int comp;
+               decNumber nmin;
+               // A very nasty case here is dn == Nmin and residue<0
+               if (dn->exponent < tinyexp) {
+                       // Go handle subnormals; this will apply round if needed.
+                       decSetSubnormal(dn, set, residue, status);
+                       return;
+               }
+               // Equals case: only subnormal if dn=Nmin and negative residue
+               decNumberZero(&nmin);
+               nmin.lsu[0] = 1;
+               nmin.exponent = set->emin;
+               comp = decCompare(dn, &nmin, 1);        // (signless compare)
+               if (comp == BADINT) {   // oops
+                       *status |= DEC_Insufficient_storage;    // abandon...
+                       return;
+               }
+               if (*residue < 0 && comp == 0) {        // neg residue and dn==Nmin
+                       decApplyRound(dn, set, *residue, status);       // might force down
+                       decSetSubnormal(dn, set, residue, status);
+                       return;
+               }
+       }
+       // now apply any pending round (this could raise overflow).
+       if (*residue != 0)
+               decApplyRound(dn, set, *residue, status);
+
+       // Check for overflow [redundant in the 'rare' case] or clamp
+       if (dn->exponent <= set->emax - set->digits + 1)
+               return;         // neither needed
+
+       // here when might have an overflow or clamp to do
+       if (dn->exponent > set->emax - dn->digits + 1) {        // too big
+               decSetOverflow(dn, set, status);
+               return;
+       }
+       // here when the result is normal but in clamp range
+       if (!set->clamp)
+               return;
+
+       // here when need to apply the IEEE exponent clamp (fold-down)
+       shift = dn->exponent - (set->emax - set->digits + 1);
+
+       // shift coefficient (if non-zero)
+       if (!ISZERO(dn)) {
+               dn->digits = decShiftToMost(dn->lsu, dn->digits, shift);
+       }
+       dn->exponent -= shift;  // adjust the exponent to match
+       *status |= DEC_Clamped; // and record the dirty deed
+       return;
+}                              // decFinalize
+
+/* ------------------------------------------------------------------ */
+/* decSetOverflow -- set number to proper overflow value              */
+/*                                                                    */
+/*   dn is the number (used for sign [only] and result)               */
+/*   set is the context [used for the rounding mode, etc.]            */
+/*   status contains the current status to be updated                 */
+/*                                                                    */
+/* This sets the sign of a number and sets its value to either        */
+/* Infinity or the maximum finite value, depending on the sign of     */
+/* dn and the rounding mode, following IEEE 754 rules.                */
+/* ------------------------------------------------------------------ */
+static void decSetOverflow(decNumber * dn, decContext * set, uInt * status)
+{
+       Flag needmax = 0;       // result is maximum finite value
+       uByte sign = dn->bits & DECNEG; // clean and save sign bit
+
+       if (ISZERO(dn)) {       // zero does not overflow magnitude
+               Int emax = set->emax;   // limit value
+               if (set->clamp)
+                       emax -= set->digits - 1;        // lower if clamping
+               if (dn->exponent > emax) {      // clamp required
+                       dn->exponent = emax;
+                       *status |= DEC_Clamped;
+               }
+               return;
+       }
+
+       decNumberZero(dn);
+       switch (set->round) {
+       case DEC_ROUND_DOWN:{
+                       needmax = 1;    // never Infinity
+                       break;
+               }               // r-d
+       case DEC_ROUND_05UP:{
+                       needmax = 1;    // never Infinity
+                       break;
+               }               // r-05
+       case DEC_ROUND_CEILING:{
+                       if (sign)
+                               needmax = 1;    // Infinity if non-negative
+                       break;
+               }               // r-c
+       case DEC_ROUND_FLOOR:{
+                       if (!sign)
+                               needmax = 1;    // Infinity if negative
+                       break;
+               }               // r-f
+       default:
+               break;          // Infinity in all other cases
+       }
+       if (needmax) {
+               decSetMaxValue(dn, set);
+               dn->bits = sign;        // set sign
+       } else
+               dn->bits = sign | DECINF;       // Value is +/-Infinity
+       *status |= DEC_Overflow | DEC_Inexact | DEC_Rounded;
+}                              // decSetOverflow
+
+/* ------------------------------------------------------------------ */
+/* decSetMaxValue -- set number to +Nmax (maximum normal value)       */
+/*                                                                    */
+/*   dn is the number to set                                          */
+/*   set is the context [used for digits and emax]                    */
+/*                                                                    */
+/* This sets the number to the maximum positive value.                */
+/* ------------------------------------------------------------------ */
+static void decSetMaxValue(decNumber * dn, decContext * set)
+{
+       Unit *up;               // work
+       Int count = set->digits;        // nines to add
+       dn->digits = count;
+       // fill in all nines to set maximum value
+       for (up = dn->lsu;; up++) {
+               if (count > DECDPUN)
+                       *up = DECDPUNMAX;       // unit full o'nines
+               else {          // this is the msu
+                       *up = (Unit) (powers[count] - 1);
+                       break;
+               }
+               count -= DECDPUN;       // filled those digits
+       }                       // up
+       dn->bits = 0;           // + sign
+       dn->exponent = set->emax - set->digits + 1;
+}                              // decSetMaxValue
+
+/* ------------------------------------------------------------------ */
+/* decSetSubnormal -- process value whose exponent is <Emin           */
+/*                                                                    */
+/*   dn is the number (used as input as well as output; it may have   */
+/*         an allowed subnormal value, which may need to be rounded)  */
+/*   set is the context [used for the rounding mode]                  */
+/*   residue is any pending residue                                   */
+/*   status contains the current status to be updated                 */
+/*                                                                    */
+/* If subset mode, set result to zero and set Underflow flags.        */
+/*                                                                    */
+/* Value may be zero with a low exponent; this does not set Subnormal */
+/* but the exponent will be clamped to Etiny.                         */
+/*                                                                    */
+/* Otherwise ensure exponent is not out of range, and round as        */
+/* necessary.  Underflow is set if the result is Inexact.             */
+/* ------------------------------------------------------------------ */
+static void decSetSubnormal(decNumber * dn, decContext * set, Int * residue,
+                           uInt * status)
+{
+       decContext workset;     // work
+       Int etiny, adjust;      // ..
+
+#if DECSUBSET
+       // simple set to zero and 'hard underflow' for subset
+       if (!set->extended) {
+               decNumberZero(dn);
+               // always full overflow
+               *status |=
+                   DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
+               return;
+       }
+#endif
+
+       // Full arithmetic -- allow subnormals, rounded to minimum exponent
+       // (Etiny) if needed
+       etiny = set->emin - (set->digits - 1);  // smallest allowed exponent
+
+       if ISZERO
+               (dn) {          // value is zero
+               // residue can never be non-zero here
+#if DECCHECK
+               if (*residue != 0) {
+                       printf("++ Subnormal 0 residue %ld\n", (LI) * residue);
+                       *status |= DEC_Invalid_operation;
+               }
+#endif
+               if (dn->exponent < etiny) {     // clamp required
+                       dn->exponent = etiny;
+                       *status |= DEC_Clamped;
+               }
+               return;
+               }
+
+       *status |= DEC_Subnormal;       // have a non-zero subnormal
+       adjust = etiny - dn->exponent;  // calculate digits to remove
+       if (adjust <= 0) {      // not out of range; unrounded
+               // residue can never be non-zero here, except in the Nmin-residue
+               // case (which is a subnormal result), so can take fast-path here
+               // it may already be inexact (from setting the coefficient)
+               if (*status & DEC_Inexact)
+                       *status |= DEC_Underflow;
+               return;
+       }
+       // adjust>0, so need to rescale the result so exponent becomes Etiny
+       // [this code is similar to that in rescale]
+       workset = *set;         // clone rounding, etc.
+       workset.digits = dn->digits - adjust;   // set requested length
+       workset.emin -= adjust; // and adjust emin to match
+       // [note that the latter can be <1, here, similar to Rescale case]
+       decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
+       decApplyRound(dn, &workset, *residue, status);
+
+       // Use 754 default rule: Underflow is set iff Inexact
+       // [independent of whether trapped]
+       if (*status & DEC_Inexact)
+               *status |= DEC_Underflow;
+
+       // if rounded up a 999s case, exponent will be off by one; adjust
+       // back if so [it will fit, because it was shortened earlier]
+       if (dn->exponent > etiny) {
+               dn->digits = decShiftToMost(dn->lsu, dn->digits, 1);
+               dn->exponent--; // (re)adjust the exponent.
+       }
+       // if rounded to zero, it is by definition clamped...
+       if (ISZERO(dn))
+               *status |= DEC_Clamped;
+}                              // decSetSubnormal
+
+/* ------------------------------------------------------------------ */
+/* decCheckMath - check entry conditions for a math function          */
+/*                                                                    */
+/*   This checks the context and the operand                          */
+/*                                                                    */
+/*   rhs is the operand to check                                      */
+/*   set is the context to check                                      */
+/*   status is unchanged if both are good                             */
+/*                                                                    */
+/* returns non-zero if status is changed, 0 otherwise                 */
+/*                                                                    */
+/* Restrictions enforced:                                             */
+/*                                                                    */
+/*   digits, emax, and -emin in the context must be less than         */
+/*   DEC_MAX_MATH (999999), and A must be within these bounds if      */
+/*   non-zero.  Invalid_operation is set in the status if a           */
+/*   restriction is violated.                                         */
+/* ------------------------------------------------------------------ */
+static uInt decCheckMath(const decNumber * rhs, decContext * set, uInt * status)
+{
+       uInt save = *status;    // record
+       if (set->digits > DEC_MAX_MATH
+           || set->emax > DEC_MAX_MATH || -set->emin > DEC_MAX_MATH)
+               *status |= DEC_Invalid_context;
+       else if ((rhs->digits > DEC_MAX_MATH
+                 || rhs->exponent + rhs->digits > DEC_MAX_MATH + 1
+                 || rhs->exponent + rhs->digits < 2 * (1 - DEC_MAX_MATH))
+                && !ISZERO(rhs))
+               *status |= DEC_Invalid_operation;
+       return (*status != save);
+}                              // decCheckMath
+
+/* ------------------------------------------------------------------ */
+/* decGetInt -- get integer from a number                             */
+/*                                                                    */
+/*   dn is the number [which will not be altered]                     */
+/*                                                                    */
+/*   returns one of:                                                  */
+/*     BADINT if there is a non-zero fraction                         */
+/*     the converted integer                                          */
+/*     BIGEVEN if the integer is even and magnitude > 2*10**9         */
+/*     BIGODD  if the integer is odd  and magnitude > 2*10**9         */
+/*                                                                    */
+/* This checks and gets a whole number from the input decNumber.      */
+/* The sign can be determined from dn by the caller when BIGEVEN or   */
+/* BIGODD is returned.                                                */
+/* ------------------------------------------------------------------ */
+static Int decGetInt(const decNumber * dn)
+{
+       Int theInt;             // result accumulator
+       const Unit *up;         // work
+       Int got;                // digits (real or not) processed
+       Int ilength = dn->digits + dn->exponent;        // integral length
+       Flag neg = decNumberIsNegative(dn);     // 1 if -ve
+
+       // The number must be an integer that fits in 10 digits
+       // Assert, here, that 10 is enough for any rescale Etiny
+#if DEC_MAX_EMAX > 999999999
+#error GetInt may need updating [for Emax]
+#endif
+#if DEC_MIN_EMIN < -999999999
+#error GetInt may need updating [for Emin]
+#endif
+       if (ISZERO(dn))
+               return 0;       // zeros are OK, with any exponent
+
+       up = dn->lsu;           // ready for lsu
+       theInt = 0;             // ready to accumulate
+       if (dn->exponent >= 0) {        // relatively easy
+               // no fractional part [usual]; allow for positive exponent
+               got = dn->exponent;
+       } else {                // -ve exponent; some fractional part to check and discard
+               Int count = -dn->exponent;      // digits to discard
+               // spin up whole units until reach the Unit with the unit digit
+               for (; count >= DECDPUN; up++) {
+                       if (*up != 0)
+                               return BADINT;  // non-zero Unit to discard
+                       count -= DECDPUN;
+               }
+               if (count == 0)
+                       got = 0;        // [a multiple of DECDPUN]
+               else {          // [not multiple of DECDPUN]
+                       Int rem;        // work
+                       // slice off fraction digits and check for non-zero
+#if DECDPUN<=4
+                       theInt = QUOT10(*up, count);
+                       rem = *up - theInt * powers[count];
+#else
+                       rem = *up % powers[count];      // slice off discards
+                       theInt = *up / powers[count];
+#endif
+                       if (rem != 0)
+                               return BADINT;  // non-zero fraction
+                       // it looks good
+                       got = DECDPUN - count;  // number of digits so far
+                       up++;   // ready for next
+               }
+       }
+       // now it's known there's no fractional part
+
+       // tricky code now, to accumulate up to 9.3 digits
+       if (got == 0) {
+               theInt = *up;
+               got += DECDPUN;
+               up++;
+       }                       // ensure lsu is there
+
+       if (ilength < 11) {
+               Int save = theInt;
+               // collect any remaining unit(s)
+               for (; got < ilength; up++) {
+                       theInt += *up * powers[got];
+                       got += DECDPUN;
+               }
+               if (ilength == 10) {    // need to check for wrap
+                       if (theInt / (Int) powers[got - DECDPUN] !=
+                           (Int) * (up - 1))
+                               ilength = 11;
+                       // [that test also disallows the BADINT result case]
+                       else if (neg && theInt > 1999999997)
+                               ilength = 11;
+                       else if (!neg && theInt > 999999999)
+                               ilength = 11;
+                       if (ilength == 11)
+                               theInt = save;  // restore correct low bit
+               }
+       }
+
+       if (ilength > 10) {     // too big
+               if (theInt & 1)
+                       return BIGODD;  // bottom bit 1
+               return BIGEVEN; // bottom bit 0
+       }
+
+       if (neg)
+               theInt = -theInt;       // apply sign
+       return theInt;
+}                              // decGetInt
+
+/* ------------------------------------------------------------------ */
+/* decDecap -- decapitate the coefficient of a number                 */
+/*                                                                    */
+/*   dn   is the number to be decapitated                             */
+/*   drop is the number of digits to be removed from the left of dn;  */
+/*     this must be <= dn->digits (if equal, the coefficient is       */
+/*     set to 0)                                                      */
+/*                                                                    */
+/* Returns dn; dn->digits will be <= the initial digits less drop     */
+/* (after removing drop digits there may be leading zero digits       */
+/* which will also be removed).  Only dn->lsu and dn->digits change.  */
+/* ------------------------------------------------------------------ */
+static decNumber *decDecap(decNumber * dn, Int drop)
+{
+       Unit *msu;              // -> target cut point
+       Int cut;                // work
+       if (drop >= dn->digits) {       // losing the whole thing
+#if DECCHECK
+               if (drop > dn->digits)
+                       printf("decDecap called with drop>digits [%ld>%ld]\n",
+                              (LI) drop, (LI) dn->digits);
+#endif
+               dn->lsu[0] = 0;
+               dn->digits = 1;
+               return dn;
+       }
+       msu = dn->lsu + D2U(dn->digits - drop) - 1;     // -> likely msu
+       cut = MSUDIGITS(dn->digits - drop);     // digits to be in use in msu
+       if (cut != DECDPUN)
+               *msu %= powers[cut];    // clear left digits
+       // that may have left leading zero digits, so do a proper count...
+       dn->digits = decGetDigits(dn->lsu, msu - dn->lsu + 1);
+       return dn;
+}                              // decDecap
+
+/* ------------------------------------------------------------------ */
+/* decBiStr -- compare string with pairwise options                   */
+/*                                                                    */
+/*   targ is the string to compare                                    */
+/*   str1 is one of the strings to compare against (length may be 0)  */
+/*   str2 is the other; it must be the same length as str1            */
+/*                                                                    */
+/*   returns 1 if strings compare equal, (that is, it is the same     */
+/*   length as str1 and str2, and each character of targ is in either */
+/*   str1 or str2 in the corresponding position), or 0 otherwise      */
+/*                                                                    */
+/* This is used for generic caseless compare, including the awkward   */
+/* case of the Turkish dotted and dotless Is.  Use as (for example):  */
+/*   if (decBiStr(test, "mike", "MIKE")) ...                          */
+/* ------------------------------------------------------------------ */
+static Flag decBiStr(const char *targ, const char *str1, const char *str2)
+{
+       for (;; targ++, str1++, str2++) {
+               if (*targ != *str1 && *targ != *str2)
+                       return 0;
+               // *targ has a match in one (or both, if terminator)
+               if (*targ == '\0')
+                       break;
+       }                       // forever
+       return 1;
+}                              // decBiStr
+
+/* ------------------------------------------------------------------ */
+/* decNaNs -- handle NaN operand or operands                          */
+/*                                                                    */
+/*   res     is the result number                                     */
+/*   lhs     is the first operand                                     */
+/*   rhs     is the second operand, or NULL if none                   */
+/*   context is used to limit payload length                          */
+/*   status  contains the current status                              */
+/*   returns res in case convenient                                   */
+/*                                                                    */
+/* Called when one or both operands is a NaN, and propagates the      */
+/* appropriate result to res.  When an sNaN is found, it is changed   */
+/* to a qNaN and Invalid operation is set.                            */
+/* ------------------------------------------------------------------ */
+static decNumber *decNaNs(decNumber * res, const decNumber * lhs,
+                         const decNumber * rhs, decContext * set,
+                         uInt * status)
+{
+       // This decision tree ends up with LHS being the source pointer,
+       // and status updated if need be
+       if (lhs->bits & DECSNAN)
+               *status |= DEC_Invalid_operation | DEC_sNaN;
+       else if (rhs == NULL) ;
+       else if (rhs->bits & DECSNAN) {
+               lhs = rhs;
+               *status |= DEC_Invalid_operation | DEC_sNaN;
+       } else if (lhs->bits & DECNAN) ;
+       else
+               lhs = rhs;
+
+       // propagate the payload
+       if (lhs->digits <= set->digits)
+               decNumberCopy(res, lhs);        // easy
+       else {                  // too long
+               const Unit *ul;
+               Unit *ur, *uresp1;
+               // copy safe number of units, then decapitate
+               res->bits = lhs->bits;  // need sign etc.
+               uresp1 = res->lsu + D2U(set->digits);
+               for (ur = res->lsu, ul = lhs->lsu; ur < uresp1; ur++, ul++)
+                       *ur = *ul;
+               res->digits = D2U(set->digits) * DECDPUN;
+               // maybe still too long
+               if (res->digits > set->digits)
+                       decDecap(res, res->digits - set->digits);
+       }
+
+       res->bits &= ~DECSNAN;  // convert any sNaN to NaN, while
+       res->bits |= DECNAN;    // .. preserving sign
+       res->exponent = 0;      // clean exponent
+       // [coefficient was copied/decapitated]
+       return res;
+}                              // decNaNs
+
+/* ------------------------------------------------------------------ */
+/* decStatus -- apply non-zero status                                 */
+/*                                                                    */
+/*   dn     is the number to set if error                             */
+/*   status contains the current status (not yet in context)          */
+/*   set    is the context                                            */
+/*                                                                    */
+/* If the status is an error status, the number is set to a NaN,      */
+/* unless the error was an overflow, divide-by-zero, or underflow,    */
+/* in which case the number will have already been set.               */
+/*                                                                    */
+/* The context status is then updated with the new status.  Note that */
+/* this may raise a signal, so control may never return from this     */
+/* routine (hence resources must be recovered before it is called).   */
+/* ------------------------------------------------------------------ */
+static void decStatus(decNumber * dn, uInt status, decContext * set)
+{
+       if (status & DEC_NaNs) {        // error status -> NaN
+               // if cause was an sNaN, clear and propagate [NaN is already set up]
+               if (status & DEC_sNaN)
+                       status &= ~DEC_sNaN;
+               else {
+                       decNumberZero(dn);      // other error: clean throughout
+                       dn->bits = DECNAN;      // and make a quiet NaN
+               }
+       }
+       decContextSetStatus(set, status);       // [may not return]
+       return;
+}                              // decStatus
+
+/* ------------------------------------------------------------------ */
+/* decGetDigits -- count digits in a Units array                      */
+/*                                                                    */
+/*   uar is the Unit array holding the number (this is often an       */
+/*          accumulator of some sort)                                 */
+/*   len is the length of the array in units [>=1]                    */
+/*                                                                    */
+/*   returns the number of (significant) digits in the array          */
+/*                                                                    */
+/* All leading zeros are excluded, except the last if the array has   */
+/* only zero Units.                                                   */
+/* ------------------------------------------------------------------ */
+// This may be called twice during some operations.
+static Int decGetDigits(Unit * uar, Int len)
+{
+       Unit *up = uar + (len - 1);     // -> msu
+       Int digits = (len - 1) * DECDPUN + 1;   // possible digits excluding msu
+#if DECDPUN>4
+       uInt const *pow;        // work
+#endif
+       // (at least 1 in final msu)
+#if DECCHECK
+       if (len < 1)
+               printf("decGetDigits called with len<1 [%ld]\n", (LI) len);
+#endif
+
+       for (; up >= uar; up--) {
+               if (*up == 0) { // unit is all 0s
+                       if (digits == 1)
+                               break;  // a zero has one digit
+                       digits -= DECDPUN;      // adjust for 0 unit
+                       continue;
+               }
+               // found the first (most significant) non-zero Unit
+#if DECDPUN>1                  // not done yet
+               if (*up < 10)
+                       break;  // is 1-9
+               digits++;
+#if DECDPUN>2                  // not done yet
+               if (*up < 100)
+                       break;  // is 10-99
+               digits++;
+#if DECDPUN>3                  // not done yet
+               if (*up < 1000)
+                       break;  // is 100-999
+               digits++;
+#if DECDPUN>4                  // count the rest ...
+               for (pow = &powers[4]; *up >= *pow; pow++)
+                       digits++;
+#endif
+#endif
+#endif
+#endif
+               break;
+       }                       // up
+       return digits;
+}                              // decGetDigits
+
+#if DECTRACE | DECCHECK
+/* ------------------------------------------------------------------ */
+/* decNumberShow -- display a number [debug aid]                      */
+/*   dn is the number to show                                         */
+/*                                                                    */
+/* Shows: sign, exponent, coefficient (msu first), digits             */
+/*    or: sign, special-value                                         */
+/* ------------------------------------------------------------------ */
+// this is public so other modules can use it
+void decNumberShow(const decNumber * dn)
+{
+       const Unit *up;         // work
+       uInt u, d;              // ..
+       Int cut;                // ..
+       char isign = '+';       // main sign
+       if (dn == NULL) {
+               printf("NULL\n");
+               return;
+       }
+       if (decNumberIsNegative(dn))
+               isign = '-';
+       printf(" >> %c ", isign);
+       if (dn->bits & DECSPECIAL) {    // Is a special value
+               if (decNumberIsInfinite(dn))
+                       printf("Infinity");
+               else {          // a NaN
+                       if (dn->bits & DECSNAN)
+                               printf("sNaN"); // signalling NaN
+                       else
+                               printf("NaN");
+               }
+               // if coefficient and exponent are 0, no more to do
+               if (dn->exponent == 0 && dn->digits == 1 && *dn->lsu == 0) {
+                       printf("\n");
+                       return;
+               }
+               // drop through to report other information
+               printf(" ");
+       }
+       // now carefully display the coefficient
+       up = dn->lsu + D2U(dn->digits) - 1;     // msu
+       printf("%ld", (LI) * up);
+       for (up = up - 1; up >= dn->lsu; up--) {
+               u = *up;
+               printf(":");
+               for (cut = DECDPUN - 1; cut >= 0; cut--) {
+                       d = u / powers[cut];
+                       u -= d * powers[cut];
+                       printf("%ld", (LI) d);
+               }               // cut
+       }                       // up
+       if (dn->exponent != 0) {
+               char esign = '+';
+               if (dn->exponent < 0)
+                       esign = '-';
+               printf(" E%c%ld", esign, (LI) abs(dn->exponent));
+       }
+       printf(" [%ld]\n", (LI) dn->digits);
+}                              // decNumberShow
+#endif
+
+#if DECTRACE || DECCHECK
+/* ------------------------------------------------------------------ */
+/* decDumpAr -- display a unit array [debug/check aid]                */
+/*   name is a single-character tag name                              */
+/*   ar   is the array to display                                     */
+/*   len  is the length of the array in Units                         */
+/* ------------------------------------------------------------------ */
+static void decDumpAr(char name, const Unit * ar, Int len)
+{
+       Int i;
+       const char *spec;
+#if DECDPUN==9
+       spec = "%09d ";
+#elif DECDPUN==8
+       spec = "%08d ";
+#elif DECDPUN==7
+       spec = "%07d ";
+#elif DECDPUN==6
+       spec = "%06d ";
+#elif DECDPUN==5
+       spec = "%05d ";
+#elif DECDPUN==4
+       spec = "%04d ";
+#elif DECDPUN==3
+       spec = "%03d ";
+#elif DECDPUN==2
+       spec = "%02d ";
+#else
+       spec = "%d ";
+#endif
+       printf("  :%c: ", name);
+       for (i = len - 1; i >= 0; i--) {
+               if (i == len - 1)
+                       printf("%ld ", (LI) ar[i]);
+               else
+                       printf(spec, ar[i]);
+       }
+       printf("\n");
+       return;
+}
+#endif
+
+#if DECCHECK
+/* ------------------------------------------------------------------ */
+/* decCheckOperands -- check operand(s) to a routine                  */
+/*   res is the result structure (not checked; it will be set to      */
+/*          quiet NaN if error found (and it is not NULL))            */
+/*   lhs is the first operand (may be DECUNRESU)                      */
+/*   rhs is the second (may be DECUNUSED)                             */
+/*   set is the context (may be DECUNCONT)                            */
+/*   returns 0 if both operands, and the context are clean, or 1      */
+/*     otherwise (in which case the context will show an error,       */
+/*     unless NULL).  Note that res is not cleaned; caller should     */
+/*     handle this so res=NULL case is safe.                          */
+/* The caller is expected to abandon immediately if 1 is returned.    */
+/* ------------------------------------------------------------------ */
+static Flag decCheckOperands(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs, decContext * set)
+{
+       Flag bad = 0;
+       if (set == NULL) {      // oops; hopeless
+#if DECTRACE || DECVERB
+               printf("Reference to context is NULL.\n");
+#endif
+               bad = 1;
+               return 1;
+       } else if (set != DECUNCONT
+                  && (set->digits < 1 || set->round >= DEC_ROUND_MAX)) {
+               bad = 1;
+#if DECTRACE || DECVERB
+               printf("Bad context [digits=%ld round=%ld].\n",
+                      (LI) set->digits, (LI) set->round);
+#endif
+       } else {
+               if (res == NULL) {
+                       bad = 1;
+#if DECTRACE
+                       // this one not DECVERB as standard tests include NULL
+                       printf("Reference to result is NULL.\n");
+#endif
+               }
+               if (!bad && lhs != DECUNUSED)
+                       bad = (decCheckNumber(lhs));
+               if (!bad && rhs != DECUNUSED)
+                       bad = (decCheckNumber(rhs));
+       }
+       if (bad) {
+               if (set != DECUNCONT)
+                       decContextSetStatus(set, DEC_Invalid_operation);
+               if (res != DECUNRESU && res != NULL) {
+                       decNumberZero(res);
+                       res->bits = DECNAN;     // qNaN
+               }
+       }
+       return bad;
+}                              // decCheckOperands
+
+/* ------------------------------------------------------------------ */
+/* decCheckNumber -- check a number                                   */
+/*   dn is the number to check                                        */
+/*   returns 0 if the number is clean, or 1 otherwise                 */
+/*                                                                    */
+/* The number is considered valid if it could be a result from some   */
+/* operation in some valid context.                                   */
+/* ------------------------------------------------------------------ */
+static Flag decCheckNumber(const decNumber * dn)
+{
+       const Unit *up;         // work
+       uInt maxuint;           // ..
+       Int ae, d, digits;      // ..
+       Int emin, emax;         // ..
+
+       if (dn == NULL) {       // hopeless
+#if DECTRACE
+               // this one not DECVERB as standard tests include NULL
+               printf("Reference to decNumber is NULL.\n");
+#endif
+               return 1;
+       }
+       // check special values
+       if (dn->bits & DECSPECIAL) {
+               if (dn->exponent != 0) {
+#if DECTRACE || DECVERB
+                       printf
+                           ("Exponent %ld (not 0) for a special value [%02x].\n",
+                            (LI) dn->exponent, dn->bits);
+#endif
+                       return 1;
+               }
+               // 2003.09.08: NaNs may now have coefficients, so next tests Inf only
+               if (decNumberIsInfinite(dn)) {
+                       if (dn->digits != 1) {
+#if DECTRACE || DECVERB
+                               printf("Digits %ld (not 1) for an infinity.\n",
+                                      (LI) dn->digits);
+#endif
+                               return 1;
+                       }
+                       if (*dn->lsu != 0) {
+#if DECTRACE || DECVERB
+                               printf("LSU %ld (not 0) for an infinity.\n",
+                                      (LI) * dn->lsu);
+#endif
+                               decDumpAr('I', dn->lsu, D2U(dn->digits));
+                               return 1;
+                       }
+               }               // Inf
+               // 2002.12.26: negative NaNs can now appear through proposed IEEE
+               //             concrete formats (decimal64, etc.).
+               return 0;
+       }
+       // check the coefficient
+       if (dn->digits < 1 || dn->digits > DECNUMMAXP) {
+#if DECTRACE || DECVERB
+               printf("Digits %ld in number.\n", (LI) dn->digits);
+#endif
+               return 1;
+       }
+
+       d = dn->digits;
+
+       for (up = dn->lsu; d > 0; up++) {
+               if (d > DECDPUN)
+                       maxuint = DECDPUNMAX;
+               else {          // reached the msu
+                       maxuint = powers[d] - 1;
+                       if (dn->digits > 1 && *up < powers[d - 1]) {
+#if DECTRACE || DECVERB
+                               printf("Leading 0 in number.\n");
+                               decNumberShow(dn);
+#endif
+                               return 1;
+                       }
+               }
+               if (*up > maxuint) {
+#if DECTRACE || DECVERB
+                       printf
+                           ("Bad Unit [%08lx] in %ld-digit number at offset %ld [maxuint %ld].\n",
+                            (LI) * up, (LI) dn->digits, (LI) (up - dn->lsu),
+                            (LI) maxuint);
+#endif
+                       return 1;
+               }
+               d -= DECDPUN;
+       }
+
+       // check the exponent.  Note that input operands can have exponents
+       // which are out of the set->emin/set->emax and set->digits range
+       // (just as they can have more digits than set->digits).
+       ae = dn->exponent + dn->digits - 1;     // adjusted exponent
+       emax = DECNUMMAXE;
+       emin = DECNUMMINE;
+       digits = DECNUMMAXP;
+       if (ae < emin - (digits - 1)) {
+#if DECTRACE || DECVERB
+               printf("Adjusted exponent underflow [%ld].\n", (LI) ae);
+               decNumberShow(dn);
+#endif
+               return 1;
+       }
+       if (ae > +emax) {
+#if DECTRACE || DECVERB
+               printf("Adjusted exponent overflow [%ld].\n", (LI) ae);
+               decNumberShow(dn);
+#endif
+               return 1;
+       }
+
+       return 0;               // it's OK
+}                              // decCheckNumber
+
+/* ------------------------------------------------------------------ */
+/* decCheckInexact -- check a normal finite inexact result has digits */
+/*   dn is the number to check                                        */
+/*   set is the context (for status and precision)                    */
+/*   sets Invalid operation, etc., if some digits are missing         */
+/* [this check is not made for DECSUBSET compilation or when          */
+/* subnormal is not set]                                              */
+/* ------------------------------------------------------------------ */
+static void decCheckInexact(const decNumber * dn, decContext * set)
+{
+#if !DECSUBSET && DECEXTFLAG
+       if ((set->status & (DEC_Inexact | DEC_Subnormal)) == DEC_Inexact
+           && (set->digits != dn->digits) && !(dn->bits & DECSPECIAL)) {
+#if DECTRACE || DECVERB
+               printf("Insufficient digits [%ld] on normal Inexact result.\n",
+                      (LI) dn->digits);
+               decNumberShow(dn);
+#endif
+               decContextSetStatus(set, DEC_Invalid_operation);
+       }
+#else
+       // next is a noop for quiet compiler
+       if (dn != NULL && dn->digits == 0)
+               set->status |= DEC_Invalid_operation;
+#endif
+       return;
+}                              // decCheckInexact
+#endif
+
+#if DECALLOC
+#undef malloc
+#undef free
+/* ------------------------------------------------------------------ */
+/* decMalloc -- accountable allocation routine                        */
+/*   n is the number of bytes to allocate                             */
+/*                                                                    */
+/* Semantics is the same as the stdlib malloc routine, but bytes      */
+/* allocated are accounted for globally, and corruption fences are    */
+/* added before and after the 'actual' storage.                       */
+/* ------------------------------------------------------------------ */
+/* This routine allocates storage with an extra twelve bytes; 8 are   */
+/* at the start and hold:                                             */
+/*   0-3 the original length requested                                */
+/*   4-7 buffer corruption detection fence (DECFENCE, x4)             */
+/* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */
+/* ------------------------------------------------------------------ */
+static void *decMalloc(size_t n)
+{
+       uInt size = n + 12;     // true size
+       void *alloc;            // -> allocated storage
+       uByte *b, *b0;          // work
+       uInt uiwork;            // for macros
+
+       alloc = malloc(size);   // -> allocated storage
+       if (alloc == NULL)
+               return NULL;    // out of strorage
+       b0 = (uByte *) alloc;   // as bytes
+       decAllocBytes += n;     // account for storage
+       UBFROMUI(alloc, n);     // save n
+       // printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n);
+       for (b = b0 + 4; b < b0 + 8; b++)
+               *b = DECFENCE;
+       for (b = b0 + n + 8; b < b0 + n + 12; b++)
+               *b = DECFENCE;
+       return b0 + 8;          // -> play area
+}                              // decMalloc
+
+/* ------------------------------------------------------------------ */
+/* decFree -- accountable free routine                                */
+/*   alloc is the storage to free                                     */
+/*                                                                    */
+/* Semantics is the same as the stdlib malloc routine, except that    */
+/* the global storage accounting is updated and the fences are        */
+/* checked to ensure that no routine has written 'out of bounds'.     */
+/* ------------------------------------------------------------------ */
+/* This routine first checks that the fences have not been corrupted. */
+/* It then frees the storage using the 'truw' storage address (that   */
+/* is, offset by 8).                                                  */
+/* ------------------------------------------------------------------ */
+static void decFree(void *alloc)
+{
+       uInt n;                 // original length
+       uByte *b, *b0;          // work
+       uInt uiwork;            // for macros
+
+       if (alloc == NULL)
+               return;         // allowed; it's a nop
+       b0 = (uByte *) alloc;   // as bytes
+       b0 -= 8;                // -> true start of storage
+       n = UBTOUI(b0);         // lift length
+       for (b = b0 + 4; b < b0 + 8; b++)
+               if (*b != DECFENCE)
+                       printf
+                           ("=== Corrupt byte [%02x] at offset %d from %ld ===\n",
+                            *b, b - b0 - 8, (LI) b0);
+       for (b = b0 + n + 8; b < b0 + n + 12; b++)
+               if (*b != DECFENCE)
+                       printf
+                           ("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n",
+                            *b, b - b0 - 8, (LI) b0, (LI) n);
+       free(b0);               // drop the storage
+       decAllocBytes -= n;     // account for storage
+       // printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n);
+}                              // decFree
+
+#define malloc(a) decMalloc(a)
+#define free(a) decFree(a)
+#endif
diff --git a/src/decnumber/decNumber.h b/src/decnumber/decNumber.h
new file mode 100644 (file)
index 0000000..cf0975d
--- /dev/null
@@ -0,0 +1,210 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Number arithmetic module header                            */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2010.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+
+#if !defined(DECNUMBER)
+#define DECNUMBER
+#define DECNAME     "decNumber"        /* Short name */
+#define DECFULLNAME "Decimal Number Module"    /* Verbose name */
+#define DECAUTHOR   "Mike Cowlishaw"   /* Who to blame */
+
+#if !defined(DECCONTEXT)
+#include "decContext.h"
+#endif
+
+  /* Bit settings for decNumber.bits                                  */
+#define DECNEG    0x80         /* Sign; 1=negative, 0=positive or zero */
+#define DECINF    0x40         /* 1=Infinity                           */
+#define DECNAN    0x20         /* 1=NaN                                */
+#define DECSNAN   0x10         /* 1=sNaN                               */
+  /* The remaining bits are reserved; they must be 0                  */
+#define DECSPECIAL (DECINF|DECNAN|DECSNAN)     /* any special value     */
+
+  /* Define the decNumber data structure.  The size and shape of the  */
+  /* units array in the structure is determined by the following      */
+  /* constant.  This must not be changed without recompiling the      */
+  /* decNumber library modules. */
+
+#define DECDPUN 3              /* DECimal Digits Per UNit [must be >0  */
+                             /* and <10; 3 or powers of 2 are best]. */
+
+  /* DECNUMDIGITS is the default number of digits that can be held in */
+  /* the structure.  If undefined, 1 is assumed and it is assumed     */
+  /* that the structure will be immediately followed by extra space,  */
+  /* as required.  DECNUMDIGITS is always >0.                         */
+#if !defined(DECNUMDIGITS)
+#define DECNUMDIGITS 1
+#endif
+
+  /* The size (integer data type) of each unit is determined by the   */
+  /* number of digits it will hold.                                   */
+#if   DECDPUN<=2
+#define decNumberUnit uint8_t
+#elif DECDPUN<=4
+#define decNumberUnit uint16_t
+#else
+#define decNumberUnit uint32_t
+#endif
+  /* The number of units needed is ceil(DECNUMDIGITS/DECDPUN)         */
+#define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)
+
+  /* The data structure... */
+typedef struct {
+       int32_t digits;         /* Count of digits in the coefficient; >0    */
+       int32_t exponent;       /* Unadjusted exponent, unbiased, in         */
+       /* range: -1999999997 through 999999999      */
+       uint8_t bits;           /* Indicator bits (see above)                */
+       /* Coefficient, from least significant unit  */
+       decNumberUnit lsu[DECNUMUNITS];
+} decNumber;
+
+  /* Notes:                                                           */
+  /* 1. If digits is > DECDPUN then there will one or more            */
+  /*    decNumberUnits immediately following the first element of lsu. */
+  /*    These contain the remaining (more significant) digits of the  */
+  /*    number, and may be in the lsu array, or may be guaranteed by  */
+  /*    some other mechanism (such as being contained in another      */
+  /*    structure, or being overlaid on dynamically allocated         */
+  /*    storage).                                                     */
+  /*                                                                  */
+  /*    Each integer of the coefficient (except potentially the last) */
+  /*    contains DECDPUN digits (e.g., a value in the range 0 through */
+  /*    99999999 if DECDPUN is 8, or 0 through 999 if DECDPUN is 3).  */
+  /*                                                                  */
+  /* 2. A decNumber converted to a string may need up to digits+14    */
+  /*    characters.  The worst cases (non-exponential and exponential */
+  /*    formats) are -0.00000{9...}# and -9.{9...}E+999999999#        */
+  /*    (where # is '\0')                                             */
+
+  /* ---------------------------------------------------------------- */
+  /* decNumber public functions and macros                            */
+  /* ---------------------------------------------------------------- */
+  /* Conversions                                                      */
+decNumber *decNumberFromInt32(decNumber *, int32_t);
+decNumber *decNumberFromUInt32(decNumber *, uint32_t);
+decNumber *decNumberFromString(decNumber *, const char *, decContext *);
+char *decNumberToString(const decNumber *, char *);
+char *decNumberToEngString(const decNumber *, char *);
+uint32_t decNumberToUInt32(const decNumber *, decContext *);
+int32_t decNumberToInt32(const decNumber *, decContext *);
+uint8_t *decNumberGetBCD(const decNumber *, uint8_t *);
+decNumber *decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
+
+  /* Operators and elementary functions                               */
+decNumber *decNumberAbs(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberAdd(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+decNumber *decNumberAnd(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+decNumber *decNumberCompare(decNumber *, const decNumber *, const decNumber *,
+                           decContext *);
+decNumber *decNumberCompareSignal(decNumber *, const decNumber *,
+                                 const decNumber *, decContext *);
+decNumber *decNumberCompareTotal(decNumber *, const decNumber *,
+                                const decNumber *, decContext *);
+decNumber *decNumberCompareTotalMag(decNumber *, const decNumber *,
+                                   const decNumber *, decContext *);
+decNumber *decNumberDivide(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberDivideInteger(decNumber *, const decNumber *,
+                                 const decNumber *, decContext *);
+decNumber *decNumberExp(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberFMA(decNumber *, const decNumber *, const decNumber *,
+                       const decNumber *, decContext *);
+decNumber *decNumberInvert(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberLn(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberLogB(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberLog10(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberMax(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+decNumber *decNumberMaxMag(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberMin(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+decNumber *decNumberMinMag(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberMinus(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberMultiply(decNumber *, const decNumber *, const decNumber *,
+                            decContext *);
+decNumber *decNumberNormalize(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberOr(decNumber *, const decNumber *, const decNumber *,
+                      decContext *);
+decNumber *decNumberPlus(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberPower(decNumber *, const decNumber *, const decNumber *,
+                         decContext *);
+decNumber *decNumberQuantize(decNumber *, const decNumber *, const decNumber *,
+                            decContext *);
+decNumber *decNumberReduce(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberRemainder(decNumber *, const decNumber *, const decNumber *,
+                             decContext *);
+decNumber *decNumberRemainderNear(decNumber *, const decNumber *,
+                                 const decNumber *, decContext *);
+decNumber *decNumberRescale(decNumber *, const decNumber *, const decNumber *,
+                           decContext *);
+decNumber *decNumberRotate(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberSameQuantum(decNumber *, const decNumber *,
+                               const decNumber *);
+decNumber *decNumberScaleB(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberShift(decNumber *, const decNumber *, const decNumber *,
+                         decContext *);
+decNumber *decNumberSquareRoot(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberSubtract(decNumber *, const decNumber *, const decNumber *,
+                            decContext *);
+decNumber *decNumberToIntegralExact(decNumber *, const decNumber *,
+                                   decContext *);
+decNumber *decNumberToIntegralValue(decNumber *, const decNumber *,
+                                   decContext *);
+decNumber *decNumberXor(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+
+  /* Utilities                                                        */
+enum decClass decNumberClass(const decNumber *, decContext *);
+const char *decNumberClassToString(enum decClass);
+decNumber *decNumberCopy(decNumber *, const decNumber *);
+decNumber *decNumberCopyAbs(decNumber *, const decNumber *);
+decNumber *decNumberCopyNegate(decNumber *, const decNumber *);
+decNumber *decNumberCopySign(decNumber *, const decNumber *, const decNumber *);
+decNumber *decNumberNextMinus(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberNextPlus(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberNextToward(decNumber *, const decNumber *,
+                              const decNumber *, decContext *);
+decNumber *decNumberTrim(decNumber *);
+const char *decNumberVersion(void);
+decNumber *decNumberZero(decNumber *);
+
+  /* Functions for testing decNumbers (normality depends on context)  */
+int32_t decNumberIsNormal(const decNumber *, decContext *);
+int32_t decNumberIsSubnormal(const decNumber *, decContext *);
+
+  /* Macros for testing decNumber *dn                                 */
+#define decNumberIsCanonical(dn) (1)   /* All decNumbers are saintly */
+#define decNumberIsFinite(dn)    (((dn)->bits&DECSPECIAL)==0)
+#define decNumberIsInfinite(dn)  (((dn)->bits&DECINF)!=0)
+#define decNumberIsNaN(dn)       (((dn)->bits&(DECNAN|DECSNAN))!=0)
+#define decNumberIsNegative(dn)  (((dn)->bits&DECNEG)!=0)
+#define decNumberIsQNaN(dn)      (((dn)->bits&(DECNAN))!=0)
+#define decNumberIsSNaN(dn)      (((dn)->bits&(DECSNAN))!=0)
+#define decNumberIsSpecial(dn)   (((dn)->bits&DECSPECIAL)!=0)
+#define decNumberIsZero(dn)      (*(dn)->lsu==0 \
+                                    && (dn)->digits==1 \
+                                    && (((dn)->bits&DECSPECIAL)==0))
+#define decNumberRadix(dn)       (10)
+
+#endif
diff --git a/src/decnumber/decNumberLocal.h b/src/decnumber/decNumberLocal.h
new file mode 100644 (file)
index 0000000..00146ec
--- /dev/null
@@ -0,0 +1,753 @@
+/* ------------------------------------------------------------------ */
+/* decNumber package local type, tuning, and macro definitions        */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2010.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+/* This header file is included by all modules in the decNumber       */
+/* library, and contains local type definitions, tuning parameters,   */
+/* etc.  It should not need to be used by application programs.       */
+/* decNumber.h or one of decDouble (etc.) must be included first.     */
+/* ------------------------------------------------------------------ */
+
+#if !defined(DECNUMBERLOC)
+#define DECNUMBERLOC
+#define DECVERSION    "decNumber 3.68" /* Package Version [16 max.] */
+#define DECNLAUTHOR   "Mike Cowlishaw" /* Who to blame */
+
+#include <stdlib.h>            /* for abs                              */
+#include <string.h>            /* for memset, strcpy                   */
+
+  /* Conditional code flag -- set this to match hardware platform     */
+#if !defined(DECLITEND)
+#define DECLITEND 1            /* 1=little-endian, 0=big-endian        */
+#endif
+
+  /* Conditional code flag -- set this to 1 for best performance      */
+#if !defined(DECUSE64)
+#define DECUSE64  1            /* 1=use int64s, 0=int32 & smaller only */
+#endif
+
+  /* Conditional code flag -- set this to 0 to exclude printf calls   */
+#if !defined(DECPRINT)
+#define DECPRINT  1            /* 1=allow printf calls; 0=no printf    */
+#endif
+
+  /* Conditional check flags -- set these to 0 for best performance   */
+#if !defined(DECCHECK)
+#define DECCHECK  0            /* 1 to enable robust checking          */
+#endif
+#if !defined(DECALLOC)
+#define DECALLOC  0            /* 1 to enable memory accounting        */
+#endif
+#if !defined(DECTRACE)
+#define DECTRACE  0            /* 1 to trace certain internals, etc.   */
+#endif
+
+  /* Tuning parameter for decNumber (arbitrary precision) module      */
+#if !defined(DECBUFFER)
+#define DECBUFFER 36           /* Size basis for local buffers.  This  */
+                             /* should be a common maximum precision */
+                             /* rounded up to a multiple of 4; must  */
+                             /* be zero or positive.                 */
+#endif
+
+  /* ---------------------------------------------------------------- */
+  /* Check parameter dependencies                                     */
+  /* ---------------------------------------------------------------- */
+#if DECCHECK & !DECPRINT
+#error DECCHECK needs DECPRINT to be useful
+#endif
+#if DECALLOC & !DECPRINT
+#error DECALLOC needs DECPRINT to be useful
+#endif
+#if DECTRACE & !DECPRINT
+#error DECTRACE needs DECPRINT to be useful
+#endif
+
+  /* ---------------------------------------------------------------- */
+  /* Definitions for all modules (general-purpose)                    */
+  /* ---------------------------------------------------------------- */
+
+  /* Local names for common types -- for safety, decNumber modules do */
+  /* not use int or long directly.                                    */
+#define Flag   uint8_t
+#define Byte   int8_t
+#define uByte  uint8_t
+#define Short  int16_t
+#define uShort uint16_t
+#define Int    int32_t
+#define uInt   uint32_t
+#define Unit   decNumberUnit
+#if DECUSE64
+#define Long   int64_t
+#define uLong  uint64_t
+#endif
+
+  /* Development-use definitions                                      */
+typedef long int LI;           /* for printf arguments only            */
+#define DECNOINT  0            /* 1 to check no internal use of 'int'  */
+                             /*   or stdint types                    */
+#if DECNOINT
+    /* if these interfere with your C includes, do not set DECNOINT   */
+#define int     ?              /* enable to ensure that plain C 'int'  */
+#define long    ??             /* .. or 'long' types are not used      */
+#endif
+
+  /* Shared lookup tables                                             */
+extern const uByte DECSTICKYTAB[10];   /* re-round digits if sticky  */
+extern const uInt DECPOWERS[10];       /* powers of ten table        */
+  /* The following are included from decDPD.h                         */
+extern const uShort DPD2BIN[1024];     /* DPD -> 0-999               */
+extern const uShort BIN2DPD[1000];     /* 0-999 -> DPD               */
+extern const uInt DPD2BINK[1024];      /* DPD -> 0-999000            */
+extern const uInt DPD2BINM[1024];      /* DPD -> 0-999000000         */
+extern const uByte DPD2BCD8[4096];     /* DPD -> ddd + len           */
+extern const uByte BIN2BCD8[4000];     /* 0-999 -> ddd + len         */
+extern const uShort BCD2DPD[2458];     /* 0-0x999 -> DPD (0x999=2457) */
+
+  /* LONGMUL32HI -- set w=(u*v)>>32, where w, u, and v are uInts      */
+  /* (that is, sets w to be the high-order word of the 64-bit result; */
+  /* the low-order word is simply u*v.)                               */
+  /* This version is derived from Knuth via Hacker's Delight;         */
+  /* it seems to optimize better than some others tried               */
+#define LONGMUL32HI(w, u, v) {             \
+    uInt u0, u1, v0, v1, w0, w1, w2, t;      \
+    u0=u & 0xffff; u1=u>>16;                 \
+    v0=v & 0xffff; v1=v>>16;                 \
+    w0=u0*v0;                                \
+    t=u1*v0 + (w0>>16);                      \
+    w1=t & 0xffff; w2=t>>16;                 \
+    w1=u0*v1 + w1;                           \
+    (w)=u1*v1 + w2 + (w1>>16);}
+
+  /* ROUNDUP -- round an integer up to a multiple of n                */
+#define ROUNDUP(i, n) ((((i)+(n)-1)/n)*n)
+#define ROUNDUP4(i)   (((i)+3)&~3)     /* special for n=4            */
+
+  /* ROUNDDOWN -- round an integer down to a multiple of n            */
+#define ROUNDDOWN(i, n) (((i)/n)*n)
+#define ROUNDDOWN4(i)   ((i)&~3)       /* special for n=4            */
+
+  /* References to multi-byte sequences under different sizes; these  */
+  /* require locally declared variables, but do not violate strict    */
+  /* aliasing or alignment (as did the UINTAT simple cast to uInt).   */
+  /* Variables needed are uswork, uiwork, etc. [so do not use at same */
+  /* level in an expression, e.g., UBTOUI(x)==UBTOUI(y) may fail].    */
+
+  /* Return a uInt, etc., from bytes starting at a char* or uByte*    */
+#define UBTOUS(b)  (memcpy((void *)&uswork, b, 2), uswork)
+#define UBTOUI(b)  (memcpy((void *)&uiwork, b, 4), uiwork)
+
+  /* Store a uInt, etc., into bytes starting at a char* or uByte*.    */
+  /* Returns i, evaluated, for convenience; has to use uiwork because */
+  /* i may be an expression.                                          */
+#define UBFROMUS(b, i)  (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork)
+#define UBFROMUI(b, i)  (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork)
+
+  /* X10 and X100 -- multiply integer i by 10 or 100                  */
+  /* [shifts are usually faster than multiply; could be conditional]  */
+#define X10(i)  (((i)<<1)+((i)<<3))
+#define X100(i) (((i)<<2)+((i)<<5)+((i)<<6))
+
+  /* MAXI and MINI -- general max & min (not in ANSI) for integers    */
+#define MAXI(x,y) ((x)<(y)?(y):(x))
+#define MINI(x,y) ((x)>(y)?(y):(x))
+
+  /* Useful constants                                                 */
+#define BILLION      1000000000        /* 10**9                 */
+  /* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC       */
+#define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')
+
+  /* ---------------------------------------------------------------- */
+  /* Definitions for arbitary-precision modules (only valid after     */
+  /* decNumber.h has been included)                                   */
+  /* ---------------------------------------------------------------- */
+
+  /* Limits and constants                                             */
+#define DECNUMMAXP 999999999   /* maximum precision code can handle  */
+#define DECNUMMAXE 999999999   /* maximum adjusted exponent ditto    */
+#define DECNUMMINE -999999999  /* minimum adjusted exponent ditto    */
+#if (DECNUMMAXP != DEC_MAX_DIGITS)
+#error Maximum digits mismatch
+#endif
+#if (DECNUMMAXE != DEC_MAX_EMAX)
+#error Maximum exponent mismatch
+#endif
+#if (DECNUMMINE != DEC_MIN_EMIN)
+#error Minimum exponent mismatch
+#endif
+
+  /* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN       */
+  /* digits, and D2UTABLE -- the initializer for the D2U table        */
+#if   DECDPUN==1
+#define DECDPUNMAX 9
+#define D2UTABLE {0,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}
+#elif DECDPUN==2
+#define DECDPUNMAX 99
+#define D2UTABLE {0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,  \
+                      11,11,12,12,13,13,14,14,15,15,16,16,17,17,18, \
+                      18,19,19,20,20,21,21,22,22,23,23,24,24,25}
+#elif DECDPUN==3
+#define DECDPUNMAX 999
+#define D2UTABLE {0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,  \
+                      8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13, \
+                      13,14,14,14,15,15,15,16,16,16,17}
+#elif DECDPUN==4
+#define DECDPUNMAX 9999
+#define D2UTABLE {0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,  \
+                      6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11, \
+                      11,11,11,12,12,12,12,13}
+#elif DECDPUN==5
+#define DECDPUNMAX 99999
+#define D2UTABLE {0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,  \
+                      5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,  \
+                      9,9,10,10,10,10}
+#elif DECDPUN==6
+#define DECDPUNMAX 999999
+#define D2UTABLE {0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,  \
+                      4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,  \
+                      8,8,8,8,8,9}
+#elif DECDPUN==7
+#define DECDPUNMAX 9999999
+#define D2UTABLE {0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,  \
+                      4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,  \
+                      7,7,7,7,7,7}
+#elif DECDPUN==8
+#define DECDPUNMAX 99999999
+#define D2UTABLE {0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,  \
+                      3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,  \
+                      6,6,6,6,6,7}
+#elif DECDPUN==9
+#define DECDPUNMAX 999999999
+#define D2UTABLE {0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,  \
+                      3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,  \
+                      5,5,6,6,6,6}
+#elif defined(DECDPUN)
+#error DECDPUN must be in the range 1-9
+#endif
+
+  /* ----- Shared data (in decNumber.c) ----- */
+  /* Public lookup table used by the D2U macro (see below)            */
+#define DECMAXD2U 49
+extern const uByte d2utable[DECMAXD2U + 1];
+
+  /* ----- Macros ----- */
+  /* ISZERO -- return true if decNumber dn is a zero                  */
+  /* [performance-critical in some situations]                        */
+#define ISZERO(dn) decNumberIsZero(dn) /* now just a local name */
+
+  /* D2U -- return the number of Units needed to hold d digits        */
+  /* (runtime version, with table lookaside for small d)              */
+#if DECDPUN==8
+#define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+7)>>3))
+#elif DECDPUN==4
+#define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+3)>>2))
+#else
+#define D2U(d) ((d)<=DECMAXD2U?d2utable[d]:((d)+DECDPUN-1)/DECDPUN)
+#endif
+  /* SD2U -- static D2U macro (for compile-time calculation)          */
+#define SD2U(d) (((d)+DECDPUN-1)/DECDPUN)
+
+  /* MSUDIGITS -- returns digits in msu, from digits, calculated      */
+  /* using D2U                                                        */
+#define MSUDIGITS(d) ((d)-(D2U(d)-1)*DECDPUN)
+
+  /* D2N -- return the number of decNumber structs that would be      */
+  /* needed to contain that number of digits (and the initial         */
+  /* decNumber struct) safely.  Note that one Unit is included in the */
+  /* initial structure.  Used for allocating space that is aligned on */
+  /* a decNumber struct boundary. */
+#define D2N(d) \
+    ((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
+
+  /* TODIGIT -- macro to remove the leading digit from the unsigned   */
+  /* integer u at column cut (counting from the right, LSD=0) and     */
+  /* place it as an ASCII character into the character pointed to by  */
+  /* c.  Note that cut must be <= 9, and the maximum value for u is   */
+  /* 2,000,000,000 (as is needed for negative exponents of            */
+  /* subnormals).  The unsigned integer pow is used as a temporary    */
+  /* variable. */
+#define TODIGIT(u, cut, c, pow) {       \
+    *(c)='0';                             \
+    pow=DECPOWERS[cut]*2;                 \
+    if ((u)>pow) {                        \
+      pow*=4;                             \
+      if ((u)>=pow) {(u)-=pow; *(c)+=8;}  \
+      pow/=2;                             \
+      if ((u)>=pow) {(u)-=pow; *(c)+=4;}  \
+      pow/=2;                             \
+      }                                   \
+    if ((u)>=pow) {(u)-=pow; *(c)+=2;}    \
+    pow/=2;                               \
+    if ((u)>=pow) {(u)-=pow; *(c)+=1;}    \
+    }
+
+  /* ---------------------------------------------------------------- */
+  /* Definitions for fixed-precision modules (only valid after        */
+  /* decSingle.h, decDouble.h, or decQuad.h has been included)        */
+  /* ---------------------------------------------------------------- */
+
+  /* bcdnum -- a structure describing a format-independent finite     */
+  /* number, whose coefficient is a string of bcd8 uBytes             */
+typedef struct {
+       uByte *msd;             /* -> most significant digit            */
+       uByte *lsd;             /* -> least ditto                       */
+       uInt sign;              /* 0=positive, DECFLOAT_Sign=negative   */
+       Int exponent;           /* Unadjusted signed exponent (q), or   */
+       /* DECFLOAT_NaN etc. for a special      */
+} bcdnum;
+
+  /* Test if exponent or bcdnum exponent must be a special, etc.      */
+#define EXPISSPECIAL(exp) ((exp)>=DECFLOAT_MinSp)
+#define EXPISINF(exp) (exp==DECFLOAT_Inf)
+#define EXPISNAN(exp) (exp==DECFLOAT_qNaN || exp==DECFLOAT_sNaN)
+#define NUMISSPECIAL(num) (EXPISSPECIAL((num)->exponent))
+
+  /* Refer to a 32-bit word or byte in a decFloat (df) by big-endian  */
+  /* (array) notation (the 0 word or byte contains the sign bit),     */
+  /* automatically adjusting for endianness; similarly address a word */
+  /* in the next-wider format (decFloatWider, or dfw)                 */
+#define DECWORDS  (DECBYTES/4)
+#define DECWWORDS (DECWBYTES/4)
+#if DECLITEND
+#define DFBYTE(df, off)   ((df)->bytes[DECBYTES-1-(off)])
+#define DFWORD(df, off)   ((df)->words[DECWORDS-1-(off)])
+#define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
+#else
+#define DFBYTE(df, off)   ((df)->bytes[off])
+#define DFWORD(df, off)   ((df)->words[off])
+#define DFWWORD(dfw, off) ((dfw)->words[off])
+#endif
+
+  /* Tests for sign or specials, directly on DECFLOATs                */
+#define DFISSIGNED(df)  ((DFWORD(df, 0)&0x80000000)!=0)
+#define DFISSPECIAL(df) ((DFWORD(df, 0)&0x78000000)==0x78000000)
+#define DFISINF(df)     ((DFWORD(df, 0)&0x7c000000)==0x78000000)
+#define DFISNAN(df)     ((DFWORD(df, 0)&0x7c000000)==0x7c000000)
+#define DFISQNAN(df)    ((DFWORD(df, 0)&0x7e000000)==0x7c000000)
+#define DFISSNAN(df)    ((DFWORD(df, 0)&0x7e000000)==0x7e000000)
+
+  /* Shared lookup tables                                             */
+extern const uInt DECCOMBMSD[64];      /* Combination field -> MSD   */
+extern const uInt DECCOMBFROM[48];     /* exp+msd -> Combination     */
+
+  /* Private generic (utility) routine                                */
+#if DECCHECK || DECTRACE
+extern void decShowNum(const bcdnum *, const char *);
+#endif
+
+  /* Format-dependent macros and constants                            */
+#if defined(DECPMAX)
+
+    /* Useful constants                                               */
+#define DECPMAX9  (ROUNDUP(DECPMAX, 9)/9)      /* 'Pmax' in 10**9s    */
+    /* Top words for a zero                                           */
+#define SINGLEZERO   0x22500000
+#define DOUBLEZERO   0x22380000
+#define QUADZERO     0x22080000
+    /* [ZEROWORD is defined to be one of these in the DFISZERO macro] */
+
+    /* Format-dependent common tests:                                 */
+    /*   DFISZERO   -- test for (any) zero                            */
+    /*   DFISCCZERO -- test for coefficient continuation being zero   */
+    /*   DFISCC01   -- test for coefficient contains only 0s and 1s   */
+    /*   DFISINT    -- test for finite and exponent q=0               */
+    /*   DFISUINT01 -- test for sign=0, finite, exponent q=0, and     */
+    /*                 MSD=0 or 1                                     */
+    /*   ZEROWORD is also defined here.                               */
+    /*                                                                */
+    /* In DFISZERO the first test checks the least-significant word   */
+    /* (most likely to be non-zero); the penultimate tests MSD and    */
+    /* DPDs in the signword, and the final test excludes specials and */
+    /* MSD>7.  DFISINT similarly has to allow for the two forms of    */
+    /* MSD codes.  DFISUINT01 only has to allow for one form of MSD   */
+    /* code.                                                          */
+#if DECPMAX==7
+#define ZEROWORD SINGLEZERO
+      /* [test macros not needed except for Zero]                     */
+#define DFISZERO(df)  ((DFWORD(df, 0)&0x1c0fffff)==0         \
+                          && (DFWORD(df, 0)&0x60000000)!=0x60000000)
+#elif DECPMAX==16
+#define ZEROWORD DOUBLEZERO
+#define DFISZERO(df)  ((DFWORD(df, 1)==0                     \
+                          && (DFWORD(df, 0)&0x1c03ffff)==0         \
+                          && (DFWORD(df, 0)&0x60000000)!=0x60000000))
+#define DFISINT(df) ((DFWORD(df, 0)&0x63fc0000)==0x22380000  \
+                         ||(DFWORD(df, 0)&0x7bfc0000)==0x6a380000)
+#define DFISUINT01(df) ((DFWORD(df, 0)&0xfbfc0000)==0x22380000)
+#define DFISCCZERO(df) (DFWORD(df, 1)==0                     \
+                          && (DFWORD(df, 0)&0x0003ffff)==0)
+#define DFISCC01(df)  ((DFWORD(df, 0)&~0xfffc9124)==0        \
+                          && (DFWORD(df, 1)&~0x49124491)==0)
+#elif DECPMAX==34
+#define ZEROWORD QUADZERO
+#define DFISZERO(df)  ((DFWORD(df, 3)==0                     \
+                          &&  DFWORD(df, 2)==0                     \
+                          &&  DFWORD(df, 1)==0                     \
+                          && (DFWORD(df, 0)&0x1c003fff)==0         \
+                          && (DFWORD(df, 0)&0x60000000)!=0x60000000))
+#define DFISINT(df) ((DFWORD(df, 0)&0x63ffc000)==0x22080000  \
+                         ||(DFWORD(df, 0)&0x7bffc000)==0x6a080000)
+#define DFISUINT01(df) ((DFWORD(df, 0)&0xfbffc000)==0x22080000)
+#define DFISCCZERO(df) (DFWORD(df, 3)==0                     \
+                          &&  DFWORD(df, 2)==0                     \
+                          &&  DFWORD(df, 1)==0                     \
+                          && (DFWORD(df, 0)&0x00003fff)==0)
+
+#define DFISCC01(df)   ((DFWORD(df, 0)&~0xffffc912)==0       \
+                          &&  (DFWORD(df, 1)&~0x44912449)==0       \
+                          &&  (DFWORD(df, 2)&~0x12449124)==0       \
+                          &&  (DFWORD(df, 3)&~0x49124491)==0)
+#endif
+
+    /* Macros to test if a certain 10 bits of a uInt or pair of uInts */
+    /* are a canonical declet [higher or lower bits are ignored].     */
+    /* declet is at offset 0 (from the right) in a uInt:              */
+#define CANONDPD(dpd) (((dpd)&0x300)==0 || ((dpd)&0x6e)!=0x6e)
+    /* declet is at offset k (a multiple of 2) in a uInt:             */
+#define CANONDPDOFF(dpd, k) (((dpd)&(0x300<<(k)))==0            \
+      || ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
+    /* declet is at offset k (a multiple of 2) in a pair of uInts:    */
+    /* [the top 2 bits will always be in the more-significant uInt]   */
+#define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0     \
+      || ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k)))                  \
+      || ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
+
+    /* Macro to test whether a full-length (length DECPMAX) BCD8      */
+    /* coefficient, starting at uByte u, is all zeros                 */
+    /* Test just the LSWord first, then the remainder as a sequence   */
+    /* of tests in order to avoid same-level use of UBTOUI            */
+#if DECPMAX==7
+#define ISCOEFFZERO(u) (                                      \
+           UBTOUI((u)+DECPMAX-4)==0                                 \
+        && UBTOUS((u)+DECPMAX-6)==0                                 \
+        && *(u)==0)
+#elif DECPMAX==16
+#define ISCOEFFZERO(u) (                                      \
+           UBTOUI((u)+DECPMAX-4)==0                                 \
+        && UBTOUI((u)+DECPMAX-8)==0                                 \
+        && UBTOUI((u)+DECPMAX-12)==0                                \
+        && UBTOUI(u)==0)
+#elif DECPMAX==34
+#define ISCOEFFZERO(u) (                                      \
+           UBTOUI((u)+DECPMAX-4)==0                                 \
+        && UBTOUI((u)+DECPMAX-8)==0                                 \
+        && UBTOUI((u)+DECPMAX-12)==0                                \
+        && UBTOUI((u)+DECPMAX-16)==0                                \
+        && UBTOUI((u)+DECPMAX-20)==0                                \
+        && UBTOUI((u)+DECPMAX-24)==0                                \
+        && UBTOUI((u)+DECPMAX-28)==0                                \
+        && UBTOUI((u)+DECPMAX-32)==0                                \
+        && UBTOUS(u)==0)
+#endif
+
+    /* Macros and masks for the sign, exponent continuation, and MSD  */
+    /* Get the sign as DECFLOAT_Sign or 0                             */
+#define GETSIGN(df) (DFWORD(df, 0)&0x80000000)
+    /* Get the exponent continuation from a decFloat *df as an Int    */
+#define GETECON(df) ((Int)((DFWORD((df), 0)&0x03ffffff)>>(32-6-DECECONL)))
+    /* Ditto, from the next-wider format                              */
+#define GETWECON(df) ((Int)((DFWWORD((df), 0)&0x03ffffff)>>(32-6-DECWECONL)))
+    /* Get the biased exponent similarly                              */
+#define GETEXP(df)  ((Int)(DECCOMBEXP[DFWORD((df), 0)>>26]+GETECON(df)))
+    /* Get the unbiased exponent similarly                            */
+#define GETEXPUN(df) ((Int)GETEXP(df)-DECBIAS)
+    /* Get the MSD similarly (as uInt)                                */
+#define GETMSD(df)   (DECCOMBMSD[DFWORD((df), 0)>>26])
+
+    /* Compile-time computes of the exponent continuation field masks */
+    /* full exponent continuation field:                              */
+#define ECONMASK ((0x03ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
+    /* same, not including its first digit (the qNaN/sNaN selector):  */
+#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
+
+    /* Macros to decode the coefficient in a finite decFloat *df into */
+    /* a BCD string (uByte *bcdin) of length DECPMAX uBytes.          */
+
+    /* In-line sequence to convert least significant 10 bits of uInt  */
+    /* dpd to three BCD8 digits starting at uByte u.  Note that an    */
+    /* extra byte is written to the right of the three digits because */
+    /* four bytes are moved at a time for speed; the alternative      */
+    /* macro moves exactly three bytes (usually slower).              */
+#define dpd2bcd8(u, dpd)  memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 4)
+#define dpd2bcd83(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 3)
+
+    /* Decode the declets.  After extracting each one, it is decoded  */
+    /* to BCD8 using a table lookup (also used for variable-length    */
+    /* decode).  Each DPD decode is 3 bytes BCD8 plus a one-byte      */
+    /* length which is not used, here).  Fixed-length 4-byte moves    */
+    /* are fast, however, almost everywhere, and so are used except   */
+    /* for the final three bytes (to avoid overrun).  The code below  */
+    /* is 36 instructions for Doubles and about 70 for Quads, even    */
+    /* on IA32.                                                       */
+
+    /* Two macros are defined for each format:                        */
+    /*   GETCOEFF extracts the coefficient of the current format      */
+    /*   GETWCOEFF extracts the coefficient of the next-wider format. */
+    /* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */
+
+#if DECPMAX==7
+#define GETCOEFF(df, bcd) {                          \
+      uInt sourhi=DFWORD(df, 0);                         \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>10);                       \
+      dpd2bcd83(bcd+4, sourhi);}
+#define GETWCOEFF(df, bcd) {                         \
+      uInt sourhi=DFWWORD(df, 0);                        \
+      uInt sourlo=DFWWORD(df, 1);                        \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>8);                        \
+      dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30));       \
+      dpd2bcd8(bcd+7, sourlo>>20);                       \
+      dpd2bcd8(bcd+10, sourlo>>10);                      \
+      dpd2bcd83(bcd+13, sourlo);}
+
+#elif DECPMAX==16
+#define GETCOEFF(df, bcd) {                          \
+      uInt sourhi=DFWORD(df, 0);                         \
+      uInt sourlo=DFWORD(df, 1);                         \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>8);                        \
+      dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30));       \
+      dpd2bcd8(bcd+7, sourlo>>20);                       \
+      dpd2bcd8(bcd+10, sourlo>>10);                      \
+      dpd2bcd83(bcd+13, sourlo);}
+#define GETWCOEFF(df, bcd) {                         \
+      uInt sourhi=DFWWORD(df, 0);                        \
+      uInt sourmh=DFWWORD(df, 1);                        \
+      uInt sourml=DFWWORD(df, 2);                        \
+      uInt sourlo=DFWWORD(df, 3);                        \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>4);                        \
+      dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26));     \
+      dpd2bcd8(bcd+7, sourmh>>16);                       \
+      dpd2bcd8(bcd+10, sourmh>>6);                       \
+      dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28));    \
+      dpd2bcd8(bcd+16, sourml>>18);                      \
+      dpd2bcd8(bcd+19, sourml>>8);                       \
+      dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30));    \
+      dpd2bcd8(bcd+25, sourlo>>20);                      \
+      dpd2bcd8(bcd+28, sourlo>>10);                      \
+      dpd2bcd83(bcd+31, sourlo);}
+
+#elif DECPMAX==34
+#define GETCOEFF(df, bcd) {                          \
+      uInt sourhi=DFWORD(df, 0);                         \
+      uInt sourmh=DFWORD(df, 1);                         \
+      uInt sourml=DFWORD(df, 2);                         \
+      uInt sourlo=DFWORD(df, 3);                         \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>4);                        \
+      dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26));     \
+      dpd2bcd8(bcd+7, sourmh>>16);                       \
+      dpd2bcd8(bcd+10, sourmh>>6);                       \
+      dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28));    \
+      dpd2bcd8(bcd+16, sourml>>18);                      \
+      dpd2bcd8(bcd+19, sourml>>8);                       \
+      dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30));    \
+      dpd2bcd8(bcd+25, sourlo>>20);                      \
+      dpd2bcd8(bcd+28, sourlo>>10);                      \
+      dpd2bcd83(bcd+31, sourlo);}
+
+#define GETWCOEFF(df, bcd) {??}        /* [should never be used]       */
+#endif
+
+    /* Macros to decode the coefficient in a finite decFloat *df into */
+    /* a base-billion uInt array, with the least-significant          */
+    /* 0-999999999 'digit' at offset 0.                               */
+
+    /* Decode the declets.  After extracting each one, it is decoded  */
+    /* to binary using a table lookup.  Three tables are used; one    */
+    /* the usual DPD to binary, the other two pre-multiplied by 1000  */
+    /* and 1000000 to avoid multiplication during decode.  These      */
+    /* tables can also be used for multiplying up the MSD as the DPD  */
+    /* code for 0 through 9 is the identity.                          */
+#define DPD2BIN0 DPD2BIN       /* for prettier code             */
+
+#if DECPMAX==7
+#define GETCOEFFBILL(df, buf) {                           \
+      uInt sourhi=DFWORD(df, 0);                              \
+      (buf)[0]=DPD2BIN0[sourhi&0x3ff]                         \
+              +DPD2BINK[(sourhi>>10)&0x3ff]                   \
+              +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
+
+#elif DECPMAX==16
+#define GETCOEFFBILL(df, buf) {                           \
+      uInt sourhi, sourlo;                                    \
+      sourlo=DFWORD(df, 1);                                   \
+      (buf)[0]=DPD2BIN0[sourlo&0x3ff]                         \
+              +DPD2BINK[(sourlo>>10)&0x3ff]                   \
+              +DPD2BINM[(sourlo>>20)&0x3ff];                  \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[1]=DPD2BIN0[((sourhi<<2) | (sourlo>>30))&0x3ff]   \
+              +DPD2BINK[(sourhi>>8)&0x3ff]                    \
+              +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
+
+#elif DECPMAX==34
+#define GETCOEFFBILL(df, buf) {                           \
+      uInt sourhi, sourmh, sourml, sourlo;                    \
+      sourlo=DFWORD(df, 3);                                   \
+      (buf)[0]=DPD2BIN0[sourlo&0x3ff]                         \
+              +DPD2BINK[(sourlo>>10)&0x3ff]                   \
+              +DPD2BINM[(sourlo>>20)&0x3ff];                  \
+      sourml=DFWORD(df, 2);                                   \
+      (buf)[1]=DPD2BIN0[((sourml<<2) | (sourlo>>30))&0x3ff]   \
+              +DPD2BINK[(sourml>>8)&0x3ff]                    \
+              +DPD2BINM[(sourml>>18)&0x3ff];                  \
+      sourmh=DFWORD(df, 1);                                   \
+      (buf)[2]=DPD2BIN0[((sourmh<<4) | (sourml>>28))&0x3ff]   \
+              +DPD2BINK[(sourmh>>6)&0x3ff]                    \
+              +DPD2BINM[(sourmh>>16)&0x3ff];                  \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[3]=DPD2BIN0[((sourhi<<6) | (sourmh>>26))&0x3ff]   \
+              +DPD2BINK[(sourhi>>4)&0x3ff]                    \
+              +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
+
+#endif
+
+    /* Macros to decode the coefficient in a finite decFloat *df into */
+    /* a base-thousand uInt array (of size DECLETS+1, to allow for    */
+    /* the MSD), with the least-significant 0-999 'digit' at offset 0. */
+
+    /* Decode the declets.  After extracting each one, it is decoded  */
+    /* to binary using a table lookup.                                */
+#if DECPMAX==7
+#define GETCOEFFTHOU(df, buf) {                           \
+      uInt sourhi=DFWORD(df, 0);                              \
+      (buf)[0]=DPD2BIN[sourhi&0x3ff];                         \
+      (buf)[1]=DPD2BIN[(sourhi>>10)&0x3ff];                   \
+      (buf)[2]=DECCOMBMSD[sourhi>>26];}
+
+#elif DECPMAX==16
+#define GETCOEFFTHOU(df, buf) {                           \
+      uInt sourhi, sourlo;                                    \
+      sourlo=DFWORD(df, 1);                                   \
+      (buf)[0]=DPD2BIN[sourlo&0x3ff];                         \
+      (buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff];                   \
+      (buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff];                   \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[3]=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff];   \
+      (buf)[4]=DPD2BIN[(sourhi>>8)&0x3ff];                    \
+      (buf)[5]=DECCOMBMSD[sourhi>>26];}
+
+#elif DECPMAX==34
+#define GETCOEFFTHOU(df, buf) {                           \
+      uInt sourhi, sourmh, sourml, sourlo;                    \
+      sourlo=DFWORD(df, 3);                                   \
+      (buf)[0]=DPD2BIN[sourlo&0x3ff];                         \
+      (buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff];                   \
+      (buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff];                   \
+      sourml=DFWORD(df, 2);                                   \
+      (buf)[3]=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff];   \
+      (buf)[4]=DPD2BIN[(sourml>>8)&0x3ff];                    \
+      (buf)[5]=DPD2BIN[(sourml>>18)&0x3ff];                   \
+      sourmh=DFWORD(df, 1);                                   \
+      (buf)[6]=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff];   \
+      (buf)[7]=DPD2BIN[(sourmh>>6)&0x3ff];                    \
+      (buf)[8]=DPD2BIN[(sourmh>>16)&0x3ff];                   \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff];   \
+      (buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff];                   \
+      (buf)[11]=DECCOMBMSD[sourhi>>26];}
+#endif
+
+    /* Macros to decode the coefficient in a finite decFloat *df and  */
+    /* add to a base-thousand uInt array (as for GETCOEFFTHOU).       */
+    /* After the addition then most significant 'digit' in the array  */
+    /* might have a value larger then 10 (with a maximum of 19).      */
+#if DECPMAX==7
+#define ADDCOEFFTHOU(df, buf) {                           \
+      uInt sourhi=DFWORD(df, 0);                              \
+      (buf)[0]+=DPD2BIN[sourhi&0x3ff];                        \
+      if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
+      (buf)[1]+=DPD2BIN[(sourhi>>10)&0x3ff];                  \
+      if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
+      (buf)[2]+=DECCOMBMSD[sourhi>>26];}
+
+#elif DECPMAX==16
+#define ADDCOEFFTHOU(df, buf) {                           \
+      uInt sourhi, sourlo;                                    \
+      sourlo=DFWORD(df, 1);                                   \
+      (buf)[0]+=DPD2BIN[sourlo&0x3ff];                        \
+      if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
+      (buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff];                  \
+      if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
+      (buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff];                  \
+      if (buf[2]>999) {buf[2]-=1000; buf[3]++;}               \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[3]+=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff];  \
+      if (buf[3]>999) {buf[3]-=1000; buf[4]++;}               \
+      (buf)[4]+=DPD2BIN[(sourhi>>8)&0x3ff];                   \
+      if (buf[4]>999) {buf[4]-=1000; buf[5]++;}               \
+      (buf)[5]+=DECCOMBMSD[sourhi>>26];}
+
+#elif DECPMAX==34
+#define ADDCOEFFTHOU(df, buf) {                           \
+      uInt sourhi, sourmh, sourml, sourlo;                    \
+      sourlo=DFWORD(df, 3);                                   \
+      (buf)[0]+=DPD2BIN[sourlo&0x3ff];                        \
+      if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
+      (buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff];                  \
+      if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
+      (buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff];                  \
+      if (buf[2]>999) {buf[2]-=1000; buf[3]++;}               \
+      sourml=DFWORD(df, 2);                                   \
+      (buf)[3]+=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff];  \
+      if (buf[3]>999) {buf[3]-=1000; buf[4]++;}               \
+      (buf)[4]+=DPD2BIN[(sourml>>8)&0x3ff];                   \
+      if (buf[4]>999) {buf[4]-=1000; buf[5]++;}               \
+      (buf)[5]+=DPD2BIN[(sourml>>18)&0x3ff];                  \
+      if (buf[5]>999) {buf[5]-=1000; buf[6]++;}               \
+      sourmh=DFWORD(df, 1);                                   \
+      (buf)[6]+=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff];  \
+      if (buf[6]>999) {buf[6]-=1000; buf[7]++;}               \
+      (buf)[7]+=DPD2BIN[(sourmh>>6)&0x3ff];                   \
+      if (buf[7]>999) {buf[7]-=1000; buf[8]++;}               \
+      (buf)[8]+=DPD2BIN[(sourmh>>16)&0x3ff];                  \
+      if (buf[8]>999) {buf[8]-=1000; buf[9]++;}               \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[9]+=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff];  \
+      if (buf[9]>999) {buf[9]-=1000; buf[10]++;}              \
+      (buf)[10]+=DPD2BIN[(sourhi>>4)&0x3ff];                  \
+      if (buf[10]>999) {buf[10]-=1000; buf[11]++;}            \
+      (buf)[11]+=DECCOMBMSD[sourhi>>26];}
+#endif
+
+    /* Set a decFloat to the maximum positive finite number (Nmax)    */
+#if DECPMAX==7
+#define DFSETNMAX(df)            \
+      {DFWORD(df, 0)=0x77f3fcff;}
+#elif DECPMAX==16
+#define DFSETNMAX(df)            \
+      {DFWORD(df, 0)=0x77fcff3f;     \
+       DFWORD(df, 1)=0xcff3fcff;}
+#elif DECPMAX==34
+#define DFSETNMAX(df)            \
+      {DFWORD(df, 0)=0x77ffcff3;     \
+       DFWORD(df, 1)=0xfcff3fcf;     \
+       DFWORD(df, 2)=0xf3fcff3f;     \
+       DFWORD(df, 3)=0xcff3fcff;}
+#endif
+
+  /* [end of format-dependent macros and constants]                   */
+#endif
+
+#else
+#error decNumberLocal included more than once
+#endif
diff --git a/theme/03_mainmenu_icon_calculator.png b/theme/03_mainmenu_icon_calculator.png
new file mode 100644 (file)
index 0000000..07612bb
Binary files /dev/null and b/theme/03_mainmenu_icon_calculator.png differ
diff --git a/theme/CMakeLists.txt b/theme/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9804dfc
--- /dev/null
@@ -0,0 +1,107 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(calculator C)
+
+SET(SRCS 
+    src/calc-main.c 
+    src/calculator_edje.c 
+    src/calculator_parser.c
+    src/calc-expression.c
+    src/calc-string.c
+    src/calc-view.c
+       src/decnumber/decNumber.c
+       src/decnumber/decContext.c)
+    
+SET(VENDOR "tizen")
+SET(PACKAGE ${PROJECT_NAME})
+SET(PKGNAME "org.${VENDOR}.${PACKAGE}")
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+#SET(INSTALL_DIR_APPS "/opt/apps/${PKGNAME}")
+SET(INSTALL_DIR_PRE "/opt")
+
+SET(BINDIR "${PREFIX}/bin")
+SET(RESDIR "${PREFIX}/res")
+SET(DATADIR "${PREFIX}/data")
+SET(LOCALEDIR "${RESDIR}/locale")
+SET(ICONDIR "${RESDIR}/icons")
+SET(DESKTOPICONDIR "${ICONDIR}/default/small")
+SET(EDJDIR "${RESDIR}/edje")
+    
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED elementary  utilX
+                                dlog svi evas edje
+                                ecore-x ecore ecore-input capi-appfw-application
+)
+
+FIND_LIBRARY(LIB_M m)
+
+# Apply Public emulator image
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+    INSTALL(FILES ${CMAKE_SOURCE_DIR}/org.tizen.calculator.png DESTINATION ${ICONDIR})
+    MESSAGE("install confidential icon ...")
+ELSE("${ARCH}" STREQUAL "arm")
+    INSTALL(FILES ${CMAKE_SOURCE_DIR}/03_mainmenu_icon_calculator.png DESTINATION ${ICONDIR} RENAME
+    org.tizen.calculator.png)
+    MESSAGE("install releasable icon ...")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS(${pkgs_CFLAGS})
+ADD_DEFINITIONS("-fpie")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+ADD_DEFINITIONS("-DSLP_DEBUG")
+ADD_DEFINITIONS("-DSLP_PROF")
+
+ADD_DEFINITIONS("-DVENDOR=\"${VENDOR}\"")
+ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"")
+ADD_DEFINITIONS("-DPACKAGE_NAME=\"${PKGNAME}\"")
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+ADD_DEFINITIONS("-DINSTALL_DIR_APPS=\"${INSTALL_DIR_APPS}\"")
+ADD_DEFINITIONS("-DBINDIR=\"${BINDIR}\"")
+ADD_DEFINITIONS("-DLOCALEDIR=\"${LOCALEDIR}\"")
+ADD_DEFINITIONS("-DICONDIR=\"${ICONDIR}\"")
+ADD_DEFINITIONS("-DEDJDIR=\"${EDJDIR}\"")
+
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-pie" ${LIB_M})
+
+ADD_CUSTOM_TARGET(calculator.edj 
+    COMMAND edje_cc -id ${CMAKE_CURRENT_SOURCE_DIR}/images
+    ${CMAKE_SOURCE_DIR}/calculator.edc ${CMAKE_BINARY_DIR}/calculator.edj
+    DEPENDS ${CMAKE_SOURCE_DIR}/calculator.edc
+)
+ADD_DEPENDENCIES(${PROJECT_NAME} calculator.edj)
+
+ADD_CUSTOM_TARGET(calculator_theme.edj
+    COMMAND edje_cc -id ${CMAKE_CURRENT_SOURCE_DIR}/theme
+    ${CMAKE_SOURCE_DIR}/theme/calculator_theme.edc ${CMAKE_BINARY_DIR}/theme/calculator_theme.edj
+    DEPENDS ${CMAKE_SOURCE_DIR}/theme/calculator_theme.edc
+)
+ADD_DEPENDENCIES(${PROJECT_NAME} calculator_theme.edj)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION 
+${BINDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/calculator.edj DESTINATION ${EDJDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/theme/calculator_theme.edj DESTINATION 
+${EDJDIR})
+
+# install application HOME directory
+INSTALL(DIRECTORY DESTINATION ${DATADIR})
+
+# process setting
+install(FILES ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.ini DESTINATION /opt/share/process-info )
+
+ADD_SUBDIRECTORY(po)
+
+# desktop icon
+set(PREFIX ${CMAKE_INSTALL_PREFIX})
+install(FILES ${CMAKE_SOURCE_DIR}/org.tizen.calculator.xml DESTINATION /opt/share/packages)
+install(FILES ${CMAKE_SOURCE_DIR}/org.tizen.calculator.png DESTINATION  /opt/share/icons/default/small)
diff --git a/theme/LICENSE b/theme/LICENSE
new file mode 100644 (file)
index 0000000..05d9069
--- /dev/null
@@ -0,0 +1,76 @@
+Flora License\r
+\r
+Version 1.0, May, 2012\r
+\r
+http://www.tizenopensource.org/license\r
+\r
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+1. Definitions.\r
+\r
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\r
+\r
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.\r
+\r
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\r
+\r
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\r
+\r
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\r
+\r
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\r
+\r
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\r
+\r
+"Tizen Certified Platform" shall mean a software platform that complies with the standards set forth in the Compatibility Definition Document and passes the Compatibility Test Suite as defined from time to time by the Tizen Technical Steering Group and certified by the Tizen Association or its designated agent.\r
+\r
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\r
+\r
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work solely as incorporated into a Tizen Certified Platform, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work solely as incorporated into a Tizen Certified Platform to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\r
+\r
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof pursuant to the copyright license above, in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\r
+\r
+  1. You must give any other recipients of the Work or Derivative Works a copy of this License; and\r
+\r
+  2. You must cause any modified files to carry prominent notices stating that You changed the files; and\r
+\r
+  3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\r
+\r
+  4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\r
+\r
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\r
+\r
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\r
+\r
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\r
+\r
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.\r
+\r
+END OF TERMS AND CONDITIONS\r
+\r
+APPENDIX: How to apply the Flora License to your work\r
+\r
+To apply the Flora License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.\r
+\r
+   Copyright 2012  Samsung Electronics Co., Ltd\r
+\r
+   Licensed under the Flora License, Version 1.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.tizenopensource.org/license\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
diff --git a/theme/NOTICE b/theme/NOTICE
new file mode 100644 (file)
index 0000000..ded3804
--- /dev/null
@@ -0,0 +1 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
\ No newline at end of file
diff --git a/theme/calculator.edc b/theme/calculator.edc
new file mode 100644 (file)
index 0000000..0ca57f6
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#include "edc/edc-macro.edc"
+
+#define WIDTH                                  720
+#define HEIGHT                                 1280
+#define WIDTH_LAN                              1280
+#define HEIGHT_LAN                             720
+#define WIDTH_POR                              720
+#define HEIGHT_POR                             1280
+images {
+        /*portrait*/
+        image: "images/P04_calculator_btn_01.png" COMP;
+        image: "images/P04_calculator_btn_01_press.png" COMP;
+        image: "images/P04_calculator_btn_02.png" COMP;
+        image: "images/P04_calculator_btn_02_press.png" COMP;
+        image: "images/P04_calculator_btn_03.png" COMP;
+        image: "images/P04_calculator_btn_03_press.png" COMP;
+        image: "images/P04_calculator_btn_04.png" COMP;
+        image: "images/P04_calculator_btn_04_press.png" COMP;
+        image: "images/P04_calculator_btn_05.png" COMP;
+        image: "images/P04_calculator_btn_05_press.png" COMP;
+        image: "images/P04_calculator_btn_06.png" COMP;
+        image: "images/P04_calculator_btn_06_press.png" COMP;
+        image: "images/P04_calculator_btn_07.png" COMP;
+        image: "images/P04_calculator_btn_07_press.png" COMP;
+        image: "images/P04_calculator_btn_08.png" COMP;
+        image: "images/P04_calculator_btn_08_press.png" COMP;
+        image: "images/P04_calculator_btn_09.png" COMP;
+        image: "images/P04_calculator_btn_09_press.png" COMP;
+        image: "images/P04_calculator_btn_10.png" COMP;
+        image: "images/P04_calculator_btn_10_press.png" COMP;
+        image: "images/P04_calculator_btn_n00.png" COMP;
+        image: "images/P04_calculator_btn_n00_press.png" COMP;
+        image: "images/P04_calculator_btn_n01.png" COMP;
+        image: "images/P04_calculator_btn_n01_press.png" COMP;
+        image: "images/P04_calculator_btn_n02.png" COMP;
+        image: "images/P04_calculator_btn_n02_press.png" COMP;
+        image: "images/P04_calculator_btn_n03.png" COMP;
+        image: "images/P04_calculator_btn_n03_press.png" COMP;
+        image: "images/P04_calculator_btn_n04.png" COMP;
+        image: "images/P04_calculator_btn_n04_press.png" COMP;
+        image: "images/P04_calculator_btn_n05.png" COMP;
+        image: "images/P04_calculator_btn_n05_press.png" COMP;
+        image: "images/P04_calculator_btn_n06.png" COMP;
+        image: "images/P04_calculator_btn_n06_press.png" COMP;
+        image: "images/P04_calculator_btn_n07.png" COMP;
+        image: "images/P04_calculator_btn_n07_press.png" COMP;
+        image: "images/P04_calculator_btn_n08.png" COMP;
+        image: "images/P04_calculator_btn_n08_press.png" COMP;
+        image: "images/P04_calculator_btn_n09.png" COMP;
+        image: "images/P04_calculator_btn_n09_press.png" COMP;
+
+        image: "images/P04_calculator_down_handle.png" COMP;
+        image: "images/P04_calculator_up_handle.png" COMP;
+        image: "images/P04_calculator_down_handle_press.png" COMP;
+        image: "images/P04_calculator_up_handle_press.png" COMP;
+
+        /*landscape*/
+        image: "images/landscape/P04_calculator_btn_01.png" COMP;
+        image: "images/landscape/P04_calculator_btn_01_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_02.png" COMP;
+        image: "images/landscape/P04_calculator_btn_02_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_03.png" COMP;
+        image: "images/landscape/P04_calculator_btn_03_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_04.png" COMP;
+        image: "images/landscape/P04_calculator_btn_04_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_05.png" COMP;
+        image: "images/landscape/P04_calculator_btn_05_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_06.png" COMP;
+        image: "images/landscape/P04_calculator_btn_06_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_07.png" COMP;
+        image: "images/landscape/P04_calculator_btn_07_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_08.png" COMP;
+        image: "images/landscape/P04_calculator_btn_08_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_09.png" COMP;
+        image: "images/landscape/P04_calculator_btn_09_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_10.png" COMP;
+        image: "images/landscape/P04_calculator_btn_10_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_11.png" COMP;
+        image: "images/landscape/P04_calculator_btn_11_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_12.png" COMP;
+        image: "images/landscape/P04_calculator_btn_12_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_13.png" COMP;
+        image: "images/landscape/P04_calculator_btn_13_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_14.png" COMP;
+        image: "images/landscape/P04_calculator_btn_14_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_15.png" COMP;
+        image: "images/landscape/P04_calculator_btn_15_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_16.png" COMP;
+        image: "images/landscape/P04_calculator_btn_16_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_17.png" COMP;
+        image: "images/landscape/P04_calculator_btn_17_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_18.png" COMP;
+        image: "images/landscape/P04_calculator_btn_18_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_19.png" COMP;
+        image: "images/landscape/P04_calculator_btn_19_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_20.png" COMP;
+        image: "images/landscape/P04_calculator_btn_20_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_21.png" COMP;
+        image: "images/landscape/P04_calculator_btn_21_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_22.png" COMP;
+        image: "images/landscape/P04_calculator_btn_22_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_23.png" COMP;
+        image: "images/landscape/P04_calculator_btn_23_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_24.png" COMP;
+        image: "images/landscape/P04_calculator_btn_24_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_25.png" COMP;
+        image: "images/landscape/P04_calculator_btn_25_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n00.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n00_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n01.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n01_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n02.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n02_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n03.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n03_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n04.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n04_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n05.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n05_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n06.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n06_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n07.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n07_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n08.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n08_press.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n09.png" COMP;
+        image: "images/landscape/P04_calculator_btn_n09_press.png" COMP;
+
+        image: "images/landscape/P04_calculator_down_handle_land.png" COMP;
+        image: "images/landscape/P04_calculator_up_handle_land.png" COMP;
+        image: "images/landscape/P04_calculator_down_handle_land_press.png" COMP;
+        image: "images/landscape/P04_calculator_up_handle_land_press.png" COMP;
+
+
+    }
+collections {
+       #include "edc/Inc.calculator.main.edc"
+       #include "edc/Inc.calculator.pannel.por.edc"
+       #include "edc/Inc.calculator.pannel.lan.edc"
+}
diff --git a/theme/calculator.ini b/theme/calculator.ini
new file mode 100644 (file)
index 0000000..5370a21
--- /dev/null
@@ -0,0 +1,3 @@
+[ProcessSetting]
+BG_SCHEDULE=true
+
index 1820b39..b31429e 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  * Copyright 2012  Samsung Electronics Co., Ltd
-  * 
-  * Licensed under the Flora License, Version 1.0 (the "License");
-  * you may not use this file except in compliance with the License.
-  * You may obtain a copy of the License at
-  * 
-  *     http://www.tizenopensource.org/license
-  * 
-  * Unless required by applicable law or agreed to in writing, software
-  * distributed under the License is distributed on an "AS IS" BASIS,
-  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  * See the License for the specific language governing permissions and
-  * limitations under the License.
-  */
-
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
 
 #define ENTRY_BLOCK_HANDLE_SOURCE2 "elm/entry/selection/block_handle_right"
 #define ENTRY_BLOCK_HANDLE_SOURCE3 "elm/entry/selection/block_handle_left"
@@ -38,7 +38,6 @@ collections {
            image: "black/copy&paste_Icon_right.png" COMP;
            image: "black/copy&paste_Icon_right_press.png" COMP;
        }
-
     group {
       name: "elm/entry/base/black";
       alias: "elm/entry/base/char_wrap";
@@ -48,26 +47,26 @@ collections {
       styles
        {
           style { name: "entry_textblock_char_wrap_style_B";
-             base: "font=SLP:style=Roman font_size=67  align=right color="ENTRY_TEXT_COLOR_INC_B" wrap=char left_margin=2 right_margin=2";
+             base: "font=SLP:style=Roman text_class=slp_roman font_size=70  align=right color="ENTRY_TEXT_COLOR_INC_B" wrap=char left_margin=2 right_margin=2";
              tag:  "br" "\n";
              tag:  "ps" "ps";
              tag:  "tab" "\t";
              tag:  "em" "+ font=SLP:style=Oblique";
-             tag:  "b" "+ font=SLP:style=Bold";
+             tag:  "b" "+ font=SLP:style=Bold text_class=slp_bold";
              tag:  "link" "+ color=#800 underline=on underline_color=#8008";
-             tag:  "hilight" "+ font=SLP:style=Bold";
+             tag:  "hilight" "+ font=SLP:style=Bold text_class=slp_bold";
              tag:  "preedit" "+ underline=on underline_color="ENTRY_PREEDIT_BACKGROUND_COLOR_INC"";
              tag:  "preedit_sel" "+ backing=on backing_color="ENTRY_PREEDIT_BACKGROUND_COLOR_INC" color="ENTRY_PREEDIT_TEXT_COLOR_INC"";
           }
           style { name: "entry_textblock_char_wrap_disabled_style_B";
-             base: "font=SLP:style=Roman font_size="ENTRY_TEXT_SIZE_INC" color=#00000080 wrap=char";
+             base: "font=SLP:style=Roman text_class=slp_roman font_size="ENTRY_TEXT_SIZE_INC" color=#00000080 wrap=char";
              tag:  "br" "\n";
              tag:  "ps" "ps";
              tag:  "tab" "\t";
              tag:  "em" "+ font=SLP:style=Oblique";
-             tag:  "b" "+ font=SLP:style=Bold";
+             tag:  "b" "+ font=SLP:style=Bold text_class=slp_bold";
              tag:  "link" "+ color=#00000080 underline=on underline_color=#00000080";
-             tag:  "hilight" "+ font=SLP:style=Bold";
+             tag:  "hilight" "+ font=SLP:style=Bold text_class=slp_bold";
              tag:  "preedit" "+ underline=on underline_color="ENTRY_PREEDIT_BACKGROUND_COLOR_INC"";
              tag:  "preedit_sel" "+ backing=on backing_color="ENTRY_PREEDIT_BACKGROUND_COLOR_INC" color="ENTRY_PREEDIT_TEXT_COLOR_INC"";
           }
diff --git a/theme/debian/changelog b/theme/debian/changelog
new file mode 100644 (file)
index 0000000..7ba69e0
--- /dev/null
@@ -0,0 +1,2491 @@
+calculator (0.1.19-1) unstable; urgency=low
+
+  * [Others]Remove UI-idlecapture to fix build error
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.19-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Thu, 02 Aug 2012 09:23:18 +0800
+
+calculator (0.1.18-1) unstable; urgency=low
+
+  * [Bug]<P120731-4507>Make the digit not jump when in minimized window
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.18-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 01 Aug 2012 13:15:56 +0800
+
+calculator (0.1.17-1) unstable; urgency=low
+
+  * [Bug]<P120725-0073>Make the cursor move to the last digit
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.17-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  SAT, 28 Jul 2012 15:15:30 +0800
+
+calculator (0.1.16-1) unstable; urgency=low
+
+  * [Bug]<P120725-0072>Calculator history not full displayed when minimized window
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.16-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 25 Jul 2012 15:39:42 +0800
+
+calculator (0.1.15-1) unstable; urgency=low
+
+  * [Others]Apply new white theme
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.15-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 24 Jul 2012 16:40:02 +0800
+
+calculator (0.1.14-1) unstable; urgency=low
+
+  * [Others]Change font size when switch to monitor
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.14-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 21 Jul 2012 14:52:23 +0800
+
+calculator (0.1.13-1) unstable; urgency=low
+
+  * [GUI][V0.8][P6]Change auto font resizing rule
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.13-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 13 Jul 2012 14:01:39 +0800
+
+calculator (0.1.12-1) unstable; urgency=low
+
+  * [Bug]<S1-5240>Add elm_object_focus_set to show cursor
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.12-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 10 Jul 2012 10:53:05 +0800
+
+calculator (0.1.11-1) unstable; urgency=low
+
+  * [Others]Hide recover and exit button for monitor mode of mini window
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.11-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 06 Jul 2012 11:51:01 +0800
+
+calculator (0.1.10-1) unstable; urgency=low
+
+  * [GUI][v0.8][P12]Rewrite edc for minimized window
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.10-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Thu, 05 Jul 2012 14:39:57 +0800
+
+calculator (0.1.9-1) unstable; urgency=low
+
+  * [Others]Modify app in app requirement in desktop mode
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.9-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  SAT, 30 Jun 2012 15:51:05 +0800
+
+calculator (0.1.8-1) unstable; urgency=low
+
+  * [Others]Fix app in app bug that show size abnormal in desktop mode
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.8-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 27 Jun 2012 19:31:34 +0800
+
+calculator (0.1.7-1) unstable; urgency=low
+
+  * [Others]Apply calculator app in app mode
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.7-1
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Mon, 25 Jun 2012 10:42:08 +0800
+
+calculator (0.1.6-12) unstable; urgency=low
+
+  * [Bug]<S1-3527>Change e^x to 10^x
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-12
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Mon, 25 Jun 2012 18:12:13 +0800
+
+calculator (0.1.6-11) unstable; urgency=low
+
+  * [GUI][Ver0.5][P13]Apply landscape mode view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-11
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 15 Jun 2012 10:45:51 +0800
+
+calculator (0.1.6-10) unstable; urgency=low
+
+  * [GUI][Ver0.6][Page7]Apply new portrait mode view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-10
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 12 Jun 2012 10:51:01 +0800
+
+calculator (0.1.6-9) unstable; urgency=low
+
+  * [Others]Change layout theme set
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-9
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 08 Jun 2012 16:07:54 +0800
+
+calculator (0.1.6-8) unstable; urgency=low
+
+  * [Others]Show the number which is less then 0.00001
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-8
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 06 Jun 2012 09:40:14 +0800
+
+calculator (0.1.6-7) unstable; urgency=low
+
+  * [Bug]<NCR-32>Press input button cause memory leak
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-7
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 05 Jun 2012 09:59:32 +0800
+
+calculator (0.1.6-6) unstable; urgency=low
+
+  * [Others]Apply scientific calculation result with different length when switch por/lan view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-6
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 02 Jun 2012 17:03:03 +0800
+
+calculator (0.1.6-5) unstable; urgency=low
+
+  * [Others]Input dot without numbers, automatically add 0 before dot
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-5
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 30 May 2012 16:39:46 +0800
+
+calculator (0.1.6-4) unstable; urgency=low
+
+  * [Others]Sync spec file with OBS in desktop icon install path
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-4
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 30 May 2012 15:19:19 +0800
+
+calculator (0.1.6-3) unstable; urgency=low
+
+  * [Request]Change default desktop icon install path
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-3
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 23 May 2012 10:00:50 +0800
+
+calculator (0.1.6-2) unstable; urgency=low
+
+  * [Request]Sync version as OBS package
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.6-2
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 21 May 2012 14:15:30 +0800
+
+calculator (0.1.3-80) unstable; urgency=low
+
+  * [Request]Add strip option
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-80
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 18 May 2012 15:51:30 +0800
+
+calculator (0.1.3-79) unstable; urgency=low
+
+  *  [Bug]Copy function cannot work well in history view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-79
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 15 May 2012 17:34:29 +0800
+
+calculator (0.1.3-78) unstable; urgency=low
+
+  *  [Request]Add text_class to font field in edc file
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-78
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 15 May 2012 14:08:41 +0800
+
+calculator (0.1.3-77) unstable; urgency=low
+
+  *  [Bug]Fix bug that input dot when calculated shows error
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-77
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 11 May 2012 16:58:10 +0800
+
+calculator (0.1.3-76) unstable; urgency=low
+
+  *  [Request]Distinguish negative and minus symbol in color and length
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-76
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Thu, 10 May 2012 10:42:09 +0800
+
+calculator (0.1.3-75) unstable; urgency=low
+
+  *  [Bug]S1-2986/S1-2988 show clear button on normal view
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-75
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 08 May 2012 10:26:23 +0800
+
+calculator (0.1.3-74) unstable; urgency=low
+
+  *  [Request]Fix round error issue
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-74
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 05 May 2012 11:32:03 +0800
+
+calculator (0.1.3-73) unstable; urgency=low
+
+  *  [Request]Remove install usr/share folder
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-73
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 04 May 2012 18:02:38 +0800
+
+calculator (0.1.3-72) unstable; urgency=low
+
+  *  [Request]Apply auto font resizing rule in UI v1.1 p15
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-72
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 25 Apr 2012 15:43:49 +0800
+
+calculator (0.1.3-71) unstable; urgency=low
+
+  *  [Bug]Fix bug that input dot issues as N_SE-877 on public
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-71
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Tue, 24 Apr 2012 15:53:31 +0800
+
+calculator (0.1.3-70) unstable; urgency=low
+
+  *  [Request]Apply 2012.04.18 GUI v0.3
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-70
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Mon, 23 Apr 2012 20:33:35 +0800
+
+calculator (0.1.3-69) unstable; urgency=low
+
+  *  [Request]Add po and delete invalid comment
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-69
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Fri, 20 Apr 2012 09:57:45 +0800
+
+calculator (0.1.3-68) unstable; urgency=low
+
+  *  [Bug]Fix bug '+number' error as N_SE-527 on public
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-68
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Wed, 18 Apr 2012 14:47:40 +0800
+
+calculator (0.1.3-67) unstable; urgency=low
+
+  *  [Bug]fix bug S1-2584/2560 and fix continuously input =
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-67
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 14 Apr 2012 17:52:49 +0800
+
+calculator (0.1.3-66) unstable; urgency=low
+
+  *  [Bug]Fix the bug S1-2589 & S1-2588
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-66
+
+ -- Xiang Zhang <x1986.zhang@samsung.com>  Sat, 14 Apr 2012 10:08:52 +0800
+
+calculator (0.1.3-65) unstable; urgency=low
+
+  * [Bug]Fix the bug that Proper error message is not displaying when the editor exceeds the range
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-65
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 27 Mar 2012 17:39:22 -0800
+calculator (0.1.3-64) unstable; urgency=low
+
+  * [Bug]Fix the bug that Cut, Copy & Paste operations are not functioning
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-64
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 24 Mar 2012 14:39:22 -0800
+calculator (0.1.3-63) unstable; urgency=low
+
+  * [Request]Change spec files name
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-63
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 23 Mar 2012 17:50:22 -0800
+calculator (0.1.3-62) unstable; urgency=low
+
+  * [Bug]Fix the change line problem
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-62
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 21 Mar 2012 10:50:22 -0800
+calculator (0.1.3-61) unstable; urgency=low
+
+  * [Request]remove the ui-idlecapture annotation code
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-61
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 17 Mar 2012 08:50:22 -0800
+calculator (0.1.3-60) unstable; urgency=low
+
+  * [Request]Changing SLP Prefix
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-60
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 16 Mar 2012 09:50:22 -0800
+calculator (0.1.3-59) unstable; urgency=low
+
+  * [Request]Change font size
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-59
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 15 Mar 2012 16:30:22 -0800
+calculator (0.1.3-58) unstable; urgency=low
+
+  * [Request]Modify the parameter of elm_win_indicator_mode_set
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-58
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 15 Mar 2012 14:30:22 -0800
+calculator (0.1.3-57) unstable; urgency=low
+
+  * [Request]Apply oneline concept 
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-57
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 14 Mar 2012 19:30:22 -0800
+calculator (0.1.3-56) unstable; urgency=low
+
+  * [Request]Apply API and Winset changes
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-56
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 13 Mar 2012 17:30:22 -0800
+calculator (0.1.3-55) unstable; urgency=low
+
+  * [Request]Add performance log
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-55
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 12 Mar 2012 14:30:22 -0800
+calculator (0.1.3-54) unstable; urgency=low
+
+  * [Request]Shrink font size to fit it as one line
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-54
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 09 Mar 2012 09:30:22 -0800
+calculator (0.1.3-53) unstable; urgency=low
+
+  * [Bug]Remove the error message that can't adapt to multi-language
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-53
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 22 Feb 2012 14:30:22 -0800
+calculator (0.1.3-52) unstable; urgency=low
+
+  * [Request]Replace deprecated API
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-52
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 20 Feb 2012 17:30:22 -0800
+calculator (0.1.3-51) unstable; urgency=low
+
+  * [Bug]Fix the bug that the number is a little broken 
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-51
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 20 Feb 2012 17:03:22 -0800
+calculator (0.1.3-50) unstable; urgency=low
+
+  * [Bug]Fix the bug that CUT&PASTE functionality is improper
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-50
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 7 Feb 2012 17:13:22 -0800
+calculator (0.1.3-49) unstable; urgency=low
+
+  * [Request]Update maintainer
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-49
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 6 Feb 2012 09:13:22 -0800
+calculator (0.1.3-48) unstable; urgency=low
+
+  * [Request]Remove white theme
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-48
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 2 Feb 2012 14:13:22 -0800
+calculator (0.1.3-47) unstable; urgency=low
+
+  * [Request]Error message is displayed in the input field instead of pop up
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-47
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 1 Feb 2012 16:13:22 -0800
+calculator (0.1.3-46) unstable; urgency=low
+
+  * [Bug]The deivce can't display the number under landscapde mode after hiding the handler under portrait mode 
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-46
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 31 Jan 2012 09:53:22 -0800
+calculator (0.1.3-45) unstable; urgency=low
+
+  * [Request]Modify for improving touch performance 
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-45
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 16 Jan 2012 14:43:22 -0800
+calculator (0.1.3-44) unstable; urgency=low
+
+  * [Bug]Fix the issue that popup message can't adapt to multi-language
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-44
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 11 Jan 2012 10:43:22 -0800
+calculator (0.1.3-43) unstable; urgency=low
+
+  * [Request]Apply CAPI
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-43
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 5 Jan 2012 15:43:22 -0800
+calculator (0.1.3-42) unstable; urgency=low
+
+  * [Bug]On different language modes pop up information is always displayed in English language
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-42
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 5 Jan 2012 14:43:22 -0800
+calculator (0.1.3-41) unstable; urgency=low
+
+  * [Request]Theme Name Change from nbeat to tizen
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-41
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 16 Dec 2011 15:32:08 -0800
+calculator (0.1.3-40) unstable; urgency=low
+
+  * [Bug]Fix the issue that menu screen is shown when popup is displayed
+  * Git: slp/apps/c/calculator
+  * Tag: calculator_0.1.3-40
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 15 Dec 2011 13:08:35 -0700
+calculator (0.1.3-39) unstable; urgency=low
+
+  * [Bug]Add automatic operator if the "p" or "e" close to digital
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-39
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 9 Dec 2011 14:08:35 -0700
+calculator (0.1.3-38) unstable; urgency=low
+
+  * [Bug]Cursor automatically move to next line after rotating device
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-38
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 7 Dec 2011 17:08:35 -0700
+calculator (0.1.3-37) unstable; urgency=low
+
+  * [Bug]Disable entry's magnifier to resolve the issue that no number seen in black magnifying window
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-37
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 7 Dec 2011 10:08:35 -0700
+calculator (0.1.3-36) unstable; urgency=low
+
+  * [Bug]Fix the issue that Warning pop up still remains after pressing home key
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-36
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 6 Dec 2011 21:08:35 -0700
+calculator (0.1.3-35) unstable; urgency=low
+
+  * [Bug]Fix the issue that select box created in input entry remains shown in history view
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-35
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 6 Dec 2011 14:15:35 -0700
+calculator (0.1.3-34) unstable; urgency=low
+
+  * [Request]Apply new License bolierplate
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-34
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 5 Dec 2011 10:45:35 -0700
+calculator (0.1.3-33) unstable; urgency=low
+
+  * [Request]If input "=" after an operator,previous input will be duplicated and calculate the expression
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-33
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 2 Dec 2011 16:05:35 -0700
+calculator (0.1.3-32) unstable; urgency=low
+
+  * [Request]Apply elm_entry copy&paste mode
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-32
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 2 Dec 2011 14:05:35 -0700
+calculator (0.1.3-31) unstable; urgency=low
+
+  * [Request]Apply new License
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-31
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 2 Dec 2011 09:45:35 -0700
+calculator (0.1.3-30) unstable; urgency=low
+
+  * [CQ]H0100137603: restrict invalid charactors inputted in number input field
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-30
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 28 Nov 2011 16:45:35 -0700
+calculator (0.1.3-29) unstable; urgency=low
+
+  * Apply Public emulator image
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-29
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 25 Nov 2011 15:45:35 -0700
+calculator (0.1.3-28) unstable; urgency=low
+
+  * [CQ]H0100137014: Fix the bug that Warning message pop up hided by the clipboard screen
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-28
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 23 Nov 2011 16:39:06 -0700
+calculator (0.1.3-27) unstable; urgency=low
+
+  * [CQ]H0100137274: Remain entry empty when inputting '*' and '/'operators with no numbers
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-27
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 22 Nov 2011 14:39:06 -0700
+calculator (0.1.3-26) unstable; urgency=low
+
+  * [CQ]H0100137220:Add popup if unvalid charactors are found ,when calculating
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-26
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 22 Nov 2011 10:39:06 -0700
+calculator (0.1.3-25) unstable; urgency=low
+
+  * Fix the issue that popup get duplicated display
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-25
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 18 Nov 2011 21:39:06 -0700
+calculator (0.1.3-24) unstable; urgency=low
+
+  * Add the operation to close parentheses automatically
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-24
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 18 Nov 2011 13:58:06 -0700
+calculator (0.1.3-23) unstable; urgency=low
+
+  * Apply new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-23
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 10 Nov 2011 09:37:06 -0700
+calculator (0.1.3-22) unstable; urgency=low
+
+  * Fix errors from checkpatch
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-22
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 10 Nov 2011 09:37:06 -0700
+calculator (0.1.3-21) unstable; urgency=low
+
+  * Fix the crash when cut&paste
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-21
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 4 Nov 2011 16:37:06 -0700
+calculator (0.1.3-20) unstable; urgency=low
+
+  * Fix desk file removable issue
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-20
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 31 Oct 2011 16:37:06 -0700
+calculator (0.1.3-19) unstable; urgency=low
+
+  * Add keypad image
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-19
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 26 Oct 2011 10:57:06 -0700
+calculator (0.1.3-18) unstable; urgency=low
+
+  * Update the license
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-18
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 20 Oct 2011 16:31:06 -0700
+calculator (0.1.3-17) unstable; urgency=low
+
+  * Unity the style
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-17
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 19 Oct 2011 15:31:06 -0700
+calculator (0.1.3-16) unstable; urgency=low
+
+  * Fix bug about cut&&paste
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-16
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 19 Oct 2011 14:31:06 -0700
+calculator (0.1.3-15) unstable; urgency=low
+
+  * Modify desktop icon
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-15
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 19 Oct 2011 09:55:06 -0700
+calculator (0.1.3-14) unstable; urgency=low
+
+  * Add warning for unvalid charactor from hardware keypad input
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-14
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 15 Oct 2011 16:26:06 -0700
+calculator (0.1.3-13) unstable; urgency=low
+
+  * Fix bug about hardware keypad input
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-13
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 14 Oct 2011 16:26:06 -0700
+calculator (0.1.3-12) unstable; urgency=low
+
+  * Support hardware keypad
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-12
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 14 Oct 2011 09:49:06 -0700
+calculator (0.1.3-11) unstable; urgency=low
+
+  * Let Inserted operation always visible after expanding Input area
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-11
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 12 Oct 2011 09:49:06 -0700
+calculator (0.1.3-10) unstable; urgency=low
+
+  * apply HD GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-10
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 12 Oct 2011 09:49:06 -0700
+calculator (0.1.3-9) unstable; urgency=low
+
+  * apply NBEAT HD Black Theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-9
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 10 Oct 2011 13:14:06 -0700
+calculator (0.1.3-8) unstable; urgency=low
+
+  * Filter out end key
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-8
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 10 Oct 2011 09:40:06 -0700
+calculator (0.1.3-7) unstable; urgency=low
+
+  * Modify the customized theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-7
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 22 Sep 2011 15:22:06 -0700
+calculator (0.1.3-6) unstable; urgency=low
+
+  * change the charactor color on black theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-6
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 22 Sep 2011 09:22:06 -0700
+calculator (0.1.3-5) unstable; urgency=low
+
+  * Correct the behavior of () button
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-5
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 20 Sep 2011 14:57:06 -0700
+calculator (0.1.3-4) unstable; urgency=low
+
+  * Update entry theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-4
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 20 Sep 2011 10:57:06 -0700
+calculator (0.1.3-3) unstable; urgency=low
+
+  * change the charactor color on black theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-3
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 17 Sep 2011 16:43:06 -0700
+calculator (0.1.3-2) unstable; urgency=low
+
+  * Resolve the leak of memory in calculate
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-2
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 16 Sep 2011 09:00:06 -0700
+calculator (0.1.3-1) unstable; urgency=low
+
+  * Restrict the validity of input on paste
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.3-1
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 13 Sep 2011 16:30:06 -0700
+calculator (0.1.2-99) unstable; urgency=low
+
+  * Fix the bug about strcpy and strcat on prevent
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-99
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 08 Sep 2011 10:30:06 -0700
+
+calculator (0.1.2-98) unstable; urgency=low
+
+  * Fix the bug that the same popup display many times
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-98
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 05 Sep 2011 16:50:06 -0700
+
+calculator (0.1.2-97) unstable; urgency=low
+
+  * Solve a issue that long expression inputting get slower.
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-97
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 03 Sep 2011 13:43:15 +0800
+
+calculator (0.1.2-96) unstable; urgency=low
+
+  * Fix rotate issue when popup shown.
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-96
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 03 Sep 2011 10:24:58 +0800
+
+calculator (0.1.2-95) unstable; urgency=low
+
+  * Correct cursor position in landscape.
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-95
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 03 Sep 2011 09:56:05 +0800
+
+calculator (0.1.2-94) unstable; urgency=low
+
+  * Replace the hard code about muti Language and add shake and sound on keypad
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-94
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 2 Sep 2011 11:20:06 -0700
+calculator (0.1.2-93) unstable; urgency=low
+
+  * Fix the wrong popup shows in Turkce
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-93
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 25 Aug 2011 16:20:06 -0700
+calculator (0.1.2-92) unstable; urgency=low
+
+  * Fix bugs caused by multi language
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-92
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 10 Aug 2011 13:45:06 -0700
+calculator (0.1.2-91) unstable; urgency=low
+
+  * Modify entry theme for adapt to the black Theme
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-91
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 03 Aug 2011 16:45:06 -0700
+calculator (0.1.2-90) unstable; urgency=low
+
+  * Correct the line wrap way of entry and remove the unused code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-90
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 29 Jul 2011 08:45:06 -0700
+calculator (0.1.2-89) unstable; urgency=low
+
+  * Modify for history entry display unormally caused by Elementary Migration
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-89
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 27 Jul 2011 10:06:06 -0700
+calculator (0.1.2-88) unstable; urgency=low
+
+  * Elementary Migration and remove warnings
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-88
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 21 Jul 2011 13:18:06 -0700
+calculator (0.1.2-86) unstable; urgency=low
+
+  * Clean up code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-86
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 13 Jul 2011 11:18:06 -0700
+calculator (0.1.2-85) unstable; urgency=low
+
+  * Fix the bug unable to delete copied numbers
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-85
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 4 May 2011 13:40:06 -0700
+calculator (0.1.2-84) unstable; urgency=low
+
+  * fix the bug that sensitive is too low on backspace button
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-84
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 3 May 2011 16:40:06 -0700
+calculator (0.1.2-83) unstable; urgency=low
+
+  * Change unsafe string C library function
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-83
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 3 May 2011 11:40:06 -0700
+calculator (0.1.2-82) unstable; urgency=low
+
+  * change the transparency of the clear image and fix the bug about unexpected exit
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-82
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 29 Apr 2011 16:40:06 -0700
+calculator (0.1.2-81) unstable; urgency=low
+
+  * change the use of CFLAGS
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-81
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 27 Apr 2011 19:01:06 -0700
+
+calculator (0.1.2-80) unstable; urgency=low
+
+  * fix the bug can't focus the result in entry
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-80
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 27 Apr 2011 11:36:51 +0800
+calculator (0.1.2-79) unstable; urgency=low
+
+  * Set different font when rotate
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-79
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 23 Apr 2011 15:36:51 +0800
+calculator (0.1.2-78) unstable; urgency=low
+
+  * modify for new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-78
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 22 Apr 2011 08:53:51 +0800
+
+calculator (0.1.2-77) unstable; urgency=low
+
+  * modify for new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-77
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 21 Apr 2011 17:23:23 +0800
+
+calculator (0.1.2-76) unstable; urgency=low
+
+  * ../util.sh -P -m "modify the background and icon"
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-76
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 19 Apr 2011 13:46:24 +0800
+
+calculator (0.1.2-75) unstable; urgency=low
+
+  * develop the new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-75
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 18 Apr 2011 17:50:25 +0800
+
+calculator (0.1.2-74) unstable; urgency=low
+
+  * develop the new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-74
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 18 Apr 2011 17:48:15 +0800
+
+calculator (0.1.2-73) unstable; urgency=low
+
+  * develop the new GUI
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-73
+
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 18 Apr 2011 17:36:19 +0800
+
+calculator (0.1.2-72) unstable; urgency=low
+
+  * apply new  App. name policy
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-72
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 11 Apr 2011 18:07:19 +0800
+
+calculator (0.1.2-71) unstable; urgency=low
+
+  * fix BS after paste many charactor
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-71
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 31 Mar 2011 08:32:11 +0800
+
+calculator (0.1.2-70) unstable; urgency=low
+
+  * remove fakeimage
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-70
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 18 Mar 2011 09:58:12 +0800
+
+calculator (0.1.2-69) unstable; urgency=low
+
+  * add long press function for delete
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-69
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 17 Mar 2011 08:59:32 +0800
+
+calculator (0.1.2-68) unstable; urgency=low
+
+  * fix application directory
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-68
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 11 Mar 2011 10:06:42 +0800
+
+calculator (0.1.2-67) unstable; urgency=low
+
+  * fix the bug
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-67
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 03 Mar 2011 10:15:42 +0800
+
+calculator (0.1.2-66) unstable; urgency=low
+
+  * deupload
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-66
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 24 Feb 2011 16:53:24 +0800
+
+calculator (0.1.2-65) unstable; urgency=low
+
+  * reduce the size of images
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-65
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 24 Feb 2011 15:12:12 +0800
+
+calculator (0.1.2-64) unstable; urgency=low
+
+  * fix CQ bug
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-64
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 17 Feb 2011 13:43:10 +0800
+
+calculator (0.1.2-63) unstable; urgency=low
+
+  * fix the CQ bug
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-63
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 16 Feb 2011 17:00:35 +0800
+
+calculator (0.1.2-62) unstable; urgency=low
+
+  * rollback, the calculator is allowed to be opened as landscape mode
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-62
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 16 Feb 2011 15:58:58 +0800
+
+calculator (0.1.2-61) unstable; urgency=low
+
+  * modify for prevent test and fix bug H0100119893
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-61
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 12 Feb 2011 15:29:21 +0800
+
+calculator (0.1.2-60) unstable; urgency=low
+
+  * fix prevent defect
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-60
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 11 Feb 2011 19:11:16 +0800
+
+calculator (0.1.2-59) unstable; urgency=low
+
+  * add history to calculator
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-59
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 10 Feb 2011 17:46:25 +0800
+
+calculator (0.1.2-58) unstable; urgency=low
+
+  * add history to calculator
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-58
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Thu, 10 Feb 2011 16:01:07 +0800
+
+calculator (0.1.2-57) unstable; urgency=low
+
+  * Change icon for new launcher
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-57
+
+ -- Junho Lee <junho4810.lee@samsung.com>  Tue, 08 Feb 2011 21:48:39 +0900
+
+calculator (0.1.2-56) unstable; urgency=low
+
+  * Change icon for new launcher
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-56
+
+ -- Junho Lee <junho4810.lee@samsung.com>  Tue, 08 Feb 2011 21:07:53 +0900
+
+calculator (0.1.2-55) unstable; urgency=low
+
+  * Change icon path
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-55
+
+ -- Junho Lee <junho4810.lee@samsung.com>  Mon, 07 Feb 2011 09:57:18 +0900
+
+calculator (0.1.2-54) unstable; urgency=low
+
+  * rollback the desktop icon
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-54
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 31 Jan 2011 18:40:28 +0800
+
+calculator (0.1.2-53) unstable; urgency=low
+
+  * apply new desktop icon
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-53
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 31 Jan 2011 11:59:30 +0800
+
+calculator (0.1.2-52) unstable; urgency=low
+
+  * fix CQ bugs and change the icon path
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-52
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 29 Jan 2011 18:20:53 +0800
+
+calculator (0.1.2-51) unstable; urgency=low
+
+  * use text only in entry
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-51
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 24 Jan 2011 15:53:00 +0800
+
+calculator (0.1.2-50) unstable; urgency=low
+
+  * remove hard code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-50
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Wed, 19 Jan 2011 11:07:50 +0800
+
+calculator (0.1.2-49) unstable; urgency=low
+
+  * remove hard code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-49
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 18 Jan 2011 17:07:18 +0800
+
+calculator (0.1.2-48) unstable; urgency=low
+
+  * remove hard code
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-48
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Tue, 18 Jan 2011 12:31:54 +0800
+
+calculator (0.1.2-47) unstable; urgency=low
+
+  * change application directory
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-47
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 17 Jan 2011 12:08:57 +0800
+
+calculator (0.1.2-46) unstable; urgency=low
+
+  * change application directory
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-46
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Mon, 17 Jan 2011 12:08:50 +0800
+
+calculator (0.1.2-45) unstable; urgency=low
+
+  * change application directory
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-45
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 15 Jan 2011 17:44:37 +0800
+
+calculator (0.1.2-44) unstable; urgency=low
+
+  * remove the API elm_ entry _text_align_set
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-44
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Fri, 14 Jan 2011 14:31:47 +0800
+
+calculator (0.1.2-43) unstable; urgency=low
+
+  * prevent pasting image
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-43
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 20 Dec 2010 14:16:10 +0800
+
+calculator (0.1.2-42) unstable; urgency=low
+
+  * increase a version
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-42
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 14 Dec 2010 16:43:37 +0800
+
+calculator (0.1.2-41) unstable; urgency=low
+
+  * for GUI v0.5
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-41
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 11 Dec 2010 13:37:13 +0800
+
+calculator (0.1.2-40) unstable; urgency=low
+
+  * modify git address in changelog
+  * Git: git@165.213.180.234:slp/apps/c/calculator
+  * Tag: calculator_0.1.2-40
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 07 Dec 2010 14:52:58 +0800
+
+calculator (0.1.2-39) unstable; urgency=low
+
+  * modify git address in changelog
+  * Git: git@165.213.180.234:slp/apps/c/calculator/
+  * Tag: calculator_0.1.2-39
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 07 Dec 2010 14:38:42 +0800
+
+calculator (0.1.2-38) unstable; urgency=low
+
+  * update
+  * Git: 165.213.180.234:slp/apps/c/calculator/
+  * Tag: calculator_0.1.2-38
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 07 Dec 2010 09:11:24 +0800
+
+calculator (0.1.2-37) unstable; urgency=low
+
+  * update for new git repository
+  * Git: 165.213.180.234:slp/apps/c/calculator/
+  * Tag: calculator_0.1.2-37
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 06 Dec 2010 13:41:51 +0800
+
+calculator (0.1.2-36) unstable; urgency=low
+
+  * fix bug about cut & paste
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-36
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 03 Dec 2010 10:26:40 +0800
+
+calculator (0.1.2-35) unstable; urgency=low
+
+  * fix bugs H0100113897 and H0100113899
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-35
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 02 Dec 2010 10:23:20 +0800
+
+calculator (0.1.2-34) unstable; urgency=low
+
+  * increase a version
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-34
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 29 Nov 2010 14:04:34 +0800
+
+calculator (0.1.2-33) unstable; urgency=low
+
+  * increase a version
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-33
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 26 Nov 2010 15:30:02 +0800
+
+calculator (0.1.2-32) unstable; urgency=low
+
+  * correct debian/deb.com.samsung.calculator.postinst
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-32
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 25 Nov 2010 15:37:34 +0800
+
+calculator (0.1.2-31) unstable; urgency=low
+
+  * comment debian/deb.com.samsung.calculator.postinst
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-31
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 25 Nov 2010 14:14:12 +0800
+
+calculator (0.1.2-30) unstable; urgency=low
+
+  * modify debian/deb.com.samsung.calculator.postinst
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-30
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 25 Nov 2010 14:11:19 +0800
+
+calculator (0.1.2-29) unstable; urgency=low
+
+  * rename postinst file
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-29
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 24 Nov 2010 16:18:13 +0800
+
+calculator (0.1.2-28) unstable; urgency=low
+
+  * rename package name & modify desktop file
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-28
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 24 Nov 2010 12:29:09 +0800
+
+calculator (0.1.2-27) unstable; urgency=low
+
+  * correct help string
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-27
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 23 Nov 2010 09:13:52 +0800
+
+calculator (0.1.2-26) unstable; urgency=low
+
+  * Bracket add automatically.
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-26
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 22 Nov 2010 11:22:06 +0800
+
+calculator (0.1.2-25) unstable; urgency=low
+
+  * modify debian/rules for dbg-package
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-25
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 11 Nov 2010 08:42:02 +0800
+
+calculator (0.1.2-24) unstable; urgency=low
+
+  * remove libui-window dependence
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-24
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 04 Nov 2010 08:50:30 +0800
+
+calculator (0.1.2-23) unstable; urgency=low
+
+  * change in to ln
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-23
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 03 Nov 2010 16:39:54 +0800
+
+calculator (0.1.2-22) unstable; urgency=low
+
+  * fix bugs on CQ and dupload.
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-22
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 01 Nov 2010 13:46:58 +0800
+
+calculator (0.1.2-21) unstable; urgency=low
+
+  * fix a bug about +/- with science number.
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-21
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 30 Oct 2010 17:20:06 +0800
+
+calculator (0.1.2-20) unstable; urgency=low
+
+  * update font size and color
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-20
+
+ -- Zhou Zhibin <zhibin.zhou@samsung.com>  Wed, 27 Oct 2010 16:31:07 +0800
+
+calculator (0.1.2-19) unstable; urgency=low
+
+  * update po files
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-19
+
+ -- Zhou Zhibin <zhibin.zhou@samsung.com>  Tue, 26 Oct 2010 16:37:07 +0800
+
+calculator (0.1.2-18) unstable; urgency=low
+
+  * update po files
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-18
+
+ -- Chen Hanwen <hanwen.chen@samsung.com>  Thu, 21 Oct 2010 16:29:29 +0800
+
+calculator (0.1.2-17) unstable; urgency=low
+
+  * Update main menu icon
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-17
+
+ -- Chen Hanwen <hanwen.chen@samsung.com>  Thu, 21 Oct 2010 10:23:08 +0800
+
+calculator (0.1.2-16) unstable; urgency=low
+
+  * reupload
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-16
+
+ -- Chen Hanwen <hanwen.chen@samsung.com>  Mon, 18 Oct 2010 14:05:32 +0800
+
+calculator (0.1.2-15) unstable; urgency=low
+
+  * update changelog
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-15
+
+ -- Zhou Zhibin <zhibin.zhou@samsung.com>  Mon, 18 Oct 2010 13:48:44 +0800
+
+calculator (0.1.2-14) unstable; urgency=low
+
+  * apply latest GUI and modify desktop.in
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-14
+
+ -- Zhou Zhibin <zhibin.zhou@samsung.com>  Mon, 18 Oct 2010 13:29:09 +0800
+
+calculator (0.1.2-13) unstable; urgency=low
+
+  * apply multi languages: System string
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-13
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 11 Oct 2010 13:14:02 +0800
+
+calculator (0.1.2-12) unstable; urgency=low
+
+  * add ui_idlecapture_exists
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-12
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 11 Oct 2010 10:07:00 +0800
+
+calculator (0.1.2-11) unstable; urgency=low
+
+  * dupload
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-11
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 29 Sep 2010 11:27:25 +0800
+
+calculator (0.1.2-10) unstable; urgency=low
+
+  * scalable ui
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-10
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 27 Sep 2010 16:26:33 +0800
+
+calculator (0.1.2-9) unstable; urgency=low
+
+  * correct idle image
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-9
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 25 Sep 2010 17:21:09 +0800
+
+calculator (0.1.2-8) unstable; urgency=low
+
+  * modify for sin/cos/tan without '('
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-8
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 24 Sep 2010 15:44:18 +0800
+
+calculator (0.1.2-7) unstable; urgency=low
+
+  * set text align to right & clean up help string
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-7
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 23 Sep 2010 16:32:31 +0800
+
+calculator (0.1.2-6) unstable; urgency=low
+
+  * add ui-window dependence for build break
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-6
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 21 Sep 2010 17:17:51 +0800
+
+calculator (0.1.2-5) unstable; urgency=low
+
+  * modify desktop file for  multi-resolution
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-5
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 21 Sep 2010 17:09:39 +0800
+
+calculator (0.1.2-4) unstable; urgency=low
+
+  * fix cursor & clean
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-4
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 15 Sep 2010 10:55:00 +0800
+
+calculator (0.1.2-3) unstable; urgency=low
+
+  * change new theme API
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-3
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 13 Sep 2010 16:48:12 +0800
+
+calculator (0.1.2-2) unstable; urgency=low
+
+  * update
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.2-2
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 13 Sep 2010 09:55:40 +0800
+
+converter (0.1.2-1) unstable; urgency=low
+
+  * implement new GUI
+  * Git: 165.213.180.234:/git/slp/apps/converter/
+  * Tag: converter_0.1.2-1
+
+ -- Yang Qing <qing_.yang@samsung.com>  Mon, 13 Sep 2010 09:48:29 +0800
+
+calculator (0.1.1-92) unstable; urgency=low
+
+  * change for upload
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.1-92
+
+ -- Zhao Danni <danni.zhao@samsung.com>  Sat, 11 Sep 2010 10:38:06 +0800
+
+calculator (0.1.1-91) unstable; urgency=low
+
+  * remove deleting long press
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.1-91
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 09 Sep 2010 13:09:13 +0800
+
+calculator (0.1.1-90) unstable; urgency=low
+
+  * delay deleting timer
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.1-90
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 09 Sep 2010 10:58:06 +0800
+
+calculator (0.1.1-89) unstable; urgency=low
+
+  * update version
+  * Git: 165.213.180.234:/git/slp/apps/calculator/
+  * Tag: calculator_0.1.1-89
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 08 Sep 2010 10:35:01 +0800
+
+calculator (0.1.1-88) unstable; urgency=low
+
+  * optimze launching tmie & fix bug
+  * Git: 165.213.180.234:/git/slp/apps/calcualtor/
+  * Tag: calculator_0.1.1-88
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 08 Sep 2010 10:23:58 +0800
+
+calculator (0.1.1-87) unstable; urgency=low
+
+  * use LED font
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-87
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 04 Sep 2010 16:05:54 +0800
+
+calculator (0.1.1-86) unstable; urgency=low
+
+  * add input area scroller
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-86
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 02 Sep 2010 17:13:54 +0800
+
+calculator (0.1.1-85) unstable; urgency=low
+
+  * add comma
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-85
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 01 Sep 2010 17:19:21 +0800
+
+calculator (0.1.1-84) unstable; urgency=low
+
+  * update input area
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-84
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 31 Aug 2010 14:56:13 +0800
+
+calculator (0.1.1-83) unstable; urgency=low
+
+  * use modeless popup
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-83
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 27 Aug 2010 13:24:59 +0800
+
+calculator (0.1.1-82) unstable; urgency=low
+
+  * fix bug about popup
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-82
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 14 Aug 2010 10:10:36 +0800
+
+calculator (0.1.1-81) unstable; urgency=low
+
+  * apply new appcore frame
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-81
+
+ -- Yang Qing <qing_.yang@samsung.com>  Thu, 05 Aug 2010 09:17:32 +0800
+
+calculator (0.1.1-80) unstable; urgency=low
+
+  * modify exprssion parser
+  * Git: 165.213.180.234:/git/slp/apps/calculator
+  * Tag: calculator_0.1.1-80
+
+ -- Yang Qing <qing_.yang@samsung.com>  Sat, 31 Jul 2010 14:17:24 +0800
+
+calculator (0.1.1-79) unstable; urgency=low
+
+  * modify security
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-79
+
+ -- Yang Qing <qing_.yang@samsung.com>  Wed, 28 Jul 2010 09:22:58 +0800
+
+calculator (0.1.1-78) unstable; urgency=low
+
+  * optimize +/- func
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-78
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 27 Jul 2010 13:15:13 +0800
+
+calculator (0.1.1-77) unstable; urgency=low
+
+  * correct cursor position when press +/-
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-77
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 23 Jul 2010 17:14:24 +0800
+
+calculator (0.1.1-76) unstable; urgency=low
+
+  * omit parenthesis of sin/cos/tan
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-76
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 23 Jul 2010 08:20:22 +0800
+
+calculator (0.1.1-75) unstable; urgency=low
+
+  * fix a bug about cursor
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-75
+
+ -- Yang Qing <qing_.yang@samsung.com>  Tue, 20 Jul 2010 09:06:45 +0800
+
+calculator (0.1.1-74) unstable; urgency=low
+
+  * fix version
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-74
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 16 Jul 2010 15:03:56 +0800
+
+calculator (0.1.1-73) unstable; urgency=low
+
+  * Fix bug about system keypad popup
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-73
+
+ -- Yang Qing <qing_.yang@samsung.com>  Fri, 16 Jul 2010 14:00:12 +0800
+
+calculator (0.1.1-72) unstable; urgency=low
+
+  * modify cursor moving.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-72
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 06 July 2010 10:30:00 +0800
+
+calculator (0.1.1-71) unstable; urgency=low
+
+  * back to original expression at violating rules.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-71
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 06 July 2010 10:00:00 +0800
+
+calculator (0.1.1-70) unstable; urgency=low
+
+  * solve repeat tapping same key problem.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-70
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 05 July 2010 16:30:00 +0800
+
+calculator (0.1.1-69) unstable; urgency=low
+
+  * short response time at tapping key.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-69
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 28 June 2010 11:30:00 +0800
+
+calculator (0.1.1-68) unstable; urgency=low
+
+  * auto font after paste.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-68
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 28 June 2010 11:00:00 +0800
+
+calculator (0.1.1-67) unstable; urgency=low
+
+  * add expression length check before tapping '='.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-67
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 24 June 2010 17:40:00 +0800
+
+calculator (0.1.1-66) unstable; urgency=low
+
+  * modify calculator_expression_check function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-66
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 24 June 2010 15:40:00 +0800
+
+calculator (0.1.1-65) unstable; urgency=low
+
+  * modify calculator_expression_check function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-65
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 24 June 2010 11:40:00 +0800
+
+calculator (0.1.1-64) unstable; urgency=low
+
+  * modify calculator_expression_check function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-64
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 24 June 2010 11:00:00 +0800
+
+calculator (0.1.1-63) unstable; urgency=low
+
+  * modify calculator_expression_check function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-63
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 23 June 2010 15:30:00 +0800
+
+calculator (0.1.1-62) unstable; urgency=low
+
+  * modify copy/cut/paste function.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-62
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 22 June 2010 17:00:00 +0800
+
+calculator (0.1.1-61) unstable; urgency=low
+
+  * update Widget_Entry_Data structure.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-61
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 18 June 2010 10:30:00 +0800
+
+calculator (0.1.1-60) unstable; urgency=low
+
+  * remove UI-window dependency.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-60
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 18 June 2010 10:30:00 +0800
+
+calculator (0.1.1-59) unstable; urgency=low
+
+  * fix potential overflow.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-59
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 17 June 2010 15:00:00 +0800
+
+calculator (0.1.1-58) unstable; urgency=low
+
+  * solve auto font problem.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-58
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 16 June 2010 10:30:00 +0800
+
+calculator (0.1.1-57) unstable; urgency=low
+
+  * remove applog.h.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-57
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 16 June 2010 9:00:00 +0800
+
+calculator (0.1.1-56) unstable; urgency=low
+
+  * apply new dlog.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-56
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 15 June 2010 15:30:00 +0800
+
+calculator (0.1.1-55) unstable; urgency=low
+
+  * modify debian rules.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-55
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 14 June 2010 21:30:00 +0800
+
+calculator (0.1.1-54) unstable; urgency=low
+
+  * repackage.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-54
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 14 June 2010 21:00:00 +0800
+
+calculator (0.1.1-53) unstable; urgency=low
+
+  * EFL update.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-53
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 11 June 2010 9:30:00 +0800
+
+calculator (0.1.1-52) unstable; urgency=low
+
+  * EFL update.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-52
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 11 June 2010 9:00:00 +0800
+
+calculator (0.1.1-51) unstable; urgency=low
+
+  * solve problem that sometimes more than one chars are deleted at one tapping.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-51
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 9 June 2010 17:00:00 +0800
+
+calculator (0.1.1-50) unstable; urgency=low
+
+  * replace elm_notify widget with elm_popup widget.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-50
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 9 June 2010 9:00:00 +0800
+
+calculator (0.1.1-49) unstable; urgency=low
+
+  * close debug macro.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-49
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tue, 8 June 2010 11:00:00 +0800
+
+calculator (0.1.1-48) unstable; urgency=low
+
+  * remove permission to executable file from calculator.postinst.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-48
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thus, 3 June 2010 13:30:00 +0800
+
+calculator (0.1.1-47) unstable; urgency=low
+
+  * modify font entry width setting to auto font accurately.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-47
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thus, 3 June 2010 10:00:00 +0800
+
+calculator (0.1.1-46) unstable; urgency=low
+
+  * remove some deprecated source code.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-46
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 2 June 2010 10:00:00 +0800
+
+calculator (0.1.1-45) unstable; urgency=low
+
+  * re-fix problem that digits overlap with indicator.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-45
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 1 June 2010 17:00:00 +0800
+
+calculator (0.1.1-44) unstable; urgency=low
+
+  * use appcore to manage app's life cycle.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-44
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 1 June 2010 17:00:00 +0800
+
+calculator (0.1.1-43) unstable; urgency=low
+
+  * fix problem that digits overlap with indicator.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-43
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 1 June 2010 11:00:00 +0800
+
+calculator (0.1.1-42) unstable; urgency=low
+
+  * modify entry for scalable ui.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-42
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 31 May 2010 13:30:00 +0800
+
+calculator (0.1.1-41) unstable; urgency=low
+
+  * remove libprivilege-control package.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-41
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 31 May 2010 10:00:00 +0800
+
+calculator (0.1.1-40) unstable; urgency=low
+
+  * modify entry for font auto suitable.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-40
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Sun, 30 May 2010 11:40:16 +0800
+
+calculator (0.1.1-39) unstable; urgency=low
+
+  * remove sysman and modify for scalable.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-39
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Sat, 29 May 2010 15:00:16 +0800
+
+calculator (0.1.1-38) unstable; urgency=low
+
+  * clean maintainer in debian/control.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-38
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 28 May 2010 15:50:16 +0800
+
+calculator (0.1.1-37) unstable; urgency=low
+
+  * add sysman and libslp-sysman-dev to CMakeLists.txt and debian/control.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-37
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 27 May 2010 13:30:16 +0800
+
+calculator (0.1.1-36) unstable; urgency=low
+
+  * change appfwk to appcore.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-36
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Thu, 27 May 2010 22:30:16 +0800
+
+calculator (0.1.1-35) unstable; urgency=low
+
+  * cleanup deprecated functions
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-35
+
+ -- Chen Hanwen <hanwen.chen@samsung.com>  Wed, 19 May 2010 11:08:16 +0800
+
+calculator (0.1.1-34) unstable; urgency=low
+
+  * apply libprivilege-control package.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-34
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 19 May 2010 15:04:12 +0800
+
+calculator (0.1.1-33) unstable; urgency=low
+
+  * EFL update.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-33
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Tues, 18 May 2010 17:33:12 +0800
+
+calculator (0.1.1-32) unstable; urgency=low
+
+  * fix UI break problem.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-32
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Mon, 26 Apr 2010 16:30:12 +0900
+
+calculator (0.1.1-31) unstable; urgency=low
+
+  * fix flash phenomenon and flash at switching to landscape.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-31
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Wed, 21 Apr 2010 11:00:12 +0900
+
+calculator (0.1.1-30) unstable; urgency=low
+
+  * modify calculator.postinst.
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-30
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Sat, 17 Apr 2010 17:00:12 +0900
+
+calculator (0.1.1-29) unstable; urgency=low
+
+  * apply permission and ownership
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-29
+
+ -- Zhou Jinhua <jinhua.zhou@samsung.com>  Fri, 16 Apr 2010 17:00:12 +0900
+
+calculator (0.1.1-28) unstable; urgency=low
+
+  * apply -fpie and -pie build option
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/calculator-0
+  * Tag: calculator_0.1.1-28
+
+ -- deokjin kim <deokjin81.kim@samsung.com>  Mon, 12 Apr 2010 12:57:12 +0900
+
+calculator (0.1.1-27) unstable; urgency=low
+
+  * fix can't enter calculator problem in p1
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 06 Apr 2010 14:41:47 +0800
+
+calculator (0.1.1-26) unstable; urgency=low
+
+  * bug fix
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 30 Mar 2010 10:41:47 +0800
+
+calculator (0.1.1-25) unstable; urgency=low
+
+  * bug fix
+
+ -- Ge Lu <lu.ge@samsung.com>  Sat, 27 Mar 2010 12:41:47 +0800
+
+calculator (0.1.1-24) unstable; urgency=low
+
+  * Toolchain upgrade.
+
+ -- Ge Lu <lu.ge@samsung.com>  Thu, 25 Mar 2010 13:41:47 +0800
+
+calculator (0.1.1-23) unstable; urgency=low
+
+  * fix bugs about error message.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 23 Mar 2010 20:41:47 +0800
+
+calculator (0.1.1-22) unstable; urgency=low
+
+  * bug fix
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 19 Mar 2010 15:41:47 +0800
+
+calculator (0.1.1-21) unstable; urgency=low
+
+  * apply new rules
+
+ -- Ge Lu <lu.ge@samsung.com>  Thu, 18 Mar 2010 16:41:47 +0800
+
+calculator (0.1.1-20) unstable; urgency=low
+
+  * reupload
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 16 Mar 2010 9:43:43 +0800
+
+calculator (0.1.1-19) unstable; urgency=low
+
+  * fix the bugs about display
+
+ -- Ge Lu <lu.ge@samsung.com>  Mon, 15 Mar 2010 17:43:43 +0800
+
+calculator (0.1.1-18) unstable; urgency=low
+
+  * change theme
+
+ -- Ge Lu <lu.ge@samsung.com>  Thu, 11 Mar 2010 10:40:35 +0800
+
+calculator (0.1.1-17) unstable; urgency=low
+
+  * bug fix.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 09 Mar 2010 12:40:35 +0800
+
+calculator (0.1.1-16) unstable; urgency=low
+
+  * font change.
+
+ -- Ge Lu <lu.ge@samsung.com>  Mon, 01 Mar 2010 11:40:35 +0800
+
+calculator (0.1.1-15) unstable; urgency=low
+
+  * scalable calculator, pannel slide effect.
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 26 Feb 2010 17:30:35 +0800
+
+calculator (0.1.1-14) unstable; urgency=low
+
+  * scalable calculator.
+
+ -- Ge Lu <lu.ge@samsung.com>  Thur, 25 Feb 2010 10:30:35 +0800
+
+calculator (0.1.1-13) unstable; urgency=low
+
+  * apply new requirement.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 23 Feb 2010 18:10:35 +0800
+
+calculator (0.1.1-12) unstable; urgency=low
+
+  * reupload
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 23 Feb 2010 10:10:35 +0800
+
+calculator (0.1.1-11) unstable; urgency=low
+
+  * new indicator.
+
+ -- Ge Lu <lu.ge@samsung.com>  Mon, 22 Feb 2010 15:10:35 +0800
+
+calculator (0.1.1-10) unstable; urgency=low
+
+  * fix the defect, enable softkey pad button work
+
+ -- Jiping Cui <jiping.cui@samsung.com>  Fri, 19 Feb 2010 16:44:35 +0800
+
+calculator (0.1.1-9) unstable; urgency=low
+
+  * flick pannel, rotate with resize.
+
+ -- Ge Lu <lu.ge@samsung.com>  Thu, 11 Feb 2010 9:57:09 +0800
+
+calculator (0.1.1-8) unstable; urgency=low
+
+  * fix BS problem when change win mode.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 09 Feb 2010 16:57:09 +0800
+
+calculator (0.1.1-7) unstable; urgency=low
+
+  * yellow operator.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 09 Feb 2010 15:57:09 +0800
+
+calculator (0.1.1-6) unstable; urgency=low
+
+  * auto font entry. yellow text.
+
+ -- Ge Lu <lu.ge@samsung.com>  Mon, 08 Feb 2010 19:57:09 +0800
+
+calculator (0.1.1-5) unstable; urgency=low
+
+  * increase limit for overflow.
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 05 Feb 2010 19:57:09 +0800
+
+calculator (0.1.1-4) unstable; urgency=low
+
+  * fix pannel overlap with text problem in landscape.
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 05 Feb 2010 19:26:09 +0800
+
+calculator (0.1.1-3) unstable; urgency=low
+
+  * resize popup textblock.
+
+ -- Ge Lu <lu.ge@samsung.com>  Fri, 05 Feb 2010 13:26:09 +0800
+
+calculator (0.1.1-2) unstable; urgency=low
+
+  * add changelog
+
+ -- jiyoun jeon <jyjeon@samsung.com>  Fri, 05 Feb 2010 10:06:09 +0900
+
+calculator (0.1.1-1) unstable; urgency=low
+
+  * add multi-lingual
+
+ -- jiyoun jeon <jyjeon@samsung.com>  Thu, 04 Feb 2010 20:28:10 +0900
+
+calculator (0.1.0-11.10) unstable; urgency=low
+
+  * support multi-lingual for menutree
+
+ -- jiyoun jeon <jyjeon@samsung.com>  Thu, 04 Feb 2010 13:21:16 +0900
+
+calculator (0.1.0-11.9) unstable; urgency=low
+
+  * add maintainer
+
+ -- Xiang Chun <chun.xiang@samsung.com>  Wed, 03 Feb 2010 22:31:55 +0800
+
+calculator (0.1.0-11.8) unstable; urgency=low
+
+  * use standard layout
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 3 Feb 2010 20:00:14 +0800
+
+calculator (0.1.0-11.7) unstable; urgency=low
+
+  * apply new GUI.
+
+ -- Ge Lu <lu.ge@samsung.com>  Tue, 2 Feb 2010 19:00:14 +0800
+
+calculator (0.1.0-11.6) unstable; urgency=low
+
+  * clean up old api.
+
+ -- Ji-Youn Jeon <jyjeon@samsung.com>  Sat, 30 Jan 2010 18:00:14 +0800
+
+calculator (0.1.0-11.5) unstable; urgency=low
+
+  * apply new fwk API.
+
+ -- Ji-Youn Jeon <jyjeon@samsung.com>  Wed, 27 Jan 2010 10:00:14 +0800
+
+calculator (0.1.0-11.4) unstable; urgency=low
+
+  * apply new cursor
+
+ -- Young-June Woo <june@samsung.com>  Sun, 24 Jan 2010 15:40:40 +0800
+
+calculator (0.1.0-11.3) unstable; urgency=low
+
+  * change popup, cursor
+
+ -- Young-June Woo <june@samsung.com>  Sat, 23 Jan 2010 21:40:40 +0800
+
+calculator (0.1.0-11.2) unstable; urgency=low
+
+  * update icon.
+
+ -- Young-June Woo <june@samsung.com>  Sat, 23 Jan 2010 15:30:40 +0800
+
+calculator (0.1.0-11.1) unstable; urgency=low
+
+  * remove warning.
+
+ -- Young-June Woo <june@samsung.com>  Sat, 23 Jan 2010 11:30:40 +0800
+
+calculator (0.1.0-11) unstable; urgency=low
+
+  * long press, negtive, GUI
+
+ -- Young-June Woo <june@samsung.com>  Fri, 22 Jan 2010 16:30:40 +0800
+
+calculator (0.1.0-10.19) unstable; urgency=low
+
+  * apply new EFL widgets
+
+ -- Young-June Woo <june@samsung.com>  Fri, 22 Jan 2010 13:30:40 +0800
+
+calculator (0.1.0-10.18) unstable; urgency=low
+
+  * update for new efl
+
+ -- Young-June Woo <june@samsung.com>  Fri, 22 Jan 2010 11:00:40 +0800
+
+calculator (0.1.0-10.17) unstable; urgency=low
+
+  * bug fix.
+
+ -- Young-June Woo <june@samsung.com>  Tue, 19 Jan 2010 11:40:40 +0800
+
+calculator (0.1.0-10.16) unstable; urgency=low
+
+  * update desktop file.
+
+ -- Young-June Woo <june@samsung.com>  Mon, 18 Jan 2010 16:40:40 +0800
+
+calculator (0.1.0-10.15.5) unstable; urgency=low
+
+  * Modified text size
+
+ -- Sun Choi <sun0467.choi@samsung.com>  Sat, 16 Jan 2010 16:36:46 +0900
+
+calculator (0.1.0-10.15.4) unstable; urgency=low
+
+  * change control file.
+
+ -- Young-June Woo <june@samsung.com>  Fri, 15 Jan 2010 17:40:40 +0800
+
+calculator (0.1.0-10.15.3) unstable; urgency=low
+
+  * pannel down screen.
+
+ -- GeLu <lu.ge@samsung.com>  Tur, 14 Jan 2010 17:30:40 +0800
+
+calculator (0.1.0-10.15.2) unstable; urgency=low
+
+  * change font, 1/x.
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 13 Jan 2010 21:30:40 +0800
+
+calculator (0.1.0-10.15.1) unstable; urgency=low
+
+  * apply new GUI
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 13 Jan 2010 17:00:40 +0800
+
+calculator (0.1.0-10.15) unstable; urgency=low
+
+  * landscape
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 12 Jan 2010 17:00:40 +0800
+
+calculator (0.1.0-10.14) unstable; urgency=low
+
+  * bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 5 Jan 2010 10:40:40 +0800
+
+calculator (0.1.0-10.13) unstable; urgency=low
+
+  * bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Mon, 4 Jan 2010 11:40:40 +0800
+
+calculator (0.1.0-10.12) unstable; urgency=low
+
+  * add backspace key.
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 30 Dec 2009 10:29:40 +0800
+
+calculator (0.1.0-10.11) unstable; urgency=low
+
+  * add maintainers in control file.
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 29 Dec 2009 17:29:40 +0800
+
+calculator (0.1.0-10.10) unstable; urgency=low
+
+  * truncate result. bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 28 Dec 2009 10:55:40 +0800
+
+calculator (0.1.0-10.9) unstable; urgency=low
+
+  * format input and output
+
+ -- GeLu <lu.ge@samsung.com>  Sat, 26 Dec 2009 14:37:40 +0800
+
+calculator (0.1.0-10.8) unstable; urgency=low
+
+  * add popup to show syntax error.
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 23 Dec 2009 16:05:40 +0800
+
+calculator (0.1.0-10.7) unstable; urgency=low
+
+  * change '()' key
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 22 Dec 2009 21:05:40 +0800
+
+calculator (0.1.0-10.6) unstable; urgency=low
+
+  * max len bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 22 Dec 2009 20:37:40 +0800
+
+calculator (0.1.0-10.5) unstable; urgency=low
+
+  * bug fix
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 22 Dec 2009 20:11:40 +0800
+
+calculator (0.1.0-10.4) unstable; urgency=low
+
+  * remove pannel, add "back", remove result area when input
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 22 Dec 2009 16:13:40 +0800
+
+calculator (0.1.0-10.3) unstable; urgency=low
+
+  * prepare demo
+
+ -- GeLu <lu.ge@samsung.com>  Mon, 21 Dec 2009 21:34:40 +0800
+
+calculator (0.1.0-10.2) unstable; urgency=low
+
+  * portrait only
+
+ -- GeLu <lu.ge@samsung.com>  Mon, 21 Dec 2009 18:11:40 +0800
+
+calculator (0.1.0-10.1) unstable; urgency=low
+
+  * landscape UI.
+
+ -- GeLu <lu.ge@samsung.com>  Fri, 18 Dec 2009 12:28:40 +0800
+
+calculator (0.1.0-10) unstable; urgency=low
+
+  * add state control and input check. basic calculator finish.
+
+ -- GeLu <lu.ge@samsung.com>  Wed, 16 Dec 2009 16:55:40 +0800
+
+calculator (0.1.0-9) unstable; urgency=low
+
+  * implement pannel according to GUI, fix abnormal exit bug, fix popup
+    message bug.
+
+ -- GeLu <lu.ge@samsung.com>  Tue, 15 Dec 2009 14:55:40 +0800
+
+calculator (0.1.0-8) unstable; urgency=low
+
+  * Modify API parameter
+
+ -- Seo Hee <heeya.seo@samsung.com>  Tue, 01 Dec 2009 16:01:40 +0900
+
+calculator (0.1.0-7) unstable; urgency=low
+
+  * Bugfix - Change control file
+
+ -- Seo Hee <heeya.seo@samsung.com>  Mon, 23 Nov 2009 16:36:52 +0900
+
+calculator (0.1.0-6) unstable; urgency=low
+
+  * Remove X1, SL
+
+ -- Seo Hee <heeya.seo@samsung.com>  Fri, 20 Nov 2009 20:24:01 +0900
+
+calculator (0.1.0-5) unstable; urgency=low
+
+  * Change control file
+
+ -- Seo Hee <heeya.seo@samsung.com>  Fri, 20 Nov 2009 11:22:01 +0900
+
+calculator (0.1.0-4) unstable; urgency=low
+
+  * debian/changelog
+
+ -- Seo Hee <heeya.seo@samsung.com>  Fri, 20 Nov 2009 09:53:20 +0900
+
+calculator (0.1.0-3) unstable; urgency=low
+
+  * Change copyright
+
+ -- Seo Hee <heeya.seo@samsung.com>  Tue, 17 Nov 2009 16:26:17 +0900
+
+calculator (0.1.0-2) unstable; urgency=low
+
+  * Change section value
+
+ -- Seo Hee <heeya.seo@samsung.com>  Mon, 16 Nov 2009 15:08:19 +0900
+
+calculator (0.1.0-1) unstable; urgency=low
+
+  * Unblock dn_makeshlibs
+
+ -- Seo Hee <heeya.seo@samsung.com>  Mon, 16 Nov 2009 11:31:58 +0900
+
+calculator (0.1.0) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Seo Hee <heeya.seo@samsung.com>  Sat, 14 Nov 2009 17:13:10 +0900
diff --git a/theme/debian/compat b/theme/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/theme/debian/control b/theme/debian/control
new file mode 100644 (file)
index 0000000..0f6a904
--- /dev/null
@@ -0,0 +1,20 @@
+Source: calculator
+Section: devel
+Priority: extra
+Maintainer: Zhang Xiang <x1986.zhang@samsung.com>, Wang YongJun <yj.wang@samsung.com>, Zhou Zhibin <zhibin.zhou@samsung.com>
+Uploaders:
+Build-Depends: debhelper (>= 5), libelm-dev, libslp-utilx-dev, dlog-dev, libsvi-dev, libevas-dev, libedje-dev, capi-appfw-application-dev
+Standards-Version: 0.1.0
+
+Package: org.tizen.calculator
+Section: utils
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Calculator application
+
+Package: org.tizen.calculator-dbg
+Section: debug
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Calculator application
+
diff --git a/theme/debian/dirs b/theme/debian/dirs
new file mode 100644 (file)
index 0000000..ca882bb
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
diff --git a/theme/debian/docs b/theme/debian/docs
new file mode 100644 (file)
index 0000000..a0f0008
--- /dev/null
@@ -0,0 +1 @@
+CMakeLists.txt
diff --git a/theme/debian/org.tizen.calculator.install.in b/theme/debian/org.tizen.calculator.install.in
new file mode 100644 (file)
index 0000000..72ce7c6
--- /dev/null
@@ -0,0 +1,8 @@
+@PREFIX@/bin/*
+@PREFIX@/res/edje/*
+@PREFIX@/res/icons/*
+@PREFIX@/res/locale/*
+@PREFIX@/data
+/opt/share/applications/*
+/opt/share/process-info/*
+/opt/share/icons/default/small/*
diff --git a/theme/debian/org.tizen.calculator.postinst b/theme/debian/org.tizen.calculator.postinst
new file mode 100644 (file)
index 0000000..ede9d62
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+if [  ${USER} == "root" ]
+then
+       # 5000 is inhouse user id
+       # do not use relative path
+       chown -R 5000:5000 /opt/apps/org.tizen.calculator/data
+fi
+       
diff --git a/theme/debian/rules b/theme/debian/rules
new file mode 100755 (executable)
index 0000000..ade4792
--- /dev/null
@@ -0,0 +1,132 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+CFLAGS += -Wall -g
+CXXFLAGS ?=  -Wall -g
+LDFLAGS ?= 
+PREFIX ?= /opt/apps/org.tizen.calculator
+DATADIR ?= /opt/apps/org.tizen.calculator/res
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+       CXXFLAGS += -O0
+else
+       CFLAGS += -O2
+       CXXFLAGS += -O2
+endif
+
+CFLAGS += -fPIC
+CXXFLAGS += -fPIC
+LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed -Wl,--hash-style=both
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+       # Add here commands to configure the package.
+       CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX)
+
+       touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp 
+       dh_testdir
+
+       # Add here commands to compile the package.
+       $(MAKE)
+       #docbook-to-man debian/wavplayer.sgml > wavplayer.1
+
+       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+               cat $$f > $${f%.in}; \
+               sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
+               sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
+       done
+
+
+       touch $@
+
+clean:
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+
+       # Add here commands to clean up after the build process.
+       -$(MAKE) clean
+       rm -rf CMakeCache.txt
+       rm -rf CMakeFiles
+       rm -rf cmake_install.cmake
+       rm -rf Makefile
+       rm -rf install_manifest.txt
+       rm -rf org.tizen.calculator.desktop
+
+       rm -rf po/CMakeCache.txt
+       rm -rf po/CMakeFiles
+       rm -rf po/cmake_install.cmake
+       rm -rf po/Makefile
+       rm -rf po/install_manifest.txt
+
+       rm -rf *.so
+       rm -rf *.edj
+       rm -rf theme/*.edj
+
+       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+               rm -f $${f%.in}; \
+       done
+
+       dh_clean 
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k 
+       dh_installdirs
+
+       # Add here commands to install the package into debian/wavplayer.
+       $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+#      dh_installchangelogs
+#      dh_installdocs
+#      dh_installexamples
+       dh_install --sourcedir=debian/tmp
+#      dh_installmenu
+#      dh_installdebconf       
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_python
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip --dbg-package=org.tizen.calculator-dbg
+       dh_compress
+       dh_fixperms
+#      dh_perl
+       dh_makeshlibs
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/theme/edc/Inc.calculator.main.edc b/theme/edc/Inc.calculator.main.edc
new file mode 100644 (file)
index 0000000..89a4e12
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#define PADDING_TOP_POR         24
+#define PADDING_BOTTOM_POR       12
+#define PADDING_LEFT_POR        24
+#define PADDING_RIGHT_POR       24
+
+#define PADDING_TOP_LAN         13
+#define PADDING_BOTTOM_LAN       3
+#define PADDING_LEFT_LAN        42
+#define PADDING_RIGHT_LAN       42
+
+group {
+    name: "main";
+
+    script {
+        public pannel_state;
+        public result_show;
+    }
+
+    parts {
+        /* background */
+           part {
+               name: "bg";
+               type: RECT;
+               mouse_events: 0;
+               description {
+                   state: "default" 0.0;
+                   rel1 { relative: 0.0 0.0;}
+                   rel2 { relative: 1.0 (1.0+1.0/1280);}
+                   color:50 50 50 255;
+               }
+               description {
+                   state: "landscape" 0.0;
+                   inherit: "default" 0.0;
+                   rel1 { relative: 0.0 0.0;}
+                   rel2 { relative: 1.0 (1.0+1.0/720);}
+                  color:50 50 50 255;
+               }
+           }
+
+        /* Input Entry */
+        part {
+            name: "entry/rect";
+            type: RECT;
+            mouse_events: 1;
+            scale: 1;
+
+            description {
+                state: "default" 0.0;
+                rel1 {relative: 0.0 0.0; to:"bg";}
+                rel2 {relative: 1.0 (24+300+13)/(1280-50-114); to:"bg";}
+                color:50 50 50 255;
+            }
+
+            description {
+                state: "landscape" 0.0;
+                inherit: "default" 0.0;
+                min: 0 144;
+                rel1 {relative: 0.0 0.0; to:"bg";}
+                rel2 {relative: 1.0 (0+187)/(720-95-50);  to:"bg";}
+            }
+        }
+
+        EDC_PART_PADDING_TL("entry_swl_pad_tl_por", EDC_SIZE(32, 24), "entry/rect")
+        EDC_PART_PADDING_BR("entry_swl_pad_br_por", EDC_SIZE(0, 13), "entry/rect")
+        EDC_PART_PADDING_TL("entry_swl_pad_tl_lan", EDC_SIZE(52, 32), "entry/rect")
+        EDC_PART_PADDING_BR("entry_swl_pad_br_lan", EDC_SIZE(20, 47), "entry/rect")
+
+        part {
+            name: "input/entry";
+            type: SWALLOW;
+            mouse_events: 1;
+            description {
+                state: "default" 0.0;
+                visible: 1;
+                rel1 {relative: 1.0 1.0; to: "entry_swl_pad_tl_por";}
+                rel2 {relative: 0.0 0.0; to: "entry_swl_pad_br_por";}
+            }
+
+            description {
+                state: "landscape" 0.0;
+                rel1 {relative: 1.0 1.0; to: "entry_swl_pad_tl_lan";}
+                rel2 {relative: 0.0 0.0; to: "entry_swl_pad_br_lan";}
+            }
+        }
+
+
+        part {
+            name: "history/rect";
+            type: RECT;
+            mouse_events: 0;
+            description {
+                state: "default" 0.0;
+                visible: 0;
+                rel1 {relative:1.0 1.0; to: "bg";}
+                rel2 {relative:1.0 1.0; to: "bg";}
+            }
+            description {
+                state: "show" 0.0;
+                visible: 1;
+                rel1 {relative:0.0 0.0; to: "bg";}
+                rel2 {relative:1.0 1.0; to: "bg";}
+                color: 50 50 50 255;
+            }
+        }
+
+
+        EDC_PART_PADDING_TL("entry_his_pad_tl_por", EDC_SIZE(32, 15), "history/rect")
+        EDC_PART_PADDING_BR("entry_his_pad_br_por", EDC_SIZE(32, 80), "history/rect")
+        EDC_PART_PADDING_TL("entry_his_pad_tl_lan", EDC_SIZE(52, 32), "history/rect")
+        EDC_PART_PADDING_BR("entry_his_pad_br_lan", EDC_SIZE(52, 0), "history/rect")
+
+       // EDC_PART_SWALLOW_HIDE_SHOW("history/scroll", "history/rect2")
+        part {
+            name: "history/scroll";
+            type: SWALLOW;
+            mouse_events: 1;
+            description {
+                state: "default" 0.0;
+                visible: 1;
+                rel1 {relative: 1.0 1.0; to: "entry_his_pad_tl_por";}
+                rel2 {relative: 0.0 0.0; to: "entry_his_pad_br_por";}
+            }
+
+            description {
+                state: "landscape" 0.0;
+                visible: 1;
+                rel1 {relative: 1.0 1.0; to: "entry_his_pad_tl_lan";}
+                rel2 {relative: 0.0 0.0; to: "entry_his_pad_br_lan";}
+            }
+        }
+
+        /* Keypad */
+        EDC_PART_SWALLOW_SHOW_HIDE("por_pannel/rect", "bg")
+        EDC_PART_SWALLOW_SHOW_HIDE("lan_pannel/rect", "bg")
+    }
+
+    programs {
+        program {
+            name: "group_load";
+            signal: "load";
+            script {
+                set_int(pannel_state, 0);
+                set_int(result_show, 0);
+            }
+        }
+
+        program {
+            name: "show_history";
+            signal: "show,hist";
+            source: "";
+            script {
+                set_state(PART:"history/rect", "show", 0.0);
+            }
+        }
+        program {
+            name: "hide_history";
+            signal: "hide,hist";
+            source: "";
+            script {
+                set_state(PART:"history/rect", "default", 0.0);
+            }
+        }
+
+        program {
+            name: "to_landscape";
+            signal: "landscape";
+            source: "";
+            script {
+                set_int(pannel_state, 1);
+                set_state(PART:"entry/rect", "landscape", 0.0);
+                set_state(PART:"input/entry", "landscape", 0.0);
+                set_state(PART:"history/scroll", "landscape", 0.0);
+                set_state(PART:"lan_pannel/rect", "default", 0.0);
+                set_state(PART:"por_pannel/rect", "hide", 0.0);
+                set_state(PART:"bg", "landscape", 0.0);
+            }
+        }
+        program {
+            name: "to_portrait";
+            signal: "portrait";
+            source: "";
+            script {
+                set_int(pannel_state, 0);
+                set_state(PART:"entry/rect", "default", 0.0);
+                set_state(PART:"input/entry", "default", 0.0);
+                set_state(PART:"history/scroll", "default", 0.0);
+                set_state(PART:"lan_pannel/rect", "hide", 0.0);
+                set_state(PART:"por_pannel/rect", "default", 0.0);
+                set_state(PART:"bg", "default", 0.0);
+            }
+        }
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/theme/edc/Inc.calculator.pannel.lan.edc b/theme/edc/Inc.calculator.pannel.lan.edc
new file mode 100644 (file)
index 0000000..172552e
--- /dev/null
@@ -0,0 +1,547 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#define BG_H_LAN               (720-95-50)
+#define PANNEL_FULL_W_LAN              1280
+#define PANNEL_FULL_H_LAN              380
+
+#define PANNEL_X_LOFF_LAN              46
+#define PANNEL_Y_LOFF_LAN              12
+#define MIDDLE_MARGIN  48
+
+#define PANNEL_KEY_W_PAD_LAN    4
+#define PANNEL_KEY_H_PAD_LAN    2
+#define PANNEL_KEY_W_LAN               160
+#define PANNEL_KEY_H_LAN               72
+#define PANNEL_KEY_FULL_W_LAN   (PANNEL_KEY_W_LAN+PANNEL_KEY_W_PAD_LAN)
+#define PANNEL_KEY_FULL_H_LAN   (PANNEL_KEY_H_LAN+PANNEL_KEY_H_PAD_LAN)
+
+#define PANNEL_COR_LAN_REF1_X(X,Y)   ((PANNEL_X_LOFF_LAN+PANNEL_KEY_FULL_W_LAN*(Y))/PANNEL_FULL_W_LAN)
+#define PANNEL_COR_LAN_REF1_Y(X,Y)   ((PANNEL_Y_LOFF_LAN+PANNEL_KEY_FULL_H_LAN*(X))/PANNEL_FULL_H_LAN)
+#define PANNEL_COR_LAN_REF2_X(X,Y)   ((PANNEL_X_LOFF_LAN+PANNEL_KEY_FULL_W_LAN*(Y)+PANNEL_KEY_W_LAN)/PANNEL_FULL_W_LAN)
+#define PANNEL_COR_LAN_REF2_Y(X,Y)   ((PANNEL_Y_LOFF_LAN+PANNEL_KEY_FULL_H_LAN*(X)+PANNEL_KEY_H_LAN)/PANNEL_FULL_H_LAN)
+
+#define PANNEL_COR_LAN_REF1_RIGHT_X(X,Y)   ((PANNEL_X_LOFF_LAN+MIDDLE_MARGIN+PANNEL_KEY_FULL_W_LAN*(Y))/PANNEL_FULL_W_LAN)
+#define PANNEL_COR_LAN_REF2_RIGHT_X(X,Y)   ((PANNEL_X_LOFF_LAN+MIDDLE_MARGIN+PANNEL_KEY_FULL_W_LAN*(Y)+PANNEL_KEY_W_LAN)/PANNEL_FULL_W_LAN)
+
+
+
+#define KEYPAD_KEY_IMG_LAN(key_name, relx1, rely1, relx2, rely2, bg_img, bg_img_press, text_img, text_img_press, to_part) \
+    EDC_PART_RECT_RELATIVE(key_name, to_part, relx1, rely1, relx2, rely2)\
+    EDC_PART_BUTTON_IMG(key_name"_bg", key_name, EDC_IMAGE(bg_img), EDC_IMAGE(bg_img))\
+    EDC_PART_BUTTON_IMG(key_name"_txt", key_name, EDC_IMAGE(text_img), EDC_IMAGE(text_img_press))
+
+#define KEYPAD_KEY_TXT_LAN(key_name, relx1, rely1, relx2, rely2, bg_img, bg_img_press, text_txt, text_txt_press, to_part) \
+    EDC_PART_RECT_RELATIVE(key_name, to_part, relx1, rely1, relx2, rely2)\
+    EDC_PART_BUTTON_IMG(key_name"_bg", key_name, EDC_IMAGE(bg_img),EDC_IMAGE(bg_img))\
+    EDC_PART_TEXT(key_name"_txt", key_name, SHADOW, \
+    EDC_TEXT_SHADOW(text_txt, 56, "SLP:style=Roman", "slp_roman", EDC_COLOR(255,255,255,255), EDC_COLOR(0,0,0,255)))\
+
+
+
+#define CALCULATOR_PROGRAMS(part_name) \
+                       program { \
+                               name: "mouse_down_"part_name; \
+                               signal: "mouse,down,1"; \
+                               source:  part_name; \
+                               action:   STATE_SET "pressed" 0.0; \
+                               target: part_name"_bg"; \
+                               target: part_name"_txt"; \
+                       } \
+                       program { \
+                               name: "mouse_up_"part_name; \
+                               signal: "mouse,up,1"; \
+                               source:  part_name; \
+                               action: STATE_SET "default" 0.0; \
+                               target: part_name"_bg"; \
+                               target: part_name"_txt"; \
+                       }
+
+///////////////////// landscape pannel  ////////////////////////////////////////
+       group {
+               name: "lan_pannel";
+               script {
+                       public pannel_state;
+               }
+               parts {
+                       /* rect for pannel keys */
+                       part {
+                               name: "lan_pannel/in";//1280*464
+                               type: RECT;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 0;
+                                       rel1 { relative: 0.0 187/BG_H_LAN;}
+                                       rel2 { relative: 1.0 (BG_H_LAN-8)/BG_H_LAN;}
+                               }
+                               description {
+                                       state: "down" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 1.0; offset: 0 0;}
+                                       rel2 { relative: 1.0 1.0; offset: 0 388;}
+                               }
+                       }
+
+                       part {
+                               name: "lan_pannel/BG";
+                               type: RECT;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 1;
+                                       rel1 { relative: 0.0 187/BG_H_LAN;}
+                                       rel2 { relative: 1.0 1.0; }
+                                       color: 59 70 85 140;
+                               }
+                               description {
+                                       state: "down" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 1.0; offset: 0 0;}
+                                       rel2 { relative: 1.0 1.0; offset: 0 388;}
+                               }
+                       }
+
+                       /* close&open icon */
+                       part {
+                               name: "pannel/icon";
+                               type: IMAGE;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 127/BG_H_LAN;}
+                                       rel2 { relative: 188/1280 (127+60)/BG_H_LAN;}
+                                       image { normal: "images/landscape/P04_calculator_down_handle_land.png"; }
+                               }
+                               description {
+                                       state: "open" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 (BG_H_LAN-60)/BG_H_LAN;}
+                                       rel2 { relative: 188/1280 (BG_H_LAN)/BG_H_LAN;}
+                                       image { normal: "images/landscape/P04_calculator_up_handle_land.png"; }
+                               }
+                               description {
+                                       state: "default_press" 0.0;
+                                       rel1 { relative: 0.0 127/BG_H_LAN;}
+                                       rel2 { relative: 188/1280 (127+60)/BG_H_LAN;}
+                                       image { normal: "images/landscape/P04_calculator_down_handle_land_press.png"; }
+                               }
+                               description {
+                                       state: "open_press" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 (BG_H_LAN-60)/BG_H_LAN;}
+                                       rel2 { relative: 188/1280 (BG_H_LAN)/BG_H_LAN;}
+                                       image { normal: "images/landscape/P04_calculator_up_handle_land_press.png"; }
+                               }
+                       }
+
+
+
+                       /* create pannel keys */
+                       // %, sqrt, x!, c, /, *, <-
+                       KEYPAD_KEY_IMG_LAN("item_fac",
+                               PANNEL_COR_LAN_REF1_X(0,0), PANNEL_COR_LAN_REF1_Y(0,0),
+                               PANNEL_COR_LAN_REF2_X(0,0), PANNEL_COR_LAN_REF2_Y(0,0),
+                               "images/landscape/P04_calculator_btn_03.png", "images/landscape/P04_calculator_btn_03_press.png",
+                               "images/landscape/P04_calculator_btn_03.png", "images/landscape/P04_calculator_btn_03_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_sqr",
+                               PANNEL_COR_LAN_REF1_X(0,1), PANNEL_COR_LAN_REF1_Y(0,1),
+                               PANNEL_COR_LAN_REF2_X(0,1), PANNEL_COR_LAN_REF2_Y(0,1),
+                               "images/landscape/P04_calculator_btn_02.png", "images/landscape/P04_calculator_btn_02_press.png",
+                               "images/landscape/P04_calculator_btn_02.png", "images/landscape/P04_calculator_btn_02_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_per",
+                               PANNEL_COR_LAN_REF1_X(0,2), PANNEL_COR_LAN_REF1_Y(0,2),
+                               PANNEL_COR_LAN_REF2_X(0,2), PANNEL_COR_LAN_REF2_Y(0,2),
+                               "images/landscape/P04_calculator_btn_01.png", "images/landscape/P04_calculator_btn_01_press.png",
+                               "images/landscape/P04_calculator_btn_01.png", "images/landscape/P04_calculator_btn_01_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_c",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(0,3), PANNEL_COR_LAN_REF1_Y(0,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(0,3), PANNEL_COR_LAN_REF2_Y(0,3),
+                               "images/landscape/P04_calculator_btn_16.png", "images/landscape/P04_calculator_btn_16_press.png",
+                               "images/landscape/P04_calculator_btn_16.png", "images/landscape/P04_calculator_btn_16_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_div",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(0,4), PANNEL_COR_LAN_REF1_Y(0,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(0,4), PANNEL_COR_LAN_REF2_Y(0,4),
+                               "images/landscape/P04_calculator_btn_17.png", "images/landscape/P04_calculator_btn_17_press.png",
+                               "images/landscape/P04_calculator_btn_17.png", "images/landscape/P04_calculator_btn_17_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_mul",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(0,5), PANNEL_COR_LAN_REF1_Y(0,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(0,5), PANNEL_COR_LAN_REF2_Y(0,5),
+                               "images/landscape/P04_calculator_btn_18.png", "images/landscape/P04_calculator_btn_18_press.png",
+                               "images/landscape/P04_calculator_btn_18.png", "images/landscape/P04_calculator_btn_18_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_del",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(0,6), PANNEL_COR_LAN_REF1_Y(0,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(0,6), PANNEL_COR_LAN_REF2_Y(0,6),
+                               "images/landscape/P04_calculator_btn_19.png", "images/landscape/P04_calculator_btn_19_press.png",
+                               "images/landscape/P04_calculator_btn_19.png", "images/landscape/P04_calculator_btn_19_press.png",
+                               "lan_pannel/in");
+
+
+                       // sin, cos, tan, 7, 8, 9, -
+                       KEYPAD_KEY_IMG_LAN("item_sin",
+                               PANNEL_COR_LAN_REF1_X(1,0), PANNEL_COR_LAN_REF1_Y(1,0),
+                               PANNEL_COR_LAN_REF2_X(1,0), PANNEL_COR_LAN_REF2_Y(1,0),
+                               "images/landscape/P04_calculator_btn_04.png", "images/landscape/P04_calculator_btn_04_press.png",
+                               "images/landscape/P04_calculator_btn_04.png", "images/landscape/P04_calculator_btn_04_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_cos",
+                               PANNEL_COR_LAN_REF1_X(1,1), PANNEL_COR_LAN_REF1_Y(1,1),
+                               PANNEL_COR_LAN_REF2_X(1,1), PANNEL_COR_LAN_REF2_Y(1,1),
+                               "images/landscape/P04_calculator_btn_05.png", "images/landscape/P04_calculator_btn_05_press.png",
+                               "images/landscape/P04_calculator_btn_05.png", "images/landscape/P04_calculator_btn_05_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_tan",
+                               PANNEL_COR_LAN_REF1_X(1,2), PANNEL_COR_LAN_REF1_Y(1,2),
+                               PANNEL_COR_LAN_REF2_X(1,2), PANNEL_COR_LAN_REF2_Y(1,2),
+                               "images/landscape/P04_calculator_btn_06.png", "images/landscape/P04_calculator_btn_06_press.png",
+                               "images/landscape/P04_calculator_btn_06.png", "images/landscape/P04_calculator_btn_06_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num7",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(1,3), PANNEL_COR_LAN_REF1_Y(1,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(1,3), PANNEL_COR_LAN_REF2_Y(1,3),
+                               "images/landscape/P04_calculator_btn_n07.png", "images/landscape/P04_calculator_btn_n07_press.png",
+                               "images/landscape/P04_calculator_btn_n07.png", "images/landscape/P04_calculator_btn_n07_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num8",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(1,4), PANNEL_COR_LAN_REF1_Y(1,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(1,4), PANNEL_COR_LAN_REF2_Y(1,4),
+                               "images/landscape/P04_calculator_btn_n08.png", "images/landscape/P04_calculator_btn_n08_press.png",
+                               "images/landscape/P04_calculator_btn_n08.png", "images/landscape/P04_calculator_btn_n08_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num9",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(1,5), PANNEL_COR_LAN_REF1_Y(1,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(1,5), PANNEL_COR_LAN_REF2_Y(1,5),
+                               "images/landscape/P04_calculator_btn_n09.png", "images/landscape/P04_calculator_btn_n09_press.png",
+                               "images/landscape/P04_calculator_btn_n09.png", "images/landscape/P04_calculator_btn_n09_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_sub",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(1,6), PANNEL_COR_LAN_REF1_Y(1,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(1,6), PANNEL_COR_LAN_REF2_Y(1,6),
+                               "images/landscape/P04_calculator_btn_20.png", "images/landscape/P04_calculator_btn_20_press.png",
+                               "images/landscape/P04_calculator_btn_20.png", "images/landscape/P04_calculator_btn_20_press.png",
+                               "lan_pannel/in");
+
+                       // ln, log, 1/x, 4, 5, 6, +
+                       KEYPAD_KEY_IMG_LAN("item_ln",
+                               PANNEL_COR_LAN_REF1_X(2,0), PANNEL_COR_LAN_REF1_Y(2,0),
+                               PANNEL_COR_LAN_REF2_X(2,0), PANNEL_COR_LAN_REF2_Y(2,0),
+                               "images/landscape/P04_calculator_btn_07.png", "images/landscape/P04_calculator_btn_07_press.png",
+                               "images/landscape/P04_calculator_btn_07.png", "images/landscape/P04_calculator_btn_07_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_log",
+                               PANNEL_COR_LAN_REF1_X(2,1), PANNEL_COR_LAN_REF1_Y(2,1),
+                               PANNEL_COR_LAN_REF2_X(2,1), PANNEL_COR_LAN_REF2_Y(2,1),
+                               "images/landscape/P04_calculator_btn_08.png", "images/landscape/P04_calculator_btn_08_press.png",
+                               "images/landscape/P04_calculator_btn_08.png", "images/landscape/P04_calculator_btn_08_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_1x",
+                               PANNEL_COR_LAN_REF1_X(2,2), PANNEL_COR_LAN_REF1_Y(2,2),
+                               PANNEL_COR_LAN_REF2_X(2,2), PANNEL_COR_LAN_REF2_Y(2,2),
+                               "images/landscape/P04_calculator_btn_09.png", "images/landscape/P04_calculator_btn_09_press.png",
+                               "images/landscape/P04_calculator_btn_09.png", "images/landscape/P04_calculator_btn_09_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num4",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(2,3), PANNEL_COR_LAN_REF1_Y(2,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(2,3), PANNEL_COR_LAN_REF2_Y(2,3),
+                               "images/landscape/P04_calculator_btn_n04.png", "images/landscape/P04_calculator_btn_n04_press.png",
+                               "images/landscape/P04_calculator_btn_n04.png", "images/landscape/P04_calculator_btn_n04_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num5",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(2,4), PANNEL_COR_LAN_REF1_Y(2,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(2,4), PANNEL_COR_LAN_REF2_Y(2,4),
+                               "images/landscape/P04_calculator_btn_n05.png", "images/landscape/P04_calculator_btn_n05_press.png",
+                               "images/landscape/P04_calculator_btn_n05.png", "images/landscape/P04_calculator_btn_n05_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num6",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(2,5), PANNEL_COR_LAN_REF1_Y(2,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(2,5), PANNEL_COR_LAN_REF2_Y(2,5),
+                               "images/landscape/P04_calculator_btn_n06.png", "images/landscape/P04_calculator_btn_n06_press.png",
+                               "images/landscape/P04_calculator_btn_n06.png", "images/landscape/P04_calculator_btn_n06_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_plus",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(2,6), PANNEL_COR_LAN_REF1_Y(2,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(2,6), PANNEL_COR_LAN_REF2_Y(2,6),
+                               "images/landscape/P04_calculator_btn_21.png", "images/landscape/P04_calculator_btn_21_press.png",
+                               "images/landscape/P04_calculator_btn_21.png", "images/landscape/P04_calculator_btn_21_press.png",
+                               "lan_pannel/in");
+
+
+                       // x^2, 10^2, x^y, 1, 2, 3, ()
+                       KEYPAD_KEY_IMG_LAN("item_x2",
+                               PANNEL_COR_LAN_REF1_X(3,0), PANNEL_COR_LAN_REF1_Y(3,0),
+                               PANNEL_COR_LAN_REF2_X(3,0), PANNEL_COR_LAN_REF2_Y(3,0),
+                               "images/landscape/P04_calculator_btn_10.png", "images/landscape/P04_calculator_btn_10_press.png",
+                               "images/landscape/P04_calculator_btn_10.png", "images/landscape/P04_calculator_btn_10_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_10x",
+                               PANNEL_COR_LAN_REF1_X(3,1), PANNEL_COR_LAN_REF1_Y(3,1),
+                               PANNEL_COR_LAN_REF2_X(3,1), PANNEL_COR_LAN_REF2_Y(3,1),
+                               "images/landscape/P04_calculator_btn_11.png", "images/landscape/P04_calculator_btn_11_press.png",
+                               "images/landscape/P04_calculator_btn_11.png", "images/landscape/P04_calculator_btn_11_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_xy",
+                               PANNEL_COR_LAN_REF1_X(3,2), PANNEL_COR_LAN_REF1_Y(3,2),
+                               PANNEL_COR_LAN_REF2_X(3,2), PANNEL_COR_LAN_REF2_Y(3,2),
+                               "images/landscape/P04_calculator_btn_12.png", "images/landscape/P04_calculator_btn_12_press.png",
+                               "images/landscape/P04_calculator_btn_12.png", "images/landscape/P04_calculator_btn_12_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num1",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(3,3), PANNEL_COR_LAN_REF1_Y(3,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(3,3), PANNEL_COR_LAN_REF2_Y(3,3),
+                               "images/landscape/P04_calculator_btn_n01.png", "images/landscape/P04_calculator_btn_n01_press.png",
+                               "images/landscape/P04_calculator_btn_n01.png", "images/landscape/P04_calculator_btn_n01_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num2",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(3,4), PANNEL_COR_LAN_REF1_Y(3,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(3,4), PANNEL_COR_LAN_REF2_Y(3,4),
+                               "images/landscape/P04_calculator_btn_n02.png", "images/landscape/P04_calculator_btn_n02_press.png",
+                               "images/landscape/P04_calculator_btn_n02.png", "images/landscape/P04_calculator_btn_n02_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num3",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(3,5), PANNEL_COR_LAN_REF1_Y(3,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(3,5), PANNEL_COR_LAN_REF2_Y(3,5),
+                               "images/landscape/P04_calculator_btn_n03.png", "images/landscape/P04_calculator_btn_n03_press.png",
+                               "images/landscape/P04_calculator_btn_n03.png", "images/landscape/P04_calculator_btn_n03_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_brack",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(3,6), PANNEL_COR_LAN_REF1_Y(3,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(3,6), PANNEL_COR_LAN_REF2_Y(3,6),
+                               "images/landscape/P04_calculator_btn_22.png", "images/landscape/P04_calculator_btn_22_press.png",
+                               "images/landscape/P04_calculator_btn_22.png", "images/landscape/P04_calculator_btn_22_press.png",
+                               "lan_pannel/in");
+
+
+                       // abs, pi, e, +/-, 0, ., =
+                       KEYPAD_KEY_IMG_LAN("item_abs",
+                               PANNEL_COR_LAN_REF1_X(4,0), PANNEL_COR_LAN_REF1_Y(4,0),
+                               PANNEL_COR_LAN_REF2_X(4,0), PANNEL_COR_LAN_REF2_Y(4,0),
+                               "images/landscape/P04_calculator_btn_13.png", "images/landscape/P04_calculator_btn_13_press.png",
+                               "images/landscape/P04_calculator_btn_13.png", "images/landscape/P04_calculator_btn_13_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_pi",
+                               PANNEL_COR_LAN_REF1_X(4,1), PANNEL_COR_LAN_REF1_Y(4,1),
+                               PANNEL_COR_LAN_REF2_X(4,1), PANNEL_COR_LAN_REF2_Y(4,1),
+                               "images/landscape/P04_calculator_btn_14.png", "images/landscape/P04_calculator_btn_14_press.png",
+                               "images/landscape/P04_calculator_btn_14.png", "images/landscape/P04_calculator_btn_14_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_e",
+                               PANNEL_COR_LAN_REF1_X(4,2), PANNEL_COR_LAN_REF1_Y(4,2),
+                               PANNEL_COR_LAN_REF2_X(4,2), PANNEL_COR_LAN_REF2_Y(4,2),
+                               "images/landscape/P04_calculator_btn_15.png", "images/landscape/P04_calculator_btn_15_press.png",
+                               "images/landscape/P04_calculator_btn_15.png", "images/landscape/P04_calculator_btn_15_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_num0",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(4,3), PANNEL_COR_LAN_REF1_Y(4,3),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(4,3), PANNEL_COR_LAN_REF2_Y(4,3),
+                               "images/landscape/P04_calculator_btn_n00.png", "images/landscape/P04_calculator_btn_n00_press.png",
+                               "images/landscape/P04_calculator_btn_n00.png", "images/landscape/P04_calculator_btn_n00_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_dot",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(4,4), PANNEL_COR_LAN_REF1_Y(4,4),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(4,4), PANNEL_COR_LAN_REF2_Y(4,4),
+                               "images/landscape/P04_calculator_btn_25.png", "images/landscape/P04_calculator_btn_25_press.png",
+                               "images/landscape/P04_calculator_btn_25.png", "images/landscape/P04_calculator_btn_25_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_neg",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(4,5), PANNEL_COR_LAN_REF1_Y(4,5),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(4,5), PANNEL_COR_LAN_REF2_Y(4,5),
+                               "images/landscape/P04_calculator_btn_24.png", "images/landscape/P04_calculator_btn_24_press.png",
+                               "images/landscape/P04_calculator_btn_24.png", "images/landscape/P04_calculator_btn_24_press.png",
+                               "lan_pannel/in");
+                       KEYPAD_KEY_IMG_LAN("item_eq",
+                               PANNEL_COR_LAN_REF1_RIGHT_X(4,6), PANNEL_COR_LAN_REF1_Y(4,6),
+                               PANNEL_COR_LAN_REF2_RIGHT_X(4,6), PANNEL_COR_LAN_REF2_Y(4,6),
+                               "images/landscape/P04_calculator_btn_23.png", "images/landscape/P04_calculator_btn_23_press.png",
+                               "images/landscape/P04_calculator_btn_23.png", "images/landscape/P04_calculator_btn_23_press.png",
+                               "lan_pannel/in");
+               }
+
+
+               programs {
+                       program {
+                               name: "group_load";
+                               signal: "load";
+                               script {
+                                       set_int(pannel_state, 1);
+                               }
+                       }
+
+                       program {
+                               name:"icon_tween_down";
+                               action: STATE_SET  "open"  0.0;
+                               transition: ACCELERATE 0.4;
+                               target: "pannel/icon";
+                       }
+
+                       program {
+                               name:"icon_tween_up";
+                               action: STATE_SET  "default"  0.0;
+                               transition: ACCELERATE 0.3;
+                               target: "pannel/icon";
+                       }
+
+                       /* pannel open/close program */
+                       //press up/down
+                       program {
+                               name: "icon_click_down";
+                               signal: "mouse,down,1";
+                               source: "pannel/icon";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               set_state(PART:"pannel/icon", "default_press", 0.0);
+                                       } else {
+                                               set_state(PART:"pannel/icon", "open_press", 0.0);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "icon_click_up";
+                               signal: "mouse,up,1";
+                               source: "pannel/icon";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               run_program(PROGRAM:"icon_tween_down");
+                                               emit("pannel,down", "lan");
+                                               set_int(pannel_state, 0);
+                                       } else {
+                                               run_program(PROGRAM:"icon_tween_up");
+                                               emit("pannel,up", "lan");
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       //flick up/down
+                       program {
+                               name: "icon_click";
+                               signal: "pannel,flick";
+                               source: "";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               emit("pannel,down", "lan");
+                                               set_state(PART:"pannel/icon", "open", 0.0);
+                                               set_int(pannel_state, 0);
+                                       } else {
+                                               emit("pannel,up", "lan");
+                                               set_state(PART:"pannel/icon", "default", 0.0);
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "pannel/down";
+                               signal: "pannel,down";
+                               source: "*";
+                               action: STATE_SET "down" 0.0;
+                               target: "lan_pannel/in";
+                               target: "lan_pannel/BG";
+                               transition: ACCELERATE 0.4;
+                               after: "check_icon_open";
+                       }
+                       program {
+                               name: "pannel/down_i";
+                               signal: "pannel,down_i";
+                               source: "*";
+                               action: STATE_SET "down" 0.0;
+                               target: "lan_pannel/in";
+                               target: "lan_pannel/BG";
+                               after: "check_icon_open";
+                       }
+                       program {
+                               name: "pannel/up";
+                               signal: "pannel,up";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "lan_pannel/in";
+                               target: "lan_pannel/BG";
+                               transition: ACCELERATE 0.3;
+                               after: "check_icon_default";
+                       }
+
+                       program {
+                               name: "check_icon_open";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               set_state(PART:"pannel/icon", "open", 0.0);
+                                               set_int(pannel_state, 0);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "check_icon_default";
+                               script {
+                                       if (get_int(pannel_state) == 0) {
+                                               set_state(PART:"pannel/icon", "default", 0.0);
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       /* programs for pennel items */
+                       CALCULATOR_PROGRAMS("item_per");
+                       CALCULATOR_PROGRAMS("item_sqr");
+                       CALCULATOR_PROGRAMS("item_fac");
+                       CALCULATOR_PROGRAMS("item_c");
+                       CALCULATOR_PROGRAMS("item_div");
+                       CALCULATOR_PROGRAMS("item_mul");
+                       CALCULATOR_PROGRAMS("item_del");
+
+                       CALCULATOR_PROGRAMS("item_sin");
+                       CALCULATOR_PROGRAMS("item_cos");
+                       CALCULATOR_PROGRAMS("item_tan");
+                       CALCULATOR_PROGRAMS("item_num7");
+                       CALCULATOR_PROGRAMS("item_num8");
+                       CALCULATOR_PROGRAMS("item_num9");
+                       CALCULATOR_PROGRAMS("item_sub");
+
+                       CALCULATOR_PROGRAMS("item_ln");
+                       CALCULATOR_PROGRAMS("item_log");
+                       CALCULATOR_PROGRAMS("item_1x");
+                       CALCULATOR_PROGRAMS("item_num4");
+                       CALCULATOR_PROGRAMS("item_num5");
+                       CALCULATOR_PROGRAMS("item_num6");
+                       CALCULATOR_PROGRAMS("item_plus");
+
+                       CALCULATOR_PROGRAMS("item_10x");
+                       CALCULATOR_PROGRAMS("item_x2");
+                       CALCULATOR_PROGRAMS("item_xy");
+                       CALCULATOR_PROGRAMS("item_num1");
+                       CALCULATOR_PROGRAMS("item_num2");
+                       CALCULATOR_PROGRAMS("item_num3");
+                       CALCULATOR_PROGRAMS("item_brack");
+
+                       CALCULATOR_PROGRAMS("item_abs");
+                       CALCULATOR_PROGRAMS("item_pi");
+                       CALCULATOR_PROGRAMS("item_e");
+                       CALCULATOR_PROGRAMS("item_dot");
+                       CALCULATOR_PROGRAMS("item_num0");
+                       CALCULATOR_PROGRAMS("item_neg");
+                       CALCULATOR_PROGRAMS("item_eq");
+               }
+       }
+///////////////////// ladscape pannel  finish ////////////////////////////////////////
+
diff --git a/theme/edc/Inc.calculator.pannel.por.edc b/theme/edc/Inc.calculator.pannel.por.edc
new file mode 100644 (file)
index 0000000..ca74fc1
--- /dev/null
@@ -0,0 +1,436 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#define BG_H_POR       (1280-114-50)
+#define PANNEL_W_POR                   720
+#define PANNEL_H_POR              (682+23)
+#define PANNEL_FULL_W_POR              720
+//#define PANNEL_FULL_H_POR            584
+#define PANNEL_FULL_H_POR              (682+12)
+
+#define PANNEL_X_LOFF_POR              16
+#define PANNEL_Y_LOFF_POR              12//???
+
+#define PANNEL_KEY_W_PAD_POR    8
+#define PANNEL_KEY_H_PAD_POR    8
+#define PANNEL_KEY_W_POR               166
+#define PANNEL_KEY_H_POR               130
+#define PANNEL_KEY_FULL_W_POR   (PANNEL_KEY_W_POR+PANNEL_KEY_W_PAD_POR)
+#define PANNEL_KEY_FULL_H_POR   (PANNEL_KEY_H_POR+PANNEL_KEY_H_PAD_POR)
+
+#define PANNEL_COR_POR_REF1_X(X,Y)   ((PANNEL_X_LOFF_POR+PANNEL_KEY_FULL_W_POR*(Y))/PANNEL_W_POR)
+#define PANNEL_COR_POR_REF1_Y(X,Y)   ((PANNEL_Y_LOFF_POR+PANNEL_KEY_FULL_H_POR*(X))/PANNEL_FULL_H_POR)
+#define PANNEL_COR_POR_REF2_X(X,Y)   ((PANNEL_X_LOFF_POR+PANNEL_KEY_FULL_W_POR*(Y)+PANNEL_KEY_W_POR)/PANNEL_W_POR)
+#define PANNEL_COR_POR_REF2_Y(X,Y)   ((PANNEL_Y_LOFF_POR+PANNEL_KEY_FULL_H_POR*(X)+PANNEL_KEY_H_POR)/PANNEL_FULL_H_POR)
+
+#define KEYPAD_KEY_IMG(key_name, relx1, rely1, relx2, rely2, bg_img, bg_img_press, text_img, text_img_press, to_part) \
+    EDC_PART_RECT_RELATIVE(key_name, to_part, relx1, rely1, relx2, rely2)\
+    EDC_PART_BUTTON_IMG(key_name"_bg", key_name, EDC_IMAGE(bg_img), EDC_IMAGE(bg_img))\
+    EDC_PART_BUTTON_IMG(key_name"_txt", key_name, EDC_IMAGE(text_img), EDC_IMAGE(text_img_press))
+
+#define KEYPAD_KEY_TXT(key_name, relx1, rely1, relx2, rely2, bg_img, bg_img_press, text_txt, text_txt_press, to_part) \
+    EDC_PART_RECT_RELATIVE(key_name, to_part, relx1, rely1, relx2, rely2)\
+    EDC_PART_BUTTON_IMG(key_name"_bg", key_name, EDC_IMAGE(bg_img), EDC_IMAGE(bg_img)))\
+    EDC_PART_TEXT(key_name"_txt", key_name, SHADOW, \
+    EDC_TEXT_SHADOW(text_txt, 70, "SLP:style=Medium", "slp_medium", EDC_COLOR(255,255,255,255), EDC_COLOR(0,0,0,255)))\
+
+
+#define KEYPAD_KEY_PROG(key_name) \
+    program { \
+        name: "mouse_down_"key_name; \
+        signal: "mouse,down,1"; \
+        source: key_name; \
+        action: STATE_SET "pressed" 0.0; \
+        target: key_name"_bg"; \
+        target: key_name"_txt"; \
+    } \
+    program { \
+        name: "mouse_up_"key_name; \
+        signal: "mouse,up,1"; \
+        source: key_name; \
+        action: STATE_SET "default" 0.0; \
+        target: key_name"_bg"; \
+        target: key_name"_txt"; \
+    }
+
+///////////////////// prtrait pannel ////////////////////////////////////////
+       group {
+               name: "por_pannel";
+               script {
+                       public pannel_state;
+               }
+
+               parts {
+                       part {
+                               name: "por_pannel/in";
+                               type: RECT;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 0;
+                                       rel1 { relative: 0.0 (24+300+13+64)/BG_H_POR; }
+                                       rel2 { relative: 1.0 (BG_H_POR-23)/BG_H_POR; }
+                               }
+                               description {
+                                       state: "down" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 1.0; offset: 0 -12;}
+                                       rel2 { relative: 1.0 1.0; offset: 0 PANNEL_H_POR;}
+                               }
+                       }
+                       part {
+                               name: "por_pannel/BG";
+                               type: RECT;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 1;
+                                       rel1 { relative: 0.0 (24+300+13+60)/BG_H_POR;}
+                                       rel2 { relative: 1.0 1.1; }
+                                       color: 59 70 85 140;
+                               }
+                               description {
+                                       state: "down" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 1.0; offset: 0 -12;}
+                                       rel2 { relative: 1.0 1.0; offset: 0 PANNEL_H_POR;}
+                               }
+                       }
+
+                       /* close&open icon */
+                       part {
+                               name: "pannel/icon";
+                               type: IMAGE;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 (24+300+13)/BG_H_POR;}
+                                       rel2 { relative: 1.0 (24+300+13+64)/BG_H_POR;}
+                                       image { normal: "images/P04_calculator_down_handle.png"; }
+                               }
+                               description {
+                                       state: "open" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 (BG_H_POR-10-64)/BG_H_POR;}
+                                       rel2 { relative: 1.0 (BG_H_POR-10)/BG_H_POR;}
+                                       image { normal: "images/P04_calculator_up_handle.png"; }
+                               }
+                               description {
+                                       state: "default_press" 0.0;
+                                       rel1 { relative: 0.0  (24+300+13)/BG_H_POR;}
+                                       rel2 { relative: 1.0  (24+300+13+64)/BG_H_POR;}
+                                       image { normal: "images/P04_calculator_down_handle_press.png"; }
+                               }
+                               description {
+                                       state: "open_press" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 { relative: 0.0 (BG_H_POR-10-64)/BG_H_POR;}
+                                       rel2 { relative: 1.0 (BG_H_POR-10)/BG_H_POR;}
+                                       image { normal: "images/P04_calculator_up_handle_press.png"; }
+                               }
+                       }
+
+                       /* create pannel keys */
+                       // c, /, *, <-
+                       KEYPAD_KEY_IMG("item_c",
+                               PANNEL_COR_POR_REF1_X(0,0), PANNEL_COR_POR_REF1_Y(0,0),
+                PANNEL_COR_POR_REF2_X(0,0), PANNEL_COR_POR_REF2_Y(0,0),
+                               "images/P04_calculator_btn_01.png", "images/P04_calculator_btn_01_press.png",
+                               "images/P04_calculator_btn_01.png", "images/P04_calculator_btn_01_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_div",
+                               PANNEL_COR_POR_REF1_X(0,1), PANNEL_COR_POR_REF1_Y(0,1),
+                PANNEL_COR_POR_REF2_X(0,1), PANNEL_COR_POR_REF2_Y(0,1),
+                               "images/P04_calculator_btn_02.png", "images/P04_calculator_btn_02_press.png",
+                               "images/P04_calculator_btn_02.png", "images/P04_calculator_btn_02_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_mul",
+                               PANNEL_COR_POR_REF1_X(0,2), PANNEL_COR_POR_REF1_Y(0,2),
+                PANNEL_COR_POR_REF2_X(0,2), PANNEL_COR_POR_REF2_Y(0,2),
+                               "images/P04_calculator_btn_03.png", "images/P04_calculator_btn_03_press.png",
+                               "images/P04_calculator_btn_03.png", "images/P04_calculator_btn_03_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_del",
+                               PANNEL_COR_POR_REF1_X(0,3), PANNEL_COR_POR_REF1_Y(0,3),
+                PANNEL_COR_POR_REF2_X(0,3), PANNEL_COR_POR_REF2_Y(0,3),
+                               "images/P04_calculator_btn_04.png", "images/P04_calculator_btn_04_press.png",
+                               "images/P04_calculator_btn_04.png", "images/P04_calculator_btn_04_press.png",
+                               "por_pannel/in");
+
+
+                       // 7, 8, 9, -
+                       KEYPAD_KEY_IMG("item_num7",
+                               PANNEL_COR_POR_REF1_X(1,0), PANNEL_COR_POR_REF1_Y(1,0),
+                PANNEL_COR_POR_REF2_X(1,0), PANNEL_COR_POR_REF2_Y(1,0),
+                               "images/P04_calculator_btn_n07.png", "images/P04_calculator_btn_n07_press.png",
+                               "images/P04_calculator_btn_n07.png", "images/P04_calculator_btn_n07_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_num8",
+                               PANNEL_COR_POR_REF1_X(1,1), PANNEL_COR_POR_REF1_Y(1,1),
+                PANNEL_COR_POR_REF2_X(1,1), PANNEL_COR_POR_REF2_Y(1,1),
+                               "images/P04_calculator_btn_n08.png", "images/P04_calculator_btn_n08_press.png",
+                               "images/P04_calculator_btn_n08.png", "images/P04_calculator_btn_n08_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_num9",
+                               PANNEL_COR_POR_REF1_X(1,2), PANNEL_COR_POR_REF1_Y(1,2),
+                PANNEL_COR_POR_REF2_X(1,2), PANNEL_COR_POR_REF2_Y(1,2),
+                               "images/P04_calculator_btn_n09.png", "images/P04_calculator_btn_n09_press.png",
+                               "images/P04_calculator_btn_n09.png", "images/P04_calculator_btn_n09_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_sub",
+                               PANNEL_COR_POR_REF1_X(1,3), PANNEL_COR_POR_REF1_Y(1,3),
+                PANNEL_COR_POR_REF2_X(1,3), PANNEL_COR_POR_REF2_Y(1,3),
+                               "images/P04_calculator_btn_05.png", "images/P04_calculator_btn_05_press.png",
+                               "images/P04_calculator_btn_05.png", "images/P04_calculator_btn_05_press.png",
+                               "por_pannel/in");
+
+
+                       // 4, 5 ,6, +
+                       KEYPAD_KEY_IMG("item_num4",
+                               PANNEL_COR_POR_REF1_X(2,0), PANNEL_COR_POR_REF1_Y(2,0),
+                PANNEL_COR_POR_REF2_X(2,0), PANNEL_COR_POR_REF2_Y(2,0),
+                               "images/P04_calculator_btn_n04.png", "images/P04_calculator_btn_n04_press.png",
+                               "images/P04_calculator_btn_n04.png", "images/P04_calculator_btn_n04_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_num5",
+                               PANNEL_COR_POR_REF1_X(2,1), PANNEL_COR_POR_REF1_Y(2,1),
+                PANNEL_COR_POR_REF2_X(2,1), PANNEL_COR_POR_REF2_Y(2,1),
+                               "images/P04_calculator_btn_n05.png", "images/P04_calculator_btn_n05_press.png",
+                               "images/P04_calculator_btn_n05.png", "images/P04_calculator_btn_n05_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_num6",
+                               PANNEL_COR_POR_REF1_X(2,2), PANNEL_COR_POR_REF1_Y(2,3),
+                PANNEL_COR_POR_REF2_X(2,2), PANNEL_COR_POR_REF2_Y(2,3),
+                               "images/P04_calculator_btn_n06.png", "images/P04_calculator_btn_n06_press.png",
+                               "images/P04_calculator_btn_n06.png", "images/P04_calculator_btn_n06_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_plus",
+                               PANNEL_COR_POR_REF1_X(2,3), PANNEL_COR_POR_REF1_Y(2,3),
+                PANNEL_COR_POR_REF2_X(2,3), PANNEL_COR_POR_REF2_Y(2,3),
+                               "images/P04_calculator_btn_06.png", "images/P04_calculator_btn_06_press.png",
+                               "images/P04_calculator_btn_06.png", "images/P04_calculator_btn_06_press.png",
+                               "por_pannel/in");
+
+
+
+                       // 1, 2, 3, ()
+                       KEYPAD_KEY_IMG("item_num1",
+                               PANNEL_COR_POR_REF1_X(3,0), PANNEL_COR_POR_REF1_Y(3,0),
+                PANNEL_COR_POR_REF2_X(3,0), PANNEL_COR_POR_REF2_Y(3,0),
+                "images/P04_calculator_btn_n01.png", "images/P04_calculator_btn_n01_press.png",
+                               "images/P04_calculator_btn_n01.png", "images/P04_calculator_btn_n01_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_num2",
+                               PANNEL_COR_POR_REF1_X(3,1), PANNEL_COR_POR_REF1_Y(3,1),
+                PANNEL_COR_POR_REF2_X(3,1), PANNEL_COR_POR_REF2_Y(3,1),
+                "images/P04_calculator_btn_n02.png", "images/P04_calculator_btn_n02_press.png",
+                               "images/P04_calculator_btn_n02.png", "images/P04_calculator_btn_n02_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_num3",
+                               PANNEL_COR_POR_REF1_X(3,2), PANNEL_COR_POR_REF1_Y(3,2),
+                PANNEL_COR_POR_REF2_X(3,2), PANNEL_COR_POR_REF2_Y(3,2),
+                "images/P04_calculator_btn_n03.png", "images/P04_calculator_btn_n03_press.png",
+                               "images/P04_calculator_btn_n03.png", "images/P04_calculator_btn_n03_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_brack",
+                               PANNEL_COR_POR_REF1_X(3,3), PANNEL_COR_POR_REF1_Y(3,3),
+                PANNEL_COR_POR_REF2_X(3,3), PANNEL_COR_POR_REF2_Y(3,3),
+                               "images/P04_calculator_btn_07.png", "images/P04_calculator_btn_07_press.png",
+                               "images/P04_calculator_btn_07.png", "images/P04_calculator_btn_07_press.png",
+                               "por_pannel/in");
+
+
+                       //0, ., +/-,  =
+                       KEYPAD_KEY_IMG("item_num0",
+                               PANNEL_COR_POR_REF1_X(4,0), PANNEL_COR_POR_REF1_Y(4,0),
+                PANNEL_COR_POR_REF2_X(4,0), PANNEL_COR_POR_REF2_Y(4,0),
+                               "images/P04_calculator_btn_n00.png", "images/P04_calculator_btn_n00_press.png",
+                               "images/P04_calculator_btn_n00.png", "images/P04_calculator_btn_n00_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_dot",
+                               PANNEL_COR_POR_REF1_X(4,1), PANNEL_COR_POR_REF1_Y(4,1),
+                PANNEL_COR_POR_REF2_X(4,1), PANNEL_COR_POR_REF2_Y(4,1),
+                               "images/P04_calculator_btn_10.png", "images/P04_calculator_btn_10_press.png",
+                               "images/P04_calculator_btn_10.png", "images/P04_calculator_btn_10_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_neg",
+                               PANNEL_COR_POR_REF1_X(4,2), PANNEL_COR_POR_REF1_Y(4,2),
+                PANNEL_COR_POR_REF2_X(4,2), PANNEL_COR_POR_REF2_Y(4,2),
+                               "images/P04_calculator_btn_09.png", "images/P04_calculator_btn_09_press.png",
+                               "images/P04_calculator_btn_09.png", "images/P04_calculator_btn_09_press.png",
+                               "por_pannel/in");
+                       KEYPAD_KEY_IMG("item_eq",
+                               PANNEL_COR_POR_REF1_X(4,3), PANNEL_COR_POR_REF1_Y(4,4),
+                PANNEL_COR_POR_REF2_X(4,3), PANNEL_COR_POR_REF2_Y(4,4),
+                               "images/P04_calculator_btn_08.png", "images/P04_calculator_btn_08_press.png",
+                               "images/P04_calculator_btn_08.png", "images/P04_calculator_btn_08_press.png",
+                               "por_pannel/in");
+               }
+
+               programs {
+                       program {
+                               name: "group_load";
+                               signal: "load";
+                               script {
+                                       set_int(pannel_state, 1);
+                               }
+                       }
+
+                       program {
+                               name:"icon_tween_down";
+                               action: STATE_SET  "open"  0.0;
+                               transition: ACCELERATE 0.4;
+                               target: "pannel/icon";
+                       }
+
+                       program {
+                               name:"icon_tween_up";
+                               action: STATE_SET  "default"  0.0;
+                               transition: ACCELERATE 0.3;
+                               target: "pannel/icon";
+                       }
+
+                       /* pannel open/close program */
+                       //press up/down
+                       program {
+                               name: "icon_click2_down";
+                               signal: "mouse,down,1";
+                               source: "pannel/icon";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               set_state(PART:"pannel/icon", "default_press", 0.0);
+                                       } else {
+                                               set_state(PART:"pannel/icon", "open_press", 0.0);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "icon_click2_up";
+                               signal: "mouse,up,1";
+                               source: "pannel/icon";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               run_program(PROGRAM:"icon_tween_down");
+                                               emit("pannel,down", "por");
+                                               set_int(pannel_state, 0);
+                                       } else {
+                                               run_program(PROGRAM:"icon_tween_up");
+                                               emit("pannel,up", "por");
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       //flick up/down
+                       program {
+                               name: "icon_click";
+                               signal: "pannel,flick";
+                               source: "";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               emit("pannel,down", "por");
+                                               set_state(PART:"pannel/icon", "open", 0.0);
+                                               set_int(pannel_state, 0);
+                                       } else {
+                                               emit("pannel,up", "por");
+                                               set_state(PART:"pannel/icon", "default", 0.0);
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "pannel/down";
+                               signal: "pannel,down";
+                               source: "*";
+                               action: STATE_SET "down" 0.0;
+                               target: "por_pannel/in";
+                               target: "por_pannel/BG";
+                               transition: ACCELERATE 0.4;
+                               after: "check_icon_open";
+                       }
+                       program {
+                               name: "pannel/down_i";
+                               signal: "pannel,down_i";
+                               source: "*";
+                               action: STATE_SET "down" 0.0;
+                               target: "por_pannel/in";
+                               target: "por_pannel/BG";
+                               after: "check_icon_open";
+                       }
+                       program {
+                               name: "pannel/up";
+                               signal: "pannel,up";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "por_pannel/in";
+                               target: "por_pannel/BG";
+                               transition: ACCELERATE 0.3;
+                               after: "check_icon_default";
+                       }
+
+                       program {
+                               name: "check_icon_open";
+                               script {
+                                       if (get_int(pannel_state) == 1) {
+                                               set_state(PART:"pannel/icon", "open", 0.0);
+                                               set_int(pannel_state, 0);
+                                       }
+                               }
+                       }
+
+                       program {
+                               name: "check_icon_default";
+                               script {
+                                       if (get_int(pannel_state) == 0) {
+                                               set_state(PART:"pannel/icon", "default", 0.0);
+                                               set_int(pannel_state, 1);
+                                       }
+                               }
+                       }
+
+                       /* programs for pennel items */
+                       KEYPAD_KEY_PROG("item_c");
+                       KEYPAD_KEY_PROG("item_div");
+                       KEYPAD_KEY_PROG("item_mul");
+                       KEYPAD_KEY_PROG("item_del");
+
+                       KEYPAD_KEY_PROG("item_num7");
+                       KEYPAD_KEY_PROG("item_num8");
+                       KEYPAD_KEY_PROG("item_num9");
+                       KEYPAD_KEY_PROG("item_sub");
+
+                       KEYPAD_KEY_PROG("item_num4");
+                       KEYPAD_KEY_PROG("item_num5");
+                       KEYPAD_KEY_PROG("item_num6");
+                       KEYPAD_KEY_PROG("item_plus");
+
+                       KEYPAD_KEY_PROG("item_num1");
+                       KEYPAD_KEY_PROG("item_num2");
+                       KEYPAD_KEY_PROG("item_num3");
+                       KEYPAD_KEY_PROG("item_brack");
+
+                       KEYPAD_KEY_PROG("item_dot");
+                       KEYPAD_KEY_PROG("item_num0");
+                       KEYPAD_KEY_PROG("item_neg");
+                       KEYPAD_KEY_PROG("item_eq");
+               }
+       }
+///////////////////// prtrait pannel  finish ////////////////////////////////////////
+
diff --git a/theme/edc/edc-macro.edc b/theme/edc/edc-macro.edc
new file mode 100644 (file)
index 0000000..0348109
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#ifndef __EDC_MACRO_H__
+#define __EDC_MACRO_H__
+
+/* Basic */
+#define EDC_COLOR(nR, nG, nB, nA)           nR nG nB nA
+#define EDC_SIZE(nW, nH)                    nW nH
+#define EDC_COOR(nX, nY)                    nX nY   /* coordinate */
+#define EDC_IMAGE_BORDER(nL, nR, nT, nB)    nL nR nT nB
+
+/* Image */
+#define EDC_IMAGE(sImage)\
+    image.normal: sImage;
+#define EDC_IMAGE_WITH_BORDER(sImage, imgBorder)\
+    image {normal: sImage; border: imgBorder; border_scale: 1;}
+
+/* Text */
+#define EDC_TEXT(sText, nSize, sFont, tClass, crFill) \
+    color: crFill;\
+    text { \
+        text: sText; \
+        size: nSize; \
+        align: 0.5 0.5; \
+        font: sFont; \
+               text_calss: tClass; \
+    }
+
+#define EDC_TEXT_SHADOW(sText, nSize, sFont, tClass, crFill, crShadow) \
+    color2: crShadow;\
+    EDC_TEXT(sText, nSize, sFont, tClass, crFill)
+
+
+/* Relative */
+#define EDC_REL_TO_XY(fpRelX, fpRelY, coorOffset, sToPartX, sToPartY)\
+    relative: fpRelX fpRelY; offset: coorOffset; to_x: sToPartX; to_y: sToPartY
+
+#define EDC_REL_TO(fpRelX, fpRelY, coorOffset, sToPart)\
+    relative: fpRelX fpRelY; offset: coorOffset; to: sToPart
+
+#define EDC_REL_ABSOLUTE(coorOffset, sToPart)\
+    EDC_REL_TO(0.0, 0.0, coorOffset, sToPart)
+
+#define EDC_REL_RELATIVE(fpRelX, fpRelY, sToPart)\
+    relative: fpRelX fpRelY; to: sToPart
+
+/* state */
+#define EDC_STATE_BASE(sName, sizeMin, bFixW, bFixH, fpAlignX, fpAlignY,\
+        relTopLeft, relBottomRight, other)\
+    description {\
+        state: sName 0.0;\
+        min: sizeMin;\
+        fixed: bFixW bFixH;\
+        align: fpAlignX fpAlignY;\
+        rel1 { relTopLeft; }\
+        rel2 { relBottomRight; } \
+        other \
+    }
+
+/* state - padding top-left */
+#define EDC_STATE_PADDING_TL(sName, sizeMin, sToPart) \
+    EDC_STATE_BASE(sName, sizeMin, 1, 1, 0.0, 0.0, \
+        EDC_REL_RELATIVE(0.0, 0.0, sToPart), \
+        EDC_REL_RELATIVE(0.0, 0.0, sToPart), visible: 0;)
+
+/* state - padding bottom-right */
+#define EDC_STATE_PADDING_BR(sName, sizeMin, sToPart) \
+    EDC_STATE_BASE(sName, sizeMin, 1, 1, 1.0, 1.0, \
+        EDC_REL_RELATIVE(1.0, 1.0, sToPart), \
+        EDC_REL_RELATIVE(1.0, 1.0, sToPart), visible: 0;)
+
+
+#define EDC_STATE_COMMON(sName, relTopLeft, relBottomRight, other) \
+    EDC_STATE_BASE(sName, EDC_SIZE(0, 0), 0, 0, 0.5, 0.5, relTopLeft, relBottomRight, other)
+
+#define EDC_STATE_COMMON_RECT(sName, relTopLeft, relBottomRight, crFill) \
+    EDC_STATE_COMMON(sName, relTopLeft, relBottomRight, color: crFill;)
+
+#define EDC_STATE_COMMON_IMAGE(sName, relTopLeft, relBottomRight, img) \
+    EDC_STATE_COMMON(sName, relTopLeft, relBottomRight, img)
+
+#define EDC_STATE_COMMON_TEXT(sName, relTopLeft, relBottomRight, txt) \
+    EDC_STATE_COMMON(sName, relTopLeft, relBottomRight, txt)
+
+/* Background */
+#define EDC_PART_BG(sName)\
+    part {\
+        name: sName;\
+        type: RECT;\
+        mouse_events: 0;\
+        description {\
+            state: "default" 0.0;\
+            rel1 { relative: 0.0 0.0;}\
+            rel2 { relative: 1.0 1.0;}\
+            color: 0 0 0 0;\
+        }\
+    }
+
+/* Part */
+#define EDC_PART_BASE(sName, enumType, bMouse, bRepeat, stateDefault, stateOther...) \
+    part {\
+        name: sName;\
+        type: enumType;\
+        mouse_events: bMouse;\
+        repeat_events: bRepeat;\
+        scale: 1;\
+        stateDefault\
+        ##stateOther\
+    }
+
+#define EDC_PART_PADDING_TL(sName, sizeMin, sToPart) \
+    EDC_PART_BASE(sName, RECT, 1, 0, \
+        EDC_STATE_PADDING_TL("default", sizeMin, sToPart))
+
+#define EDC_PART_PADDING_BR(sName, sizeMin, sToPart) \
+    EDC_PART_BASE(sName, RECT, 1, 0, \
+        EDC_STATE_PADDING_BR("default", sizeMin, sToPart))
+
+/* Part - Rectagnle */
+#define EDC_PART_RECT_COMMON(sName, relTopLeft, relBottomRight) \
+    EDC_PART_BASE(sName, RECT, 1, 1, \
+        EDC_STATE_COMMON_RECT("default", relTopLeft, relBottomRight, EDC_COLOR(0, 0, 0, 0)))
+
+#define EDC_PART_RECT_ABSOLUTE(sName, sToPart, coorTopLeft, coorBottomRight) \
+    EDC_PART_RECT_COMMON(sName, \
+        EDC_REL_ABSOLUTE(coorTopLeft, sToPart),\
+        EDC_REL_ABSOLUTE(coorBottomRight, sToPart))
+
+#define EDC_PART_RECT_RELATIVE(sName, sToPart, fpRel1X, fpRel1Y, fpRel2X, fpRel2Y) \
+    EDC_PART_RECT_COMMON(sName, \
+        EDC_REL_RELATIVE(fpRel1X, fpRel1Y, sToPart), \
+        EDC_REL_RELATIVE(fpRel2X, fpRel2Y, sToPart))
+
+#define EDC_PART_RECT_PADDING(sName, sToPart, coorTopLeft, coorBottomRight) \
+    EDC_PART_PADDING_TL(sName"_padding_tl", coorTopLeft, sToPart)\
+    EDC_PART_PADDING_BR(sName"_padding_br", coorBottomRight, sToPart)\
+    EDC_PART_RECT_COMMON(sName, \
+        EDC_REL_RELATIVE(1.0, 1.0, sName"_padding_tl"), \
+        EDC_REL_RELATIVE(0.0, 0.0, sName"_padding_br"))
+
+#define EDC_PART_RECT_COLOR(sName, sToPart, crFill) \
+    EDC_PART_BASE(sName, RECT, 1, 0, \
+        EDC_STATE_COMMON_RECT("default", \
+            EDC_REL_RELATIVE(0.0, 0.0, sToPart), \
+            EDC_REL_RELATIVE(1.0, 1.0, sToPart), crFill))
+
+/* Part - Image */
+#define EDC_PART_IMAGE(sName, sToPart, img)\
+    EDC_PART_BASE(sName, IMAGE, 1, 0, \
+        EDC_STATE_COMMON_IMAGE("default", \
+            EDC_REL_RELATIVE(0.0, 0.0, sToPart), \
+            EDC_REL_RELATIVE(1.0, 1.0, sToPart), img))
+
+/* Part - Text */
+#define EDC_PART_TEXT(sName, sToPart, enumEffect, txt)\
+    EDC_PART_BASE(sName, TEXT, 1, 1, \
+        effect: enumEffect;\
+        EDC_STATE_COMMON_TEXT("default", \
+            EDC_REL_RELATIVE(0.0, 0.0, sToPart), \
+            EDC_REL_RELATIVE(1.0, 1.0, sToPart), txt))
+
+/* Two state part */
+#define EDC_PART_TWO_STATE(sName, enumType, sToPart, sStateName2, state1Do, state2Do)\
+    EDC_PART_BASE(sName, enumType, 1, 1, \
+        EDC_STATE_COMMON("default", \
+            EDC_REL_RELATIVE(0.0, 0.0, sToPart), \
+            EDC_REL_RELATIVE(1.0, 1.0, sToPart), state1Do;)\
+        EDC_STATE_COMMON(sStateName2, \
+            EDC_REL_RELATIVE(0.0, 0.0, sToPart), \
+            EDC_REL_RELATIVE(1.0, 1.0, sToPart), state2Do;))
+
+#define EDC_PART_BUTTON_IMG(sName, sToPart, imgNormal, imgPressed) \
+    EDC_PART_TWO_STATE(sName, IMAGE, sToPart, "pressed", imgNormal, imgPressed)
+
+#define EDC_PART_TWO_IMG(sName, sToPart, sState, imgNormal, imgPressed) \
+    EDC_PART_TWO_STATE(sName, IMAGE, sToPart, sState, imgNormal, imgPressed)
+
+#define EDC_PART_SWALLOW_SHOW_HIDE(sName, sToPart) \
+    EDC_PART_TWO_STATE(sName, SWALLOW, sToPart, "hide", visible: 1;, visible: 0;)
+
+#define EDC_PART_SWALLOW_HIDE_SHOW(sName, sToPart) \
+    EDC_PART_TWO_STATE(sName, SWALLOW, sToPart, "show", visible: 0;, visible: 1;)
+
+
+#endif /* __EDC_MACRO_H__ */
diff --git a/theme/images/P04_calculator_btn_01.png b/theme/images/P04_calculator_btn_01.png
new file mode 100644 (file)
index 0000000..a359535
Binary files /dev/null and b/theme/images/P04_calculator_btn_01.png differ
diff --git a/theme/images/P04_calculator_btn_01_press.png b/theme/images/P04_calculator_btn_01_press.png
new file mode 100644 (file)
index 0000000..e7a74f3
Binary files /dev/null and b/theme/images/P04_calculator_btn_01_press.png differ
diff --git a/theme/images/P04_calculator_btn_02.png b/theme/images/P04_calculator_btn_02.png
new file mode 100644 (file)
index 0000000..48eb309
Binary files /dev/null and b/theme/images/P04_calculator_btn_02.png differ
diff --git a/theme/images/P04_calculator_btn_02_press.png b/theme/images/P04_calculator_btn_02_press.png
new file mode 100644 (file)
index 0000000..f5d1775
Binary files /dev/null and b/theme/images/P04_calculator_btn_02_press.png differ
diff --git a/theme/images/P04_calculator_btn_03.png b/theme/images/P04_calculator_btn_03.png
new file mode 100644 (file)
index 0000000..2b34de6
Binary files /dev/null and b/theme/images/P04_calculator_btn_03.png differ
diff --git a/theme/images/P04_calculator_btn_03_press.png b/theme/images/P04_calculator_btn_03_press.png
new file mode 100644 (file)
index 0000000..3a0fa83
Binary files /dev/null and b/theme/images/P04_calculator_btn_03_press.png differ
diff --git a/theme/images/P04_calculator_btn_04.png b/theme/images/P04_calculator_btn_04.png
new file mode 100644 (file)
index 0000000..63d68ec
Binary files /dev/null and b/theme/images/P04_calculator_btn_04.png differ
diff --git a/theme/images/P04_calculator_btn_04_press.png b/theme/images/P04_calculator_btn_04_press.png
new file mode 100644 (file)
index 0000000..4606568
Binary files /dev/null and b/theme/images/P04_calculator_btn_04_press.png differ
diff --git a/theme/images/P04_calculator_btn_05.png b/theme/images/P04_calculator_btn_05.png
new file mode 100644 (file)
index 0000000..e7aaef5
Binary files /dev/null and b/theme/images/P04_calculator_btn_05.png differ
diff --git a/theme/images/P04_calculator_btn_05_press.png b/theme/images/P04_calculator_btn_05_press.png
new file mode 100644 (file)
index 0000000..45cca0b
Binary files /dev/null and b/theme/images/P04_calculator_btn_05_press.png differ
diff --git a/theme/images/P04_calculator_btn_06.png b/theme/images/P04_calculator_btn_06.png
new file mode 100644 (file)
index 0000000..15143b8
Binary files /dev/null and b/theme/images/P04_calculator_btn_06.png differ
diff --git a/theme/images/P04_calculator_btn_06_press.png b/theme/images/P04_calculator_btn_06_press.png
new file mode 100644 (file)
index 0000000..f593641
Binary files /dev/null and b/theme/images/P04_calculator_btn_06_press.png differ
diff --git a/theme/images/P04_calculator_btn_07.png b/theme/images/P04_calculator_btn_07.png
new file mode 100644 (file)
index 0000000..ff49f90
Binary files /dev/null and b/theme/images/P04_calculator_btn_07.png differ
diff --git a/theme/images/P04_calculator_btn_07_press.png b/theme/images/P04_calculator_btn_07_press.png
new file mode 100644 (file)
index 0000000..47b09cc
Binary files /dev/null and b/theme/images/P04_calculator_btn_07_press.png differ
diff --git a/theme/images/P04_calculator_btn_08.png b/theme/images/P04_calculator_btn_08.png
new file mode 100644 (file)
index 0000000..f3c550b
Binary files /dev/null and b/theme/images/P04_calculator_btn_08.png differ
diff --git a/theme/images/P04_calculator_btn_08_press.png b/theme/images/P04_calculator_btn_08_press.png
new file mode 100644 (file)
index 0000000..f6230e3
Binary files /dev/null and b/theme/images/P04_calculator_btn_08_press.png differ
diff --git a/theme/images/P04_calculator_btn_09.png b/theme/images/P04_calculator_btn_09.png
new file mode 100644 (file)
index 0000000..8538496
Binary files /dev/null and b/theme/images/P04_calculator_btn_09.png differ
diff --git a/theme/images/P04_calculator_btn_09_press.png b/theme/images/P04_calculator_btn_09_press.png
new file mode 100644 (file)
index 0000000..33b8abe
Binary files /dev/null and b/theme/images/P04_calculator_btn_09_press.png differ
diff --git a/theme/images/P04_calculator_btn_10.png b/theme/images/P04_calculator_btn_10.png
new file mode 100644 (file)
index 0000000..79409a3
Binary files /dev/null and b/theme/images/P04_calculator_btn_10.png differ
diff --git a/theme/images/P04_calculator_btn_10_press.png b/theme/images/P04_calculator_btn_10_press.png
new file mode 100644 (file)
index 0000000..d243091
Binary files /dev/null and b/theme/images/P04_calculator_btn_10_press.png differ
diff --git a/theme/images/P04_calculator_btn_n00.png b/theme/images/P04_calculator_btn_n00.png
new file mode 100644 (file)
index 0000000..1c69966
Binary files /dev/null and b/theme/images/P04_calculator_btn_n00.png differ
diff --git a/theme/images/P04_calculator_btn_n00_press.png b/theme/images/P04_calculator_btn_n00_press.png
new file mode 100644 (file)
index 0000000..bb8c045
Binary files /dev/null and b/theme/images/P04_calculator_btn_n00_press.png differ
diff --git a/theme/images/P04_calculator_btn_n01.png b/theme/images/P04_calculator_btn_n01.png
new file mode 100644 (file)
index 0000000..cb20456
Binary files /dev/null and b/theme/images/P04_calculator_btn_n01.png differ
diff --git a/theme/images/P04_calculator_btn_n01_press.png b/theme/images/P04_calculator_btn_n01_press.png
new file mode 100644 (file)
index 0000000..7b1660b
Binary files /dev/null and b/theme/images/P04_calculator_btn_n01_press.png differ
diff --git a/theme/images/P04_calculator_btn_n02.png b/theme/images/P04_calculator_btn_n02.png
new file mode 100644 (file)
index 0000000..db3f725
Binary files /dev/null and b/theme/images/P04_calculator_btn_n02.png differ
diff --git a/theme/images/P04_calculator_btn_n02_press.png b/theme/images/P04_calculator_btn_n02_press.png
new file mode 100644 (file)
index 0000000..de1b4af
Binary files /dev/null and b/theme/images/P04_calculator_btn_n02_press.png differ
diff --git a/theme/images/P04_calculator_btn_n03.png b/theme/images/P04_calculator_btn_n03.png
new file mode 100644 (file)
index 0000000..414c484
Binary files /dev/null and b/theme/images/P04_calculator_btn_n03.png differ
diff --git a/theme/images/P04_calculator_btn_n03_press.png b/theme/images/P04_calculator_btn_n03_press.png
new file mode 100644 (file)
index 0000000..be8d401
Binary files /dev/null and b/theme/images/P04_calculator_btn_n03_press.png differ
diff --git a/theme/images/P04_calculator_btn_n04.png b/theme/images/P04_calculator_btn_n04.png
new file mode 100644 (file)
index 0000000..b5a1d07
Binary files /dev/null and b/theme/images/P04_calculator_btn_n04.png differ
diff --git a/theme/images/P04_calculator_btn_n04_press.png b/theme/images/P04_calculator_btn_n04_press.png
new file mode 100644 (file)
index 0000000..7a69390
Binary files /dev/null and b/theme/images/P04_calculator_btn_n04_press.png differ
diff --git a/theme/images/P04_calculator_btn_n05.png b/theme/images/P04_calculator_btn_n05.png
new file mode 100644 (file)
index 0000000..0605be5
Binary files /dev/null and b/theme/images/P04_calculator_btn_n05.png differ
diff --git a/theme/images/P04_calculator_btn_n05_press.png b/theme/images/P04_calculator_btn_n05_press.png
new file mode 100644 (file)
index 0000000..2d73744
Binary files /dev/null and b/theme/images/P04_calculator_btn_n05_press.png differ
diff --git a/theme/images/P04_calculator_btn_n06.png b/theme/images/P04_calculator_btn_n06.png
new file mode 100644 (file)
index 0000000..851e041
Binary files /dev/null and b/theme/images/P04_calculator_btn_n06.png differ
diff --git a/theme/images/P04_calculator_btn_n06_press.png b/theme/images/P04_calculator_btn_n06_press.png
new file mode 100644 (file)
index 0000000..f73337f
Binary files /dev/null and b/theme/images/P04_calculator_btn_n06_press.png differ
diff --git a/theme/images/P04_calculator_btn_n07.png b/theme/images/P04_calculator_btn_n07.png
new file mode 100644 (file)
index 0000000..287ba59
Binary files /dev/null and b/theme/images/P04_calculator_btn_n07.png differ
diff --git a/theme/images/P04_calculator_btn_n07_press.png b/theme/images/P04_calculator_btn_n07_press.png
new file mode 100644 (file)
index 0000000..512982d
Binary files /dev/null and b/theme/images/P04_calculator_btn_n07_press.png differ
diff --git a/theme/images/P04_calculator_btn_n08.png b/theme/images/P04_calculator_btn_n08.png
new file mode 100644 (file)
index 0000000..e936d80
Binary files /dev/null and b/theme/images/P04_calculator_btn_n08.png differ
diff --git a/theme/images/P04_calculator_btn_n08_press.png b/theme/images/P04_calculator_btn_n08_press.png
new file mode 100644 (file)
index 0000000..bda8637
Binary files /dev/null and b/theme/images/P04_calculator_btn_n08_press.png differ
diff --git a/theme/images/P04_calculator_btn_n09.png b/theme/images/P04_calculator_btn_n09.png
new file mode 100644 (file)
index 0000000..6b5cab0
Binary files /dev/null and b/theme/images/P04_calculator_btn_n09.png differ
diff --git a/theme/images/P04_calculator_btn_n09_press.png b/theme/images/P04_calculator_btn_n09_press.png
new file mode 100755 (executable)
index 0000000..ed409dd
Binary files /dev/null and b/theme/images/P04_calculator_btn_n09_press.png differ
old mode 100644 (file)
new mode 100755 (executable)
similarity index 74%
rename from images/P04_calculator_down_arrow.png
rename to theme/images/P04_calculator_down_handle.png
index fba8895..b692928
Binary files a/images/P04_calculator_down_arrow.png and b/theme/images/P04_calculator_down_handle.png differ
diff --git a/theme/images/P04_calculator_down_handle_press.png b/theme/images/P04_calculator_down_handle_press.png
new file mode 100644 (file)
index 0000000..ffe24e1
Binary files /dev/null and b/theme/images/P04_calculator_down_handle_press.png differ
diff --git a/theme/images/P04_calculator_up_handle.png b/theme/images/P04_calculator_up_handle.png
new file mode 100644 (file)
index 0000000..ddaac85
Binary files /dev/null and b/theme/images/P04_calculator_up_handle.png differ
diff --git a/theme/images/P04_calculator_up_handle_press.png b/theme/images/P04_calculator_up_handle_press.png
new file mode 100644 (file)
index 0000000..f0c5c23
Binary files /dev/null and b/theme/images/P04_calculator_up_handle_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_01.png b/theme/images/landscape/P04_calculator_btn_01.png
new file mode 100755 (executable)
index 0000000..a66588d
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_01.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_01_press.png b/theme/images/landscape/P04_calculator_btn_01_press.png
new file mode 100644 (file)
index 0000000..ea9da9a
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_01_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_02.png b/theme/images/landscape/P04_calculator_btn_02.png
new file mode 100644 (file)
index 0000000..2f10a72
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_02.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_02_press.png b/theme/images/landscape/P04_calculator_btn_02_press.png
new file mode 100644 (file)
index 0000000..e3274af
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_02_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_03.png b/theme/images/landscape/P04_calculator_btn_03.png
new file mode 100644 (file)
index 0000000..15ca5ed
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_03.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_03_press.png b/theme/images/landscape/P04_calculator_btn_03_press.png
new file mode 100644 (file)
index 0000000..43f2789
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_03_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_04.png b/theme/images/landscape/P04_calculator_btn_04.png
new file mode 100644 (file)
index 0000000..aa28c4e
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_04.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_04_press.png b/theme/images/landscape/P04_calculator_btn_04_press.png
new file mode 100644 (file)
index 0000000..81b1618
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_04_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_05.png b/theme/images/landscape/P04_calculator_btn_05.png
new file mode 100644 (file)
index 0000000..e068988
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_05.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_05_press.png b/theme/images/landscape/P04_calculator_btn_05_press.png
new file mode 100644 (file)
index 0000000..ab17023
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_05_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_06.png b/theme/images/landscape/P04_calculator_btn_06.png
new file mode 100644 (file)
index 0000000..de3d39d
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_06.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_06_press.png b/theme/images/landscape/P04_calculator_btn_06_press.png
new file mode 100644 (file)
index 0000000..29dffc2
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_06_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_07.png b/theme/images/landscape/P04_calculator_btn_07.png
new file mode 100644 (file)
index 0000000..c11494a
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_07.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_07_press.png b/theme/images/landscape/P04_calculator_btn_07_press.png
new file mode 100644 (file)
index 0000000..bc28cc2
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_07_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_08.png b/theme/images/landscape/P04_calculator_btn_08.png
new file mode 100644 (file)
index 0000000..238680b
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_08.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_08_press.png b/theme/images/landscape/P04_calculator_btn_08_press.png
new file mode 100644 (file)
index 0000000..864999d
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_08_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_09.png b/theme/images/landscape/P04_calculator_btn_09.png
new file mode 100644 (file)
index 0000000..bcabc05
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_09.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_09_press.png b/theme/images/landscape/P04_calculator_btn_09_press.png
new file mode 100644 (file)
index 0000000..1982608
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_09_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_10.png b/theme/images/landscape/P04_calculator_btn_10.png
new file mode 100644 (file)
index 0000000..bf27fc8
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_10.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_1011.png b/theme/images/landscape/P04_calculator_btn_1011.png
new file mode 100644 (file)
index 0000000..726751c
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_1011.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_10_press.png b/theme/images/landscape/P04_calculator_btn_10_press.png
new file mode 100644 (file)
index 0000000..b6d3f29
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_10_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_11.png b/theme/images/landscape/P04_calculator_btn_11.png
new file mode 100644 (file)
index 0000000..46d51af
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_11.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_11_press.png b/theme/images/landscape/P04_calculator_btn_11_press.png
new file mode 100644 (file)
index 0000000..4b72b7f
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_11_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_12.png b/theme/images/landscape/P04_calculator_btn_12.png
new file mode 100644 (file)
index 0000000..0c01def
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_12.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_12_press.png b/theme/images/landscape/P04_calculator_btn_12_press.png
new file mode 100644 (file)
index 0000000..6c1fb45
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_12_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_13.png b/theme/images/landscape/P04_calculator_btn_13.png
new file mode 100644 (file)
index 0000000..4c13a57
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_13.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_13_press.png b/theme/images/landscape/P04_calculator_btn_13_press.png
new file mode 100644 (file)
index 0000000..b26f02c
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_13_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_14.png b/theme/images/landscape/P04_calculator_btn_14.png
new file mode 100644 (file)
index 0000000..83f3058
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_14.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_14_press.png b/theme/images/landscape/P04_calculator_btn_14_press.png
new file mode 100644 (file)
index 0000000..c70220c
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_14_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_15.png b/theme/images/landscape/P04_calculator_btn_15.png
new file mode 100644 (file)
index 0000000..4970270
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_15.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_15_press.png b/theme/images/landscape/P04_calculator_btn_15_press.png
new file mode 100644 (file)
index 0000000..fbe233b
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_15_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_16.png b/theme/images/landscape/P04_calculator_btn_16.png
new file mode 100644 (file)
index 0000000..16cad92
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_16.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_16_press.png b/theme/images/landscape/P04_calculator_btn_16_press.png
new file mode 100644 (file)
index 0000000..6a2d7d4
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_16_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_17.png b/theme/images/landscape/P04_calculator_btn_17.png
new file mode 100644 (file)
index 0000000..cc2b329
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_17.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_17_press.png b/theme/images/landscape/P04_calculator_btn_17_press.png
new file mode 100644 (file)
index 0000000..c0e99c4
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_17_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_18.png b/theme/images/landscape/P04_calculator_btn_18.png
new file mode 100644 (file)
index 0000000..d36f63a
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_18.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_18_press.png b/theme/images/landscape/P04_calculator_btn_18_press.png
new file mode 100644 (file)
index 0000000..58fbaf7
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_18_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_19.png b/theme/images/landscape/P04_calculator_btn_19.png
new file mode 100644 (file)
index 0000000..9372bbf
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_19.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_19_press.png b/theme/images/landscape/P04_calculator_btn_19_press.png
new file mode 100644 (file)
index 0000000..e62d237
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_19_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_20.png b/theme/images/landscape/P04_calculator_btn_20.png
new file mode 100644 (file)
index 0000000..5b37951
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_20.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_20_press.png b/theme/images/landscape/P04_calculator_btn_20_press.png
new file mode 100644 (file)
index 0000000..02978c8
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_20_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_21.png b/theme/images/landscape/P04_calculator_btn_21.png
new file mode 100644 (file)
index 0000000..f661a32
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_21.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_21_press.png b/theme/images/landscape/P04_calculator_btn_21_press.png
new file mode 100644 (file)
index 0000000..23bf199
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_21_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_22.png b/theme/images/landscape/P04_calculator_btn_22.png
new file mode 100644 (file)
index 0000000..6f1a8d9
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_22.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_22_press.png b/theme/images/landscape/P04_calculator_btn_22_press.png
new file mode 100644 (file)
index 0000000..d168b99
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_22_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_23.png b/theme/images/landscape/P04_calculator_btn_23.png
new file mode 100644 (file)
index 0000000..d5d495a
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_23.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_23_press.png b/theme/images/landscape/P04_calculator_btn_23_press.png
new file mode 100644 (file)
index 0000000..ec56f12
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_23_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_24.png b/theme/images/landscape/P04_calculator_btn_24.png
new file mode 100644 (file)
index 0000000..73e3d5b
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_24.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_24_press.png b/theme/images/landscape/P04_calculator_btn_24_press.png
new file mode 100644 (file)
index 0000000..4571ca0
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_24_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_25.png b/theme/images/landscape/P04_calculator_btn_25.png
new file mode 100644 (file)
index 0000000..ea0fe61
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_25.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_25_press.png b/theme/images/landscape/P04_calculator_btn_25_press.png
new file mode 100644 (file)
index 0000000..9449c53
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_25_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n00.png b/theme/images/landscape/P04_calculator_btn_n00.png
new file mode 100644 (file)
index 0000000..6500ede
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n00.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n00_press.png b/theme/images/landscape/P04_calculator_btn_n00_press.png
new file mode 100644 (file)
index 0000000..8f3f0d1
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n00_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n01.png b/theme/images/landscape/P04_calculator_btn_n01.png
new file mode 100644 (file)
index 0000000..d3e6be3
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n01.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n01_press.png b/theme/images/landscape/P04_calculator_btn_n01_press.png
new file mode 100644 (file)
index 0000000..c6e62c7
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n01_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n02.png b/theme/images/landscape/P04_calculator_btn_n02.png
new file mode 100644 (file)
index 0000000..a350714
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n02.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n02_press.png b/theme/images/landscape/P04_calculator_btn_n02_press.png
new file mode 100644 (file)
index 0000000..c368242
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n02_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n03.png b/theme/images/landscape/P04_calculator_btn_n03.png
new file mode 100644 (file)
index 0000000..6404e11
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n03.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n03_press.png b/theme/images/landscape/P04_calculator_btn_n03_press.png
new file mode 100644 (file)
index 0000000..14bf490
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n03_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n04.png b/theme/images/landscape/P04_calculator_btn_n04.png
new file mode 100644 (file)
index 0000000..541df0e
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n04.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n04_press.png b/theme/images/landscape/P04_calculator_btn_n04_press.png
new file mode 100644 (file)
index 0000000..4eb5f75
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n04_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n05.png b/theme/images/landscape/P04_calculator_btn_n05.png
new file mode 100644 (file)
index 0000000..f7a5b54
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n05.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n05_press.png b/theme/images/landscape/P04_calculator_btn_n05_press.png
new file mode 100644 (file)
index 0000000..22c8501
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n05_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n06.png b/theme/images/landscape/P04_calculator_btn_n06.png
new file mode 100644 (file)
index 0000000..a3d9399
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n06.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n06_press.png b/theme/images/landscape/P04_calculator_btn_n06_press.png
new file mode 100644 (file)
index 0000000..d27b3a3
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n06_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n07.png b/theme/images/landscape/P04_calculator_btn_n07.png
new file mode 100644 (file)
index 0000000..186b40d
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n07.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n07_press.png b/theme/images/landscape/P04_calculator_btn_n07_press.png
new file mode 100644 (file)
index 0000000..4915e5b
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n07_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n08.png b/theme/images/landscape/P04_calculator_btn_n08.png
new file mode 100644 (file)
index 0000000..bebada7
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n08.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n08_press.png b/theme/images/landscape/P04_calculator_btn_n08_press.png
new file mode 100644 (file)
index 0000000..fd33ef4
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n08_press.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n09.png b/theme/images/landscape/P04_calculator_btn_n09.png
new file mode 100644 (file)
index 0000000..0b09b7c
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n09.png differ
diff --git a/theme/images/landscape/P04_calculator_btn_n09_press.png b/theme/images/landscape/P04_calculator_btn_n09_press.png
new file mode 100644 (file)
index 0000000..61eb62b
Binary files /dev/null and b/theme/images/landscape/P04_calculator_btn_n09_press.png differ
diff --git a/theme/images/landscape/P04_calculator_down_handle_land.png b/theme/images/landscape/P04_calculator_down_handle_land.png
new file mode 100644 (file)
index 0000000..5351bec
Binary files /dev/null and b/theme/images/landscape/P04_calculator_down_handle_land.png differ
diff --git a/theme/images/landscape/P04_calculator_down_handle_land_press.png b/theme/images/landscape/P04_calculator_down_handle_land_press.png
new file mode 100644 (file)
index 0000000..0da3bb8
Binary files /dev/null and b/theme/images/landscape/P04_calculator_down_handle_land_press.png differ
diff --git a/theme/images/landscape/P04_calculator_up_handle_land.png b/theme/images/landscape/P04_calculator_up_handle_land.png
new file mode 100644 (file)
index 0000000..15b53a6
Binary files /dev/null and b/theme/images/landscape/P04_calculator_up_handle_land.png differ
diff --git a/theme/images/landscape/P04_calculator_up_handle_land_press.png b/theme/images/landscape/P04_calculator_up_handle_land_press.png
new file mode 100644 (file)
index 0000000..3676bff
Binary files /dev/null and b/theme/images/landscape/P04_calculator_up_handle_land_press.png differ
diff --git a/theme/include/calc-expression.h b/theme/include/calc-expression.h
new file mode 100644 (file)
index 0000000..a7ad73d
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#ifndef __DEF_CALC_EXPRESSION_H_
+#define __DEF_CALC_EXPRESSION_H_
+
+#ifdef __cplusplus
+extern "C" {
+
+#endif /* __cplusplus */
+
+#include "calculator_parser.h"
+
+#define IS_SIGN(ch)         ((ch) == '+' || (ch) == '-')
+#define IS_SCIENCE_E(ch)    ((ch) == 'E' || (ch) == 'e')
+#define IS_OPERATOER(ch)    ((ch) == '+' || (ch) == '-' || (ch) == 'x' || (ch) == '/' || (ch) == '^')
+#define IS_DIGITAL(ch)         (isdigit((ch)) || (ch) == 'p' || (ch) == 'e')
+
+/* */
+#define FLOAT_EQUAL(a, b)       (fabs((a) - (b)) < 0.000000000001)
+         struct calc_func_t  {
+               op_id_t id;
+               char *symbol;
+       };
+
+/**
+* @describe
+*
+*
+* @param    expr_in
+* @param    expr_out
+* @return    void
+* @exception
+*/
+       void calc_expr_format_expression(const char *expr_in, char *expr_out);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @return    int
+* @exception
+*/
+       int calc_expr_get_operator_num(const char *expr);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @return    int
+* @exception
+*/
+       int calc_expr_get_left_parentheses_num(const char *expr);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @return    void
+* @exception
+*/
+       void calc_expr_replace_with_special_char(char *expr);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @return    void
+* @exception
+*/
+       void calc_expr_replace_from_special_char(char *expr);
+
+/**
+* @describe
+*
+*
+* @param    result
+* @param    text
+* @return    void
+* @exception
+*/
+       void calc_expr_num_format_result(double result, char *text);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @param    cursor
+* @return    void
+* @exception
+*/
+       char *calc_expr_get_current_func_at_cursor(char *expr, int cursor);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @param    cursor
+* @param    begin
+* @param    length
+* @return    int
+* @exception
+*/
+       int calc_expr_get_current_num_at_cursor(char *expr, int cursor,
+                                               int *begin, int *length);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @return    void
+* @exception
+*/
+       void calc_expr_close_parentheses(char *exp);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @return    void
+* @exception
+*/
+       void calc_expr_preprocess(char *exp);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @param    cursor
+* @return    void
+* @exception
+*/
+       void calc_expr_input_backspace(char *exp, int *cursor);
+
+/**
+* @describe
+*
+*
+* @param    expr
+* @param    cursor
+* @param    cursor
+* @return    str
+* @exception
+*/
+       void calc_expr_input_insert(char *exp, int *cursor, char *str);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __DEF_CALC_EXPRESSION_H_ */
+
diff --git a/theme/include/calc-main.h b/theme/include/calc-main.h
new file mode 100644 (file)
index 0000000..1bcc066
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#ifndef __DEF_CALCULATOR_H_
+#define __DEF_CALCULATOR_H_
+
+#include <Elementary.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <dlog.h>
+#include <app.h>
+
+/* Path & Name */
+#define PACKAGE                                "calculator"
+#define LAYOUT_EDJ_NAME                        EDJDIR"/calculator.edj"
+#define CALCULATOR_THEME               EDJDIR"/calculator_theme.edj"
+
+#define GRP_MAIN                               "main"
+#define GRP_POR_PANNEL                         "por_pannel"
+#define GRP_LAN_PANNEL                         "lan_pannel"
+
+//#define COM_SAMSUNG_S           "com.samsung.%s"
+
+#define SAVE_HISTORY
+
+/* Max */
+#define MAX_FONT_SIZE           44
+#define NUMBER_LENGTH 1024
+#define MAX_EXPRESSION_LENGTH   1024
+#define MAX_RESULT_LENGTH       1024
+#define MAX_ERROR_MESSAGE_LENGTH  256
+
+//#define MAX_TAG_EXPRESSION_LENGTH 4096
+#define MAX_TAG_EXPRESSION_LENGTH 420*48
+
+//#define MAX_RESULT_LENGTH       128
+
+#define MAX_HISTORY_NUM         10
+#define MAX_DECIMAL_NUM         5
+#define MAX_NUM_LENGTH          15
+#define MAX_OPERATOR_NUM        20
+#define MAX_PARENTHESES_NUM     64
+
+/* Math */
+#define PI                                     3.1415926535897932384626433832795
+#define EXPONENT                               2.718281828459045235360287471352662497757
+#define RADIAN_FACTOR                  (PI/180)
+#define DEGREEN_FACTOR                         (180/PI)
+#define PI_STR                                 "3.1415926535897932384626433832795"
+#define EXPONENT_STR                   "2.718281828459045235360287471352662497757"
+
+/* Function */
+#ifndef _EDJ
+#define _EDJ(x) (Evas_Object *)elm_layout_edje_get(x)
+#endif                         /* _EDJ */
+
+#ifndef _
+#define _(str) gettext(str)
+#endif                         /* _ */
+
+#ifndef gettext_noop
+#define gettext_noop(str) (str)
+#endif                         /* gettext_noop */
+
+#ifndef N_
+#define N_(str) gettext_noop(str)
+#endif                         /* N_ */
+
+#define SFREE(var)\
+       if(var != NULL){\
+               free((void *)var);\
+               var = NULL;\
+               }\
+
+#define CALCULATOR_CONTENT_LEN                                 32
+
+#define CALCULATOR_MAX_RESULT_SUM2                             (10e+100)                               /**<maximum num of result sum*/
+#define CALCULATOR_MIN_RESULT_SUM2                             (-10e+100)                              /**<minimum num of result sum*/
+
+/* BEGIN DEBUG LOG MACRO */
+#ifdef  LOG_TAG
+#undef  LOG_TAG
+#endif
+#define LOG_TAG "CALCULATOR"
+
+#define CALC_INFO(fmt, arg...) LOGD("[%s:%d] "fmt,__FILE__, __LINE__, ##arg);
+#define FONT_COLOR_RESET    "\033[0m"
+#define FONT_COLOR_RED      "\033[31m"
+#define FONT_COLOR_GREEN    "\033[32m"
+#define FONT_COLOR_YELLOW   "\033[33m"
+#define FONT_COLOR_BLUE     "\033[34m"
+#define FONT_COLOR_PURPLE   "\033[35m"
+#define FONT_COLOR_CYAN     "\033[36m"
+#define FONT_COLOR_GRAY     "\033[37m"
+
+#define CALC_INFO_RED(fmt, arg...) CALC_INFO(FONT_COLOR_RED fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_GREEN(fmt, arg...) CALC_INFO(FONT_COLOR_GREEN fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_YELLOW(fmt, arg...) CALC_INFO(FONT_COLOR_YELLOW fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_BLUE(fmt, arg...) CALC_INFO(FONT_COLOR_BLUE fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_PURPLE(fmt, arg...) CALC_INFO(FONT_COLOR_PURPLE fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_CYAN(fmt, arg...) CALC_INFO(FONT_COLOR_CYAN fmt FONT_COLOR_RESET, ##arg)
+#define CALC_INFO_GRAY(fmt, arg...) CALC_INFO(FONT_COLOR_GRAY fmt FONT_COLOR_RESET, ##arg)
+
+
+//#define PERFORMANCE_LOG
+#ifdef PERFORMANCE_LOG
+#define DBG(fmt, arg...) SLOGD("%s(%d) " fmt, __FUNCTION__, __LINE__, ##arg)
+#define CALC_FUN_BEG() DBG("START")
+#define CALC_FUN_END() DBG("END")
+#else
+#define CALC_FUN_BEG()
+#define CALC_FUN_END()
+#endif
+
+/* Help String of UI Guideline */
+#define CALC_MSG_MAX_DIGIT                 _("IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE")
+#define CALC_MSG_MAX_DEC_DIGIT         _("IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE")
+#define CALC_MSG_MAX_OP                            _("IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE")
+#define CALC_MSG_DIVIDE_BY_ZERO                _("IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO")
+#define CALC_MSG_NUM_FIRST                 _("IDS_CCL_POP_NO_NUMBER_ERROR")
+#define CALC_MSG_OUT_OF_RANGE          _("IDS_CCL_POP_ERROR")
+#define CALC_MSG_NUM_AFTER_OP          _("IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR")
+#define CALC_MSG_INVALID_SQUARE                _("IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION")
+#define CALC_MSG_INVALID_LOG           _("IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION")
+#define CALC_MSG_INVALID_FAC           _("IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION")
+#define CALC_MSG_NUM_FIRST_FAC         _("IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION")
+#define CALC_MSG_NUM_FIRST_RECIP       _("IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION")
+#define CALC_MSG_NUM_FIRST_X2          _("IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION")
+#define CALC_MSG_NUM_FIRST_XY          _("IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION")
+
+/* Custtom Error Message */
+#define CALC_MSG_OP_FIRST                  _("IDS_CCL_POP_NO_OPERATOR_ERROR")
+#define CALC_MSG_SYNTAX_ERROR       _("IDS_CCL_POP_SYNTAX_ERROR")
+#if 0
+#define CALC_MSG_INVALID_LN         _("Invalid input for ln function")
+#define CALC_MSG_INVALID_XY         _("Invalid param for x^y")
+#define CALC_MSG_INVALID_TAN        _("Invalid param for tan")
+#define CALC_MSG_ENTRY_LIMIT        _("Already had decimal in digit")
+#endif
+#define ARRAY_SIZE(array)  (sizeof(array)/sizeof(array[0]))
+
+struct appdata {
+       Evas_Object *win;       //main window
+       Evas_Object *bg;
+       Evas_Object *layout;
+       Evas_Object *edje;
+       Evas_Object *eo;
+
+       Evas_Object *input_scroller;
+       Evas_Object *input_entry;
+       Evas_Object *por_pannel;
+       Evas_Object *lan_pannel;
+       Evas_Object *btn;
+
+       Ecore_Timer *calc_timer;
+       Ecore_Timer *wrong_timer;
+       int svi_handle;
+
+       Evas_Object *nf;
+       Elm_Object_Item *navi_it;
+       Evas_Object *tool_bar;
+       Elm_Object_Item *clear_btn;
+       Elm_Object_Item *invalid_btn;
+#ifdef SAVE_HISTORY
+       Evas_Object *hist_scroll;
+       Evas_Object *hist_area;
+#endif
+};
+
+/**
+* @describe
+*       Load edj file from group to elm_layout.
+*
+* @param    parent
+* @param    file
+* @param    group
+* @return
+* @exception
+*/
+Evas_Object *load_edj(Evas_Object * parent, const char *file,
+                     const char *group);
+void _calc_entry_clear(Evas_Object * entry);
+
+#endif                         /* __DEF_CALCULATOR_H__ */
diff --git a/theme/include/calc-string.h b/theme/include/calc-string.h
new file mode 100644 (file)
index 0000000..3d163db
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#ifndef __DEF_CALC_STRING_H_
+#define __DEF_CALC_STRING_H_
+
+#ifdef __cplusplus
+extern "C" {
+
+#endif /* __cplusplus */
+
+/**
+* @describe
+*
+*
+* @param    str
+* @param    index
+* @param    str2
+* @return    void
+* @exception
+*/
+       void string_insert(char *str, int index, char *str2);
+
+/**
+* @describe
+*
+*
+* @param    str
+* @param    a
+* @param    b
+* @return    void
+* @exception
+*/
+       void string_replace(char *str, char *a, char *b);
+
+/**
+* @describe
+*
+*
+* @param    str
+* @param    at
+* @param    length
+* @return    void
+* @exception
+*/
+       void string_remove_at(char *str, int at, int length);
+
+#ifdef _DEBUG
+/**
+* @describe
+*
+*
+* @param    i
+* @param    at
+* @return    char*
+* @exception
+*/
+
+/* DON'T REMOVE
+char* itoa(int i);
+*/
+#endif /* _DEBUG */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __DEF_CALC_STRING_H_ */
+
diff --git a/theme/include/calc-view.h b/theme/include/calc-view.h
new file mode 100644 (file)
index 0000000..28a52a7
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#ifndef __DEF_CALC_VIEW_H_
+#define __DEF_CALC_VIEW_H_
+
+#include "calc-main.h"
+
+/**
+* @struct      history_item
+* @brief       store the calculation history
+*/
+struct history_item  {
+       char expression[MAX_EXPRESSION_LENGTH]; /**<Store the express in string format */
+       double result;  /**<Store the calculate result in double format */
+};
+
+/**
+* @describe
+*
+*
+* @param    ad
+* @return    void
+* @exception
+*/
+void calc_view_load(struct appdata *ad);
+
+/**
+* @describe
+*
+*
+* @param    ad
+* @return    void
+* @exception
+*/
+void calc_view_load_in_idle(struct appdata *ad);
+
+/**
+* @describe
+*
+*
+* @param    ad
+* @return    void
+* @exception
+*/
+void calc_view_revise_input_scroller(struct appdata *ad);
+
+/**
+* @describe
+*
+*
+* @param    result
+* @param    ad
+* @return    void
+* @exception
+*/
+//void calc_view_show_result(const char *result, struct appdata *ad, int font_size);
+void calc_view_show_result(const char *result, struct appdata *ad);
+
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @return    int
+* @exception
+*/
+int calc_view_cursor_get_position(Evas_Object * entry);
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @param    pos
+* @return    void
+* @exception
+*/
+void calc_view_cursor_set_position(Evas_Object * entry, int pos);
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @param    pos
+* @return    void
+* @exception
+*/
+void calc_view_save_history(struct history_item item);
+
+#endif /* __DEF_CALC_VIEW_H_ */
+
diff --git a/theme/include/calculator_parser.h b/theme/include/calculator_parser.h
new file mode 100644 (file)
index 0000000..9c216a6
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#ifndef __CALCULATOR_PARSER_H
+#define __CALCULATOR_PARSER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif                         /* __cplusplus */
+
+#include <glib.h>
+
+       typedef enum {
+               CHAR_IS_NULL = 0,       //
+               CHAR_IS_DIGIT,  //0,1,2...
+               CHAR_IS_LEFT_PARENTHESE,        //(
+               CHAR_IS_RIGHT_PARENTHESE,
+               CHAR_IS_PLUS_MINUS,     //+/-
+               CHAR_IS_PI,     //Pi
+               CHAR_IS_E,      //e
+               CHAR_IS_MULTIPLY_DIVIDE,        // */
+               CHAR_IS_CHARACTER,      //a,P,C,^
+               CHAR_IS_POINT,  //point
+       } last_char_t;
+
+/**
+
+*@enum calculator_state_t, define calculator current state
+
+* This enum is used to judge or record which state is current.
+
+*/
+       typedef enum {
+               CALCULATOR_WAITING_INPUT = 0,           /**<waiting input state*/
+               CALCULATOR_OPERAND_INPUT,                       /**<operand input state*/
+               CALCULATOR_OPERAND_FRACTION_INPUT,      /**<fraction operand input state*/
+               CALCULATOR_OPERATOR_INPUT,                      /**<[basic] operator input state*/
+               CALCULATOR_OPERATOR_OPERAND_INPUT,      /**<operand after [basic] operator input state*/
+               CALCULATOR_SPECIAL_SYMBOL_INPUT,        /**<special symbol inputting state*/
+               CALCULATOR_SPECIAL_SYMBOL_INPUT_OVER,
+                                               /**<special symbol inputed state*/
+               CALCULATOR_SPECIAL_FUNCTION_INPUT,      /**<function[excluding basic operator] input state*/
+               CALCULATOR_NAVIGATION,                          /**<browser in entry state, depreated*/
+               CALCULATOR_CALCULATED,                          /**<calculation completed state*/
+               CALCULATOR_ERROR_OCCURED,                       /**<error occured state*/
+       } calculator_state_t;
+
+/**
+
+*@enum calculator_calculate_priority_t, define calculation priorities
+
+* This enum is used to mark operator &functions's priority.
+
+*/
+       typedef enum {
+               CALCULATOR_CALCULATE_PRIORITY_INVALID = 0,
+                                                       /**<invalid priority*/
+               CALCULATOR_CALCULATE_PRIORITY_LOW,              /**<lowest priority*/
+               CALCULATOR_CALCULATE_PRIORITY_MIDDLE,   /**<middle priority*/
+               CALCULATOR_CALCULATE_PRIORITY_HIGH,             /**<high priority*/
+               CALCULATOR_CALCULATE_PRIORITY_HIGHER,   /**<higher priority*/
+               CALCULATOR_CALCULATE_PRIORITY_HIGHEST,  /**<highest priority*/
+       } calculator_calculate_priority_t;
+
+/**
+
+*@enum operator_type_t, define calculator operator type
+
+*/
+       typedef enum {
+               OPERATOR_TYPE_INVALID = 0,
+                                       /**<operator type invalid*/
+               OPERATOR_TYPE_UNARY,            /**<operator unary*/
+               OPERATOR_TYPE_BINARY,           /**<operator binary*/
+               OPERATOR_TYPE_CNT,              /**<max count*/
+       } operator_type_t;
+
+/**
+
+*@enum function_category_t, define calculator function category
+
+*/
+       typedef enum {
+               FUNCTION_INVALID = 0,
+                               /**<category invalid*/
+               FUNCTION_PREFIX,        /**<prefix category, operand follows functions*/
+               FUNCTION_POSTFIX,       /**<postfix category, function follows operand*/
+               FUNCTION_CONSTANT,
+                               /**<constant category, only for PI*/
+               FUNCTION_CNT,           /**<max count*/
+       } function_category_t;
+
+       typedef enum {
+               OP_INVALID = 0,
+
+               /* basic pannel */
+               OP_PARENTHESIS, // 1
+               OP_DELETE,
+               OP_CLEAR,
+               OP_DIVIDE,
+
+               OP_NUM_7,       // 5
+               OP_NUM_8,
+               OP_NUM_9,
+               OP_MULTIPLY,
+
+               OP_NUM_4,       // 9
+               OP_NUM_5,
+               OP_NUM_6,
+               OP_MINUS,
+
+               OP_NUM_1,       // 13
+               OP_NUM_2,
+               OP_NUM_3,
+               OP_PLUS,
+
+               OP_DOT,         // 17
+               OP_NUM_0,
+               OP_PLUS_MINUS,
+               OP_EQUAL,
+
+               /* function pannel */
+               OP_PERCENT,     //21
+               OP_ROOT,
+               OP_FACT,
+
+               OP_SIN,         // 24
+               OP_COS,
+               OP_TAN,
+
+               OP_LN,          // 27
+               OP_LOG,
+               OP_1X,
+
+               OP_10X,         // 30
+               OP_X2,
+               OP_XY,
+
+               OP_ABS,         // 33
+               OP_PI,
+               OP_E,
+       } op_id_t;
+
+       typedef struct {
+               op_id_t op_id;
+               char *op_sym;
+               char *op_name;
+       } op_item_t;
+
+/**
+
+* @struct calculator_node_data_t, calculator node data structure
+
+* This structure is used as node data of n-ary tree
+
+*/
+       typedef struct {
+               //double tmp_result;                                                    /**<store result by temoprary*/
+               char tmp_result[MAX_RESULT_LENGTH];
+               calculator_calculate_priority_t node_calcu_priority;
+                                                               /**<node calculation priority*/
+               operator_type_t operator_type;                                  /**<node operator type*/
+               int children_num;                                                       /**<node children number*/
+               char cur_operator;                                                      /**<node operator char*/
+               int negative_flag;                                                      /**<node negative flag*/
+       } calculator_node_data_t;
+
+/**
+
+* @struct calculator_parentheses_data_t, calculator parentheses data structure
+
+*/
+       typedef struct {
+//      GNode* tree;            /**<parentheses tree node*/
+               char *start_pos;/**<parentheses start position in original string*/
+               char *end_pos;  /**<parentheses end position in original string*/
+               bool matched;
+                       /**<parentheses if is matched*/
+       } calculator_parentheses_data_t;
+
+/**
+
+* @struct function_t, calculator function data structure
+
+*/
+       typedef struct {
+               char *func_name;                                                /**<function name, use only prompt*/
+               char *func_string;                                              /**<function string, use in text view*/
+               gint str_len;                                                   /**<function string length*/
+               char function_char;                                     /**<function char*/
+               function_category_t category;                   /**<fuction category, input after operand*/
+               operator_type_t op_type;                                /**<operator type*/
+               calculator_calculate_priority_t priority;
+                                                       /**<calculation priority*/
+               bool has_parentheses;                           /**<if function has parentheses*/
+       } function_t;
+
+/**
+* @describe
+*
+*
+* @param    tmp_result
+* @return    bool
+* @exception
+*/
+//bool calculator_calculate_truncate_result(double* tmp_result);
+
+/**
+* @describe
+*
+*
+* @param    szInputString
+* @return    bool
+* @exception
+*/
+       int calculator_get_open_braket(const char *szInputString);
+
+/**
+* @describe
+*
+*
+* @param    szInput
+* @param    pDigitCnt
+* @param    pPointCnt
+* @return    bool
+* @exception
+*/
+       bool calculator_get_digits_number(char *szInput, int *pDigitCnt,
+                                         int *pPointCnt);
+
+/**
+* @describe
+*
+*
+* @param    szInput
+* @param    pDigitCnt
+* @param    pPointCnt
+* @return    bool
+* @exception
+*/
+       bool calculator_calculate(char *string, double *result,
+                                 char *error_msg);
+
+#ifdef __cplusplus
+}
+#endif                         /* __cplusplus */
+#endif
diff --git a/theme/org.tizen.calculator.png b/theme/org.tizen.calculator.png
new file mode 100644 (file)
index 0000000..056893b
Binary files /dev/null and b/theme/org.tizen.calculator.png differ
diff --git a/theme/org.tizen.calculator.xml b/theme/org.tizen.calculator.xml
new file mode 100755 (executable)
index 0000000..a2ce990
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?> \r
+<manifest xmlns="http://tizen.org/ns/packages" package="org.tizen.calculator" version="0.1.12" install-location="internal-only">\r
+       <label>Calculator</label> \r
+       <description>Calculator</description> \r
+       <ui-application appid="org.tizen.calculator" exec="/opt/apps/org.tizen.calculator/bin/calculator" nodisplay="false" multiple="false" type="capp" taskmanage="true">\r
+               <icon>org.tizen.calculator.png</icon> \r
+               <label>Calculator</label> \r
+               <label xml:lang="en-us">Calculator</label> \r
+               <label xml:lang="nl-nl">Calculator</label> \r
+               <label xml:lang="de-de">Rechner</label> \r
+               <label xml:lang="zh-hk">計算機</label> \r
+               <label xml:lang="zh-cn">计算器</label> \r
+               <label xml:lang="ru-ru">Калькулятор</label> \r
+               <label xml:lang="zh-tw">計算器</label> \r
+               <label xml:lang="ja-jp">電卓</label> \r
+               <label xml:lang="es-es">Calculadora</label> \r
+               <label xml:lang="el-gr">Αριθμομηχανή</label> \r
+               <label xml:lang="it-it">Calcolatrice</label> \r
+               <label xml:lang="tr-tr">Hesap makinesi</label> \r
+               <label xml:lang="pt-pt">Calculadora</label> \r
+               <label xml:lang="fr-fr">Calculatrice</label> \r
+               <label xml:lang="ko-kr">계산기</label> \r
+       </ui-application>\r
+</manifest>\r
diff --git a/theme/packaging/org.tizen.calculator.spec b/theme/packaging/org.tizen.calculator.spec
new file mode 100644 (file)
index 0000000..e1b00a2
--- /dev/null
@@ -0,0 +1,55 @@
+#sbs-git:slp/apps/c/calculator calculator 0.1.3 3ce35911eff2a8f151a092f346ab7239d7d0658e
+%define PREFIX /opt/apps/org.tizen.calculator
+Name: org.tizen.calculator
+Version:    0.1.22
+Release:    1
+Summary: SLP Calculator application
+URL: http://slp-source.sec.samsung.net
+Source: %{name}-%{version}.tar.gz
+License: TIZEN
+Group: tizen/Application
+BuildRequires: cmake
+BuildRequires: pkgconfig(edje)
+BuildRequires: pkgconfig(embryo)
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(elementary)
+BuildRequires: pkgconfig(utilX)
+BuildRequires: pkgconfig(appcore-efl)
+BuildRequires: pkgconfig(appcore-common)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(svi)
+BuildRequires: pkgconfig(capi-appfw-application)
+
+BuildRequires: gettext-tools
+BuildRequires: edje-bin, embryo-bin
+
+%description
+SLP Calculator application
+
+%prep
+%setup -q
+
+%build
+
+LDFLAGS+="-Wl,--rpath=%{PREFIX}/lib -Wl,--as-needed -Wl,--hash-style=both"; export LDFLAGS
+
+cmake . -DCMAKE_INSTALL_PREFIX=%{PREFIX}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%files
+%defattr(-,root,root,-)
+%attr(-,inhouse,inhouse)
+/opt/apps/org.tizen.calculator/bin/calculator
+/opt/apps/org.tizen.calculator/res/edje/calculator.edj
+/opt/apps/org.tizen.calculator/res/edje/calculator_theme.edj
+/opt/share/icons/default/small/org.tizen.calculator.png
+/opt/apps/org.tizen.calculator/res/icons/org.tizen.calculator.png
+/opt/apps/org.tizen.calculator/res/locale/*
+/opt/share/packages/org.tizen.calculator.xml
+/opt/share/process-info/calculator.ini
+
diff --git a/theme/po/CMakeLists.txt b/theme/po/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d496ff3
--- /dev/null
@@ -0,0 +1,24 @@
+# for i18n
+
+SET(POFILES ar.po  de_DE.po  fi.po     hu.po     lt.po     pl.po     sl.po     uk.po bg.po  el_GR.po  fr_FR.po  id.po     lv.po     pt_PT.po  sr.po     vi.po ca.po  en.po     he.po     it_IT.po  ms.po     ro.po     sv.po     zh_CN.po cs.po  en_US.po  hi.po     ja_JP.po  nl_NL.po  ru_RU.po  th.po     zh_HK.po da.po  es_ES.po  hr.po     ko_KR.po  no.po     sk.po     tr_TR.po  zh_TW.po)
+
+SET(MSGFMT "/usr/bin/msgfmt")
+
+FOREACH(pofile ${POFILES})
+       SET(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${pofile})
+       MESSAGE("PO: ${pofile}")
+       GET_FILENAME_COMPONENT(absPofile ${pofile} ABSOLUTE)
+       GET_FILENAME_COMPONENT(lang ${absPofile} NAME_WE)
+       SET(moFile ${CMAKE_CURRENT_BINARY_DIR}/${lang}.mo)
+       ADD_CUSTOM_COMMAND(
+                       OUTPUT ${moFile}
+                       COMMAND ${MSGFMT} -o ${moFile} ${absPofile}
+                       DEPENDS ${absPofile}
+       )
+       INSTALL(FILES ${moFile}
+                       DESTINATION /opt/apps/org.tizen.calculator/res/locale/${lang}/LC_MESSAGES RENAME ${PROJECT_NAME}.mo)
+       SET(moFiles ${moFiles} ${moFile})
+ENDFOREACH(pofile)
+
+MESSAGE(".mo files: ${moFiles}")
+ADD_CUSTOM_TARGET(po ALL DEPENDS ${moFiles})
diff --git a/theme/po/POTFILES.in b/theme/po/POTFILES.in
new file mode 100644 (file)
index 0000000..91a05f5
--- /dev/null
@@ -0,0 +1,8 @@
+# List of source files containing translatable strings.
+calculator.h
+calculator.c
+calculator_edje.c
+calculator_parser.h
+calculator_parser.c
+calculator_def.h
+strtbl.h
diff --git a/theme/po/ar.po b/theme/po/ar.po
new file mode 100644 (file)
index 0000000..f45c1b9
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "التحويل إلى"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "خطأ لغوي"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "يتوفر عدد 5 أرقام عشرية بحد أقصى"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "يتوفر عدد 20 معامل بحد أقصى"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "تتعذر القسمة على صفر"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "أدخل الرقم أولا"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "خارج المدى"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "إدخال رقم بعد التشغيل"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "إدخال غير صالح لدالة الجذر التربيعي"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "إدخال غير صالح لدالة اللوغاريتم"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "رقم طبيعي فقط لدالة x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "أدخل رقما قبل إدخال الدالة 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "أدخل رقما قبل إدخال الدالة x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "أدخل رقما قبل إدخال الدالة x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "أدخل رقما قبل إدخال الدالة x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "أدخل المزود أولا"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "يتوفر 15 رقمًا بحد أقصى"
+
diff --git a/theme/po/bg.po b/theme/po/bg.po
new file mode 100644 (file)
index 0000000..1f86c09
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Във валута:"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Синтактична грешка"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Възможни до 5 десетични знака"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Възможни до 20 оператора"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Не може да се дели на нула"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Първо въвед. число"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Извън обхват"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Въведете число след оператора"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Невалидно въвеждане за функция квадратен корен"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Невалидно въвеждане за функцията log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Само естествено число за функцията x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Въведете число, преди да изберете функцията 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Въведете число, преди да изберете функцията x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Въведете число, преди да изберете функцията x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Въведете число, преди да изберете функцията x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Първо във. оператор"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Възможни до 15 цифри"
+
diff --git a/theme/po/ca.po b/theme/po/ca.po
new file mode 100644 (file)
index 0000000..ab87aef
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Convertir a"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Error de sintaxi"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Fins a 5 decimals disponibles"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Fins a 20 operadors disponibles"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "No es pot dividir per zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Introdueixi primer el número"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Fora de rang"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Introdueixi un número després de l'operador"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Entrada no vàlida per a la funció d'arrel quadrada"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Entrada no vàlida per a la funció log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Només un número natural per a la funció x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Introdueixi un número abans d'introduir la funció 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Introdueixi un número abans d'introduir la funció x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Introdueixi un número abans d'introduir la funció x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Introdueixi un número abans d'introduir la funció x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Introdueixi primer l'operador"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Fins a 15 dígits disponibles"
+
diff --git a/theme/po/calculator.pot b/theme/po/calculator.pot
new file mode 100644 (file)
index 0000000..6fac66e
--- /dev/null
@@ -0,0 +1,161 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-08-17 15:35+0800\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: calculator_edje.c:3467
+msgid "Invalid expression"
+msgstr ""
+
+#: calculator_edje.c:3505 calculator_edje.c:3510
+msgid "Invalid digit!"
+msgstr ""
+
+#: calculator_edje.c:3545 calculator_edje.c:3563 calculator_edje.c:3573
+#: calculator_edje.c:3591 calculator_edje.c:3974 calculator_edje.c:3979
+#: calculator_edje.c:3997 calculator_edje.c:4007 calculator_edje.c:4012
+#: calculator_edje.c:4051 calculator_edje.c:4064 calculator_edje.c:4083
+#: calculator_edje.c:4094 calculator_edje.c:4100 calculator_edje.c:4124
+#: calculator_edje.c:4139 calculator_edje.c:4158
+msgid "Invalid expression!"
+msgstr ""
+
+#: calculator_edje.c:3602 calculator_edje.c:3607 calculator_edje.c:3612
+#: calculator_edje.c:3630 calculator_edje.c:3640 calculator_edje.c:3645
+#: calculator_edje.c:3650 calculator_edje.c:3663 calculator_edje.c:3673
+#: calculator_edje.c:3678 calculator_edje.c:3691 calculator_edje.c:3701
+#: calculator_edje.c:3706 calculator_edje.c:3712 calculator_edje.c:3725
+#: calculator_edje.c:3735 calculator_edje.c:3748 calculator_edje.c:3758
+#: calculator_edje.c:3763 calculator_edje.c:3781 calculator_edje.c:3791
+#: calculator_edje.c:3796 calculator_edje.c:3809 calculator_edje.c:3819
+#: calculator_edje.c:3832 calculator_edje.c:3842 calculator_edje.c:3847
+#: calculator_edje.c:3852 calculator_edje.c:3865 calculator_edje.c:3875
+#: calculator_edje.c:3880 calculator_edje.c:3885 calculator_edje.c:3898
+#: calculator_edje.c:3908 calculator_edje.c:3913 calculator_edje.c:3918
+#: calculator_edje.c:3931 calculator_edje.c:3941 calculator_edje.c:3946
+#: calculator_edje.c:3951 calculator_edje.c:3964 calculator_edje.c:4134
+msgid "Invalid operator!"
+msgstr ""
+
+#: calculator_edje.c:4106
+msgid "Parenthesis error!"
+msgstr ""
+
+#: calculator_parser.c:633 calculator_parser.c:664
+msgid "Syntax error"
+msgstr ""
+
+#. 5
+#. error msgs
+#: calculator_def.h:77
+msgid "IDS_CCL_POP_UP_TO_15_CHARACTERS_AVAILABLE"
+msgstr ""
+
+#: calculator_def.h:78
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr ""
+
+#: calculator_def.h:79
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr ""
+
+#: calculator_def.h:80
+msgid "IDS_CCL_POP_UP_TO_40_CHARACTERS_AVAILABLE"
+msgstr ""
+
+#: calculator_def.h:81
+msgid "IDS_CCL_POP_ENTER_OPERATOR_FIRST_ORANGE"
+msgstr ""
+
+#: calculator_def.h:82
+msgid "IDS_CCL_POP_ENTER_NUMBER_FIRST_ORANGE"
+msgstr ""
+
+#: calculator_def.h:83
+msgid "IDS_CCL_POP_ERROR"
+msgstr ""
+
+#: calculator_def.h:84
+msgid "IDS_CCL_POP_DIVIDE_ZERO"
+msgstr ""
+
+#: calculator_def.h:85
+msgid "IDS_CCL_POP_PARENTHESES_ERRORs"
+msgstr ""
+
+#: calculator_def.h:86
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr ""
+
+#: calculator_def.h:87
+msgid "IDS_CCL_POP_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr ""
+
+#: calculator_def.h:88
+msgid "IDS_CCL_POP_INVALID_INPUT_FOR LOG_FUNCTION"
+msgstr ""
+
+#: calculator_def.h:89
+msgid "IDS_CCL_POP_INVALID_INPUT_FOR LN_FUNCTION"
+msgstr ""
+
+#: calculator_def.h:90
+msgid "IDS_CCL_POP_NATURAL_NUMBER_ONLY_FOR_FACTORIAL"
+msgstr ""
+
+#: calculator_def.h:91
+msgid "IDS_CCL_POP_INVALID_PARAMETER_FOR_XY"
+msgstr ""
+
+#: calculator_def.h:92
+msgid "IDS_CCL_POP_INVALID_PARAMETER_FOR_TAN"
+msgstr ""
+
+#: calculator_def.h:93
+msgid "IDS_CCL_POP_ENTER_NUMBER_FIRST_BEFORE_TAPPING_FACTORIAL"
+msgstr ""
+
+#: calculator_def.h:94
+msgid "IDS_CCL_POP_ENTER_NUMBER_FIRST_BEFORE_TAPPING_1X"
+msgstr ""
+
+#: calculator_def.h:95
+msgid "IDS_CCL_POP_ENTER_NUMBER_FIRST_BEFORE_TAPPING_X2"
+msgstr ""
+
+#: calculator_def.h:96
+msgid "IDS_CCL_POP_ENTER_NUMBER_FIRST_BEFORE_TAPPING_XY"
+msgstr ""
+
+#: calculator_def.h:97
+msgid "IDS_CCL_POP_NO_INPUT"
+msgstr ""
+
+#: calculator_def.h:98
+msgid "IDS_CCL_POP_OVERFLOW"
+msgstr ""
+
+#: calculator_def.h:99
+msgid "IDS_CCL_POP_THE_RESULT_IS_TOO_LONG_TO_BE_DISPLAYED"
+msgstr ""
+
+#: calculator_def.h:100
+msgid "IDS_CCL_POP_ALREADY_HAD_DECIMAL_IN_DIGIT"
+msgstr ""
+
+#: calculator_def.h:101
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr ""
diff --git a/theme/po/cs.po b/theme/po/cs.po
new file mode 100644 (file)
index 0000000..02f2a40
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Převést na"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Chyba syntaxe"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Až 5 desetinných míst"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Až 20 operátorů"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nulou nelze dělit"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Zadejte číslo"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Mimo rozsah"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Za operátorem zadejte číslo"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neplatné zadání pro funkci odmocniny"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neplatné zadání pro funkci logaritmu"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Pro funkci x! lze použít pouze přirozená čísla"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Před zadáním funkce 1/x zadejte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Před zadáním funkce x^2 zadejte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Před zadáním funkce x^y zadejte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Před zadáním funkce x! zadejte číslo"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Zadejte operátor"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Až 15 cifer"
+
diff --git a/theme/po/csv2po_v2 b/theme/po/csv2po_v2
new file mode 100644 (file)
index 0000000..85b9c61
Binary files /dev/null and b/theme/po/csv2po_v2 differ
diff --git a/theme/po/da.po b/theme/po/da.po
new file mode 100644 (file)
index 0000000..c83fb3e
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konverter til"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaksfejl"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Op til 5 tilgængelige decimaler"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Op til 20 tilgængelige operatører"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Kan ikke dividere med nul"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Indtast først nr."
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Uden for rækkevidde"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Indtast nummer efter operatør"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Ugyldig indtastning til kvadratrodsfunktion"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Ugyldigt input til log-funktion"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Naturligt tal kun for x!-funktionen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Indtast tal inden indtastning af 1/x-funktionen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Indtast tal inden indtastning af x^2-funktionen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Indtast tal inden indtastning af x^y-funktionen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Indtast tal inden indtastning af x!-funktionen"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Tast operator først"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Op til 15 tilgængelige cifre"
+
diff --git a/theme/po/de_DE.po b/theme/po/de_DE.po
new file mode 100644 (file)
index 0000000..822948a
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Umrechnen in"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaxfehler"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Bis zu 5 Dezimalstellen verfügbar"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Bis zu 20 Operatoren verfügbar"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Division durch Null nicht möglich"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Zuerst Nr. Eingeben"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Überlauf"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Zahl hinter Operator eingeben"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Ungültige Eingabe für Quadratwurzelfunktion"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Ungültige Eingabe für Protokollfunktion"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Natürliche Zahl nur für x!-Funktion"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Zahl vor Eingabe der 1/x-Funktion eingeben"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Zahl vor Eingabe der x^2-Funktion eingeben"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Zahl vor Eingabe der x^y-Funktion eingeben"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Zahl vor x!-Funktion eingeben"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Zuerst Op. eing."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Bis zu 15 Stellen verfügbar"
+
diff --git a/theme/po/el_GR.po b/theme/po/el_GR.po
new file mode 100644 (file)
index 0000000..fc00a9c
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Μετατροπή σε"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Σφάλμα σύνταξης"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Διαθέσιμα μέχρι 5 δεκαδικά ψηφία"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Μέχρι 20 διαθέσιμοι παροχείς"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Δεν είναι δυνατή η διαίρεση με μηδέν"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Εισάγετε πρώτα αριθμό"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Εκτός εμβέλειας"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Εισάγετε αριθμό μετά τον παροχέα"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Μη έγκυρη εισαγωγή για συνάρτηση τετραγωνικής ρίζας"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Μη έγκυρη εισαγωγή για συνάρτηση αρχείου καταγραφής"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Φυσικός αριθμός μόνο για συνάρτηση x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Εισαγωγή αριθμού πριν από την εισαγωγή συνάρτησης 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Εισαγωγή αριθμού πριν από την εισαγωγή συνάρτησης x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Εισαγωγή αριθμού πριν από την εισαγωγή συνάρτησης x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Εισαγωγή αριθμού πριν από την εισαγωγή συνάρτησης x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Εισαγ.συμβόλου πρώτα"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Διαθέσιμα μέχρι 15 ψηφία"
+
diff --git a/theme/po/en.po b/theme/po/en.po
new file mode 100644 (file)
index 0000000..beaa509
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Convert to"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntax error"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Up to 5 decimals available"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Up to 20 operators available"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Unable to divide by zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Enter number first"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Out of range"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Enter number after operator"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Invalid input for square root function"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Invalid input for log function"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Natural number only for x! function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Enter number before inputting 1/x function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Enter number before inputting x^2 function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Enter number before inputting x^y function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Enter number before inputting x! function"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Enter operator first"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Up to 15 digits available"
+
diff --git a/theme/po/en_US.po b/theme/po/en_US.po
new file mode 100644 (file)
index 0000000..beaa509
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Convert to"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntax error"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Up to 5 decimals available"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Up to 20 operators available"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Unable to divide by zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Enter number first"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Out of range"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Enter number after operator"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Invalid input for square root function"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Invalid input for log function"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Natural number only for x! function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Enter number before inputting 1/x function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Enter number before inputting x^2 function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Enter number before inputting x^y function"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Enter number before inputting x! function"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Enter operator first"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Up to 15 digits available"
+
diff --git a/theme/po/es_ES.po b/theme/po/es_ES.po
new file mode 100644 (file)
index 0000000..de23789
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Convertir a"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Error de sintaxis"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Hasta 5 decimales disponibles"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Hasta 20 operadores disponibles"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "No se puede dividir por cero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Introduc. número 1º"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Fuera de intervalo"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Introduzca número después del operador"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Entrada incorrecta de función de raíz cuadrada"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Entrada incorrecta de función de registro"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Número natural sólo para función x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Introducir número antes de escribir función 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Introducir número antes de escribir función x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Introducir número antes de escribir función x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Introducir número antes de escribir función x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Introduz operador 1º"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Hasta 15 dígitos disponibles"
+
diff --git a/theme/po/fi.po b/theme/po/fi.po
new file mode 100644 (file)
index 0000000..e05734c
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Muunna yksiköksi"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaksivirhe"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Enintään 5 desimaalia"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Enintään 20 operaattoria"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Ei voi jakaa nollalla"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Anna ensin numero"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Liian suuri tai pieni"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Anna numero operaattorin jälkeen"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neliöjuuritoiminnon syötetiedot ovat virheelliset"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Lokitoiminnon syötetiedot ovat virheelliset"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "x!-toiminnon kanssa voi käyttää vain luonnollista numeroa"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Anna numero ennen 1/x-toiminnon käyttöä"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Anna numero ennen x^2-toiminnon käyttöä"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Anna numero ennen x^y-toiminnon käyttöä"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Anna numero ennen x!-toiminnon käyttöä"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Anna ensin operaattori"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Enintään 15 numeroa"
+
diff --git a/theme/po/fr_FR.po b/theme/po/fr_FR.po
new file mode 100644 (file)
index 0000000..fa34161
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Convertir en"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Erreur de syntaxe"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Jusqu'à 5 décimales"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Jusqu'à 20 opérateurs"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Impossible de diviser par zéro"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Entrez chiffre"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Maximum atteint"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Entrez le nombre après l'opérateur"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Saisie non valide pour la fonction racine carrée"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Saisie non valide pour la fonction logarithme"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Entier naturel uniquement pour la fonction x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Entrez un nombre avant la saisie de la fonction 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Entrez un nombre avant la saisie de la fonction x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Entrez un nombre avant la saisie de la fonction x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Entrez un nombre avant la saisie de la fonction x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Entrez opérateur"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Jusqu'à 15 chiffres"
+
diff --git a/theme/po/he.po b/theme/po/he.po
new file mode 100644 (file)
index 0000000..6af1446
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "המר ל"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "שגיאת תחביר"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "עד 5 מקומות אחרי הנקודה העשרונית זמינים"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "עד 20 אופרטורים זמינים"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "לא ניתן לחלק באפס"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "הזן מספר תחילה"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "מחוץ לטווח"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "הזן מספר לאחר האופרטור"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "קלט לא חוקי עבור פונקציית שורש ריבועי"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "קלט לא חוקי עבור פונקציית יומן"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "מספר טבעי עבור פונקציית x! בלבד"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "הזן מספר לפני הזנת פונקציית 1‎/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "הזן מספר לפני הזנת פונקציית x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "הזן מספר לפני הזנת פונקציית x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "הזן מספר לפני הזנת פונקציית x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "ראשית הכנס פונקציה"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "עד 15 ספרות זמינות"
+
diff --git a/theme/po/hi.po b/theme/po/hi.po
new file mode 100644 (file)
index 0000000..1d87d32
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "इसमें परिवर्तित करें"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "सिंटैक्स में त्रुटी"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "5 दशमलव तक उपलब्‍ध"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "20 ऑपरेटर तक उपलब्‍ध"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "शून्‍य से विभाजित करने में अक्षम"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "पहले नंबर प्रविष्ट करें"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "सीमा से बाहर"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "ऑपरेटर के बाद नंबर दर्ज करें"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "स्क्वेयर रूट फंक्शन के लिए अमान्‍य इनपुट"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "लॉग फंक्शन के लिए अमान्‍य इनपुट"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "नैचुरल नंबर केवल x! फंक्शन के लिए"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "1/x फंक्शन इनपुट करने के पहले नंबर दर्ज करें"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "x^2 फंक्शन इनपुट करने के पहले नंबर एडिट करें"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "x^y फंक्शन इनपुट करने के पहले नंबर दर्ज करें"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "x! फंक्शन इनपुट करने के पहले नंबर दर्ज करें"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "पहले ऑपरेटर प्रविष्ट करें"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "15 अंकों तक उपलब्‍ध"
+
diff --git a/theme/po/hr.po b/theme/po/hr.po
new file mode 100644 (file)
index 0000000..a2fbaad
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Preračunaj u"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Greška unosa"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Dostupno do 5 decimala"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Dostupno do 20 operatora"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nemoguće dijeljenje s nulom"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Prvo unesite broj"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Izvan dosega"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Unesite broj nakon operatora"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neispravan unos za funkciju korjenovanja"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Netočan unos za funkciju log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Za funkciju x! unesite samo prirodni broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Prije odabira funkcije 1/x unesite broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Prije odabira funkcije x^2 unesite broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Prije odabira funkcije x^y unesite broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Prije odabira funkcije x! unesite broj"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Prvo unesite operaciju"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Dostupno do 15 znamenaka"
+
diff --git a/theme/po/hu.po b/theme/po/hu.po
new file mode 100644 (file)
index 0000000..4fc5b1f
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Átalakítás erre:"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Szintaktikai hiba"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Legfeljebb 5 tizedesjegy lehetséges"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Legfeljebb 20 szolgáltató lehetséges"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nullával nem lehet osztani"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Előbb szám kell"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Túl nagy szám"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "A műveleti jel után adjon meg egy számot"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Érvénytelen bevitel a négyzetgyök függvényhez"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Érvénytelen bevitel a log függvényhez"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Az x! függvény csak természetes számmal használható"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Az 1/x függvény kiválasztása előtt adjon meg egy számot"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Az x^2 függvény kiválasztása előtt adjon meg egy számot"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Az x^y függvény kiválasztása előtt adjon meg egy számot"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Az x! függvény kiválasztása előtt adjon meg egy számot"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Előbb operátor kell"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Legfeljebb 15 számjegy lehetséges"
+
diff --git a/theme/po/id.po b/theme/po/id.po
new file mode 100644 (file)
index 0000000..d35495d
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konversi ke"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Kesalahan Syntax"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Hingga 5 desimal tersedia"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Hingga 20 operator tersedia"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Tdk bisa dibagi dengan nol"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Masukkan nomor lebih dulu"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Diluar jangkauan"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Masukkan angka setelah operator"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Masukan tdk berlaku untuk fungsi akar persegi"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Masukan tdk berlaku utk fungsi log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Angka alami hanya untuk x! fungsi"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Masukkan angka sebelum memasukkan fungsi 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Masukkan angka sebelum memasukkan fungsi x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Masukkan angka sebelum memasukkan fungsi x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Masukkan angka sebelum memasukkan fungsi x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Masukkan Operator lebih dulu"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Hingga 15 digit tersedia"
+
diff --git a/theme/po/it_IT.po b/theme/po/it_IT.po
new file mode 100644 (file)
index 0000000..aa54118
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Converti in"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Errore di sintassi"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Fino a 5 decimali disponibili"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Fino a 20 operazioni disponibili"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Impossibile dividere per zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Inserire numero"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Fuori intervallo"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Immetti numero dopo operatore"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Immissione non valida per funzione radice quadrata"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Immissione non valida per funzione logaritmo"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Numero naturale solo per funzione x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Inserisci numero prima di digitare la funzione 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Inserisci numero prima di digitare la funzione x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Inserisci numero prima di digitare la funzione x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Inserisci numero prima di digitare la funzione x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Inser. prima operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Fino a 15 cifre disponibili"
+
diff --git a/theme/po/ja_JP.po b/theme/po/ja_JP.po
new file mode 100644 (file)
index 0000000..60f5d49
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "に​換算"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "シンタックス​エラー"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "最大​小数点​以下​5桁​まで​使用​できます"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "最大​20の演算子が​使用​できます"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "0​で​割ること​は​できません"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "まず​数字​を​入力して​ください"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "圏外"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "演算子の後に​数字​を入力します"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "平方根関数の入力が正しくありません"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "ログ関数の入力を正しくありません"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "x! 関数の場合だけ自然数"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "入力 1/x 機能の前に数を入力してください"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "x^2​関数​を入力する前に​数字を​入力してください"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "入力x^y機能の前に数を入力してください"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "入力x!機能の前に数を入力してください"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "まず​計算式​を​入力して​ください"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "最大​​15桁​まで​使用​できます"
+
diff --git a/theme/po/ko_KR.po b/theme/po/ko_KR.po
new file mode 100644 (file)
index 0000000..da1830f
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "단위환산으로 이동"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "시스템 오류가 발생하였습니다"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "소수점 5자리까지 입력할 수 있습니다"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "연산자는 20개까지 입력할 수 있습니다"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "0으로 나눌 수 없습니다"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "먼저 숫자를 입력하세요"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "계산 범위를 벗어났습니다"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "연산기호 입력 후 숫자를 입력하세요"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "제곱근 함수의 입력 내용이 바르지 않습니다"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "로그 함수의 입력 내용이 바르지 않습니다"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "x! 함수에는 자연수만 입력할 수 있습니다"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "1/x 함수를 입력하기 전 숫자를 입력하세요"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "제곱근 함수를 입력하기 전  숫자를 입력하세요"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "x^y 함수를 입력하기 전 숫자를 입력하세요"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "x! 함수를 입력하기 전 숫자를 입력하세요"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "먼저 연산기호를 입력하세요"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "숫자는 15자리까지 입력할 수 있습니다"
+
diff --git a/theme/po/lt.po b/theme/po/lt.po
new file mode 100644 (file)
index 0000000..ed2ebe2
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Keisti į"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Sintaksės klaida"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Leidžiama iki 5 dešimtainių"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Leidžiama iki 20 operatorių"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Dalyba iš nulio negalima"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Pirma įveskite sk."
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Už ribų"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Po operatoriaus įveskite numerį"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neteisinga įvestis kvadratinės šaknies funkcijai"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neteisinga įvestis log funkcijai"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "x! funkcijai – tik natūralus skaičius"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Skaičių įveskite prieš įvesdami 1/x funkciją"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Skaičių įveskite prieš įvesdami x^2 funkciją"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Skaičių įveskite prieš įvesdami x^y funkciją"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Skaičių įveskite prieš įvesdami x! funkciją"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Pirma įvesk. operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Leidžiama iki 15 skaitmenų"
+
diff --git a/theme/po/lv.po b/theme/po/lv.po
new file mode 100644 (file)
index 0000000..416c09f
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Pārvērst par"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Sintakses kļūda"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Pieejami ne vairāk kā 5 decimālskaitļi"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Pieejami ne vairāk kā 20 operatori"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nevar dalīt ar nulli"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Visp.iev. skaitli"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Ārpus robežas"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Ievadiet skaitli pēc operatora"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Nederīga ievade kvadrātsaknes funkcijā"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Nederīga ievade log funkcijai"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Naturālais skaitlis paredzēts tikai funkcijai x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Ievadiet skaitli pirms funkcijas 1/x ievadīšanas"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Ievadiet skaitli pirms funkcijas x^2 ievadīšanas"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Ievadiet skaitli pirms funkcijas x^y ievadīšanas"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Ievadiet skaitli pirms funkcijas x! ievadīšanas"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Visp. ievad. operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Pieejami ne vairāk kā 15 cipari"
+
diff --git a/theme/po/ms.po b/theme/po/ms.po
new file mode 100644 (file)
index 0000000..027565a
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Tukar kepada"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Ralat sintaks"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Sehingga 5 perpuluhan tersedia"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Sehingga 20 pengendali didpti"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Tdk dpt dibahagi dengan kosong"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Masukkan Nombor Dahulu"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Di luar julat"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Masukkan nombor selepas pengendali"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Kemasukan tdk sah utk fungsi punca kuasa dua"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Kemasukan tdk sah utk fungsi log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Nombor lazim hanya utk fungsi x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Masukkan nombor sebelum masukkan fungsi 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Masukkan nombor sebelum memasukkan fungsi x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Masukkan nombor sebelum memasukkan fungsi x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Masukkan nombor sebelum memasukkan fungsi x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Masukkan Pengendali Dulu"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Sehingga 15 digit tersedia"
+
diff --git a/theme/po/nl_NL.po b/theme/po/nl_NL.po
new file mode 100644 (file)
index 0000000..5b92b6c
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Converteren naar"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaxfout"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Maximaal 5 decimalen beschikbaar"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Max. 20 reken-tekens beschikbaar"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Kan niet delen door nul"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Geef eerst het getal in"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Buiten bereik"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Geef getal in na operator"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Ongeldige invoer voor vierkantswortelfunctie"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Ongeldige invoer voor logfunctie"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Alleen natuurlijk getal voor x!-functie"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Geef eerst getal in en dan de functie 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Geef eerst getal in en dan de functie x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Geef eerst getal in en dan de functie x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Geef eerst getal in en dan de functie x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Geef eerst het reken-teken in"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Maximaal 15 cijfers beschikbaar"
+
diff --git a/theme/po/no.po b/theme/po/no.po
new file mode 100644 (file)
index 0000000..04831f7
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konverter til"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaksfeil"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Opptil 5 desimaler tilgjengelig"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Opptil 20 operatører tilgjengelig"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Kan ikke dele på null"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Skriv først nummer"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Utenfor verdiområdet"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Angi nummer etter operatør"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Ugyldig inndata for kvadratrotfunksjon"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Ugyldig inndata for loggfunksjon"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Naturlig nummer bare for funksjonen x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Angi nummer før du skriver inn 1/x-funksjonen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Angi nummer før du skriver inn x^2-funksjonen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Angi nummer før du skriver inn x^y-funksjonen"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Angi nummer før du skriver inn x!-funksjonen"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Skriv først operatør"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Opptil 15 sifre tilgjengelig"
+
diff --git a/theme/po/pl.po b/theme/po/pl.po
new file mode 100644 (file)
index 0000000..e13b146
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Przelicz na"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Błąd składni"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Dostępne maksymalnie 5 miejsc dziesiętnych"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Dostępne maksymalnie 20 operatorów"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nie można dzielić przez zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Wprowadź liczbę"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Poza zakresem"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Po operatorze wprowadź liczbę"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Nieprawidłowe dane wejściowe do wyliczenia pierwiastka kwadratowego"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Nieprawidłowe dane wejściowe do wyliczenia logarytmu"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Funkcja x! wymaga wyłącznie liczb naturalnych"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Przed wstawieniem funkcji 1/x wprowadź liczbę"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Przed wstawieniem funkcji x^2 wprowadź liczbę"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Przed wstawieniem funkcji x^y wprowadź liczbę"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Przed wstawieniem funkcji x! wprowadź liczbę"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Najpierw wpr. znak"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Dostępne maksymalnie 15 cyfr"
+
diff --git a/theme/po/pt_PT.po b/theme/po/pt_PT.po
new file mode 100644 (file)
index 0000000..f09416b
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Converter em"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Erro de sintaxe"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Até 5 decimais disponíveis"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Até 20 operadores disponíveis"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Impossível dividir por zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Intr. n.º primeiro"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Fora de alcance"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Introduzir número depois do operador"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Introdução inválida para a função de raiz quadrada"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Introdução inválida para função de registo"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Número natural apenas para função x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Introduzir número antes da introdução da função 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Introduzir número antes da introdução da função x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Introduzir número antes da introdução da função x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Introduzir número antes da introdução da função x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Intr. oper. primeiro"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Até 15 dígitos disponíveis"
+
diff --git a/theme/po/ro.po b/theme/po/ro.po
new file mode 100644 (file)
index 0000000..08d597c
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Conversie în"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Eroare de sintaxă"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Până la 5 zecimale disponibile"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Până la 20 de operatori disponibili"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Imposibil de împărţit la zero"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Introd. întâi nr."
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "În afara limitelor"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Introduceţi numărul după operator"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Intrare nevalidă pentru funcţia rădăcină pătrată"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Intrare nevalidă pentru funcţia logaritm"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Numai număr natural pentru funcţia x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Introduceţi numărul înainte de a introduce funcţia 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Introduceţi numărul înainte de a introduce funcţia x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Introduceţi numărul înainte de a introduce funcţia x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Introduceţi numărul înainte de a introduce funcţia x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Introd. întâi operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Până la 15 cifre disponibile"
+
diff --git a/theme/po/ru_RU.po b/theme/po/ru_RU.po
new file mode 100644 (file)
index 0000000..6103999
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Преобразовать в"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Синтаксическая ошибка"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Доступно до 5 десятичных знаков"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Доступно до 20 операторов"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Деление на ноль невозможно"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Введите число"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Вне диапазона"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Введите число за оператором"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Введены недопустимые данные для функции квадратного корня"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Введены недопустимые данные для функции логарифма"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Функция x! поддерживает только натуральные числа"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Введите число перед вводом функции 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Введите число перед вводом функции x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Введите число перед вводом функции x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Введите число перед вводом функции x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Введите оператор"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Доступно до 15 цифр"
+
diff --git a/theme/po/sk.po b/theme/po/sk.po
new file mode 100644 (file)
index 0000000..188f8a2
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konvertovať na"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Chyba syntaxe"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "K dispozícii je max. 5 desatinných miest"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "K dispozícii je max. 20 operátorov"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nulou sa nedá deliť"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Najprv zad. číslo"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Mimo rozsahu"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Zadajte číslo po operátore"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neplatný vstup pre funkciu druhej odmocniny"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neplatný vstup pre funkciu log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Prirodzené číslo iba pre funkciu x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Pred zadaním funkcie 1/x zadajte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Pred zadaním funkcie x^2 zadajte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Pred zadaním funkcie x^y zadajte číslo"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Pred zadaním funkcie x! zadajte číslo"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Najprv zad. operátor"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "K dispozícii je max. 15 číslic"
+
diff --git a/theme/po/sl.po b/theme/po/sl.po
new file mode 100644 (file)
index 0000000..813320e
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Pretvori v"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Napaka sintakse"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Na voljo je do 5 decimalnih mest"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Na voljo je do 20 operaterjev"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Deljenje z 0 ni mogoče"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Najprej vnesi št."
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Izven dovoljenega obsega"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Vnesite številko za operacijo"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neveljaven vnos za kvadratno korensko funkcijo"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neveljaven vnos za logaritemsko funkcijo"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Za funkcijo x! uporabite samo naravna števila"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Vnesite številko, preden vstavite funkcijo 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Vnesite številko, preden vstavite funkcijo x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Vnesite številko, preden vstavite funkcijo x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Vnesite številko, preden vstavite funkcijo x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Najprej vnes.operat."
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Na voljo je do 15 mest"
+
diff --git a/theme/po/sr.po b/theme/po/sr.po
new file mode 100644 (file)
index 0000000..02f5b3c
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konvertuj u"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Sintaksna greška"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Dostupno do 5 decimala"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Dostupno do 20 operatera"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Nemoguće deliti sa nulom"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Prvo unesi broj"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Van opsega"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Unesi broj nakon operatora"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Neispravan unos za funkciju kvadratnog korena"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Neispravan unos za funkciju log"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Funkcija x! zahteva prirodan broj"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Unesi broj pre unosa funkcije 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Unesi broj pre unosa funkcije x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Unesi broj pre unosa funkcije x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Unesi broj pre unosa funkcije x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Prvo unesi operatora"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Dostupno do 15 cifara"
+
diff --git a/theme/po/sv.po b/theme/po/sv.po
new file mode 100644 (file)
index 0000000..da2781c
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Konvertera till"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Syntaxfel"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Upp till 5 decimaler kan anges"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Upp till 20 operatorer kan anges"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Det går inte att dividera med noll"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Ange siffra först"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Utanför område"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Ange nummer efter operatör"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Ogiltig inmatning för kvadratrotsfunktion"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Ogiltig inmatning för loggfunktionen"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Endast naturligt tal för funktionen x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Ange nummer före inmatning av funktionen 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Ange nummer före inmatning av funktionen x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Ange nummer före inmatning av funktionen x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Ange nummer före inmatning av funktionen x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Ange operator först"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Upp till 15 siffror kan anges"
+
diff --git a/theme/po/th.po b/theme/po/th.po
new file mode 100644 (file)
index 0000000..80883f8
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "แปลง​เป็น"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "ซิ​นแท็ก​ซ์​ผิด"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "ได้​ถึง 5 ​ตัว​เลข"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "ได้​ถึง 20 ​เครื่อง​หมาย​"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "หาร​ด้วย​\nศูนย์​ไม่​ได้"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "ใส่​เลข​ก่อน"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "อยู่​นอก​ช่วง"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "ใส่​ตัว​เลข​หลัง​โอ​เปอร์เร​เตอร์"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "การ​ใส่​ข้อ​มูล​ฟังก์​ชั่นสแควร์​รู​ท​ไม่​ถูก​ต้อง"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "การ​ใส่​ข้อมูล​ฟังก์ชัน​ล็อก​ไม่​ถูก​ต้อง"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "หมาย​เลข​ธรรมชาติ​สำ​หรับ​ฟัง​ก์ชั่น x! ​เท่า​นั้น"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "ใส่​หมาย​เลข​ก่อน​ใส่​ข้อมูล​ฟังก์ชัน 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "ใส่​หมาย​เลข​ก่อน​ใส่​ข้อมูล​ฟังก์ชัน x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "ใส่​หมาย​เลข​ก่อน​ใส่​ข้อมูล​ฟังก์ชัน x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "ใส่​หมาย​เลข​ก่อน​ใส่​ข้อมูล​ฟังก์ชัน x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "ใส่​เครื่อง​หมาย​ก่อน"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "​ได้​ถึง 15 ​ดิ​จิต"
+
diff --git a/theme/po/tr_TR.po b/theme/po/tr_TR.po
new file mode 100644 (file)
index 0000000..d74ebee
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Hedef birim"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Sözdizimi hatası"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "En fazla 5 hane kullanılabilir"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "En fazla 20 operatör kullanılabilir"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Sıfıra bölünemez"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Önce sayı girin"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Aralık dışında"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Operatörün ardından numara girin"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Kare kök fonksiyonu için geçersiz giriş"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Günlük fonksiyonu için geçersiz giriş"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Yalnızca x! fonksiyonu için doğal sayı"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "1/x fonksiyonu girmeden önce numara girin"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "x^2 fonksiyonu girmeden önce numara girin"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "x^y fonksiyonu girmeden önce numara girin"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "x! fonksiyonu girmeden önce numara girin"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Önce operatörü girin"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "En fazla 15 hane kullanılabilir"
+
diff --git a/theme/po/uk.po b/theme/po/uk.po
new file mode 100644 (file)
index 0000000..0a85210
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Перетворити на"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Синтаксична помилка"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Доступно до 5 десяткових знаків"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Доступно до 20 операторів"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Неможливо ділити на нуль"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Введіть номер"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Поза мережею"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Введіть номер після оператора"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Хибне введення для функції квадратного кореня"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Хибне введення для функції логарифму"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Лише натуральні числа для функції x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Введіть число перед введенням функції 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Введіть число перед введенням функції x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Введіть число перед введенням функції x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Введіть число перед введенням функції x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Введіть оператора"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Доступно до 15 цифр"
+
diff --git a/theme/po/update-po.sh b/theme/po/update-po.sh
new file mode 100644 (file)
index 0000000..f21f253
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+PACKAGE=calculator
+SRCROOT=..
+POTFILES=POTFILES.in
+
+#ALL_LINGUAS= am az be ca cs da de el en_CA en_GB es et fi fr hr hu it ja ko lv mk ml ms nb ne nl pa pl pt pt_BR ru rw sk sl sr sr@Latn sv ta tr uk vi zh_CN zh_TW
+ALL_LINGUAS="en_US en_GB ja ko zh_CN"
+
+XGETTEXT=/usr/bin/xgettext
+MSGMERGE=/usr/bin/msgmerge
+
+echo -n "Make ${PACKAGE}.pot  "
+if [ ! -e $POTFILES ] ; then
+       echo "$POTFILES not found"
+       exit 1
+fi
+
+$XGETTEXT --default-domain=${PACKAGE} --directory=${SRCROOT} \
+               --add-comments --keyword=_ --keyword=N_ --files-from=$POTFILES \
+&& test ! -f ${PACKAGE}.po \
+       || (rm -f ${PACKAGE}.pot && mv ${PACKAGE}.po ${PACKAGE}.pot)
+
+if [ $? -ne 0 ]; then
+       echo "error"
+       exit 1
+else
+       echo "done"
+fi
+
+for LANG in $ALL_LINGUAS; do 
+       echo "$LANG : "
+
+       if [ ! -e $LANG.po ] ; then
+               cp ${PACKAGE}.pot ${LANG}.po
+               echo "${LANG}.po created"
+       else
+               if $MSGMERGE ${LANG}.po ${PACKAGE}.pot -o ${LANG}.new.po ; then
+                       if cmp ${LANG}.po ${LANG}.new.po > /dev/null 2>&1; then
+                               rm -f ${LANG}.new.po
+                       else
+                               if mv -f ${LANG}.new.po ${LANG}.po; then
+                                       echo "" 
+                               else
+                                       echo "msgmerge for $LANG.po failed: cannot move $LANG.new.po to $LANG.po" 1>&2
+                                       rm -f ${LANG}.new.po
+                                       exit 1
+                               fi
+                       fi
+               else
+                       echo "msgmerge for $LANG failed!"
+                       rm -f ${LANG}.new.po
+               fi
+       fi
+       echo ""
+done
+
diff --git a/theme/po/vi.po b/theme/po/vi.po
new file mode 100644 (file)
index 0000000..2d19a99
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "Chuyển đổi thành"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "Lỗi cú pháp"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "Cho phép lên đến 5 số thập phân"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "Cho phép lên đến 20 phép tính"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "Không chia được cho 0"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "Nhập số trước"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "Số quá lớn"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "Nhập số sau toán tử"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "Đầu vào không hợp lệ cho hàm bậc hai"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "Đầu vào không hợp lệ cho hàm lôgarít"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "Số tự nhiên chỉ cho hàm x!"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "Nhập số trước khi nhập hàm 1/x"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "Nhập số trước khi nhập hàm x^2"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "Nhập số trước khi nhập hàm x^y"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "Nhập số trước khi nhập hàm x!"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "Nhập phép tính trước"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "Cho phép tối đa 15 số"
+
diff --git a/theme/po/zh_CN.po b/theme/po/zh_CN.po
new file mode 100644 (file)
index 0000000..75b554d
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "换算成"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "语法错误"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "小数点后最多可达 5 位"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "最多可达20个运算符"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "不能除以零"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "请先输入数字"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "超出范围"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "在运算符后输入数字"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "输入无效平方根函数"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "输入无效对数函数"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "x!函数只可输入自然数"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "在输入1/x函数之前输入数字"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "在输入x^2函数之前输入数字"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "在输入x^y函数之前输入数字"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "在输入x!函数之前输入数字"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "请先输入运算符"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "最多可达15 位"
+
diff --git a/theme/po/zh_HK.po b/theme/po/zh_HK.po
new file mode 100644 (file)
index 0000000..e3d3180
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "換算為"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "語法錯誤"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "最多5 位小數點可用"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "20 個營運商可用"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "無法除以零"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "先輸入數字"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "超出範圍"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "在運算後輸入數字"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "無效的平方根函數輸入"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "無效的記錄函數輸入"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "自然數只適用於 x! 函數"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "輸入 1/x 函數前,請先輸入數字"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "輸入 x^2 函數前,請先輸入數字"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "輸入 x^y 函數前,請先輸入數字"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "輸入 x! 函數前,請先輸入數字"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "先輸入運算符"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "最多 15 位數字可用"
+
diff --git a/theme/po/zh_TW.po b/theme/po/zh_TW.po
new file mode 100644 (file)
index 0000000..f3f1968
--- /dev/null
@@ -0,0 +1,51 @@
+msgid "IDS_CCL_OPT_CONVERT_TO"
+msgstr "轉換到"
+
+msgid "IDS_CCL_POP_SYNTAX_ERROR"
+msgstr "語法錯誤"
+
+msgid "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE"
+msgstr "最多可使用 5 個小數位數"
+
+msgid "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE"
+msgstr "最多可使用 20 個運算子"
+
+msgid "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO"
+msgstr "無法除以0"
+
+msgid "IDS_CCL_POP_NO_NUMBER_ERROR"
+msgstr "請先輸入數字"
+
+msgid "IDS_CCL_POP_ERROR"
+msgstr "超出範圍"
+
+msgid "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR"
+msgstr "運算元後輸入數字"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION"
+msgstr "輸入無效平方根函數"
+
+msgid "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION"
+msgstr "無效的輸入日誌功能"
+
+msgid "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION"
+msgstr "自然數只對 x!函數"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION"
+msgstr "輸入數字,然後輸入 1 / x的函數"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION"
+msgstr "輸入號碼前輸入χ^ 2功能"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION"
+msgstr "輸入號碼前輸入χ^ y功能"
+
+msgid "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION"
+msgstr "輸入數字,然後輸入到X!函數"
+
+msgid "IDS_CCL_POP_NO_OPERATOR_ERROR"
+msgstr "先輸入運算子"
+
+msgid "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE"
+msgstr "最多可使用 15 位數"
+
diff --git a/theme/src/calc-expression.c b/theme/src/calc-expression.c
new file mode 100644 (file)
index 0000000..b82070d
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#include <string.h>
+#include <stdbool.h>
+#include <stdio.h>             //snprintf
+#include <ctype.h>             //isdigit
+#include <math.h>
+#include "calc-main.h"
+#include "calc-string.h"
+#include "calc-expression.h"
+
+/* special characters */
+#define PI_S                                   "\xcf\x80"
+#define DIVIDE                                         "\xc3\xb7"
+#define MULTIPLY                               "\xc3\x97"
+#define SQRT                                   "\xe2\x88\x9a"
+#define MINUS                                  "\xe2\x88\x92"
+extern char decimal_ch;
+extern char separator_ch;
+extern int scientific_result_len;
+struct calc_func_t calc_func[] = {
+           {OP_PERCENT, "%"},
+    {OP_ROOT, "sqrt("},
+    {OP_FACT, "!"},
+    {OP_SIN, "sin("},
+    {OP_COS, "cos("},
+    {OP_TAN, "tan("},
+    {OP_LN, "ln("},
+    {OP_LOG, "log("},
+    {OP_1X, "1/x"},
+    {OP_10X, "10^("}, {OP_X2, "^2"}, {OP_XY, "^("}, {OP_ABS, "abs("},
+};
+
+
+/*
+ * format number with comma
+ */
+static void _calc_expr_format_number(const char *in, char *out)
+{
+       char number[NUMBER_LENGTH] = { 0 };
+       char *dot = strchr(in, decimal_ch);
+       int length = (dot == NULL ? strlen(in) : dot - in);
+       bool negative = (in[0] == '-' ? true : false);
+       length -= (negative ? 1 : 0);   /* the number length between '-' and '.' */
+       strncpy(number, negative ? in + 1 : in, length);
+       int comma_count = length / 3;   /* the count of comma that will be add */
+       comma_count -= (length % 3 == 0 ? 1 : 0);
+       int p = length - 3;     /* insert ',' at number[p] */
+       while (comma_count--)
+                {
+               int l = length;
+               while (l > p)
+                        {
+                       number[l] = number[l - 1];
+                       l--;
+                       }
+               number[p] = separator_ch;
+               length++;
+               p -= 3;
+               }
+       char *s = out;
+       if (negative)
+                {
+               out[0] = '-';
+               s += 1;
+               }
+       strncpy(s, number, length);
+       s[length] = '\0';
+       if (dot != NULL)
+                {
+               strcpy(s + length, dot);
+               }
+}
+
+
+/**
+ * @description
+ *  Get the fisrt number's postion in the expression string.
+ *
+ * @param       expr    Expression string
+ * @param       begin   The index of fisrt digit(maybe '-')
+ * @param       end     The index of last digit
+ * @return      bool
+ * @exception   none
+ */
+static bool _calc_expr_get_number_position(const char *expr, int *begin,
+                                          int *end)
+{
+       if (expr == NULL) {
+               return false;
+       }
+       bool negative = false;
+       char *digit = "0123456789";
+       char digit_with_dot[32] = { 0 };
+       snprintf(digit_with_dot, sizeof(digit_with_dot), "%s%c", digit,
+                 decimal_ch);
+       int b = strcspn(expr, digit);
+       if (b == strlen(expr)) {
+               return false;
+       }
+       if (b > 0 && expr[b - 1] == '-')
+                {
+
+                   /* if before '-' is ')' or digit, I cosider it as minus. */
+                   if (b > 1 && (expr[b - 2] == ')' || isdigit(expr[b - 2])))
+                        {
+                       negative = false;
+                       }
+
+               else
+                        {
+                       negative = true;
+                       }
+               }
+       int length = strspn(expr + b, digit_with_dot);
+       *begin = (negative ? b - 1 : b);
+       *end = b + length - 1;
+       return true;
+}
+
+/*
+ * replace common char with special locally.
+ */
+void calc_expr_replace_with_special_char(char *expr)
+{
+       CALC_FUN_BEG();
+       string_replace(expr, "p", PI_S);
+       string_replace(expr, "x", MULTIPLY);
+       string_replace(expr, "/", DIVIDE);
+       string_replace(expr,"-",MINUS);
+       string_replace(expr, "sqrt", SQRT);
+       CALC_FUN_END();
+}
+
+void calc_expr_replace_from_special_char(char *expr)
+{
+       CALC_FUN_BEG();
+       string_replace(expr, PI_S, "p");
+       string_replace(expr, MULTIPLY, "x");
+       string_replace(expr, DIVIDE, "/");
+       string_replace(expr,MINUS,"-");
+       string_replace(expr, SQRT, "sqrt");
+       CALC_FUN_END();
+}
+
+/*
+ * convert string for calculate to string for display
+ */
+void calc_expr_format_expression(const char *expr_in, char *expr_out)
+{
+       CALC_FUN_BEG();
+       char number1[NUMBER_LENGTH] = { 0 };
+       char number2[NUMBER_LENGTH] = { 0 };
+       const char *in = expr_in;
+       char *out = expr_out;
+       int begin, end;
+       while (_calc_expr_get_number_position(in, &begin, &end)) {
+               int l = end - begin + 1;
+               strncpy(number1, in + begin, l);
+               number1[l] = '\0';
+               _calc_expr_format_number(number1, number2);
+               strncpy(out, in, begin);
+               out += begin;
+               strcpy(out, number2);
+               in = in + end + 1;
+               out = out + strlen(out);
+         }
+         strcpy(out, in);
+       calc_expr_replace_with_special_char(expr_out);
+       CALC_FUN_END();
+}
+
+int calc_expr_get_operator_num(const char *expr)
+{
+       if (expr == NULL) {
+               return 0;
+       }
+       char *operator = "+-x/^";
+       int count = 0;
+       int i = 0;
+       while (expr[i]) {
+               int j = 0;
+               while (operator[j]) {
+                       if (operator[j] == expr[i]) {
+                               count++;
+                               break;
+                       }
+                       ++j;
+               }
+               ++i;
+        }
+       return count;
+}
+
+int calc_expr_get_left_parentheses_num(const char *expr)
+{
+       if (expr == NULL) {
+               return 0;
+       }
+       int i = 0;
+       int count = 0;
+       while (expr[i] != '\0') {
+               if (expr[i] == '(') {
+                       count++;
+               }
+               i++;
+       }
+       return count;
+}
+
+void calc_expr_num_remove_end_zero(char *number)
+{
+       int len = strlen(number);
+       if (strchr(number, 'e') != NULL || strchr(number, 'E') != NULL) {
+               return;
+       }
+       if (strchr(number, decimal_ch) != NULL) {
+               while (len > 0 && number[len - 1] == '0') {
+                       number[len - 1] = '\0';
+                       len--;
+               }
+               if (len > 0 && number[len - 1] == decimal_ch) {
+                       number[len - 1] = '\0';
+                       len--;
+               }
+       }
+}
+
+/**
+* @description
+* Format calculate result to show it suitably in the entry
+* Mainly, remove end zero, if too long, change it to scientific form
+*
+* @param[in]   result  The calculate result
+* @param[out]  text    The format string of the result
+* @return      void
+* @exception
+*/
+void calc_expr_num_format_result(double result, char *text)
+{
+       CALC_FUN_BEG();
+       char buf[MAX_EXPRESSION_LENGTH] = { 0 };
+       if ((fabs(result) - 0.00001) < 0) {
+               /* Solve the bug of "-0" */
+               if (ceil(fabs(result)) - 0 < 0.000000000001) {
+                       strcpy(text, "0");
+                       return;
+               }
+               snprintf(buf, sizeof(buf), "%.*E", scientific_result_len, result);
+       } else {
+               snprintf(buf, sizeof(buf), "%.*lf", MAX_DECIMAL_NUM, result);
+               calc_expr_num_remove_end_zero(buf);
+               if (strlen(buf) > MAX_NUM_LENGTH) {
+                       double revise_result = result;
+                   /* 12345678650*100,000 The result should be 1.23456787+E15, not 1.23456786+E15. */
+                        if (buf[9] == '5') {
+                               buf[9] = '6';
+                               sscanf(buf, "%lf", &revise_result);
+                       }
+                       snprintf(buf, sizeof(buf), "%.*E", scientific_result_len, revise_result);
+               }
+       }
+       strcpy(text, buf);
+       CALC_FUN_END();
+}
+
+
+/**
+ * Get fucntion at current cursor position.
+ * If get successfully return the function symbol.
+ * If at the cursor position is not a function, return NULL.
+ */
+char *calc_expr_get_current_func_at_cursor(char *expr, int cursor)
+{
+       if (cursor == 0) {
+               return NULL;
+       }
+       int pos = cursor - 1;   //previous cursor position
+       int func_num = sizeof(calc_func) / sizeof(calc_func[0]);        //the number of fucntions
+       int i = 0;
+       char *ch = NULL;
+       for (i = 0; i < func_num; ++i) {
+               if ((ch = strchr(calc_func[i].symbol, expr[pos])) == NULL){
+                       continue;
+               }
+               int t = pos - (ch - calc_func[i].symbol);
+               if (t < 0) {
+                       continue;
+               }
+               if (!strncmp(calc_func[i].symbol, expr + t, strlen(calc_func[i].symbol)))       //equal
+               {
+                       return calc_func[i].symbol;
+               }
+       }
+       return NULL;
+}
+
+
+/**
+ * Parse the first number and give the number length in the expression.
+ * @param   exp     the expression string
+ * @param   number  the first number in the expression
+ * @param   length  the number's length in the expression string
+ * @return  int     0 if parse succefully, else return -1
+ */
+int calc_expr_parse_number(const char *exp, double *number, int *length)
+{
+       const char *ptr = IS_SIGN(exp[0]) ? exp + 1 : exp;
+       char *digit = "0123456789";
+       int t = strspn(ptr, digit);
+       if (t == 0) {
+               return -1;
+       }                       /* has no digit */
+       ptr += t;
+       if (ptr[0] == decimal_ch) {
+               ptr += 1;
+               t = strspn(ptr, digit);
+               ptr += t;
+       }
+       if (IS_SCIENCE_E(ptr[0]))       /* science number */ {
+               ptr += 1;
+               ptr += IS_SIGN(ptr[0]) ? 1 : 0;
+               t = strspn(ptr, digit);
+               ptr += (t == 0 && IS_SIGN(ptr[-1]) ? -1 : t);   /* "1.0E-" are not allowed */
+       }
+       int len = ptr - exp;
+       double num = 0.0;
+       char *buf = (char *)malloc(len + 1);
+       if (buf == NULL) {
+               return -1;
+       }
+       strncpy(buf, exp, len);
+       buf[len] = '\0';
+       sscanf(buf, "%lf", &num);
+       free(buf);
+       if (number != NULL) {
+               *number = num;
+       }
+       if (length != NULL) {
+               *length = len;
+       }
+       return 0;               /* successfully */
+}
+
+
+/*
+ * Return the current number position at the cursor in expr
+ * @expr, the expression string
+ * @cursor, the cursor postion
+ * @[out]begin, the current number begin position
+ * @[out]length, the current number's length
+ * @return, return 0 if get succefully, else return -1
+ */
+int calc_expr_get_current_num_at_cursor(char *expr, int cursor, int *begin,
+                                       int *length)
+{
+       int index = cursor;
+       int _begin = 0;
+       int _length = 0;
+       int counter = 0;
+       if (expr[index] == 'p' || expr[index] == 'e') {
+               if (index > 0 && expr[index - 1] == '-') {      //-e  OR -p
+                       _begin = index - 1;
+                       _length = 2;
+                }
+                 else {
+                       _begin = index;
+                       _length = 1;
+                 }
+        }
+        else {
+               if (expr[index] == 'E' || expr[index] == decimal_ch) {
+                       index--;
+                }
+               while (calc_expr_parse_number(expr + index, NULL, &_length) ==
+                       0){
+                       counter++;      /* flag */
+                       if (index + _length <= cursor) {
+                               index += 1;
+                               break;
+                        }
+                       if (index == 0)
+                               break;
+                       index--;
+                       if (expr[index] == 'E' || expr[index] == decimal_ch)
+                               index--;
+                       }
+                       if (counter == 0) {
+                               return -1;
+                        }              /* not a number */
+                       if (0 != calc_expr_parse_number(expr + index, NULL, NULL)) {
+                               index += 1;
+                       }
+                   calc_expr_parse_number(expr + index, NULL, &_length);
+                  if (IS_SIGN(expr[index])) {
+                               if (index > 0
+                                    && (isdigit(expr[index - 1])
+                                        || expr[index - 1] == ')')) {
+                                       index += 1;
+                                       _length -= 1;
+                                }
+                       }
+                  _begin = index;
+         }
+       if (begin != NULL) {
+                 *begin = _begin;
+         }
+        if (length != NULL) {
+                 *length = _length;
+         }
+       return 0;               /* successfully */
+}
+
+
+/*
+ * Auto close parentheses at the end of exp.
+ */
+void calc_expr_close_parentheses(char *exp)
+{
+       int cnt_l = 0, cnt_r = 0;
+       int i = 0;
+       for (i = 0; exp[i]; ++i) {
+               if ('(' == exp[i]) {
+                       cnt_l++;
+                }
+               if (')' == exp[i]) {
+                       cnt_r++;
+                }
+        }
+       int n = cnt_l - cnt_r;
+       while (n > 0) {
+               strcat(exp, ")");
+               n--;
+        }
+}
+
+
+/**
+ * According "[Fraser] UI_Calculator_v0.5_20101125.pdf",
+ *  *123+2=125
+ *  /123+2=125
+ * Enter operator at first are allowed.
+ * So it should remove 'x' or '/' at the first position.
+ */
+void calc_expr_remove_first_operator(char *exp)
+{
+       if (exp != NULL && strlen(exp) > 0) {
+               if (exp[0] == 'x' || exp[0] == '/' || exp[0] == '+') {
+                       string_remove_at(exp, 0, 1);
+                }
+        }
+}
+
+
+/**
+ * @description
+ * According "[Fraser] UI_Calculator_v0.5_20101125.pdf",
+ *  123+= : 123+123=246
+ *  123-= : 123-123=0
+ *  123*= : 123*123=15129
+ *  123/= : 123/123=1
+ * The operator at last are allowed.
+ * The function process these conditions.
+ *
+ * @param       exp
+ * @return      void
+ * @exception   none
+ */
+void calc_expr_process_last_operator(char *exp)
+{
+       int len = strlen(exp);
+       if (len > 1 && IS_OPERATOER(exp[len - 1])) {
+               int b, l;
+               if (0 ==
+                    calc_expr_get_current_num_at_cursor(exp, len - 2, &b, &l)) {
+                       strncat(exp, exp + b, l);
+                       exp[len + l] = '\0';
+                }
+        }
+}
+
+
+/*
+ * Preprocess befeore calculating.
+ */
+void calc_expr_preprocess(char *exp)
+{
+       calc_expr_close_parentheses(exp);
+       calc_expr_remove_first_operator(exp);
+       calc_expr_process_last_operator(exp);
+}
+
+/*
+ * process expression input backspace
+ * @[in/out]expr, the expression string
+ * @[in/out]cursor, the cursor postion
+ * When the fuction return, the exp and cursor will be updated.
+ */
+void calc_expr_input_backspace(char *exp, int *cursor)
+{
+       int _cursor = *cursor;
+       int count = 0;
+       if (_cursor <= 0) {
+               return;
+       }
+       if (_cursor > strlen(exp)) {
+               _cursor = strlen(exp);
+       }                       /* set to the end */
+       char *func = calc_expr_get_current_func_at_cursor(exp, _cursor);
+       if (NULL == func) {
+               count = 1;
+               _cursor -= 1;
+       } else {
+               int p = _cursor;
+               while (p >= 0 && (strncmp(func, exp + p, strlen(func)) != 0)) {
+                       p--;
+               }
+               count = strlen(func);
+               _cursor = p;
+       }
+       string_remove_at(exp, _cursor, count);
+       *cursor = _cursor;
+}
+
+
+/*
+ * insert str in exp at sursor position
+ * @[in/out]expr, the expression string
+ * @[in/out]cursor, the cursor postion
+ * @[in]str, the string insert into
+ * When the fuction return, the exp and cursor will be updated.
+ */
+void calc_expr_input_insert(char *exp, int *cursor, char *str)
+{
+       int _cursor = *cursor;
+       if (_cursor < 0) {
+               return;
+       }
+       if (_cursor > strlen(exp)) {
+               _cursor = strlen(exp) + 1;
+       }                       /* set to the end */
+       string_insert(exp, _cursor, str);
+       *cursor = _cursor + strlen(str);
+}
+
+
diff --git a/theme/src/calc-main.c b/theme/src/calc-main.c
new file mode 100644 (file)
index 0000000..dd3f225
--- /dev/null
@@ -0,0 +1,444 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+#include <dlog.h>
+#include <Ecore_X.h>           /* ecore_x_window_size_get */
+#include <utilX.h>             /* KEY_END */
+#include <svi.h>
+#include "calc-main.h"
+#include "calc-view.h"
+
+extern char calculator_input_str[];
+extern int calculator_cursor_pos;
+
+extern int cur_fontsize;
+extern int default_fontsize;
+extern int min_len;
+extern int max_len;
+extern int small_fontsize;
+extern int scientific_result_len;
+
+extern void calc_xxx(struct appdata *ap);      /* will be removed */
+extern void _calc_entry_text_set_rotate(struct appdata *ad);
+extern void calc_por_pannel_load(struct appdata *ad);
+extern void calc_lans_pannel_load(struct appdata *ad);
+Evas_Object *load_edj(Evas_Object * parent, const char *file, const char *group)
+{
+       CALC_FUN_BEG();
+       Evas_Object *eo;
+       int r;
+       eo = elm_layout_add(parent);
+       if (eo) {
+               r = elm_layout_file_set(eo, file, group);
+               if (!r) {
+                       evas_object_del(eo);
+                       return NULL;
+               }
+               evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND,
+                                                EVAS_HINT_EXPAND);
+       }
+       CALC_FUN_END();
+       return eo;
+}
+
+/**
+* @describe
+* @When rotate to landscape view (Scientific calculation)
+* @param[in]   ad      The appdata
+* @param[in]   angle   The rotate angle 90 or 270
+* @return      void
+* @exception
+*/
+static void __to_landscape(struct appdata *ad, int angle)
+{
+       CALC_FUN_BEG();
+       if (ad == NULL) {
+               return;
+       }
+       elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
+       calc_lans_pannel_load(ad);
+       edje_object_signal_emit(_EDJ(ad->edje), "landscape", "");
+       elm_win_rotation_with_resize_set(ad->win, angle);
+       elm_win_rotation_with_resize_set(ad->eo, angle);/*when rotating, resize the window eo*/
+       default_fontsize = 98;
+       cur_fontsize = 98;
+       small_fontsize = 98;
+       min_len = 30;
+       max_len = 37;
+       scientific_result_len = 13;
+       _calc_entry_text_set_rotate(ad);
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+* @When rotate to protrait view (Basic calculation)
+* @param[in]   ad      The appdata
+* @param[in]   angle   The rotate angle 0 or 180
+* @return      void
+* @exception
+*/
+static void __to_portrait(struct appdata *ad, int angle)
+{
+    CALC_FUN_BEG();
+       if (ad == NULL) {
+               return;
+       }
+       elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
+       calc_por_pannel_load(ad);
+       edje_object_signal_emit(_EDJ(ad->edje), "portrait", "");
+       elm_win_rotation_with_resize_set(ad->win, angle);
+       elm_win_rotation_with_resize_set(ad->eo, angle);/*when rotating, resize the window eo*/
+       default_fontsize = 70;
+       cur_fontsize = 70;
+       small_fontsize = 58;
+       min_len = 13;
+       max_len = 16;
+       scientific_result_len = 8;
+       _calc_entry_text_set_rotate(ad);
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param    mode
+* @param    data
+* @return    int
+* @exception
+*/
+static  void _rotate(app_device_orientation_e  mode, void *data)
+{
+       CALC_FUN_BEG();
+       if (data == NULL) {
+               return;
+       }
+       struct appdata *ad = (struct appdata *)data;
+
+       switch (mode) {
+       case APP_DEVICE_ORIENTATION_0:  //[1]0
+               __to_portrait(ad, 0);
+               break;
+
+       case APP_DEVICE_ORIENTATION_180:        //[2]180
+               __to_portrait(ad, 180);
+               break;
+
+       case APP_DEVICE_ORIENTATION_270:        //[3]-90
+               __to_landscape(ad, 270);
+               break;
+
+       case APP_DEVICE_ORIENTATION_90: //[4]90
+               __to_landscape(ad, 90);
+               break;
+
+       default:
+               break;
+       }
+
+       /* When rotate, the size of input scroller will be changed. So it should adjust to cursor position. */
+       calc_view_revise_input_scroller(ad);
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param    data
+* @param    obj
+* @param    event_info
+* @return    void
+* @exception
+*/
+static void _win_del(void *data, Evas_Object * obj, void *event_info)
+{
+       elm_exit();
+}
+
+/**
+* @describe
+*
+*
+* @param    data
+* @return    int
+* @exception
+*/
+static int _set_input_entry_focus(void *data)
+{
+       CALC_FUN_BEG();
+       struct appdata *ad = (struct appdata *)data;
+       elm_object_focus_set(ad->input_entry, EINA_TRUE);       //set focus
+       _calc_entry_clear(ad->input_entry);
+       CALC_FUN_END();
+       return ECORE_CALLBACK_CANCEL;   //0
+}
+
+/**
+* @describe
+*
+*
+* @param    data
+* @return    int
+* @exception
+*/
+static int _load_idle_view(void *data)
+{
+       CALC_FUN_BEG();
+       struct appdata *ad = (struct appdata *)data;
+       calc_view_load_in_idle(ad);
+       CALC_FUN_END();
+       return ECORE_CALLBACK_CANCEL;   //0
+}
+
+/**
+* @describe
+*
+*
+* @param    name
+* @return    Evas_Object*
+* @exception
+*/
+static Evas_Object *_create_win(const char *name)
+{
+    CALC_FUN_BEG();
+       Evas_Object *eo;
+       int w, h;
+       eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
+       if (eo) {
+               elm_win_title_set(eo, name);
+               evas_object_smart_callback_add(eo, "delete,request", _win_del,
+                                              NULL);
+               ecore_x_window_size_get(ecore_x_window_root_first_get(), &w,
+                                       &h);
+               evas_object_resize(eo, w, h);
+       }
+       CALC_FUN_END();
+       return eo;
+}
+
+/**
+* @describe
+*
+*
+* @param    ad
+* @return    void
+* @exception
+*/
+static void _on_exit(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       if (ad->por_pannel) {
+               evas_object_del(ad->por_pannel);
+               ad->por_pannel = NULL;
+       }
+
+       if (ad->lan_pannel) {
+               evas_object_del(ad->lan_pannel);
+               ad->lan_pannel = NULL;
+       }
+
+       if (ad->input_entry) {
+               evas_object_del(ad->input_entry);
+               ad->input_entry = NULL;
+       }
+       if (ad->clear_btn) {
+               elm_object_item_del(ad->clear_btn);
+               ad->clear_btn = NULL;
+       }
+
+       if (ad->invalid_btn) {
+               elm_object_item_del(ad->invalid_btn);
+               ad->invalid_btn = NULL;
+       }
+
+       if (ad->tool_bar) {
+               evas_object_del(ad->tool_bar);
+               ad->tool_bar = NULL;
+       }
+
+       if (ad->navi_it) {
+               elm_object_item_del(ad->navi_it);
+               ad->navi_it = NULL;
+       }
+
+       if (ad->nf) {
+               evas_object_del(ad->nf);
+               ad->nf = NULL;
+       }
+#ifdef SAVE_HISTORY
+       if (ad->hist_area) {
+               evas_object_del(ad->hist_area);
+               ad->hist_area = NULL;
+       }
+
+       if (ad->hist_scroll) {
+               evas_object_del(ad->hist_scroll);
+               ad->hist_scroll = NULL;
+       }
+#endif
+
+       if (ad->edje) {
+               evas_object_del(ad->edje);
+               ad->edje = NULL;
+       }
+
+       if (ad->layout) {
+               evas_object_del(ad->layout);
+               ad->layout = NULL;
+       }
+
+       if (ad->bg) {
+               evas_object_del(ad->bg);
+               ad->bg = NULL;
+       }
+
+       if (ad->win) {
+               evas_object_del(ad->win);
+               ad->win = NULL;
+       }
+
+       /* delete timer */
+       if (ad->calc_timer) {
+               ecore_timer_del(ad->calc_timer);
+               ad->calc_timer = NULL;
+       }
+       if (ad->wrong_timer) {
+               ecore_timer_del(ad->wrong_timer);
+               ad->wrong_timer = NULL;
+       }
+       if (ad->svi_handle) {
+               svi_fini(ad->svi_handle);
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param    data
+* @return    int
+* @exception
+*/
+static bool app_create(void *data)
+{
+       CALC_FUN_BEG();
+       struct appdata *ad = (struct appdata *)data;
+
+       /*  Use elm_theme_extension_add() API before creating any widgets */
+       elm_theme_extension_add(NULL, CALCULATOR_THEME);
+
+       /* main widnow */
+       ad->win = _create_win(PACKAGE);
+       if (ad->win == NULL) {
+               return FALSE;
+       }
+       evas_object_show(ad->win);
+
+       elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
+
+       /* will be removed */
+       calc_xxx(ad);
+
+       /* load main view */
+       calc_view_load(ad);
+
+       app_device_orientation_e curr = app_get_device_orientation();
+       _rotate(curr, ad);
+
+       /* register callback */
+       ecore_idler_add((Ecore_Task_Cb) _set_input_entry_focus, ad);
+       ecore_idler_add((Ecore_Task_Cb) _load_idle_view, ad);
+       CALC_FUN_END();
+       return TRUE;            //EXIT_SUCCESS
+
+}
+
+/**
+* @describe
+*
+*
+* @param    data
+* @return    int
+* @exception
+*/
+static void app_terminate(void *data)
+{
+       // Release all resources
+       struct appdata *ad = (struct appdata *)data;
+       _on_exit(ad);
+}
+
+/**
+* @describe
+*
+*
+* @param    data
+* @return    int
+* @exception
+*/
+static void app_pause(void *data)
+{
+       // Take necessary actions when application becomes invisible
+}
+
+/**
+* @describe
+*
+*
+* @param    data
+* @return    int
+* @exception
+*/
+static void app_resume(void *data)
+{
+       // Take necessary actions when application becomes visible.
+}
+
+/**
+* @describe
+*   The entry of the program
+*
+* @param    argc
+* @param    argv
+* @param    int
+* @exception
+*/
+int main(int argc, char *argv[])
+{
+    CALC_FUN_BEG();
+       struct appdata ad;
+
+       app_event_callback_s event_callback;
+
+       event_callback.create = app_create;
+       event_callback.terminate = app_terminate;
+       event_callback.pause = app_pause;
+       event_callback.resume = app_resume;
+       event_callback.service = NULL;
+       event_callback.low_memory = NULL;
+       event_callback.low_battery = NULL;
+       event_callback.device_orientation = _rotate;
+       event_callback.language_changed = NULL;
+       event_callback.region_format_changed = NULL;
+
+       memset(&ad, 0x0, sizeof(struct appdata));
+       return app_efl_main(&argc, &argv, &event_callback, &ad);
+}
+
diff --git a/theme/src/calc-string.c b/theme/src/calc-string.c
new file mode 100644 (file)
index 0000000..9237df8
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "calc-main.h"
+#include "calc-string.h"
+#include <glib.h>
+
+#undef  BUFLEN
+#define BUFLEN 1024
+
+/*
+ * Insert str2 to str at index.
+ */
+void string_insert(char *str, int index, char *str2)
+{
+       int buf_size = strlen(str) + strlen(str2) + 1;
+       char *buf = (char *)malloc(buf_size);
+       if (buf == NULL) {
+               return;
+       }
+       memset(buf, 0, buf_size);
+       strncpy(buf, str, index);
+       buf[index] = '\0';
+       strncat(buf, str2, buf_size - 1 - strlen(buf)); //don't use g_strlcat, because has bug.
+        strncat(buf, str + index, buf_size - 1 - strlen(buf));
+       strcpy(str, buf);
+       free(buf);
+}
+
+
+/*
+ * Replace a with b in str locally.
+ */
+void string_replace(char *str, char *a, char *b)
+{
+       char *pch = NULL;
+       char buf[BUFLEN] = { 0 };
+       if(strcmp(a, b)){
+               while ((pch = strstr(str, a)) != NULL) {
+                       strncpy(buf, str, pch - str);
+                       buf[pch - str] = '\0';
+                       g_strlcat(buf, b, sizeof(buf));
+                       g_strlcat(buf, pch + strlen(a), sizeof(buf));
+                       strcpy(str, buf);
+               }
+       }
+}
+
+void string_remove_at(char *str, int at, int length)
+{
+       int i = at;
+       while ((str[i] = str[i + length]) != '\0') {
+               i++;
+       }
+}
+
+
+#ifdef _DEBUG
+/* @attention   DON'T REMOVE
+char* itoa(int i)
+{
+       char *a = (char *)malloc(42);
+       if (a) { sprintf(a, "%d", i); }
+       return a;
+}
+*/
+#endif /* _DEBUG */
+
+/* Remove later.
+if (i != 0)//last digit number
+{
+    //if ((new_node) && (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == PI || CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == EXPONENT))
+    if ((new_node) && (FLOAT_EQUAL(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result,PI)
+        || FLOAT_EQUAL(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, EXPONENT)))
+    {
+        node_data = g_malloc0(sizeof(calculator_node_data_t));
+        node_data->cur_operator = 'x';
+        node_data->negative_flag = 1;
+        node_data->operator_type = OPERATOR_TYPE_BINARY;
+        node_data->node_calcu_priority = CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+        tree = g_node_new(node_data);
+
+        if (last_node)
+        {
+            __calculator_calculate_insert_node(&last_node, tree, new_node);
+        }
+        else
+        {
+            g_node_insert(tree, -1, new_node);
+            CALCULATOR_GET_NODE_DATA(tree)->children_num++;
+        }
+        last_node = tree;
+        new_node = NULL;
+    }
+
+    factor = atof(tmp);
+    memset(tmp, 0x00, sizeof(tmp));
+    i = 0;
+
+    node_data = g_malloc0(sizeof(calculator_node_data_t));
+    node_data->tmp_result = factor;
+    node_data->negative_flag = 1;
+    node_data->negative_flag *= negative_sign;
+    negative_sign = 1;
+    new_node = g_node_new(node_data);
+
+    if (last_node != NULL)
+    {
+        if (CALCULATOR_GET_NODE_DATA(last_node)->children_num > CALCULATOR_GET_NODE_DATA(last_node)->operator_type)
+        {
+            strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+            return FALSE;
+        }
+        else
+        {
+            g_node_insert(last_node, -1, new_node);
+            CALCULATOR_GET_NODE_DATA(last_node)->children_num++;
+        }
+        new_node = NULL;
+    }
+}
+*/
+
diff --git a/theme/src/calc-view.c b/theme/src/calc-view.c
new file mode 100644 (file)
index 0000000..754459a
--- /dev/null
@@ -0,0 +1,512 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+#include <app.h>
+#include <Elementary.h>
+#include <stdbool.h>
+#include "calc-main.h"
+#include "calc-string.h"
+#include "calc-expression.h"
+#include "calc-view.h"
+#include <Ecore_X.h>
+
+extern char decimal_ch;
+extern char separator_ch;
+extern char calculator_input_str[];
+extern void _calc_add_tag(char *string, char *format_string);
+extern int cur_fontsize;
+extern void _calc_view_keypad_cb_register(Evas_Object * keypad);
+extern calculator_state_t calculator_get_state();
+static bool calculator_pannel_show = TRUE;
+
+/*
+ * BEGIN INPUT SCROLLER REVISE
+ *
+ * Accturally it needn't these fuction.
+ * But scroller lack fuction and has many bugs.
+ * So we need to revise it.
+ */
+
+/**
+* @describe
+*   The entry of the program
+*
+* @param    data
+* @return   Eina_Bool
+*/
+static Eina_Bool  _calc_view_revise_input_scroller_timer_cb(void *data)
+{
+       CALC_FUN_BEG();
+       struct appdata *ad = (struct appdata *)data;
+       int child_w, child_h;
+       elm_scroller_child_size_get(ad->input_scroller, &child_w, &child_h);
+       printf("|| Child size : w=%d h=%d\n", child_w, child_h);
+       int scroller_w, scroller_h;
+       elm_scroller_region_get(ad->input_scroller, NULL, NULL, &scroller_w,
+                                &scroller_h);
+       printf("|| Region size : w=%d h=%d\n", scroller_w, scroller_h);
+       int region_y = child_h - scroller_h;
+       elm_scroller_region_bring_in(ad->input_scroller, 0, region_y,
+                                      scroller_w, scroller_h);
+       CALC_FUN_BEG();
+       return ECORE_CALLBACK_CANCEL;   //0
+}
+
+
+/**
+* @describe
+*   The entry of the program
+*
+* @param    ad      the appdata
+* @return   void
+*/
+void  calc_view_revise_input_scroller(struct appdata *ad)
+{
+
+       CALC_FUN_BEG();
+    /* Because return ECORE_CALLBACK_CANCEL, the timer will be deleted automatically */
+    ecore_timer_add(0.05, _calc_view_revise_input_scroller_timer_cb,
+                   ad);
+       CALC_FUN_END();
+}
+
+/* END INPUT SCROLLER REVISE */
+void  calc_view_show_result(const char *result, struct appdata *ad)
+{
+       char buf[MAX_RESULT_LENGTH] = { 0 };
+       char temp[MAX_RESULT_LENGTH] = { 0 };
+       snprintf(buf, MAX_RESULT_LENGTH,
+                 "<br><+ font_size=%d><color=#FFB400FF>=",
+                 cur_fontsize);
+       snprintf(temp, MAX_RESULT_LENGTH,
+                 "<+ font_size=%d><color=#FFB400FF>%s",
+                 cur_fontsize, result);
+       strncat(buf, temp, strlen(temp));
+
+#if 0
+           elm_entry_entry_set(entry, buf);
+
+#else  /*  */
+           elm_entry_cursor_end_set(ad->input_entry);
+       elm_object_focus_set(ad->input_entry, EINA_TRUE);
+       elm_entry_entry_insert(ad->input_entry, buf);
+       calc_view_revise_input_scroller(ad);
+
+#endif /*  */
+           evas_object_show(ad->input_entry);
+}
+
+/* BEGIN ABOUT CURSOR */
+
+/**
+* @description
+*   Because display expression and calculate expression are not the same.
+*   The display expression has comma or some special character.
+*   So we should correct the cursor position for input expression
+*
+* @param    entry       input entry
+* @param    cur_pos     the cursor position in display expression
+* @return   int         the cursor position in input expression
+*/
+static int
+_calc_view_cursor_correct_position(Evas_Object * entry, int cur_pos)
+{
+       char buf[MAX_EXPRESSION_LENGTH] = { 0 };
+       char *ss = elm_entry_markup_to_utf8(elm_entry_entry_get(entry));
+       strncpy(buf, ss, MAX_EXPRESSION_LENGTH - 1);
+       int i = 0, len = cur_pos;
+       int count_sqrt = 0;     /* the number of sqrt before cursor */
+       int count_comma = 0;    /* the number of comma before cursor */
+       int count_br = 0;
+       for (i = 0; i < len; ++i) {
+               if (buf[i] == separator_ch){
+                       count_comma++;
+               } else if (buf[i] == '\xcf' || buf[i] == '\xc3') {
+                       len += 1;
+               } else if (buf[i] == '\xe2') {
+                       if (buf[i+2]=='\x92') {
+                               len += 2;
+                       } else if (buf[i+2]=='\x9a') {
+                               len += 2;
+                               count_sqrt++;
+                       }
+               }else if (buf[i]==10) {
+                       count_br++;
+               }
+       }
+       SFREE(ss);
+       return cur_pos + count_sqrt * 3 - count_comma-count_br;
+}
+
+int calc_view_cursor_get_position(Evas_Object * entry)
+{
+       int pos = elm_entry_cursor_pos_get(entry);
+       return _calc_view_cursor_correct_position(entry, pos);
+}
+
+void calc_view_cursor_set_position(Evas_Object * entry, int pos)
+{
+       CALC_FUN_BEG();
+       const char *expr =
+           elm_entry_markup_to_utf8(elm_entry_entry_get(entry));
+       const char *input = calculator_input_str;
+       int i = 0, j = 0;
+       int cur_pos = 0;
+       while (j < pos){
+               if (expr[i] == input[j]){
+                       cur_pos++;
+                       i++;
+                       j++;
+                    }
+
+               else if (expr[i] == separator_ch)
+                        {
+                       cur_pos++;
+                       i++;
+                       }
+
+               else if (expr[i] == '\xc3' || expr[i] == '\xcf')        /* mutiply/devide or PI */
+                        {
+                       cur_pos++;
+                       i += 2;
+                       j++;
+                       }
+
+               else if (expr[i] == '\xe2' && input[j] == 's')  /* sqrt */
+                        {
+                       cur_pos++;
+                       i += 3;
+                       j += 4;
+                       }
+
+               else if (expr[i] == '\xe2' && input[j] == '-')  /* sqrt */
+                        {
+                       cur_pos++;
+                       i += 3;
+                       j ++;
+                       }
+
+               else if (expr[i] == '*' && input[j] == 'x')
+                        {
+                       cur_pos++;
+                       i++;
+                       j++;
+                       }
+               else if(expr[i]==10) {
+                       cur_pos++;
+                       i++;
+                       }
+
+               else
+                        {
+                       break;
+                       }
+               }
+       elm_entry_cursor_pos_set(entry, cur_pos);
+       elm_object_focus_set(entry, EINA_TRUE);
+       SFREE(expr);
+       CALC_FUN_END();
+}
+
+#ifdef SAVE_HISTORY
+
+/* BEGIN ABOUT HISTORY */
+static struct history_item history[MAX_HISTORY_NUM];
+static int history_index = 0;
+
+/**
+* @descrption
+* @Save the current calculate result to history
+* @Called by "__calculator_op_equal" function in calculator_edje.c
+* @param[in]   item    The history item will be stored
+* @return      void
+* @exception
+*/
+void calc_view_save_history(struct history_item item)
+{
+       CALC_FUN_BEG();
+       history[history_index] = item;
+       history_index = (1 + history_index) % MAX_HISTORY_NUM;
+       CALC_FUN_END();
+}
+
+/**
+* @descrption
+* @Show calculate result when switch between protrait/landscape view
+* @Called by "_calc_entry_text_set_rotate" function in calculator_edje.c
+* @param[in]   entry   The input entry
+* @return      void
+* @exception
+*/
+void _calc_view_show_newest_histroy(Evas_Object *entry)
+{
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
+       char content[MAX_TAG_EXPRESSION_LENGTH + MAX_RESULT_LENGTH] = { 0 };
+       char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
+       char buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_format[MAX_RESULT_LENGTH] = { 0 };
+       int new_index = (history_index - 1) % MAX_HISTORY_NUM;
+       if (strlen(history[new_index].expression) == 0) {
+               return;
+       }
+       _calc_add_tag(history[new_index].expression, tag_text);
+       strncat(content, tag_text, strlen(tag_text));
+       snprintf(buf, MAX_RESULT_LENGTH,
+                 "<br><align=right><+ font_size=%d><color=#FFB400FF>=",
+                 cur_fontsize);
+       strncat(content, buf, strlen(buf));
+       calc_expr_num_format_result(history[new_index].result, result_buf);
+       calc_expr_format_expression(result_buf, result_format);
+       if (result_buf[0] == '-') {
+               string_replace(result_format, "\xe2\x88\x92", "-");
+       }
+       snprintf(buf, MAX_RESULT_LENGTH,
+                 "<align=right><color=#FFB400FF><+ font_size=%d>%s",
+                 cur_fontsize, result_format);
+       strncat(content, buf, strlen(buf));
+       elm_entry_entry_set(entry, content);
+       CALC_FUN_END();
+}
+
+/**
+* @descrption
+* @Show calculate history when history view is load
+* @Called by "_calc_view_show_history_cb" function
+* @param[in]   entry   The history view entry
+* @return      void
+* @exception
+*/
+static void __calc_view_show_histroy(Evas_Object *entry)
+{
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
+       char content[(MAX_TAG_EXPRESSION_LENGTH + MAX_TAG_EXPRESSION_LENGTH) *
+                     MAX_HISTORY_NUM] = { 0 };
+
+       char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
+       char buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_format[MAX_RESULT_LENGTH] = { 0 };
+       char input_str[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
+       char input_str_tag[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
+       int i = 0;
+       int j = 0;
+       for (i = history_index; i <= history_index + MAX_HISTORY_NUM - 1; i++) {
+               j = i % MAX_HISTORY_NUM;
+               if (strlen(history[j].expression) > 0) {
+                       _calc_add_tag(history[j].expression, tag_text);
+                       strncat(content, tag_text, strlen(tag_text));
+                       memset(tag_text, 0, sizeof(tag_text));
+                       snprintf(buf, MAX_RESULT_LENGTH,
+                                 "<br><align=right><+ font_size=%d><color=#FFB400FF>=",
+                                 cur_fontsize);
+                       strncat(content, buf, strlen(buf));
+                       memset(result_buf, 0, sizeof(result_buf));
+                       calc_expr_num_format_result(history[j].result, result_buf);
+                       memset(result_format, 0, sizeof(result_format));
+                       calc_expr_format_expression(result_buf, result_format);
+                       if (result_buf[0] == '-') {
+                               string_replace(result_format, "\xe2\x88\x92", "-");
+                       }
+                       snprintf(buf, MAX_RESULT_LENGTH,
+                                 "<align=right><color=#FFB400FF><+ font_size=%d>%s<br>",
+                                       cur_fontsize, result_format);
+                       strncat(content, buf, strlen(buf));
+                }
+       }
+       calculator_state_t tmp_state = calculator_get_state();
+       if (tmp_state != CALCULATOR_CALCULATED) {
+               calc_expr_format_expression(calculator_input_str, input_str);
+               _calc_add_tag(input_str, input_str_tag);
+               strncat(content, input_str_tag, strlen(input_str_tag));
+       }
+       elm_entry_entry_set(entry, content);
+       CALC_FUN_END();
+}
+
+/**
+* @descrption
+* @Clear calculate history "Clear History" Button is clicked
+* @param[in]   entry   The history view entry
+* @return      void
+* @exception
+*/
+void _calc_view_clear_histroy(Evas_Object *entry)
+{
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
+       int i = 0;
+       for (i = history_index + MAX_HISTORY_NUM - 1; i >= history_index; --i) {
+               int j = i % MAX_HISTORY_NUM;
+               if (strlen(history[j].expression) > 0) {
+                       memset(history[j].expression, 0,
+                               sizeof(history[j].expression));
+                       history[j].result = 0;
+                       }
+               }
+       _calc_entry_clear(entry);
+       CALC_FUN_END();
+}
+
+void _calc_view_show_history_cb
+    (void *data, Evas_Object * o, const char *emission, const char *source)
+ {
+       CALC_FUN_BEG();
+       calculator_pannel_show = FALSE;
+       struct appdata *ad = (struct appdata *)data;
+       evas_object_hide(ad->input_entry);/*hide the input entry,before showing history area*/
+       evas_object_hide(ad->input_scroller);
+       edje_object_part_unswallow(_EDJ(ad->edje), ad->input_scroller);
+       evas_object_show(ad->hist_area);
+       evas_object_show(ad->hist_scroll);
+       __calc_view_show_histroy(ad->hist_area);
+       edje_object_signal_emit(_EDJ(ad->edje), "show,hist", "");
+    /* sync lan & por pannel state */
+    Evas_Object * pannel =
+           !strcmp(source, "por") ? ad->lan_pannel : ad->por_pannel;
+       edje_object_signal_emit(_EDJ(pannel), "pannel,down", source);
+       CALC_FUN_END();
+}
+
+void
+_calc_view_hide_history_cb(void *data, Evas_Object * o, const char *emission,
+                          const char *source)
+{
+       CALC_FUN_BEG();
+       calculator_pannel_show = TRUE;
+       struct appdata *ad = (struct appdata *)data;
+       edje_object_signal_emit(_EDJ(ad->edje), "hide,hist", "");
+
+    /* sync lan & por pannel state */
+    Evas_Object * pannel =
+           !strcmp(source, "por") ? ad->lan_pannel : ad->por_pannel;
+       edje_object_signal_emit(_EDJ(pannel), "pannel,up", source);
+       evas_object_hide(ad->hist_area);
+       evas_object_hide(ad->hist_scroll);
+       evas_object_show(ad->input_scroller);
+       evas_object_show(ad->input_entry);  /*show the input entry,after hide history area */
+       edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
+                                ad->input_scroller);
+       elm_object_focus_set(ad->input_entry, EINA_TRUE);       //can't remove show cursor
+       CALC_FUN_END();
+}
+
+static Evas_Object *
+_calc_view_create_history_entry(Evas_Object * parent)
+{
+    CALC_FUN_BEG();
+       Evas_Object * entry = elm_entry_add(parent);
+       elm_entry_single_line_set(entry, EINA_FALSE);
+       elm_entry_line_wrap_set(entry, ELM_WRAP_WORD);
+       elm_entry_editable_set(entry, EINA_FALSE);
+       elm_entry_entry_set(entry, "<align=right>");
+       evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0.0);
+       evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0.0);
+       evas_object_show(entry);
+       CALC_FUN_END();
+       return entry;
+}
+
+static Evas_Object *
+_calc_view_create_history_scroller(Evas_Object * parent)
+{
+    CALC_FUN_BEG();
+       Evas_Object * scroller = elm_scroller_add(parent);
+       elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
+       evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
+                                         EVAS_HINT_EXPAND);
+       evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
+                                        EVAS_HINT_FILL);
+       evas_object_show(scroller);
+       CALC_FUN_END();
+       return scroller;
+}
+
+
+/* END ABOUT HISTORY */
+
+#endif /*  */
+void calc_view_load_in_idle(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+#ifdef SAVE_HISTORY
+           /* history area */
+       ad->hist_area = _calc_view_create_history_entry(ad->edje);
+       ad->hist_scroll = _calc_view_create_history_scroller(ad->edje);
+       elm_object_content_set(ad->hist_scroll, ad->hist_area);
+       edje_object_part_swallow(_EDJ(ad->edje), "history/scroll",
+                                 ad->hist_scroll);
+#endif /*  */
+       CALC_FUN_END();
+}
+
+/* pannels */
+void calc_por_pannel_load(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       if(ad->por_pannel == NULL)
+    {
+               ad->por_pannel = load_edj(ad->edje, LAYOUT_EDJ_NAME, GRP_POR_PANNEL);
+               edje_object_part_swallow(_EDJ(ad->edje), "por_pannel/rect",
+                                ad->por_pannel);
+               _calc_view_keypad_cb_register(_EDJ(ad->por_pannel));
+
+               edje_object_signal_callback_add(_EDJ(ad->por_pannel), "pannel,down",
+                                                 "por", _calc_view_show_history_cb,
+                                                 ad);
+               edje_object_signal_callback_add(_EDJ(ad->por_pannel), "pannel,up",
+                                                 "por", _calc_view_hide_history_cb,
+                                                 ad);
+
+    }
+       if(!calculator_pannel_show){
+               edje_object_signal_emit(_EDJ(ad->por_pannel), "pannel,down_i", "por");
+       }
+       CALC_FUN_END();
+}
+
+void calc_lans_pannel_load(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       if(ad->lan_pannel == NULL)
+    {
+               ad->lan_pannel = load_edj(ad->edje, LAYOUT_EDJ_NAME, GRP_LAN_PANNEL);
+               edje_object_part_swallow(_EDJ(ad->edje), "lan_pannel/rect",
+                                        ad->lan_pannel);
+               _calc_view_keypad_cb_register(_EDJ(ad->lan_pannel));
+               edje_object_signal_callback_add(_EDJ(ad->lan_pannel), "pannel,down",
+                                             "lan", _calc_view_show_history_cb,
+                                             ad);
+               edje_object_signal_callback_add(_EDJ(ad->lan_pannel), "pannel,up",
+                                                 "lan", _calc_view_hide_history_cb,
+                                                 ad);
+    }
+       if(!calculator_pannel_show){
+               edje_object_signal_emit(_EDJ(ad->lan_pannel), "pannel,down_i", "lan");
+       }
+       CALC_FUN_END();
+}
+
+
diff --git a/theme/src/calculator_edje.c b/theme/src/calculator_edje.c
new file mode 100644 (file)
index 0000000..0dfcddf
--- /dev/null
@@ -0,0 +1,2600 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#include <stdbool.h>           /*  true/false */
+#include <Elementary.h>
+#include <dlog.h>
+
+#include "calc-main.h"
+#include "calculator_parser.h"
+#include "calc-string.h"
+#include "calc-expression.h"
+#include "calc-view.h"
+#include <svi.h>
+
+#define CALCULATOR_CHAR_IS_OPERATOR(C) ((C == '+')||(C == '-')||(C == 'x')||(C == '/'))        /**<judge if a char is a basic operator*/
+#define CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(C) ((C == 'x')||(C == '/'))                   /**<judge if an operator is "*" or "/"*/
+#define CALCULATOR_CHAR_IS_PLUS_DEDUCT(C) ((C == '+')||(C == '-'))
+#define CALCULATOR_CHAR_IS_DIGITAL(C)(C >= '0' && C <= '9')
+#define CALCULATOR_IS_DIGIT_DOT(ch, decimal) (isdigit(ch) || decimal == (ch))
+
+static Elm_Entry_Filter_Limit_Size limit_filter_data;
+extern void _calc_view_show_newest_histroy(Evas_Object * entry);
+extern void _calc_view_clear_histroy(Evas_Object * entry);
+extern gboolean __calculator_search_function(char *op, int* len);
+static void __calculator_wrong_format_create(char * wrong_string);
+
+static struct appdata *ad;     /* will be removed */
+static calculator_state_t calculator_state = CALCULATOR_WAITING_INPUT;
+static double last_result = 0.0;
+int calculator_cursor_pos = 0;
+char calculator_input_str[MAX_EXPRESSION_LENGTH] = { 0 };
+char calculator_before_paste_str[MAX_EXPRESSION_LENGTH] = { 0 };
+bool paste_flag = FALSE;
+
+struct lconv *locale = NULL;
+char *decimal = NULL;
+char *separator = NULL;
+char decimal_ch = 0;
+char separator_ch = 0;
+
+int cur_fontsize = 70;
+int small_fontsize = 58;
+int default_fontsize = 0;
+int min_len = 13;
+int max_len = 0;
+int scientific_result_len = 8;
+
+
+static op_item_t calc_op_item[] = {
+       {OP_INVALID, "", NULL},
+
+       /* basic */
+       {OP_PARENTHESIS, "()", NULL},
+       {OP_DELETE, "<-", NULL},
+       {OP_CLEAR, "C", NULL},
+       {OP_DIVIDE, "/", NULL},
+
+       {OP_NUM_7, "7", NULL},
+       {OP_NUM_8, "8", NULL},
+       {OP_NUM_9, "9", NULL},
+       {OP_MULTIPLY, "x", NULL},
+
+       {OP_NUM_4, "4", NULL},
+       {OP_NUM_5, "5", NULL},
+       {OP_NUM_6, "6", NULL},
+       {OP_MINUS, "-", NULL},
+
+       {OP_NUM_1, "1", NULL},
+       {OP_NUM_2, "2", NULL},
+       {OP_NUM_3, "3", NULL},
+       {OP_PLUS, "+", NULL},
+
+       {OP_DOT, ".", NULL},
+       {OP_NUM_0, "0", NULL},
+       {OP_PLUS_MINUS, "+/-", NULL},
+       {OP_EQUAL, "=", NULL},
+
+       /* functional */
+       {OP_PERCENT, "%", NULL},
+       {OP_ROOT, "sqrt", "sqrt("},
+       {OP_FACT, "x!", "!"},
+
+       {OP_SIN, "sin", "sin("},
+       {OP_COS, "cos", "cos("},
+       {OP_TAN, "tan", "tan("},
+
+       {OP_LN, "ln", "ln("},
+       {OP_LOG, "log", "log("},
+       {OP_1X, "1/x", "1/x"},
+
+       {OP_10X, "10^x", "10^("},
+       {OP_X2, "x^2", "^2"},
+       {OP_XY, "x^y", "^("},
+
+       {OP_ABS, "abs", "abs("},
+       {OP_PI, "Pi", "p"},
+       {OP_E, "e", "e"},
+};
+char *error_string[] = {
+    "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE",
+    "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE",
+    "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE",
+    "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO",
+    "IDS_CCL_POP_NO_NUMBER_ERROR",
+    "IDS_CCL_POP_ERROR",
+    "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR",
+    "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION",
+    "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION",
+    "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION",
+    "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION",
+    "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION",
+    "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION",
+    "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION",
+    "IDS_CCL_POP_NO_OPERATOR_ERROR",
+    "IDS_CCL_POP_SYNTAX_ERROR",
+};
+
+calculator_state_t calculator_get_state()
+{
+       return calculator_state;
+}
+
+void _calc_add_tag(char *string, char *format_string)
+{
+       CALC_FUN_BEG();
+       int i = 0;
+       int begin = 0;
+       int end = 0;
+       char buf[MAX_EXPRESSION_LENGTH] = { 0 };
+       char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
+       char *p = NULL;
+       while (string[i] != '\0') {
+               if (CALCULATOR_CHAR_IS_DIGITAL(string[i])
+                   || string[i] == separator_ch || string[i] == decimal_ch
+                   ||( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92')) {
+                       if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
+                               memset(buf, 0, sizeof(buf));
+                               snprintf(buf, sizeof(buf),
+                                "<align=right><font_size=%d><color=#7A9CC6FF>(<align=right><font_size=%d><color=#FFFFFFFF>-",
+                                cur_fontsize, cur_fontsize);
+                               strcat(format_string, buf);
+                               i=i+4;
+                       }
+                       begin = i;
+                       p = &string[begin];
+                       while (CALCULATOR_CHAR_IS_DIGITAL(string[i])
+                              || string[i] == separator_ch
+                              || string[i] == decimal_ch) {
+                               i++;
+                       }
+                       end = i - 1;
+                       strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
+                       tmp[end - begin + 1] = '\0';
+                       memset(buf, 0, sizeof(buf));
+                       snprintf(buf, sizeof(buf),
+                                "<align=right><font_size=%d><color=#FFFFFFFF>%s",
+                                cur_fontsize, tmp);
+                       strcat(format_string, buf);
+               } else {
+                       begin = i;
+                       p = &string[begin];
+                       while (!CALCULATOR_CHAR_IS_DIGITAL(string[i])
+                              && string[i] != separator_ch
+                              && string[i] != decimal_ch
+                              && string[i] != '\0') {
+                              if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
+                                       break;
+                              } else {
+                                       i++;
+                              }
+                       }
+                       end = i - 1;
+                       strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
+                       tmp[end - begin + 1] = '\0';
+                       memset(buf, 0, sizeof(buf));
+                       snprintf(buf, sizeof(buf),
+                                "<align=right><font_size=%d><color=#7A9CC6FF>%s",
+                                cur_fontsize, tmp);
+                       strcat(format_string, buf);
+               }
+
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+* Change line and font size when it is needed.
+* Refer to the auto font resizing rules.
+* @param       tag_text                The text with tags.
+* @return      void
+* @exception
+*/
+void _calc_add_br(char *tag_text)
+{
+       CALC_FUN_BEG();
+       if (tag_text  == NULL) {
+               return;
+       }
+       int line_valid_num = 0;
+       int whole_valid_num = 0;
+       int operator_tag = -1;
+       int operator_location = -1;
+       /* record is there an operator in one line? */
+       bool operator_flag = FALSE;
+       /* when change to small font, we should rescan the tag_text */
+       bool rescan_flag = FALSE;
+       int cur_len = 0;
+       char buf[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
+       strcpy(buf, tag_text);
+       int br_number = 0;
+       int i = 0;
+       int j = 0;
+       for ( ; tag_text[i] != '\0' && calculator_input_str[j] != '\0'; ) {
+               while (tag_text[i] == '<') {
+                       while (tag_text[i++] != '>');
+               }
+               /* if calculator_input_str[j] is "*" or "/", tag_text[i] would be
+                       "\xc3\x97" or "\xc3\xb7" */
+               if (tag_text[i] == calculator_input_str[j] || (tag_text[i] == '\xc3') ||
+                       ((tag_text[i] == '\xe2') && (tag_text[i+1] == '\x88') && (tag_text[i+2] == '\x92'))) {
+
+                       if ((CALCULATOR_CHAR_IS_OPERATOR(calculator_input_str[j])) &&
+                               (!(calculator_input_str[j] == '-' && calculator_input_str[j-1] == '('))) {
+                               if (!operator_flag || rescan_flag) {
+                                       operator_location = j;
+                                       operator_tag = i;
+                                       operator_flag = TRUE;
+                               }
+                       }
+
+                       whole_valid_num++;
+                       line_valid_num++;
+                       if (br_number < 2) {
+                               cur_fontsize = default_fontsize;
+                               cur_len = min_len;
+                       } else {
+                               if ((line_valid_num >= min_len) && (!rescan_flag)) {
+                                       rescan_flag = TRUE;
+                                       cur_fontsize = small_fontsize;
+                                       strcpy(tag_text, buf);
+                                       /* restore to the original state, then scan from the begin */
+                                       i = 0;
+                                       j = 0;
+                                       whole_valid_num = 1;
+                                       line_valid_num = 1;
+                                       operator_flag = FALSE;
+                                       operator_tag = -1;
+                                       operator_location = -1;
+                                       cur_len = max_len + 1;
+                               }
+                       }
+
+                       if (line_valid_num >= cur_len) {
+                               if (operator_flag && operator_tag > 0) {
+                                       string_insert(tag_text, operator_tag, "<br>");
+                                       line_valid_num = whole_valid_num-operator_location;
+                                       operator_flag = FALSE;
+                                       operator_tag = -1;
+                                       operator_location = -1;
+                               } else {
+                                       string_insert(tag_text, i, "<br>");
+                                       line_valid_num = 0;
+
+                               }
+                               i = i + 4;
+                               if (br_number < 2) {
+                                       br_number++;
+                               }
+                       }
+                       i++;
+                       j++;
+               }else {
+                       i++;
+               }
+    }
+    CALC_FUN_END();
+}
+
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @param    str
+* @return    void
+* @exception
+*/
+static void _calc_entry_text_set(Evas_Object * entry, const char *str)
+{
+       CALC_FUN_BEG();
+       char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
+       char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
+       char new_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
+       char old_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
+
+       if (str == NULL) {
+               return;
+       }
+
+       if (strlen(str) == 0) {
+               elm_entry_entry_set(entry, "");
+               elm_entry_cursor_end_set(entry);
+               elm_object_focus_set(entry, EINA_TRUE);
+               CALC_FUN_END();
+               return;
+       }
+       calc_expr_format_expression(str, tmp);
+       _calc_add_tag(tmp, tag_text);
+       int pre_fontsize = cur_fontsize;
+       _calc_add_br(tag_text);
+       snprintf(old_font_str, sizeof(old_font_str), "=%d", pre_fontsize);
+       snprintf(new_font_str, sizeof(new_font_str), "=%d", cur_fontsize);
+       string_replace(tag_text, old_font_str, new_font_str);
+       elm_entry_entry_set(entry, tag_text);
+       if(calculator_cursor_pos == strlen(calculator_input_str)){
+               elm_entry_cursor_end_set(entry);
+               elm_object_focus_set(entry, EINA_TRUE);
+       }else {
+               calc_view_cursor_set_position(entry, calculator_cursor_pos);
+       }
+       CALC_FUN_END();
+}
+
+void _calc_entry_text_set_rotate(struct appdata *ad)
+{
+    CALC_FUN_BEG();
+       if (calculator_state == CALCULATOR_CALCULATED) {
+               _calc_view_show_newest_histroy(ad->input_entry);
+               elm_entry_cursor_end_set(ad->input_entry);
+               elm_object_focus_set(ad->input_entry, EINA_TRUE);
+       } else {
+               _calc_entry_text_set(ad->input_entry, calculator_input_str);
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @param    str
+* @return    void
+* @exception
+*/
+static void _calc_entry_text_insert(Evas_Object * entry, char *str)
+{
+       CALC_FUN_BEG();
+       calc_expr_input_insert(calculator_input_str, &calculator_cursor_pos,
+                              str);
+       _calc_entry_text_set(entry, calculator_input_str);
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @param    from_pos
+* @param    end_pos
+* @return    void
+* @exception
+*/
+static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
+                                   const int end_pos)
+{
+       CALC_FUN_BEG();
+       string_remove_at(calculator_input_str, from_pos,
+                        end_pos - from_pos + 1);
+       calculator_cursor_pos = from_pos;
+       _calc_entry_text_set(entry, calculator_input_str);
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*       Set correct cursor position in entry.
+*
+* @param    entry
+* @return    void
+* @exception
+*/
+static void _calc_entry_cursor_set(Evas_Object * entry)
+{
+       CALC_FUN_BEG();
+       calc_view_cursor_set_position(entry, calculator_cursor_pos);
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @return    void
+* @exception
+*/
+static void _calc_entry_backspace(Evas_Object * entry)
+{
+       CALC_FUN_BEG();
+       calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
+       _calc_entry_text_set(entry, calculator_input_str);
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @return    void
+* @exception
+*/
+void _calc_entry_clear(Evas_Object * entry)
+{
+       CALC_FUN_BEG();
+       memset(calculator_input_str, 0, sizeof(calculator_input_str));
+       calculator_cursor_pos = 0;
+       _calc_entry_text_set(entry, "");
+       calc_view_cursor_set_position(entry, calculator_cursor_pos);
+       CALC_FUN_END();
+}
+
+/* END INPUT ENTRY RELATED */
+
+/**
+* @describe
+* Get the operand start and end location where the cursor in.
+* 1.2+6.|43 (cursor is before 4), then return begin=4 end=7
+* Espcially, cursor is after +, it means the operand which follows
+* the operator, so it return the same result as before.
+* This is add by on 2012/5/29
+*
+* @param[in]   text    The current calculator input string
+* @param[out]  begin   The start location of an operand
+* @param[out]  end     The end location of an operand
+* @return              Is cursor in an operand
+* @retval      true    The cursor is in the operand
+* @retval      false   The cursor is not in the operand
+* @exception
+*/
+static bool
+__calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
+                                             int *begin, int *end)
+{
+       CALC_FUN_BEG();
+       if (text == NULL) {
+               return false;
+       }
+       int pos = cur_pos - 1;
+       if (pos < 0) {
+               pos = 0;
+       }
+       int _begin = 0;
+       int _end = 0;
+
+       if ('p' == text[pos] || 'e' == text[pos]) {
+               *begin = pos;
+               *end = pos;
+               return true;
+       } else if (CALCULATOR_IS_DIGIT_DOT(text[pos], decimal_ch)) {
+               for (_begin = pos - 1;
+                    CALCULATOR_IS_DIGIT_DOT(text[_begin], decimal_ch)
+                    && _begin >= 0; --_begin) {
+                       ;       /* NULL */
+               }
+               _begin++;
+               if (_begin > 1 && '-' == text[_begin - 1]
+                   && '(' == text[_begin - 2]) {
+                       _begin--;
+               }
+               for (_end = pos + 1;
+                    CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
+                    && _end < strlen(text); ++_end) {
+                       ;       /* NULL */
+               }
+               _end--;
+
+               *begin = _begin;
+               *end = _end;
+               return true;
+       } else if (CALCULATOR_CHAR_IS_OPERATOR(text[pos]) || text[pos] == '(') {
+               for (_end = pos + 1;
+                    CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
+                    && _end < strlen(text); ++_end) {
+                       ;       /* NULL */
+               }
+               _end--;
+               *begin = pos+1;
+               *end = _end;
+               return true;
+       } else {
+               return false;
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+* Get the operand start and end location where the cursor in the operand
+* Actually, it would call "__calculator_get_float_num_in_cursor_position"
+* function to recognize whether the cursor is in the operand.
+*
+* @param[in]   entry_text      The current calcualtor input string
+* @param[out]  str     The operand which the cursor in
+* @param[out]  from    The operand start location which contain the cursor
+* @param[out]  end     The operand end location which contain the cursor
+* @return              Is cursor in an operand
+* @retval      true    The cursor is in the operand
+* @retval      false   The cursor is not in the operand
+* @exception
+*/
+static bool
+__calculator_get_cursor_position_float_string(char *entry_text, char *str,
+                                             int cur_pos, int *from, int *end)
+{
+       CALC_FUN_BEG();
+       if (entry_text == NULL) {
+               return false;
+       }
+       int from_pos = cur_pos;
+       int end_pos = cur_pos;
+
+       if (false ==
+           __calculator_get_float_num_in_cursor_position(entry_text, cur_pos,
+                                                         &from_pos,
+                                                         &end_pos)) {
+               return false;
+       }
+
+       /* set from&end position */
+       if (from != NULL) {
+               *from = from_pos;
+       }
+       if (end != NULL) {
+               *end = end_pos;
+       }
+
+       strncpy(str, entry_text + from_pos, end_pos - from_pos + 1);
+       str[end_pos - from_pos + 1] = '\0';
+       CALC_FUN_END();
+       return true;
+}
+
+/**
+* @describe
+*   Get the float number in current cursor
+*
+* @param    entry_text
+* @param    str
+* @return    void
+* @exception
+*/
+static bool
+__calculator_get_before_cursor_float_string(char *entry_text, char *str)
+{
+       CALC_FUN_BEG();
+
+       int from_pos = calculator_cursor_pos;
+       int end_pos = calculator_cursor_pos;
+
+       if (false ==
+           __calculator_get_float_num_in_cursor_position(entry_text,
+                                                         calculator_cursor_pos,
+                                                         &from_pos,
+                                                         &end_pos)) {
+               return false;
+       }
+       snprintf(str, calculator_cursor_pos - from_pos + 1, "%s",
+                entry_text + from_pos);
+       CALC_FUN_END();
+       return true;
+}
+
+/**
+* @describe
+*   Get string before cursor in the Entry.
+*
+* @param    entry_text
+* @param    str
+* @return    void
+* @exception
+*/
+static void
+__calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
+{
+       CALC_FUN_BEG();
+
+       if (calculator_cursor_pos > 0) {
+               strncpy(str, entry_text, calculator_cursor_pos);
+               str[calculator_cursor_pos] = '\0';
+       } else {
+               strcpy(str, "");
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+* judge the type of current input
+*
+* @param    input
+* @return    void
+* @exception
+*/
+static last_char_t __calculator_string_get_char_type( char ch_in)
+{
+       CALC_FUN_BEG();
+       if (ch_in == '\0') {
+               return CHAR_IS_NULL;
+       }
+       if (ch_in == 'p') {
+               return CHAR_IS_PI;
+       }
+       if (ch_in == 'e') {
+               return CHAR_IS_E;
+       }
+       if (CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(ch_in)) {
+               return CHAR_IS_MULTIPLY_DIVIDE;
+       }
+       if (ch_in == '(') {
+               return CHAR_IS_LEFT_PARENTHESE;
+       }
+       if (ch_in == ')') {
+               return CHAR_IS_RIGHT_PARENTHESE;
+       }
+       if (CALCULATOR_CHAR_IS_DIGITAL(ch_in)) {
+               return CHAR_IS_DIGIT;
+       }
+       if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(ch_in) ){
+               return CHAR_IS_PLUS_MINUS;
+       }
+       if (ch_in == decimal_ch) {
+               return CHAR_IS_POINT;
+       }
+       return CHAR_IS_CHARACTER;
+       CALC_FUN_END();
+}
+
+static bool  __calculator_string_digit_in(const char *input)
+{
+       int i =0;
+       while(input[i]!='\0'){
+               if(IS_DIGITAL(input[i])){/*here ,digit include "p" and "e"*/
+                       return TRUE;
+               }else{
+                       i++;
+               }
+       }
+        return FALSE;
+}
+
+/*
+* search charactor in input string, if have charactor, return True and index of first charactor;
+* else return False;
+*/
+static bool __calculator_string_char_search(const char *input, int *index)
+{
+       CALC_FUN_BEG();
+       int len_cp = strlen(input);
+       if(len_cp <= 0){
+               return FALSE;
+       }
+       int i = 0;
+       for(; i < len_cp ; i++){
+               last_char_t cur_char_type = __calculator_string_get_char_type(input[i]);
+               if (CHAR_IS_CHARACTER == cur_char_type) {
+                       *index  = i;
+                       return TRUE;
+               }
+       }
+       return FALSE;
+       CALC_FUN_END();
+}
+
+/*
+* search invalid charactor in input string, if have invalid charactor, return True and index of first invalid charactor;
+* else return False;
+*/
+static bool __calculator_string_invalid_char_search(char *input, int *index)
+{
+       int sub_index = 0;
+       char *p = input;
+       bool char_in = FALSE;
+       int len = 0;
+       char_in = __calculator_string_char_search(p, &sub_index);
+       if(!char_in){/*no charactor*/
+               return FALSE;
+       }
+       while(p){
+               /* charactor  present*/
+               *index += sub_index;
+               p += sub_index;
+               if(!__calculator_search_function(p, &len)){/*charactor not a function*/
+               return TRUE;
+               }else{/*the first sevaral charactors are function, continue search*/
+                       *index += len;
+                       p += len;
+               }
+       }
+       return FALSE;
+}
+/**
+* @describe
+*
+*
+* @param    entry
+* @param    op_item
+* @return    void
+* @exception
+*/
+static void
+__calculator_control_panel_number_button_clicked(Evas_Object * entry,
+                                                op_item_t * op_item)
+{
+       CALC_FUN_BEG();
+
+       /* replace special characters */
+       char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
+       snprintf(entry_text, sizeof(entry_text), "%s", calculator_input_str);
+
+       //Current state is calculated, clear all
+       if (calculator_state == CALCULATOR_CALCULATED) {
+               edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
+               _calc_entry_clear(entry);
+               _calc_entry_text_insert(entry, op_item->op_sym);
+               calculator_state = CALCULATOR_OPERAND_INPUT;
+               return;
+       }
+
+       char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
+       char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
+       int before_len = 0;
+       int nDigitCnt = 0;
+       int nPointCnt = 0;
+       __calculator_get_cursor_position_float_string(entry_text, str_buf,
+                                                     calculator_cursor_pos,
+                                                     NULL, NULL);
+       __calculator_get_input_from_begin_to_cursor(entry_text, before_cursor);
+       before_len = strlen(before_cursor);
+       calculator_get_digits_number(str_buf, &nDigitCnt, &nPointCnt);
+
+       char str_bufa[MAX_EXPRESSION_LENGTH] = { 0 };
+       __calculator_get_before_cursor_float_string(entry_text, str_bufa);
+       if (strcmp(str_bufa, "0") == 0) {
+               _calc_entry_backspace(entry);
+       }
+
+       if (strlen(str_buf) >= MAX_NUM_LENGTH) {
+               __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
+               return;
+       } else if (nPointCnt >= MAX_DECIMAL_NUM
+                  && calculator_cursor_pos > nDigitCnt) {
+               __calculator_wrong_format_create(CALC_MSG_MAX_DEC_DIGIT);
+               return;
+       } else if (before_len > 0
+                  && (__calculator_string_get_char_type(before_cursor[before_len - 1]) ==
+                  CHAR_IS_PI
+                  || __calculator_string_get_char_type(before_cursor[before_len - 1]) ==
+                  CHAR_IS_E)) {
+               /* input digital after "e" or "p", the "x" opeartor will be added automatically */
+               _calc_entry_text_insert(entry, "x");
+               _calc_entry_text_insert(entry, op_item->op_sym);
+               calculator_state = CALCULATOR_OPERAND_INPUT;
+               return;
+       } else if (before_len > 0
+                  && ((before_cursor[before_len - 1] == '(')
+                      ||
+                      CALCULATOR_CHAR_IS_DIGITAL(before_cursor[before_len - 1])
+                      || CALCULATOR_CHAR_IS_OPERATOR(before_cursor[before_len - 1]) || (int)before_cursor[before_len - 1] > 120))      //* or/
+       {
+               _calc_entry_text_insert(entry, op_item->op_sym);
+               calculator_state = CALCULATOR_OPERAND_INPUT;
+               return;
+       } else if (before_len > 0 && (before_cursor[before_len - 1] == ')')) {
+               __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+               return;
+       } else {
+               _calc_entry_text_insert(entry, op_item->op_sym);
+               calculator_state = CALCULATOR_OPERAND_INPUT;
+               return;
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+* Deal the event when dot clicked on the keyboard
+*
+* @param[in]   entry   The input entry
+* @return              void
+* @exception
+*/
+static void _calc_btn_dot_clicked(Evas_Object *entry)
+{
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
+       char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
+       int str_num_len = 0;
+
+       char decimal_str[32] = { 0 };
+
+       /* replace special characters */
+       char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
+       strncpy(entry_text, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
+
+       if (calculator_state == CALCULATOR_CALCULATED) {
+               _calc_entry_clear(entry);
+               memset(entry_text,0x00,sizeof(entry_text));
+       }
+
+       int from_pos = 0;
+       int end_pos = 0;
+       if (!__calculator_get_cursor_position_float_string
+           (entry_text, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
+               if (calculator_cursor_pos == 0
+                   || IS_OPERATOER(calculator_input_str[from_pos - 1])
+                       || calculator_input_str[from_pos - 1] == '(') {
+                       snprintf(decimal_str, sizeof(decimal_str), "0%c",
+                                decimal_ch);
+                       _calc_entry_text_insert(entry, decimal_str);
+                       calculator_state = CALCULATOR_OPERAND_INPUT;
+                       return;
+               }
+               return;
+       } else {
+               if (strcmp(str_num, "p") == 0 || strcmp(str_num, "e") == 0) {
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                       return;
+               }
+       }
+
+       str_num_len = strlen(str_num);
+       if (str_num_len > 0 && str_num[str_num_len - 1] == decimal_ch) {
+               return;
+       }
+
+       int nDigitCnt = 0;
+       int nPointCnt = 0;
+       calculator_get_digits_number(str_num, &nDigitCnt, &nPointCnt);
+
+       if (nDigitCnt >= 15) {
+               __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
+               return;
+       }
+
+       if (nPointCnt > 0) {
+               return;
+       }
+       if (IS_OPERATOER(calculator_input_str[calculator_cursor_pos-1])
+               || calculator_input_str[calculator_cursor_pos-1] == '(') {
+               snprintf(decimal_str, sizeof(decimal_str), "0%c", decimal_ch);
+       } else {
+               snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
+       }
+       _calc_entry_text_insert(entry, decimal_str);
+       calculator_state = CALCULATOR_OPERAND_INPUT;
+       CALC_FUN_END();
+       return;
+}
+
+/**
+* @describe
+*
+*
+* @param        entry
+* @return       void
+* @exception
+*/
+static void _calc_btn_backspace_clicked(Evas_Object * entry)
+{
+       CALC_FUN_BEG();
+
+       if (calculator_state == CALCULATOR_CALCULATED) {
+               calculator_state = CALCULATOR_OPERATOR_INPUT;
+               if (calculator_cursor_pos > strlen(calculator_input_str)) {
+                       calculator_cursor_pos = strlen(calculator_input_str);   /* set last position */
+               }
+       }
+       _calc_entry_backspace(entry);
+       CALC_FUN_END();
+}
+
+static int __calculator_delete_long_press(void *data)
+{
+       CALC_FUN_BEG();
+       Evas_Object *entry = (Evas_Object *) data;
+       _calc_btn_backspace_clicked(entry);
+       CALC_FUN_END();
+       return 1;
+}
+
+/**
+* @describe
+*   Process +.-.*.\ these four buttons clicked.
+*
+* @param        entry
+* @param        op_item
+* @return       void
+* @exception
+*/
+static void
+__calculator_control_normal_func_clicked(Evas_Object * entry,
+                                        op_item_t * op_item)
+{
+       CALC_FUN_BEG();
+       char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
+       strncpy(all_input, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
+
+       if (calculator_state == CALCULATOR_CALCULATED) {
+               edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
+               char temp[20] = { 0 };
+
+               calc_expr_num_format_result(last_result, temp);
+               _calc_entry_clear(entry);
+
+               if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or sicience number
+               {
+                       _calc_entry_text_insert(entry, "(");
+                       _calc_entry_text_insert(entry, temp);
+                       _calc_entry_text_insert(entry, ")");
+               } else {
+                       _calc_entry_text_insert(entry, temp);
+               }
+
+               _calc_entry_text_insert(entry, op_item->op_sym);
+               calculator_state = CALCULATOR_OPERATOR_INPUT;
+               return;
+
+       }
+    if(!strcmp(op_item->op_sym, "x")||!strcmp(op_item->op_sym, "/")
+               ||!strcmp(op_item->op_sym, "+")){
+               if(!__calculator_string_digit_in(calculator_input_str)){ return; }
+       }
+       int nCntOp = calc_expr_get_operator_num(all_input);
+       if (nCntOp >= MAX_OPERATOR_NUM) {       /* Can't exceed 20 operators */
+               __calculator_wrong_format_create(CALC_MSG_MAX_OP);
+               return;
+       }
+
+       char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
+       int input_len = 0;
+
+       __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
+       input_len = strlen(before_cursor);
+
+       if (input_len > 0) {
+               if (before_cursor[input_len - 1] == '('
+                   && !strcmp(op_item->op_sym, "-")) {
+                       _calc_entry_text_insert(entry, op_item->op_sym);
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+               } else if (((input_len > 1) && (before_cursor[input_len - 1] == '-') && (before_cursor[input_len - 2] == '('))  //(-
+                          || /*before_cursor[input_len - 1] == decimal_ch ||*/ before_cursor[input_len - 1] == '(')    // . or (
+               {
+
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                       return;
+               } else if (IS_OPERATOER(before_cursor[input_len - 1])) {
+                       if ((input_len > 1 || !strcmp(op_item->op_sym, "-"))
+                           || input_len == 1) {
+                               _calc_entry_backspace(entry);
+                               _calc_entry_text_insert(entry, op_item->op_sym);
+                               calculator_state = CALCULATOR_OPERATOR_INPUT;
+                       } else {
+                               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                       }
+                       return;
+               } else if (before_cursor[input_len - 1] == ')') //
+               {
+                       _calc_entry_text_insert(entry, op_item->op_sym);
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+                       return;
+               } else {
+                       if (!IS_DIGITAL(before_cursor[input_len - 1])
+                                       && (before_cursor[input_len - 1] != decimal_ch)) {
+                               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                               return;
+                       } else {
+                               _calc_entry_text_insert(entry, op_item->op_sym);
+                               calculator_state = CALCULATOR_OPERATOR_INPUT;
+                               return;
+                       }
+               }
+       } else {                /* before_cursor si empty */
+
+               _calc_entry_text_insert(entry, op_item->op_sym);
+               calculator_state = CALCULATOR_OPERATOR_INPUT;
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param    entry
+* @return    void
+* @exception
+*/
+static void __calculator_symbol_negative_clicked(Evas_Object * entry)
+{
+       CALC_FUN_BEG();
+
+       char result[MAX_RESULT_LENGTH] = { 0 };
+
+       if (calculator_state == CALCULATOR_CALCULATED) {
+               edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
+
+               calc_expr_num_format_result(last_result, result);
+               if (last_result < 0) {
+                       string_remove_at(result, 0, 1); //remove '-'
+               } else {
+                       string_insert(result, 0, "(-"); // add (-xxx)
+                       string_insert(result, strlen(result), ")");
+               }
+
+               _calc_entry_clear(entry);
+               _calc_entry_text_insert(entry, result);
+
+               calculator_state = CALCULATOR_OPERAND_INPUT;
+               //use_last_result = 1;
+
+               return;
+       }
+
+       int cursor = calculator_cursor_pos;
+       int begin = 0, length = 0;
+       char expr[MAX_EXPRESSION_LENGTH] = { 0 };
+       strncpy(expr, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
+       int flag = 0;
+       cursor -= 1;
+       if (expr[cursor] == ')') {
+               cursor -= 1;
+               flag = 1;       /* before current cursor is ')' */
+       }
+
+       if (0 ==
+           calc_expr_get_current_num_at_cursor(expr, cursor, &begin,
+                                               &length)) {
+               if (expr[begin] == '-') {
+                       if (begin > 0 && expr[begin - 1] == '('
+                           && expr[begin + length] == ')') {
+                               string_remove_at(expr, begin + length, 1);      //remove ')'
+                               string_remove_at(expr, begin - 1, 2);   // remove '(-'
+                               calculator_cursor_pos -= flag ? 3 : 2;
+                       } else {
+                               string_remove_at(expr, begin, 1);
+                               calculator_cursor_pos -= 1;
+                       }
+
+               } else {
+                       if (flag == 1)  //not '(-xxx)' but has ')'
+                       {
+                               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                               return;
+                       } else {
+                               string_insert(expr, begin + length, ")");
+                               string_insert(expr, begin, "(-");
+                               calculator_cursor_pos +=
+                                   (((begin + length) ==
+                                     calculator_cursor_pos) ? 3 : 2);
+                       }
+               }
+               strncpy(calculator_input_str, expr, MAX_EXPRESSION_LENGTH - 1);
+
+               _calc_entry_text_set(entry, calculator_input_str);
+               _calc_entry_cursor_set(entry);
+
+               calculator_state = CALCULATOR_OPERAND_INPUT;
+
+       } else {
+               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+       }
+       CALC_FUN_END();
+}
+
+/* search the previous operator and value */
+static char * __calculator_search_prev_input(char *input_str)
+{
+       CALC_FUN_BEG();
+       int i = 0;
+       int bracket_number = 0;
+       char *prev_input = NULL;
+       for(; i< strlen(input_str); i++) {
+               if ('(' ==(input_str[i]) ){
+                       bracket_number++;
+               }
+               if( ')' == input_str[i]){
+                       bracket_number --;
+               }
+               if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
+                       || CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) {
+                       if ( !bracket_number){
+                               prev_input = &input_str[i];
+                               return prev_input;
+                       }
+               }
+       }
+       CALC_FUN_BEG();
+       return prev_input;
+}
+
+/**
+* @describe
+* Deal the event when "=" clicked on the keyboard
+*
+* @param[in]   entry   The input entry
+* @return              void
+* @exception
+*/
+static void __calculator_op_equal(Evas_Object *entry)
+{
+       CALC_FUN_BEG();
+       if (entry == NULL) {
+               return;
+       }
+       if (calculator_state == CALCULATOR_CALCULATED) {
+               /*duplicate previous input operator and value*/
+               char *p = __calculator_search_prev_input(calculator_input_str);
+               if (p == NULL) {
+                       return;
+               }
+               char prev_input[32] = { 0 };
+               int len = g_strlcpy(prev_input, p, sizeof(prev_input));
+               if (len >= sizeof(prev_input)) {
+                       return;
+               }
+               char temp[32] = { 0 };
+               calc_expr_num_format_result(last_result, temp);
+               _calc_entry_clear(entry);
+
+               if (temp[0] == '-' || strchr(temp, 'E')) {
+                       _calc_entry_text_insert(entry, "(");
+                       _calc_entry_text_insert(entry, temp);
+                       _calc_entry_text_insert(entry, ")");
+               } else {
+                       _calc_entry_text_insert(entry, temp);
+               }
+               _calc_entry_text_insert(entry, prev_input);
+               calculator_state = CALCULATOR_OPERATOR_INPUT;
+       }
+
+       double result = 0;
+       char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
+       char result_buf[MAX_RESULT_LENGTH] = { 0 };
+       char result_format[MAX_RESULT_LENGTH] = { 0 };
+       int str_len = 0;
+       char error_msg[MAX_ERROR_MESSAGE_LENGTH] = { 0 };
+       calc_expr_close_parentheses(calculator_input_str);
+       _calc_entry_text_set(entry, calculator_input_str);
+       snprintf(str_buf, sizeof(str_buf), "%s", calculator_input_str);
+       str_len = strlen(str_buf);
+       if (str_len == 0) {
+               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+               return;
+       }
+
+       if (!calculator_calculate(str_buf, &result, error_msg)) {
+               __calculator_wrong_format_create(error_msg);
+               calculator_state = CALCULATOR_ERROR_OCCURED;
+               return;
+       } else {
+               last_result = result;
+               memset(result_buf, 0, CALCULATOR_CONTENT_LEN + 1);
+               calc_expr_num_format_result(result, result_buf);
+               /* save result */
+
+               struct history_item item;
+               memset(item.expression, 0, sizeof(item.expression));
+               memset(result_format, 0, sizeof(result_format));
+               calc_expr_format_expression(calculator_input_str,
+                                           item.expression);
+               item.result = result;
+               calc_expr_format_expression(result_buf, result_format);
+               if (result_buf[0] == '-') {
+                       string_replace(result_format, "\xe2\x88\x92", "-");
+               }
+#ifdef SAVE_HISTORY
+               calc_view_save_history(item);
+#endif
+               /* show result */
+               calculator_state = CALCULATOR_CALCULATED;
+               calc_view_show_result(result_format, ad);
+
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*
+*
+* @param        entry
+* @return       void
+* @exception    none
+*/
+static void __calculator_parenthesis_clicked(Evas_Object * entry)
+{
+       CALC_FUN_BEG();
+       char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
+       snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
+       if (calculator_state == CALCULATOR_CALCULATED) {
+               edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
+
+               char temp[MAX_RESULT_LENGTH] = { 0 };
+
+               calc_expr_num_format_result(last_result, temp);
+               _calc_entry_clear(entry);
+
+               if (temp[0] == '-' || strchr(temp, 'E') != NULL)        //result < 0 or science number
+               {
+                       _calc_entry_text_insert(entry, "((");
+                       _calc_entry_text_insert(entry, temp);
+                       _calc_entry_text_insert(entry, ")");
+               } else {
+                       _calc_entry_text_insert(entry, "(");
+                       _calc_entry_text_insert(entry, temp);
+               }
+               calculator_state = CALCULATOR_OPERATOR_INPUT;
+               return;
+       }
+       char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
+       int input_len = 0;
+       __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
+       input_len = strlen(before_cursor);
+
+       if (input_len == 0) {
+               _calc_entry_text_insert(entry, "(");
+               calculator_state = CALCULATOR_OPERATOR_INPUT;
+               return;
+       }
+       int bracket_num = calculator_get_open_braket(all_input);
+       if (input_len > 0) {
+               if (before_cursor[input_len - 1] == decimal_ch) {
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                       return;
+               } else if (bracket_num > 0      //'(' is more than ')'
+                          && before_cursor[input_len - 1] != '('
+                          && (before_cursor[input_len - 1] == ')'
+                              || isdigit(before_cursor[input_len - 1])
+                              ||
+                              (__calculator_string_get_char_type
+                               (before_cursor[input_len - 1]) == CHAR_IS_PI
+                               ||
+                               __calculator_string_get_char_type
+                               (before_cursor[input_len - 1]) == CHAR_IS_E))) {
+                       _calc_entry_text_insert(entry, ")");
+                       return;
+               } else if (bracket_num == 0) {
+                       if (calc_expr_get_left_parentheses_num
+                           (calculator_input_str) < MAX_PARENTHESES_NUM) {
+                               _calc_entry_text_insert(entry, "(");
+                       }
+                       return;
+               } else if (before_cursor[input_len - 1] != ')') //'(' is less than ')'!isdigit(before_cursor[input_len-1])&&(
+               {
+                       if (calc_expr_get_left_parentheses_num
+                           (calculator_input_str) < MAX_PARENTHESES_NUM) {
+                               _calc_entry_text_insert(entry, "(");
+                       }
+                       return;
+               }
+       }
+       CALC_FUN_END();
+       return;
+}
+
+/**
+* @describe
+*
+*
+* @param        entry
+* @param        op_item
+* @return       void
+* @exception
+*/
+static void
+__calculator_control_functions_button_clicked(Evas_Object * entry,
+                                             op_item_t * op_item)
+{
+       CALC_FUN_BEG();
+
+       char *str = NULL;
+       function_t function = { 0 };
+
+       memset(&function, 0x0, sizeof(function_t));
+       str = op_item->op_name;
+
+       char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
+       int input_len = 0;
+       char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
+       int before_len = 0;
+       last_char_t last_char_type = 0;
+
+       snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
+       __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
+       input_len = strlen(all_input);
+       before_len = strlen(before_cursor);
+       if(before_len > 0){
+               last_char_type = __calculator_string_get_char_type(before_cursor[before_len - 1]);
+       }
+
+       switch (op_item->op_id) {
+       case OP_PERCENT:
+               /* if it is calculated state */
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+
+                       char temp[CALCULATOR_CONTENT_LEN] = { 0 };
+                       double per_result = last_result / 100.0;
+
+                       calc_expr_num_format_result(per_result, temp);
+                       _calc_entry_clear(entry);
+
+                       if (strcmp(temp, "0") == 0) {
+                               _calc_entry_text_insert(entry, "0");
+                       } else if (temp[0] == '-')      //result < 0
+                       {
+                               _calc_entry_text_insert(entry, "(");
+                               _calc_entry_text_insert(entry, temp);
+                               _calc_entry_text_insert(entry, ")");
+                       } else {
+                               _calc_entry_text_insert(entry, temp);
+                       }
+                       calculator_state = CALCULATOR_OPERAND_INPUT;
+                       return;
+               }
+
+               {
+                       int from_pos, end_pos;
+                       char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
+                       char temp[CALCULATOR_CONTENT_LEN] = { 0 };
+                       double per_result = 0.0;
+
+                       if (false ==
+                           __calculator_get_cursor_position_float_string
+                           (all_input, str_num, calculator_cursor_pos,
+                            &from_pos, &end_pos)) {
+                               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                               return;
+                       }
+
+                       {
+                               if (strlen(str_num) == 0) {
+                                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                                       return;
+                               }
+
+                               if (strcmp(str_num, "0") == 0) {
+                                       return;
+                               }
+
+                               per_result = atof(str_num);
+                               per_result /= 100.0;
+
+                               calc_expr_num_format_result(per_result, temp);
+
+                               _calc_entry_text_remove(entry, from_pos,
+                                                       end_pos);
+                               _calc_entry_text_insert(entry, temp);
+
+                               calculator_state = CALCULATOR_OPERAND_INPUT;
+                               return;
+                       }
+               }
+               break;
+       case OP_PI:
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+                       _calc_entry_clear(entry);
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       break;
+               }
+               if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
+                   && (!IS_OPERATOER(before_cursor[before_len - 1]))
+                   && (before_cursor[before_len - 1] != '(')
+                   && (before_cursor[before_len - 1] != 'P')
+                   && before_cursor[before_len - 1] != 'C') {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+               /* input digital after "p", the "x" opeartor will be added automatically */
+               if(IS_DIGITAL(before_cursor[before_len - 1])){
+                       _calc_entry_text_insert(entry, "x");
+               }
+               _calc_entry_text_insert(entry, op_item->op_name);
+               break;
+
+       case OP_E:
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+                       _calc_entry_clear(entry);
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       break;
+               }
+               if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
+                   && (!IS_OPERATOER(before_cursor[before_len - 1]))
+                   && (before_cursor[before_len - 1] != '(')
+                   && (before_cursor[before_len - 1] != 'P')
+                   && before_cursor[before_len - 1] != 'C') {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+               /* input digital after "e", the "x" opeartor will be added automatically */
+               if(IS_DIGITAL(before_cursor[before_len - 1])){
+                       _calc_entry_text_insert(entry, "x");
+               }
+               _calc_entry_text_insert(entry, op_item->op_name);
+               break;
+
+       case OP_SIN:            //sin()
+       case OP_COS:            //cos()
+       case OP_TAN:            //tan()
+       case OP_LOG:            //log()
+       case OP_ABS:            //abs()
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+
+                       _calc_entry_clear(entry);
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       break;
+               }
+               if (last_char_type == CHAR_IS_PI || last_char_type == CHAR_IS_E) {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+
+               _calc_entry_text_insert(entry, op_item->op_name);
+               break;
+
+       case OP_LN:             //ln()
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+                       _calc_entry_clear(entry);
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       break;
+               }
+               if (last_char_type == CHAR_IS_PI) {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+               if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
+                   && (before_cursor[before_len - 1] != '-')
+                   && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
+                   && (before_cursor[before_len - 1] != '^')
+                   && (before_cursor[before_len - 1] != '(')
+                   && (before_cursor[before_len - 1] != 'C')
+                   && (before_cursor[before_len - 1] != 'P')) {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+               _calc_entry_text_insert(entry, op_item->op_name);
+               break;
+
+       case OP_ROOT:           //sqrt()
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+
+                       _calc_entry_clear(entry);
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       break;
+               }
+               if (last_char_type == CHAR_IS_PI) {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+               if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
+                   && (before_cursor[before_len - 1] != '-')
+                   && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
+                   && (before_cursor[before_len - 1] != '^')
+                   && (before_cursor[before_len - 1] != '(')
+                   && (before_cursor[before_len - 1] != 'C')
+                   && (before_cursor[before_len - 1] != 'P')) {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+               _calc_entry_text_insert(entry, op_item->op_name);
+               break;
+
+       case OP_10X:            //10^
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+                       _calc_entry_clear(entry);
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       break;
+               }
+               if (last_char_type == CHAR_IS_PI) {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+               if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
+                   && (before_cursor[before_len - 1] != '-')
+                   && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
+                   && (before_cursor[before_len - 1] != '^')
+                   && (before_cursor[before_len - 1] != '(')
+                   && (before_cursor[before_len - 1] != 'C')
+                   && (before_cursor[before_len - 1] != 'P')) {
+                       __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
+                       break;
+               }
+               _calc_entry_text_insert(entry, op_item->op_name);
+               break;
+
+       case OP_X2:             //x^2
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+
+                       char temp[CALCULATOR_CONTENT_LEN] = { 0 };
+                       calc_expr_num_format_result(last_result, temp);
+                       _calc_entry_clear(entry);
+
+                       if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or science number
+                       {
+                               _calc_entry_text_insert(entry, "(");
+                               _calc_entry_text_insert(entry, temp);
+                               _calc_entry_text_insert(entry, ")");
+                       } else {
+                               _calc_entry_text_insert(entry, temp);
+                       }
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       calculator_state = CALCULATOR_OPERAND_INPUT;
+                       //use_last_result = 1;
+                       return;
+               }
+
+               if (input_len == 0) {
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
+                       break;
+               }
+               if (last_char_type == CHAR_IS_PI) {
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       calculator_state = CALCULATOR_OPERAND_INPUT;
+                       break;
+               } else if ((before_len > 0)
+                          && (!isdigit(before_cursor[before_len - 1]))
+                          && (before_cursor[before_len - 1] != ')')) {
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
+                       break;
+               }
+               _calc_entry_text_insert(entry, op_item->op_name);
+               calculator_state = CALCULATOR_OPERAND_INPUT;
+               break;
+       case OP_XY:             //x^y
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+
+                       char temp[CALCULATOR_CONTENT_LEN] = { 0 };
+
+                       calc_expr_num_format_result(last_result, temp);
+                       _calc_entry_clear(entry);
+
+                       if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or science number
+                       {
+                               _calc_entry_text_insert(entry, "(");
+                               _calc_entry_text_insert(entry, temp);
+                               _calc_entry_text_insert(entry, ")");
+                       } else {
+                               _calc_entry_text_insert(entry, temp);
+                       }
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+                       return;
+               }
+
+               if (input_len == 0) {
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
+                       break;
+               }
+               if ((last_char_type == CHAR_IS_PI)
+                   || (last_char_type == CHAR_IS_E)) {
+                       _calc_entry_text_insert(entry, op_item->op_name);
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+                       break;
+               } else if ((before_len > 0)
+                          && !isdigit(before_cursor[before_len - 1])
+                          && (before_cursor[before_len - 1] != ')')) {
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
+                       break;
+               }
+               _calc_entry_text_insert(entry, op_item->op_name);
+               calculator_state = CALCULATOR_OPERATOR_INPUT;
+               break;
+
+       case OP_FACT:           //x!
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+
+                       char temp[MAX_RESULT_LENGTH] = { 0 };
+
+                       calc_expr_num_format_result(last_result, temp);
+
+                       if (strchr(temp, decimal_ch) != NULL || strchr(temp, '-') != NULL)      //revise by bfl
+                       {
+                               __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
+                               calculator_state = CALCULATOR_WAITING_INPUT;    //revise by bfl
+                               return;
+                       }
+
+                       _calc_entry_clear(entry);
+                       _calc_entry_text_insert(entry, "(");
+                       _calc_entry_text_insert(entry, temp);
+                       _calc_entry_text_insert(entry, "!)");
+
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+                       return;
+               }
+
+               if (input_len == 0) {
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_FAC);
+                       break;
+               }
+               if ((last_char_type == CHAR_IS_PI)
+                   || (last_char_type == CHAR_IS_E)) {
+                       __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
+                       break;
+               }
+
+               /* check if it is natural */
+               {
+                       char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
+                       int from_pos = 0, end_pos = 0;
+
+                       if (false ==
+                           __calculator_get_cursor_position_float_string
+                           (all_input, str_buf, calculator_cursor_pos,
+                            &from_pos, &end_pos)) {
+                               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
+                               break;
+                       }
+
+                       if (strchr(str_buf, decimal_ch) != NULL
+                           || str_buf[0] == '-') {
+                               __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
+                               break;
+                       }
+
+                       _calc_entry_text_remove(entry, from_pos, end_pos);
+                       _calc_entry_text_insert(entry, "(");
+                       _calc_entry_text_insert(entry, str_buf);
+                       _calc_entry_text_insert(entry, "!)");
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+               }
+               break;
+       case OP_1X:
+               if (calculator_state == CALCULATOR_CALCULATED) {
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+
+                       char temp[MAX_RESULT_LENGTH] = { 0 };
+                       int i = 0;
+
+                       calc_expr_num_format_result(last_result, temp);
+                       if (strchr(temp, 'E') != NULL)  //science number
+                       {
+                               temp[strlen(temp)] = ')';
+                               for (i = strlen(temp); i > 0; --i) {
+                                       temp[i] = temp[i - 1];
+                               }
+                               temp[0] = '(';
+                       }
+
+                       _calc_entry_clear(entry);
+                       if (temp[0] == '-') {
+                               _calc_entry_text_insert(entry, "(-1");
+                               _calc_entry_text_insert(entry, "/");
+
+                               _calc_entry_text_insert(entry, &temp[1]);
+                               _calc_entry_text_insert(entry, ")");
+                       } else {
+                               _calc_entry_text_insert(entry, "(1");
+                               _calc_entry_text_insert(entry, "/");
+
+                               _calc_entry_text_insert(entry, temp);
+                               _calc_entry_text_insert(entry, ")");
+                       }
+
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+                       //use_last_result = 1;
+                       return;
+               }
+               if (input_len == 0) {
+                       __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
+                       break;
+               }
+
+               /* check if it is digit */
+               {
+                       char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
+                       int from_pos = 0, end_pos = 0;
+
+                       if (false ==
+                           __calculator_get_cursor_position_float_string
+                           (all_input, str_buf, calculator_cursor_pos,
+                            &from_pos, &end_pos)) {
+                               __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
+                               break;
+                       }
+
+                       if (strcmp(str_buf, "p") && strcmp(str_buf, "e")
+                           && atof(str_buf) == 0) {
+                               __calculator_wrong_format_create(CALC_MSG_DIVIDE_BY_ZERO);
+                               break;
+                       }
+
+                       _calc_entry_text_remove(entry, from_pos, end_pos);
+                       if (str_buf[0] == '-') {
+                               _calc_entry_text_insert(entry, "(-1");
+                               _calc_entry_text_insert(entry, "/");
+
+                               _calc_entry_text_insert(entry, &str_buf[1]);
+                               _calc_entry_text_insert(entry, ")");
+                       } else {
+                               _calc_entry_text_insert(entry, "(1");
+                               _calc_entry_text_insert(entry, "/");
+
+                               _calc_entry_text_insert(entry, str_buf);
+                               _calc_entry_text_insert(entry, ")");
+                       }
+
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+               }
+               break;
+
+       default:
+               break;
+       }
+       calculator_state = CALCULATOR_SPECIAL_FUNCTION_INPUT;
+       CALC_FUN_END();
+       return;
+}
+
+/////////////////////////// input text finish ////////////////////////////
+
+/**
+* @describe
+*
+*
+* @param    evas_obj
+* @param    obj
+* @return    void
+* @exception
+*/
+static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
+{
+       CALC_FUN_BEG();
+
+       int val = 0;
+       if (evas_obj == edje_object_part_object_get(obj, "item_brack")) {
+               val = OP_PARENTHESIS;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_del")) {
+               val = OP_DELETE;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_c")) {
+               val = OP_CLEAR;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_div")) {
+               val = OP_DIVIDE;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num7")) {
+               val = OP_NUM_7;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num8")) {
+               val = OP_NUM_8;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num9")) {
+               val = OP_NUM_9;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_mul")) {
+               val = OP_MULTIPLY;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num4")) {
+               val = OP_NUM_4;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num5")) {
+               val = OP_NUM_5;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num6")) {
+               val = OP_NUM_6;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_sub")) {
+               val = OP_MINUS;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num1")) {
+               val = OP_NUM_1;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num2")) {
+               val = OP_NUM_2;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num3")) {
+               val = OP_NUM_3;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_plus")) {
+               val = OP_PLUS;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_dot")) {
+               val = OP_DOT;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_num0")) {
+               val = OP_NUM_0;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_neg")) {
+               val = OP_PLUS_MINUS;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_eq")) {
+               val = OP_EQUAL;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_per")) {
+               val = OP_PERCENT;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_sqr")) {
+               val = OP_ROOT;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_fac")) {
+               val = OP_FACT;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_sin")) {
+               val = OP_SIN;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_cos")) {
+               val = OP_COS;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_tan")) {
+               val = OP_TAN;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_ln")) {
+               val = OP_LN;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_log")) {
+               val = OP_LOG;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_1x")) {
+               val = OP_1X;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_10x")) {
+               val = OP_10X;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_x2")) {
+               val = OP_X2;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_xy")) {
+               val = OP_XY;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_abs")) {
+               val = OP_ABS;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_pi")) {
+               val = OP_PI;
+       } else if (evas_obj == edje_object_part_object_get(obj, "item_e")) {
+               val = OP_E;
+       }
+       CALC_FUN_END();
+       return val;
+}
+
+/////////////////////////// input text finish ////////////////////////////
+
+#ifdef __i386__
+/**
+* @describe
+*
+*
+* @param    evas_obj
+* @param    obj
+* @return    void
+* @exception
+*/
+static int _calculator_get_input_item_hd(const char *keyname, Evas_Object * obj)
+{
+       CALC_FUN_BEG();
+       int val = 0;
+       if (0 == strcmp(keyname, "KP_7")) {
+               val = OP_NUM_7;
+       } else if (0 == strcmp(keyname, "KP_8")) {
+               val = OP_NUM_8;
+       } else if (0 == strcmp(keyname, "KP_9")) {
+               val = OP_NUM_9;
+       } else if (0 == strcmp(keyname, "KP_4")) {
+               val = OP_NUM_4;
+       } else if (0 == strcmp(keyname, "KP_5")) {
+               val = OP_NUM_5;
+       } else if (0 == strcmp(keyname, "KP_6")) {
+               val = OP_NUM_6;
+       } else if (0 == strcmp(keyname, "KP_1")) {
+               val = OP_NUM_1;
+       } else if (0 == strcmp(keyname, "KP_2")) {
+               val = OP_NUM_2;
+       } else if (0 == strcmp(keyname, "KP_3")) {
+               val = OP_NUM_3;
+       } else if (0 == strcmp(keyname, "KP_0")) {
+               val = OP_NUM_0;
+       }else if (0 == strcmp(keyname, "KP_Decimal")) {
+               val = OP_DOT;
+       } else if (0 == strcmp(keyname, "Return")) {
+               val = OP_EQUAL;
+       } else if (0 == strcmp(keyname, "KP_Add")) {
+               val = OP_PLUS;
+       } else if (0 == strcmp(keyname, "KP_Subtract")) {
+               val = OP_MINUS;
+       } else if (0 == strcmp(keyname, "minus")) {
+               val = OP_MINUS;
+       } else if (0 == strcmp(keyname, "KP_Multiply")) {
+               val = OP_MULTIPLY;
+       } else if (0 == strcmp(keyname, "slash")) {
+               val = OP_DIVIDE;
+       } else if (0 == strcmp(keyname, "KP_Divide")) {
+               val = OP_DIVIDE;
+       }else if (0 == strcmp(keyname, "BackSpace")) {
+               val = OP_DELETE;
+       }
+       CALC_FUN_END();
+       return val;
+}
+#endif
+
+/**
+* @description
+*   Interpret all of our different signals, and do things !
+*
+* @param        data
+* @param        e
+* @param        evas_obj
+* @param        event_info
+* @return       void
+* @exception    none
+*/
+static void
+_calculator_interp(void *data, Evas * e, Evas_Object * evas_obj,
+                  void *event_info)
+{
+       CALC_FUN_BEG();
+       int val = 0;
+       if (data) {
+
+               Evas_Object *obj = (Evas_Object *) data;
+               val = _calculator_get_input_item(evas_obj, obj);
+               if (ad->wrong_timer) {
+                       ecore_timer_del(ad->wrong_timer);
+                       ad->wrong_timer = NULL;
+               }
+               switch (val) {
+               case OP_DELETE:
+                       _calc_btn_backspace_clicked(ad->input_entry);
+                       if (ad->calc_timer) {
+                               ecore_timer_del(ad->calc_timer);
+                               ad->calc_timer = NULL;
+                       }
+                       ad->calc_timer =
+                           ecore_timer_add(0.1,
+                                           (Ecore_Task_Cb)
+                                           __calculator_delete_long_press,
+                                           ad->input_entry);
+                       break;
+               case OP_CLEAR:
+                       edje_object_signal_emit(_EDJ(ad->edje), "show,input",
+                                               "");
+                       _calc_entry_clear(ad->input_entry);
+                       calculator_state = CALCULATOR_WAITING_INPUT;
+                       break;
+               case OP_PLUS:
+               case OP_MINUS:
+               case OP_MULTIPLY:
+               case OP_DIVIDE:
+                       __calculator_control_normal_func_clicked(ad->
+                                                                input_entry,
+                                                                &calc_op_item
+                                                                [val]);
+                       break;
+               case OP_DOT:
+                       _calc_btn_dot_clicked(ad->input_entry);
+                       break;
+               case OP_PARENTHESIS:
+                       __calculator_parenthesis_clicked(ad->input_entry);
+                       break;
+               case OP_EQUAL:
+                       __calculator_op_equal(ad->input_entry);
+                       break;
+               case OP_NUM_0:
+               case OP_NUM_1:
+               case OP_NUM_2:
+               case OP_NUM_3:
+               case OP_NUM_4:
+               case OP_NUM_5:
+               case OP_NUM_6:
+               case OP_NUM_7:
+               case OP_NUM_8:
+               case OP_NUM_9:
+                       __calculator_control_panel_number_button_clicked(ad->
+                                                                        input_entry,
+                                                                        &calc_op_item
+                                                                        [val]);
+                       break;
+               case OP_PLUS_MINUS:
+                       __calculator_symbol_negative_clicked(ad->input_entry);
+                       break;
+               case OP_PERCENT...OP_E:
+                       __calculator_control_functions_button_clicked(ad->
+                                                                     input_entry,
+                                                                     &calc_op_item
+                                                                     [val]);
+                       break;
+               default:
+                       break;
+               }
+               if (ad->svi_handle) {
+                       svi_play_sound(ad->svi_handle, SVI_SND_TOUCH_SIP);
+                       svi_play_vib(ad->svi_handle, SVI_VIB_TOUCH_SIP);
+               }
+       }
+
+       CALC_FUN_END();
+}
+
+static void __calculator_wrong_format_delete(Evas_Object *in_entry)
+{
+       _calc_entry_text_set(in_entry, calculator_input_str);
+       if (ad->wrong_timer) {
+               ecore_timer_del(ad->wrong_timer);
+               ad->wrong_timer = NULL;
+       }
+}
+
+static void __calculator_wrong_text_set(char * wrong_string)
+{
+       char buf[MAX_EXPRESSION_LENGTH] = { 0 };
+       memset(buf, 0, sizeof(buf));
+       snprintf(buf, sizeof(buf),
+                "<align=right><+ font_size=%d><color=#855B11FF>%s",
+                cur_fontsize, wrong_string);
+       elm_entry_entry_set(ad->input_entry, buf);
+       elm_entry_cursor_end_set(ad->input_entry);
+       elm_object_focus_set(ad->input_entry, EINA_TRUE);
+       calc_view_revise_input_scroller(ad);
+}
+
+/**
+* @describe
+*
+*
+* @param        msg
+* @return       void
+* @exception    none
+*/
+static void __calculator_wrong_format_create(char * wrong_string)
+{
+       __calculator_wrong_text_set(wrong_string);
+       if (ad->wrong_timer) {
+               ecore_timer_del(ad->wrong_timer);
+               ad->wrong_timer = NULL;
+       }
+       ad->wrong_timer =
+    ecore_timer_add(3,
+                   (Ecore_Task_Cb)
+                   __calculator_wrong_format_delete,
+                   ad->input_entry);
+}
+
+/* mouse up for delete button. */
+static void
+__calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
+                       void *event_info)
+{
+       CALC_FUN_BEG();
+       if (ad->calc_timer) {
+               ecore_timer_del(ad->calc_timer);
+               ad->calc_timer = NULL;
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @describe
+*   Register clicked callback of the keys on the keypad.
+*
+* @param    keypad      the keypad
+* @return   void
+*/
+void _calc_view_keypad_cb_register(Evas_Object * keypad)
+{
+       CALC_FUN_BEG();
+       char *key_name[] = {
+               "item_per", "item_sqr", "item_fac", "item_c", "item_div",
+                   "item_mul", "item_del",
+               "item_sin", "item_cos", "item_tan", "item_num7", "item_num8",
+                   "item_num9", "item_sub",
+               "item_ln", "item_log", "item_1x", "item_num4", "item_num5",
+                   "item_num6", "item_plus",
+               "item_10x", "item_x2", "item_xy", "item_num1", "item_num2",
+                   "item_num3", "item_brack",
+               "item_abs", "item_pi", "item_e", "item_num0", "item_dot",
+                   "item_neg", "item_eq",
+       };
+
+       Evas_Object *item = NULL;
+       int key_num = sizeof(key_name) / sizeof(key_name[0]);
+       int i = 0;
+
+       for (i = 0; i < key_num; ++i) {
+               item =
+                   (Evas_Object *) edje_object_part_object_get(keypad,
+                                                               key_name[i]);
+               if (item != NULL) {
+                       evas_object_event_callback_add(item,
+                                                      EVAS_CALLBACK_MOUSE_DOWN,
+                                                      _calculator_interp,
+                                                      (void *)keypad);
+                       if (0 == strcmp(key_name[i], "item_del")) {
+                               evas_object_event_callback_add(item,
+                                                              EVAS_CALLBACK_MOUSE_UP,
+                                                              __calculator_delelte_up,
+                                                              (void *)keypad);
+                       }
+
+               }
+       }
+       CALC_FUN_END();
+}
+
+/**
+* @description
+*   The callback of input entry when mouse up.
+*
+* @param    data        unused
+* @param    e           unused
+* @param    entry       the input entry
+* @param    event_info  unused
+* @return   void
+*/
+static void
+_calc_view_input_entry_mouseup_cb(void *data, Evas * e, Evas_Object * entry,
+                                 void *event_info)
+{
+       calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for  softkey input and mouse move
+}
+
+static void
+_calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
+{
+       CALC_FUN_BEG();
+       strncpy(internal_str, entry_str, buf_size - 1);
+       /* remove result that behind '='(include '=') */
+       char *enter = strchr(internal_str, '=');
+       if (enter != NULL) {
+               enter--;
+               *enter = '\0';
+       }
+       calc_expr_replace_from_special_char(internal_str);
+       /* remove all ','  and '\n'*/
+       int i = 0;
+       int j = 0;
+       while (internal_str[j] != '\0'){
+
+               if (internal_str[j] == separator_ch || internal_str[j] == '\n'){
+                       j++;
+               } else {
+                       internal_str[i++] = internal_str[j++];
+               }
+       }
+       internal_str[i] = '\0';
+       CALC_FUN_END();
+}
+
+#ifdef __i386__
+static void
+_calc_view_input_entry_keyup_cb(void *data, Evas * e, Evas_Object * entry,
+                               void *event_info)
+{
+       CALC_FUN_BEG();
+       calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for hardkey input
+       int val = 0;
+       if (data) {
+               Evas_Object *obj = (Evas_Object *) data;
+               Evas_Event_Key_Up *evt = (Evas_Event_Key_Up *) event_info;
+               if (0 == strcmp(evt->key, "Return")) {
+                       //calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
+                       __calculator_op_equal(entry);
+
+               }
+               val = _calculator_get_input_item_hd(evt->key, obj);
+               switch (val) {
+               case OP_PLUS:
+               case OP_MINUS:
+               case OP_MULTIPLY:
+               case OP_DIVIDE:
+                       __calculator_control_normal_func_clicked(ad->input_entry, &calc_op_item[val]);
+                       break;
+               case OP_DOT:
+                       _calc_btn_dot_clicked(ad->input_entry);
+                       break;
+               case OP_NUM_0:
+               case OP_NUM_1:
+               case OP_NUM_2:
+               case OP_NUM_3:
+               case OP_NUM_4:
+               case OP_NUM_5:
+               case OP_NUM_6:
+               case OP_NUM_7:
+               case OP_NUM_8:
+               case OP_NUM_9:
+                       __calculator_control_panel_number_button_clicked(ad-> input_entry, &calc_op_item[val]);
+                       break;
+               case OP_DELETE:
+                       calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
+                       break;
+               default:
+                       break;
+               }
+       }
+       CALC_FUN_END();
+}
+#endif
+
+static bool
+_calc_view_input_entry_error_include(char *string)
+{
+    int i = 0;
+    for(; i < ARRAY_SIZE(error_string); i++)
+       {
+               if(!strcmp(string, _(error_string[i]))){
+                       return TRUE;
+           }
+    }
+    return FALSE;
+}
+
+/**
+* @description
+* The callback of input entry when text changed
+*
+* @param[in]   data    the appdata
+* @param[in]   obj     the input entry
+* @param[in]   event_info      unused
+* @return      void
+*/
+static void
+_calc_view_input_entry_changed_cb(void *data, Evas_Object *obj,
+                                 void *event_info)
+{
+       CALC_FUN_BEG();
+       if (data == NULL || obj == NULL) {
+               return;
+       }
+       struct appdata *ad = (struct appdata *)data;
+       const char *str = (char *)elm_entry_entry_get(obj);
+
+       if (paste_flag) {
+               char *entry_tmp = elm_entry_markup_to_utf8(str);
+               char *entry_expr= elm_entry_markup_to_utf8(entry_tmp);/*because the string format from clipboard is not correct*/
+               char internal_expr[MAX_EXPRESSION_LENGTH] = { 0 };
+               char f_number_buf[NUMBER_LENGTH] = { 0 };
+               char s_number_buf[NUMBER_LENGTH] = { 0 };
+               paste_flag = FALSE;
+               _calc_view_input_entry_to_str(entry_expr, internal_expr,
+                                             MAX_EXPRESSION_LENGTH);
+               int index = 0;
+               bool char_in =__calculator_string_invalid_char_search(internal_expr, &index);
+               __calculator_get_cursor_position_float_string(internal_expr,
+                                                             f_number_buf,
+                                                             calculator_cursor_pos,
+                                                             NULL, NULL);
+               int cur_pos = calc_view_cursor_get_position(ad->input_entry);
+               __calculator_get_cursor_position_float_string(internal_expr,
+                                                             s_number_buf,
+                                                             cur_pos, NULL,
+                                                             NULL);
+               int nCntOp = calc_expr_get_operator_num(internal_expr);
+
+        if ((strlen(f_number_buf) > MAX_NUM_LENGTH)
+                          || (strlen(s_number_buf) > MAX_NUM_LENGTH)) {
+                       __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
+               } else if (nCntOp >= MAX_OPERATOR_NUM) {
+                       __calculator_wrong_format_create(CALC_MSG_MAX_OP);
+               } else {
+                       if (char_in) {
+                               strncpy(calculator_input_str, internal_expr,
+                                       index);
+                               calculator_cursor_pos = index;
+                       } else {
+                               strncpy(calculator_input_str, internal_expr,
+                                       sizeof(calculator_input_str) - 1);
+                               calculator_cursor_pos = cur_pos;
+                       }
+                       _calc_entry_text_set(ad->input_entry, calculator_input_str);
+               }
+
+               if (entry_tmp) {
+                       free(entry_tmp);
+                       entry_tmp = NULL;
+               }
+               if (entry_expr) {
+                       free(entry_expr);
+                       entry_expr = NULL;
+               }
+       } else {
+               char *entry_expr_s = elm_entry_markup_to_utf8(str);
+               char internal_expr_s[MAX_EXPRESSION_LENGTH] = { 0 };
+               _calc_view_input_entry_to_str(entry_expr_s, internal_expr_s,
+                                             MAX_EXPRESSION_LENGTH);
+               if(!_calc_view_input_entry_error_include(internal_expr_s)){
+                       /*change calculator_input_str, after cut operation*/
+                       strncpy(calculator_input_str, internal_expr_s,
+                       MAX_EXPRESSION_LENGTH - 1);
+               }
+               if (entry_expr_s) {
+                       free(entry_expr_s);
+                       entry_expr_s = NULL;
+               }
+       }
+       /*
+        * Prevent pasting images into entry.
+        * If a image pasted, "<item absize=... href=...>" will be appended into entry.
+        */
+       if (strstr(str, "item") != NULL) {
+               int pos = 0;
+               char buf[MAX_EXPRESSION_LENGTH] = { 0 };
+
+               while (elm_entry_cursor_prev(obj)) {
+                       pos++;
+               }               /* save cursor position */
+               pos -= 1;       /* correct */
+
+               strncpy(buf, str, sizeof(buf));
+               char *begin = strstr(buf, "<item");
+               char *end = strchr(begin, '>');
+               string_remove_at(buf, begin - buf, end - begin + 1);    /* remove "<item...>" */
+               elm_entry_entry_set(obj, buf);
+
+               while (pos--) {
+                       elm_entry_cursor_next(obj);
+               }               /* retrieve cursor position */
+
+               calc_view_revise_input_scroller(ad);
+       }
+       CALC_FUN_END();
+}
+
+static void
+_calc_view_input_entry_paste_cb(void *data, Evas_Object * obj, void *event_info)
+{
+       CALC_FUN_BEG();
+       paste_flag = TRUE;
+       strncpy(calculator_before_paste_str, calculator_input_str,
+               MAX_EXPRESSION_LENGTH - 1);
+       CALC_FUN_END();
+}
+
+
+/**
+* @description
+*   Create an entry for inputing expression.
+*
+* @param    parent          the entry's parent
+* @param    ad              the appdata
+* @return   Evas_Object*    the input entry
+*/
+static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
+                                                 struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       Evas_Object *entry = elm_entry_add(ad->edje);
+       elm_entry_single_line_set(entry, EINA_FALSE);
+       elm_entry_editable_set(entry, EINA_TRUE);
+       elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
+       elm_entry_entry_set(entry, "");
+       elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_NO_IMAGE);
+       elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
+       elm_entry_cursor_end_set(entry);
+       elm_object_focus_set(entry, EINA_TRUE);
+    elm_object_style_set(entry, "black");
+       evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND,
+                                        EVAS_HINT_EXPAND);
+       evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+       evas_object_event_callback_add(entry, EVAS_CALLBACK_MOUSE_UP,
+                                      _calc_view_input_entry_mouseup_cb, ad);
+       evas_object_smart_callback_add(entry, "changed",
+                                      _calc_view_input_entry_changed_cb, ad);
+       evas_object_smart_callback_add(entry, "selection,paste",
+                                      _calc_view_input_entry_paste_cb, ad);
+#ifdef __i386__
+       evas_object_event_callback_add(entry, EVAS_CALLBACK_KEY_UP,
+                                      _calc_view_input_entry_keyup_cb, ad);
+       evas_object_smart_callback_del (entry, "changed",  _calc_view_input_entry_changed_cb);
+#endif
+       evas_object_show(entry);
+       limit_filter_data.max_char_count = 0;
+       limit_filter_data.max_byte_count = 419 + 20;    //19*21+20//result:20
+       elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size,
+                                    &limit_filter_data);
+       elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
+       CALC_FUN_END();
+       return entry;
+}
+
+/**
+* @description
+*   Create a input scrooler which around the input entry.
+*   It can give a input entry a scroller.
+*
+* @param    parent          the parent of input scroller
+* @return   Evas_Object*    the input scroller
+* @exception
+*/
+static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
+{
+       CALC_FUN_BEG();
+       Evas_Object *scroller = elm_scroller_add(parent);
+       elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
+       evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
+                                        EVAS_HINT_EXPAND);
+       evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
+                                       EVAS_HINT_FILL);
+
+       evas_object_show(scroller);
+       CALC_FUN_END();
+       return scroller;
+}
+
+/**
+* @description
+* Create the background
+*
+* @param[in]   parent  background's parent
+* @return              when success return background, return NULL oppositely
+* @retval      layout  if success, return the background
+* @retval      NULL    if create failed or parent is null, return null
+* @exception
+*/
+static Evas_Object *__create_bg(Evas_Object *parent)
+{
+       CALC_FUN_BEG();
+       if (parent == NULL) {
+               return NULL;
+       }
+       Evas_Object *bg = elm_bg_add(parent);
+       if (bg == NULL) {
+               return NULL;
+       }
+       evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_win_resize_object_add(parent, bg);
+       evas_object_show(bg);
+       CALC_FUN_END();
+       return bg;
+}
+
+/**
+* @description
+* Create the main layout
+*
+* @param[in]   parent  main layout's parent
+* @return              when success return a layout, return NULL oppositely
+* @retval      layout  if success, return the main layout
+* @retval      NULL    if create failed or parent is null, return null
+* @exception
+*/
+static Evas_Object *__calc_view_create_layout_main(Evas_Object *parent)
+{
+       CALC_FUN_BEG();
+
+       if (parent == NULL) {
+               return NULL;
+       }
+
+       Evas_Object *layout = elm_layout_add(parent);
+       if (layout == NULL) {
+               return NULL;
+       }
+
+       const char *profile = elm_config_profile_get();
+       if (!strcmp(profile, "mobile")) {
+               elm_layout_theme_set(layout, "layout", "application", "default");
+       } else if (!strcmp(profile, "desktop")) {
+               elm_layout_theme_set(layout, "layout", "application", "noindicator");
+       }
+
+       evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
+                                        EVAS_HINT_EXPAND);
+       elm_win_resize_object_add(parent, layout);
+
+       edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator",
+                               "elm");
+       evas_object_show(layout);
+
+       CALC_FUN_END();
+
+       return layout;
+}
+
+void _btn_clicked_cb(void *data, Evas_Object * obj, void *event_info)
+{
+       CALC_FUN_BEG();
+       Evas_Object *win_main = (Evas_Object *) data;
+       elm_win_lower(win_main);
+       CALC_FUN_END();
+}
+
+/**
+* @description
+*   Callback function of "Clear" Button on naviframe
+*
+* @param    data      the appdata
+* @param    obj
+* @param    event_info
+* @return   void
+
+*/
+static void
+__calc_view_clear_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       CALC_FUN_BEG();
+       struct appdata *ad = (struct appdata *)data;
+       elm_entry_entry_set(ad->hist_area, "");
+       elm_entry_entry_set(ad->input_entry, "");
+       _calc_view_clear_histroy(ad->hist_area);
+       CALC_FUN_END();
+}
+
+/**
+* @description
+*   Load the Naviframe.
+*
+* @param    ad      the appdata
+* @return   naviframe object
+
+*/
+static Evas_Object *__calc_view_create_navigation_layout(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       Evas_Object *nf = elm_naviframe_add(ad->layout);
+       Evas_Object *back_btn = elm_button_add(nf);
+       elm_object_style_set(back_btn, "naviframe/end_btn/default");
+       evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
+       ad->navi_it =
+           elm_naviframe_item_push(nf, NULL, back_btn, NULL, ad->edje, NULL);
+       elm_naviframe_item_title_visible_set(ad->navi_it, EINA_FALSE);
+       ad->tool_bar = elm_toolbar_add(nf);
+       elm_toolbar_shrink_mode_set(ad->tool_bar, ELM_TOOLBAR_SHRINK_EXPAND);
+       elm_object_item_part_content_set(ad->navi_it, "controlbar", ad->tool_bar);
+       ad->clear_btn = elm_toolbar_item_append(ad->tool_bar, NULL, "Clear History", __calc_view_clear_clicked_cb, ad);
+       ad->invalid_btn = elm_toolbar_item_append(ad->tool_bar, NULL, NULL, NULL, ad);
+       elm_object_item_disabled_set(ad->invalid_btn, EINA_TRUE);
+       evas_object_show(nf);
+       CALC_FUN_END();
+       return nf;
+}
+
+/**
+* @description
+*   Load the main view of calculator.
+*   Create the input entry and keypad.
+*
+* @param    ad      the appdata
+* @return   void
+*/
+void calc_view_load(struct appdata *ad)
+{
+       CALC_FUN_BEG();
+       ad->bg = __create_bg(ad->win);
+       ad->layout = __calc_view_create_layout_main(ad->win);
+       ad->edje = load_edj(ad->layout, LAYOUT_EDJ_NAME, GRP_MAIN);
+       evas_object_show(ad->edje);
+       evas_object_name_set(ad->edje, "edje");
+
+       ad->nf = __calc_view_create_navigation_layout(ad);
+       elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf);
+
+       /* inititialize environment variable */
+       locale = localeconv();
+       decimal = locale->decimal_point;
+       separator = locale->thousands_sep;
+       int len_seq = strlen(separator);
+       decimal_ch = decimal[0];
+       separator_ch = separator[0];
+       if (len_seq == 2 || len_seq == 0) {
+               separator_ch = 32;
+       }
+
+       /*init svi */
+       svi_init(&ad->svi_handle);
+
+       /* input area */
+       ad->input_entry = _calc_view_create_input_entry(ad->edje, ad);
+       ad->input_scroller = _calc_view_create_input_scroller(ad->edje);
+       elm_object_content_set(ad->input_scroller, ad->input_entry);
+       edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
+                                ad->input_scroller);
+       CALC_FUN_END();
+
+}
+
+/**
+* @description
+*   assign global variable  , this will be removed
+*
+* @param        ad
+* @return       void
+* @exception
+*/
+void calc_xxx(struct appdata *ap)
+{
+       ad = ap;
+}
diff --git a/theme/src/calculator_parser.c b/theme/src/calculator_parser.c
new file mode 100644 (file)
index 0000000..dfe13bd
--- /dev/null
@@ -0,0 +1,1523 @@
+/*
+*
+* Copyright 2012  Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.tizenopensource.org/license
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#include <math.h>              /* For math functions, cos(), sin(), etc. */
+#include <dlog.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "calc-main.h"
+#include "calc-string.h"
+#include "calc-expression.h"
+#include "calculator_parser.h"
+
+#define  DECNUMDIGITS 34
+#include "decnumber/decNumber.h"
+
+#define CALCULATOR_MAX_FUNC_NUMBER                             16              /**<maximum num of function*/
+
+extern char decimal_ch;
+static char g_stack[MAX_EXPRESSION_LENGTH];
+
+static calculator_parentheses_data_t g_parentheses_data[MAX_PARENTHESES_NUM];
+
+static int oper_num = 0;
+
+static const function_t g_functions[CALCULATOR_MAX_FUNC_NUMBER] = {
+       {"x^y", "^", 1, '^', FUNCTION_POSTFIX, OPERATOR_TYPE_BINARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGH, FALSE},
+       {"ln", "ln", 2, 'L', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
+       {"sqrt", "sqrt", 4, 'q', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
+       {"10^x", "10^", 3, 'T', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, FALSE},
+       {"x!", "!", 1, '!', FUNCTION_POSTFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHEST, FALSE},
+       {"1/x", "/", 1, 'x', FUNCTION_POSTFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHEST, FALSE},
+       {"sin", "sin", 3, 's', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
+       {"cos", "cos", 3, 'c', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
+       {"tan", "tan", 3, 't', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
+       {"Pi", "p", 1, 'p', FUNCTION_CONSTANT, OPERATOR_TYPE_INVALID,
+        CALCULATOR_CALCULATE_PRIORITY_INVALID, FALSE},
+       {"e", "e", 1, 'e', FUNCTION_CONSTANT, OPERATOR_TYPE_INVALID,
+        CALCULATOR_CALCULATE_PRIORITY_INVALID, FALSE},
+       {"log", "log", 3, 'l', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
+       {"abs", "abs", 3, 'b', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
+       {"2^x", "2^", 2, '2', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGHER, FALSE},
+       {"xCy", "C", 1, 'C', FUNCTION_POSTFIX, OPERATOR_TYPE_BINARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGH, FALSE},
+       {"xPy", "P", 1, 'P', FUNCTION_POSTFIX, OPERATOR_TYPE_BINARY,
+        CALCULATOR_CALCULATE_PRIORITY_HIGH, FALSE},
+};
+
+#define CALCULATOR_GET_NODE_DATA(t)    ((calculator_node_data_t*)(((GNode*)(t))->data))/**<to get data from GNode structure*/
+
+/**
+* @describe
+*
+*
+* @param    out_tree
+* @param    to_insert
+* @param    const_node
+* @return    gboolean
+* @exception
+*/
+static gboolean
+__calculator_calculate_insert_node(GNode ** out_tree, GNode * to_insert,
+                                  GNode * const_node)
+{
+       GNode *upper_node = NULL;
+       GNode *node = NULL;
+       calculator_node_data_t *node_data = NULL;
+
+       if ((!out_tree) || (!*out_tree) || (!to_insert)) {
+               return FALSE;
+       }
+
+       upper_node = *out_tree;
+       node = upper_node;
+
+       while (CALCULATOR_GET_NODE_DATA(upper_node)->node_calcu_priority >
+              CALCULATOR_GET_NODE_DATA(to_insert)->node_calcu_priority) {
+               if (G_NODE_IS_ROOT(upper_node)) {
+                       g_node_insert(to_insert, -1, upper_node);
+                       CALCULATOR_GET_NODE_DATA(to_insert)->children_num++;
+
+                       if (const_node) {
+                               g_node_insert(*out_tree, -1, const_node);       //value of last node's priority>= upper_node's > to_insert's
+                               CALCULATOR_GET_NODE_DATA(*out_tree)->
+                                   children_num++;
+                       }
+                       break;
+               }
+               node = upper_node;
+               upper_node = upper_node->parent;
+       }
+
+       if (CALCULATOR_GET_NODE_DATA(upper_node)->node_calcu_priority ==
+           CALCULATOR_GET_NODE_DATA(to_insert)->node_calcu_priority) {
+               if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type ==
+                   OPERATOR_TYPE_BINARY) {
+                       GNode *parent_node = NULL;
+
+                       if (!G_NODE_IS_ROOT(upper_node)) {
+                               parent_node = upper_node->parent;
+                               g_node_unlink(upper_node);
+                               g_node_insert(parent_node, -1, to_insert);
+                       }
+
+                       g_node_insert(to_insert, -1, upper_node);
+                       CALCULATOR_GET_NODE_DATA(to_insert)->children_num++;
+
+                       if (const_node) {
+                               g_node_insert(*out_tree, -1, const_node);
+                               CALCULATOR_GET_NODE_DATA(*out_tree)->
+                                   children_num++;
+                       }
+               } else if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type ==
+                          OPERATOR_TYPE_UNARY) {
+                       GNode *tmp_node = NULL;
+
+                       if (const_node) {
+                               node_data =
+                                   g_malloc0(sizeof(calculator_node_data_t));
+                               node_data->cur_operator = 'x';
+                               node_data->negative_flag = 1;
+                               node_data->operator_type = OPERATOR_TYPE_BINARY;
+                               node_data->node_calcu_priority =
+                                   CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                               tmp_node = g_node_new(node_data);
+
+                               if (CALCULATOR_GET_NODE_DATA(to_insert)->
+                                   cur_operator != '!') {
+                                       __calculator_calculate_insert_node
+                                           (out_tree, tmp_node, const_node);
+                               } else  //(CALCULATOR_GET_NODE_DATA(to_insert)->cur_operator == '!')
+                               {
+                                       g_node_insert(to_insert, -1,
+                                                     const_node);
+                                       CALCULATOR_GET_NODE_DATA(to_insert)->
+                                           children_num++;
+                               }
+
+                               g_node_insert(*out_tree, -1, to_insert);
+                               CALCULATOR_GET_NODE_DATA(*out_tree)->
+                                   children_num++;
+                       } else {
+                               g_node_insert(upper_node, -1, to_insert);       //combine from right
+                               CALCULATOR_GET_NODE_DATA(upper_node)->
+                                   children_num++;
+                       }
+               }
+       } else if (CALCULATOR_GET_NODE_DATA(upper_node)->node_calcu_priority <
+                  CALCULATOR_GET_NODE_DATA(to_insert)->node_calcu_priority) {
+               if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type ==
+                   OPERATOR_TYPE_BINARY) {
+                       if (node != upper_node) {
+                               g_node_unlink(node);
+                               CALCULATOR_GET_NODE_DATA(upper_node)->
+                                   children_num--;
+
+                               g_node_insert(to_insert, -1, node);
+                               CALCULATOR_GET_NODE_DATA(to_insert)->
+                                   children_num++;
+                       }
+
+                       if (const_node) {
+                               if (CALCULATOR_GET_NODE_DATA(*out_tree)->
+                                   node_calcu_priority >
+                                   CALCULATOR_GET_NODE_DATA(to_insert)->
+                                   node_calcu_priority) {
+                                       g_node_insert(*out_tree, -1,
+                                                     const_node);
+                                       CALCULATOR_GET_NODE_DATA(*out_tree)->
+                                           children_num++;
+                               } else {
+                                       g_node_insert(to_insert, -1,
+                                                     const_node);
+                                       CALCULATOR_GET_NODE_DATA(to_insert)->
+                                           children_num++;
+                               }
+                       }
+
+                       g_node_insert(upper_node, -1, to_insert);
+                       CALCULATOR_GET_NODE_DATA(upper_node)->children_num++;
+               }
+
+               else if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type == OPERATOR_TYPE_UNARY)     //upper_node must be equal to node equalized to *out_tree, for no functions' prority higher than unary operator
+               {
+                       if (const_node) {
+
+                               if (CALCULATOR_GET_NODE_DATA(to_insert)->
+                                   cur_operator != '!') {
+                                       GNode *tmp_node = NULL;
+
+                                       node_data =
+                                           g_malloc0(sizeof
+                                                     (calculator_node_data_t));
+                                       node_data->cur_operator = 'x';
+                                       node_data->negative_flag = 1;
+                                       node_data->operator_type =
+                                           OPERATOR_TYPE_BINARY;
+                                       node_data->node_calcu_priority =
+                                           CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                                       tmp_node = g_node_new(node_data);
+
+                                       __calculator_calculate_insert_node
+                                           (out_tree, tmp_node, const_node);
+                               } else  //(CALCULATOR_GET_NODE_DATA(to_insert)->cur_operator == '!')
+                               {
+                                       g_node_insert(to_insert, -1,
+                                                     const_node);
+                                       CALCULATOR_GET_NODE_DATA(to_insert)->
+                                           children_num++;
+                               }
+                       }
+
+                       g_node_insert(*out_tree, -1, to_insert);
+                       CALCULATOR_GET_NODE_DATA(*out_tree)->children_num++;
+               }
+
+       }
+
+       *out_tree = to_insert;
+       return TRUE;
+}
+
+/**
+* @describe
+*
+*
+* @param    node
+* @param    data
+* @return    gboolean
+* @exception
+*/
+static gboolean
+__calculator_tree_destroy_traverse_func(GNode * node, gpointer data)
+{
+       if (CALCULATOR_GET_NODE_DATA(node)) {
+               g_free(CALCULATOR_GET_NODE_DATA(node));
+       }
+       g_node_destroy(node);
+       return FALSE;
+}
+
+/**
+* @describe
+*
+*
+* @param    tree
+* @return    gboolean
+* @exception
+*/
+static gboolean __calculator_tree_destroy_all(GNode ** tree)
+{
+       guint depth = 0;
+       GNode *root = NULL;
+
+       if (*tree) {
+               root = g_node_get_root(*tree);
+               depth = g_node_max_height(root);
+               g_node_traverse(root, G_POST_ORDER, G_TRAVERSE_ALL, depth,
+                               __calculator_tree_destroy_traverse_func, NULL);
+
+               *tree = NULL;
+       }
+       return TRUE;
+}
+
+/**
+* @describe
+*
+*
+* @param    result
+* @param    error_msg
+* @return    gboolean
+* @exception
+*/
+static gboolean __calculator_check_overflow(double result, char *error_msg)
+{
+       if ((result > CALCULATOR_MAX_RESULT_SUM2)
+           || (result < CALCULATOR_MIN_RESULT_SUM2)) {
+               strcat(error_msg, CALC_MSG_OUT_OF_RANGE);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/**
+* @describe
+*   add parenthesis between function and paremeter.
+*
+* @param    exp
+* @param    func
+* @return    void
+* @exception
+*/
+static void __calculator_expression_add_parenthesis(char *exp, const char *func)
+{
+       char *p = exp;
+       char *digit = "0123456789.";
+
+       while ((p = strstr(p, func)) != NULL) {
+               p = p + strlen(func);
+               if (*p != '(') {
+                       int l = strspn(p, digit);
+                       string_insert(exp, p - exp, "(");
+                       string_insert(exp, p - exp + l + 1, ")");
+                       p += l + 2;
+               }
+       }
+}
+
+/**
+* @describe
+*   If sin/cos/tan function omitted parenthesis, add it
+*
+* @param    exp
+* @return    void
+* @exception
+*/
+static void __calculator_expression_tri_func_parenthesis(char *exp)
+{
+       __calculator_expression_add_parenthesis(exp, "sin");
+       __calculator_expression_add_parenthesis(exp, "cos");
+       __calculator_expression_add_parenthesis(exp, "tan");
+}
+
+/**
+* @describe
+*   record every matching parentheses position
+*
+* @param    string
+* @param    end_pos
+* @param    error_msg
+* @return    bool
+* @exception
+*/
+static bool
+__calculator_calculate_formula_scan(char *string, int *end_idx, char *error_msg)
+{
+       CALC_FUN_BEG();
+       gint i = 0;
+       gchar *p = NULL;
+
+       p = string;
+       memset(g_parentheses_data, 0x0, sizeof(g_parentheses_data));
+
+       __calculator_expression_tri_func_parenthesis(string);
+
+       while (*p != '\0') {
+               if (*p == '(') {
+                       while (g_parentheses_data[i].start_pos) {
+                               i++;
+                       }
+                       g_parentheses_data[i].start_pos = p;
+               }
+               if (*p == ')') {
+                       while (g_parentheses_data[i].end_pos) {
+                               i--;
+                       }
+                       if (g_parentheses_data[i].start_pos) {
+                               g_parentheses_data[i].end_pos = p;
+                       }
+               }
+               p++;
+       }
+       *end_idx = p - 1 - string;
+       CALC_FUN_END();
+       return TRUE;
+}
+
+/**
+* @describe
+*
+*
+* @param    n
+* @param    err_msg
+* @return    double
+* @exception
+*/
+static double __calculator_calculate_factorial(double n, char *err_msg)
+{
+       if (n < 0) {
+               strcat(err_msg, CALC_MSG_INVALID_FAC);
+               return -1;
+       } else if (n >= 30) {
+               strcat(err_msg, CALC_MSG_OUT_OF_RANGE);
+               return -1;
+       }
+
+       double i = 0;
+       double result = 1;
+       for (i = 2; i <= n; ++i) {
+               result *= i;
+       }
+       return result;
+}
+
+/**
+* @describe
+*   Judge the op is a operator, if yes, give fucntion type
+*
+* @param    op
+* @param    function
+* @return    gboolean
+* @exception
+*/
+static gboolean __calculator_util_get_operator(char *op, function_t * function)
+{
+       gint i = 0;
+       gboolean ret = FALSE;
+       if ((*op == decimal_ch) || (*op == '(') || (*op == ')')) {
+               ret = FALSE;
+       } else if (isdigit(*op)) {
+               ret = FALSE;
+       } else if ((*op == '+') || (*op == '-') || (*op == 'x') || (*op == '/')) {
+               function->category = FUNCTION_POSTFIX;
+               function->function_char = *op;
+               function->func_name = NULL;
+               function->func_string = NULL;
+               function->has_parentheses = FALSE;
+               function->op_type = OPERATOR_TYPE_BINARY;
+               if ((*op == '+') || (*op == '-')) {
+                       function->priority = CALCULATOR_CALCULATE_PRIORITY_LOW;
+               } else {
+                       function->priority =
+                           CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+               }
+               function->str_len = 1;
+               ret = TRUE;
+       } else {
+               for (i = 0; i < CALCULATOR_MAX_FUNC_NUMBER; i++) {
+                       if (!strncmp
+                           (op, g_functions[i].func_string,
+                            strlen(g_functions[i].func_string))) {
+                               memcpy(function, &g_functions[i],
+                                      sizeof(function_t));
+                               ret = TRUE;
+                               break;
+                       }
+               }
+       }
+       return ret;
+}
+
+/* search function, if have, return TRUE and get the length of current function;else return FALSE */
+gboolean __calculator_search_function(char *op, int* len)
+{
+       gint i = 0;
+       gboolean ret = FALSE;
+       for (i = 0; i < CALCULATOR_MAX_FUNC_NUMBER; i++) {
+               if (!strncmp
+                   (op, g_functions[i].func_string,
+                    strlen(g_functions[i].func_string))) {
+                       ret = TRUE;
+                       if(len){
+                               *len = strlen(g_functions[i].func_string);
+                       }
+                       break;
+               }
+       }
+       return ret;
+}
+
+/**
+* @describe
+*
+*
+* @param    pos
+* @return    calculator_parentheses_data_t*
+* @exception
+*/
+static calculator_parentheses_data_t
+    *__calculator_calculate_get_parentheses_info(gchar * pos)
+{
+       calculator_parentheses_data_t *found = NULL;
+       gint i = 0;
+
+       while ((g_parentheses_data[i].start_pos) ||
+              (g_parentheses_data[i].end_pos)) {
+               if (g_parentheses_data[i].start_pos == pos) {
+                       found = &g_parentheses_data[i];
+                       break;
+               } else if (g_parentheses_data[i].end_pos == pos) {
+                       found = &g_parentheses_data[i];
+                       break;
+               }
+               i++;
+       }
+
+       return found;
+}
+
+/**
+* @describe
+*
+*
+* @param    tmp_result
+* @param    out_tree
+* @param    start_pos
+* @param    end_pos
+* @param    error_msg
+* @return    gboolean
+* @exception
+*/
+static gboolean
+__calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
+                                    char *start_pos, int end_idx,
+                                    char *error_msg)
+{
+       CALC_FUN_BEG();
+       char *end_pos = start_pos + end_idx;
+       gchar *p = NULL;
+       gchar *q = NULL;
+       gchar tmp[MAX_RESULT_LENGTH];
+       gint i = 0;
+       calculator_state_t calculator_state = CALCULATOR_OPERAND_INPUT;
+       calculator_node_data_t *node_data = NULL;
+       GNode *tree = NULL;
+       GNode *new_node = NULL;
+       GNode *last_node = NULL;        //to proc parentheses
+       calculator_parentheses_data_t *p_data = NULL;
+       gint negative_sign = 1;
+       function_t function = { 0 };
+
+       memset(tmp, 0x00, sizeof(tmp));
+
+       if (start_pos > end_pos) {
+               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+               return FALSE;
+       }
+
+       /* Scan from start to end of string */
+       for (p = start_pos; p <= end_pos;) {
+               q = p;          /* Point to start of string */
+               if (q != NULL && __calculator_util_get_operator(q, &function))  //('.'::'('::')') and digits are four exceptions
+               {
+                       oper_num++;
+                       if (oper_num > MAX_OPERATOR_NUM) {
+                               strcat(error_msg, CALC_MSG_MAX_OP);
+                               return false;
+                       }
+
+                       p = q + function.str_len;       /* Shift */
+                       if ((NULL == p)
+                           && (function.category != FUNCTION_CONSTANT)) {
+                               return false;
+                       }
+                       if ((NULL != p) && (*p == decimal_ch)) {
+                               printf("p:%s\n", p);
+                               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                               return false;
+                       }
+                       calculator_state = CALCULATOR_OPERATOR_INPUT;
+                       if (i != 0)     //save the before operator,create a node.such as 345sin(),save 345
+                       {
+                               i = 0;
+
+                               node_data =
+                                   g_malloc0(sizeof(calculator_node_data_t));
+                               strcpy(node_data->tmp_result, tmp);
+                               memset(tmp, 0x00, sizeof(tmp));
+                               node_data->negative_flag = 1;
+                               node_data->negative_flag *= negative_sign;
+                               new_node = g_node_new(node_data);
+                               negative_sign = 1;
+                       } else {
+                               if (!new_node)  //no leaf node before, first factor's "+/-" sign allowed.
+                               {
+                                       if (((function.op_type ==
+                                             OPERATOR_TYPE_BINARY)
+                                            /*&& (function.function_char != '+')*/
+                                            && (function.function_char != '-'))
+                                           ||
+                                           ((function.op_type ==
+                                             OPERATOR_TYPE_UNARY)
+                                            && (function.category ==
+                                                FUNCTION_POSTFIX))) {
+                                               strcat(error_msg,CALC_MSG_SYNTAX_ERROR);
+                                               return FALSE;
+                                       } else if (function.function_char ==
+                                                  '-') {
+                                               negative_sign = -1;
+                                               continue;
+                                       }
+                               }
+                       }
+
+                       if (function.category == FUNCTION_CONSTANT)     //Pi, e
+                       {
+                               if (new_node)   //have the operator like 345,now it will 345*Pi
+                               {
+                                       node_data =
+                                           g_malloc0(sizeof
+                                                     (calculator_node_data_t));
+                                       node_data->cur_operator = 'x';
+                                       node_data->negative_flag = 1;
+                                       node_data->operator_type =
+                                           OPERATOR_TYPE_BINARY;
+                                       node_data->node_calcu_priority =
+                                           CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                                       tree = g_node_new(node_data);
+
+                                       if (last_node == NULL)  //first node
+                                       {
+                                               g_node_insert(tree, -1,
+                                                             new_node);
+                                               CALCULATOR_GET_NODE_DATA(tree)->
+                                                   children_num++;
+                                       } else {
+                                               if (CALCULATOR_GET_NODE_DATA
+                                                   (last_node)->children_num >
+                                                   CALCULATOR_GET_NODE_DATA
+                                                   (last_node)->
+                                                   operator_type) {
+                                                       strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                                                       return FALSE;
+                                               }
+                                               __calculator_calculate_insert_node
+                                                   (&last_node, tree,
+                                                    new_node);
+                                       }
+                                       new_node = NULL;
+                                       last_node = tree;
+
+                               }       //Pi will like a leaf
+                               node_data =
+                                   g_malloc0(sizeof(calculator_node_data_t));
+                               if (function.function_char == 'p') {
+                                       strcpy(node_data->tmp_result, PI_STR);
+                               } else if (function.function_char == 'e') {
+                                       strcpy(node_data->tmp_result,
+                                              EXPONENT_STR);
+                               }
+                               node_data->cur_operator =
+                                   function.function_char;
+                               node_data->node_calcu_priority =
+                                   function.priority;
+                               node_data->negative_flag = 1;
+                               node_data->negative_flag *= negative_sign;
+                               new_node = g_node_new(node_data);
+                               negative_sign = 1;
+                               continue;
+                       } else if (function.category == FUNCTION_PREFIX)        //sin()
+                       {
+                               if (!last_node) //first node
+                               {
+                                       if (new_node) {
+                                               node_data =
+                                                   g_malloc0(sizeof
+                                                             (calculator_node_data_t));
+                                               node_data->cur_operator = 'x';
+                                               node_data->negative_flag = 1;
+                                               node_data->operator_type =
+                                                   OPERATOR_TYPE_BINARY;
+                                               node_data->node_calcu_priority =
+                                                   CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                                               tree = g_node_new(node_data);
+
+                                               g_node_insert(tree, -1,
+                                                             new_node);
+                                               CALCULATOR_GET_NODE_DATA(tree)->
+                                                   children_num++;
+
+                                               last_node = tree;
+                                               new_node = NULL;
+                                       }
+                               }
+
+                       }
+
+                       node_data = g_malloc0(sizeof(calculator_node_data_t));
+                       node_data->cur_operator = function.function_char;
+                       node_data->node_calcu_priority = function.priority;
+                       node_data->operator_type = function.op_type;
+                       node_data->negative_flag = 1;
+                       tree = g_node_new(node_data);
+
+                       if (last_node == NULL)  //first node
+                       {
+                               if (new_node) {
+                                       g_node_insert(tree, -1, new_node);
+                                       CALCULATOR_GET_NODE_DATA(tree)->
+                                           children_num++;
+                               }
+                       } else {
+                               if (CALCULATOR_GET_NODE_DATA(last_node)->
+                                   children_num >
+                                   CALCULATOR_GET_NODE_DATA(last_node)->
+                                   operator_type) {
+                                       strcat(error_msg,
+                                              CALC_MSG_SYNTAX_ERROR);
+                                       return FALSE;
+                               }
+                               __calculator_calculate_insert_node(&last_node,
+                                                                  tree,
+                                                                  new_node);
+                       }
+                       last_node = tree;
+                       new_node = NULL;
+               } else {
+                       p++;    /* Shift */
+               }
+
+               if (NULL == q) {
+                       strcat(error_msg, CALC_MSG_SYNTAX_ERROR);       //add for "6((" ,then "="
+                       return FALSE;
+               }               //added by zhaodanni for prevent
+               else if (*q == decimal_ch) {
+                       if (!isdigit(*p)
+                           || (calculator_state ==
+                               CALCULATOR_OPERAND_FRACTION_INPUT)) {
+                               //strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                               //return FALSE;
+                       } else {
+                               calculator_state =
+                                   CALCULATOR_OPERAND_FRACTION_INPUT;
+                       }
+                       tmp[i++] = *q;
+               } else if (*q == '(') {
+                       if (__calculator_util_get_operator(p, &function)) {
+                               if ((function.category == FUNCTION_POSTFIX) && ((*p != '+') && (*p != '-')))    //"(*","(/", not allowed.
+                               {
+                                       strcat(error_msg,
+                                              CALC_MSG_SYNTAX_ERROR);
+                                       return FALSE;
+                               }
+                       }
+                       //if ((new_node) && (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == PI || CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == EXPONENT))
+                       if ((new_node)
+                           &&
+                           (!strcmp
+                            (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, PI_STR)
+                            ||
+                            !strcmp(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, EXPONENT_STR))) {
+                               node_data =
+                                   g_malloc0(sizeof(calculator_node_data_t));
+                               node_data->cur_operator = 'x';
+                               node_data->negative_flag = 1;
+                               node_data->operator_type = OPERATOR_TYPE_BINARY;
+                               node_data->node_calcu_priority =
+                                   CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                               tree = g_node_new(node_data);
+
+                               if (last_node) {
+                                       __calculator_calculate_insert_node
+                                           (&last_node, tree, new_node);
+                               } else {
+                                       g_node_insert(tree, -1, new_node);
+                                       CALCULATOR_GET_NODE_DATA(tree)->
+                                           children_num++;
+                               }
+                               last_node = tree;
+                               new_node = NULL;
+                       }
+
+                       if (i != 0) {
+                               i = 0;
+
+                               node_data =
+                                   g_malloc0(sizeof(calculator_node_data_t));
+                               strcpy(node_data->tmp_result, tmp);
+                               memset(tmp, 0x00, sizeof(tmp));
+                               node_data->negative_flag = 1;
+                               node_data->negative_flag *= negative_sign;
+                               negative_sign = 1;
+                               new_node = g_node_new(node_data);
+
+                               node_data =
+                                   g_malloc0(sizeof(calculator_node_data_t));
+                               node_data->cur_operator = 'x';
+                               node_data->negative_flag = 1;
+                               node_data->operator_type = OPERATOR_TYPE_BINARY;
+                               node_data->node_calcu_priority =
+                                   CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                               tree = g_node_new(node_data);
+
+                               if (last_node == NULL)  //first node
+                               {
+                                       g_node_insert(tree, -1, new_node);
+                                       CALCULATOR_GET_NODE_DATA(tree)->
+                                           children_num++;
+                               } else {
+                                       if (CALCULATOR_GET_NODE_DATA
+                                           (last_node)->children_num >
+                                           CALCULATOR_GET_NODE_DATA
+                                           (last_node)->operator_type) {
+                                               strcat(error_msg,
+                                                      CALC_MSG_SYNTAX_ERROR);
+                                               return FALSE;
+                                       }
+
+                                       __calculator_calculate_insert_node
+                                           (&last_node, tree, new_node);
+                               }
+                               last_node = tree;
+                               new_node = NULL;
+                       }
+
+                       p_data = __calculator_calculate_get_parentheses_info(q);
+                       if (!p_data) {
+                               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                               return FALSE;
+                       }
+                       p = p_data->end_pos;
+               } else if (*q == ')') {
+                       if (*p == decimal_ch)   //").", not allowed.
+                       {
+                               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                               return FALSE;
+                       }
+
+                       p_data = __calculator_calculate_get_parentheses_info(q);
+                       if (!p_data) {
+                               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                               return FALSE;
+                       }
+                       if (!__calculator_calculate_formula_parse
+                           (NULL, &new_node, (p_data->start_pos + 1),
+                            (p_data->end_pos - 1) - (p_data->start_pos + 1),
+                            error_msg)) {
+                               if (new_node != NULL) {
+                                       __calculator_tree_destroy_all
+                                           (&new_node);
+                               } else {
+                                       LOGD("current node is null\n");
+                               }
+                               return FALSE;
+                       }
+                       if (new_node) {
+                               CALCULATOR_GET_NODE_DATA(new_node)->
+                                   negative_flag *= negative_sign;
+                       }
+                       negative_sign = 1;
+
+                       if ((*p == '(') || (isdigit(*p))) {
+                               node_data =
+                                   g_malloc0(sizeof(calculator_node_data_t));
+                               node_data->cur_operator = 'x';
+                               node_data->negative_flag = 1;
+                               node_data->operator_type = OPERATOR_TYPE_BINARY;
+                               node_data->node_calcu_priority =
+                                   CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                               tree = g_node_new(node_data);
+
+                               if (last_node == NULL)  //first node
+                               {
+                                       if (new_node) {
+                                               g_node_insert(tree, -1,
+                                                             new_node);
+                                               CALCULATOR_GET_NODE_DATA(tree)->
+                                                   children_num++;
+                                       }
+                               } else {
+                                       if (CALCULATOR_GET_NODE_DATA
+                                           (last_node)->children_num >
+                                           CALCULATOR_GET_NODE_DATA
+                                           (last_node)->operator_type) {
+                                               strcat(error_msg,
+                                                      CALC_MSG_SYNTAX_ERROR);
+                                               return FALSE;
+                                       }
+
+                                       __calculator_calculate_insert_node
+                                           (&last_node, tree, new_node);
+                               }
+                               last_node = tree;
+                               new_node = NULL;
+                       }
+               } else if (isdigit(*q)) {
+                       if (new_node) {
+                               node_data =
+                                   g_malloc0(sizeof(calculator_node_data_t));
+                               node_data->cur_operator = 'x';
+                               node_data->negative_flag = 1;
+                               node_data->operator_type = OPERATOR_TYPE_BINARY;
+                               node_data->node_calcu_priority =
+                                   CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                               tree = g_node_new(node_data);
+
+                               if (last_node) {
+                                       __calculator_calculate_insert_node
+                                           (&last_node, tree, new_node);
+                               } else {
+                                       g_node_insert(tree, -1, new_node);
+                                       CALCULATOR_GET_NODE_DATA(tree)->
+                                           children_num++;
+                               }
+                               last_node = tree;
+                               new_node = NULL;
+                       }
+                       calculator_state = CALCULATOR_OPERAND_INPUT;
+                       tmp[i++] = *q;
+               }/*for unvalid input ,such as "clipborad"*/
+               else if ((*q != '+') && (*q != '-') && (*q != 'x')
+                        && (*q != '/')) {
+                       if (!__calculator_search_function(q, NULL)) {
+                               printf("q=%s,line=%d\n", q, __LINE__);
+                               strcat(error_msg, "invalid input");
+                               return FALSE;
+                       }
+               }
+       }
+
+       if (i != 0)             //last digit number
+       {
+               //if ((new_node) && (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == PI || CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == EXPONENT))
+               if ((new_node)
+                   &&
+                   (!strcmp
+                    (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, PI_STR)
+                    || !strcmp(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result,
+                               EXPONENT_STR))) {
+                       node_data = g_malloc0(sizeof(calculator_node_data_t));
+                       node_data->cur_operator = 'x';
+                       node_data->negative_flag = 1;
+                       node_data->operator_type = OPERATOR_TYPE_BINARY;
+                       node_data->node_calcu_priority =
+                           CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
+                       tree = g_node_new(node_data);
+
+                       if (last_node) {
+                               __calculator_calculate_insert_node(&last_node,
+                                                                  tree,
+                                                                  new_node);
+                       } else {
+                               g_node_insert(tree, -1, new_node);
+                               CALCULATOR_GET_NODE_DATA(tree)->children_num++;
+                       }
+                       last_node = tree;
+                       new_node = NULL;
+               }
+               i = 0;
+
+               node_data = g_malloc0(sizeof(calculator_node_data_t));
+               strcpy(node_data->tmp_result, tmp);
+               memset(tmp, 0x00, sizeof(tmp));
+               node_data->negative_flag = 1;
+               node_data->negative_flag *= negative_sign;
+               negative_sign = 1;
+               new_node = g_node_new(node_data);
+
+               if (last_node != NULL) {
+                       if (CALCULATOR_GET_NODE_DATA(last_node)->children_num >
+                           CALCULATOR_GET_NODE_DATA(last_node)->
+                           operator_type) {
+                               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                               return FALSE;
+                       } else {
+                               g_node_insert(last_node, -1, new_node);
+                               CALCULATOR_GET_NODE_DATA(last_node)->
+                                   children_num++;
+                       }
+                       new_node = NULL;
+               }
+       }
+
+       if (new_node != NULL) {
+               CALCULATOR_GET_NODE_DATA(new_node)->negative_flag *=
+                   negative_sign;
+               negative_sign = 1;
+
+               if (last_node != NULL) {
+                       if (CALCULATOR_GET_NODE_DATA(last_node)->children_num >
+                           CALCULATOR_GET_NODE_DATA(last_node)->
+                           operator_type) {
+                               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+                               return FALSE;
+                       } else {
+                               g_node_insert(last_node, -1, new_node);
+                               CALCULATOR_GET_NODE_DATA(last_node)->
+                                   children_num++;
+                       }
+               } else {
+                       last_node = new_node;
+               }
+               new_node = NULL;
+       }
+       *out_tree = g_node_get_root(last_node);
+       CALC_FUN_END();
+       return TRUE;
+}
+
+/**
+* @describe
+*
+*
+* @param        node
+* @param        data
+* @return       gboolean
+* @exception
+*/
+static gboolean
+__calculator_calculate_exec_traverse_func(GNode * node, gpointer data)
+{
+       gdouble operand0, operand1 = 0.0;
+       double tmp_ret = 0.0;
+       decNumber doperand0, doperand1, dresult;
+       decContext set;
+       char dec_result[DECNUMDIGITS + 14];
+       char *error_msg = (char *)data;
+       char op0buf[MAX_RESULT_LENGTH] = { 0 };
+       char op1buf[MAX_RESULT_LENGTH] = { 0 };
+       if (CALCULATOR_GET_NODE_DATA(node)->children_num !=
+           CALCULATOR_GET_NODE_DATA(node)->operator_type) {
+               strcat(error_msg, CALC_MSG_NUM_AFTER_OP);
+               return TRUE;    //break the recursion
+       }
+
+       decContextTestEndian(0);
+       decContextDefault(&set, DEC_INIT_BASE);
+       set.digits = DECNUMDIGITS;
+
+       if (CALCULATOR_GET_NODE_DATA(node->children)->negative_flag == -1) {
+               strcat(op0buf, "-");
+               CALCULATOR_GET_NODE_DATA(node->children)->negative_flag = 1;
+       }
+       strcat(op0buf, CALCULATOR_GET_NODE_DATA(node->children)->tmp_result);
+       operand0 = atof(op0buf);
+       decNumberFromString(&doperand0, op0buf, &set);
+
+       if (CALCULATOR_GET_NODE_DATA(node)->operator_type ==
+           OPERATOR_TYPE_BINARY) {
+               if (CALCULATOR_GET_NODE_DATA
+                   (node->children->next)->negative_flag == -1) {
+                       strcat(op1buf, "-");
+                       CALCULATOR_GET_NODE_DATA(node->children->
+                                                next)->negative_flag = 1;
+               }
+               strcat(op1buf,
+                      CALCULATOR_GET_NODE_DATA(node->children->
+                                               next)->tmp_result);
+               operand1 = atof(op1buf);
+               decNumberFromString(&doperand1, op1buf, &set);
+       }
+       switch (CALCULATOR_GET_NODE_DATA(node)->cur_operator) {
+       case '+':
+               decNumberAdd(&dresult, &doperand0, &doperand1, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               break;
+       case '-':
+               decNumberSubtract(&dresult, &doperand0, &doperand1, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               break;
+       case 'x':
+               decNumberMultiply(&dresult, &doperand0, &doperand1, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               break;
+       case '/':
+               if (FLOAT_EQUAL(operand1, 0)) {
+                       strcat(error_msg, CALC_MSG_DIVIDE_BY_ZERO);
+                       return TRUE;    //break the recursion
+               } else {
+                       decNumberDivide(&dresult, &doperand0, &doperand1, &set);
+                       decNumberToString(&dresult, dec_result);
+                       strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result,
+                              dec_result);
+               }
+               break;
+       case '^':
+               if (operand0 < 0) {
+                       gdouble power = 0.0;
+                       power = floor(operand1);
+                       if (!FLOAT_EQUAL(power, operand1))      //operand1 is not an integer
+                       {
+                               return TRUE;
+                       }
+               }
+               tmp_ret =pow(operand0, operand1);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+       case '!':
+               if (operand0 < 0) {
+                       gdouble power = 0.0;
+                       power = floor(operand1);
+                       if (!FLOAT_EQUAL(power, operand1))      //operand1 is not an integer
+                       {
+                               strcat(error_msg, CALC_MSG_INVALID_FAC);
+                               return TRUE;
+                       }
+               }
+               if (strlen(error_msg) != 0) {
+                       return TRUE;
+               }
+               tmp_ret = __calculator_calculate_factorial(operand0, error_msg);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               if (strlen(error_msg) != 0) {
+                       return TRUE;
+               }
+               break;
+
+       case 'L':
+               if (operand0 < 0) {
+                       return TRUE;
+               } else if (FLOAT_EQUAL(operand0, 0)) {
+                       return TRUE;
+               }
+               set.emax = 999999;
+               set.emin = -999999;
+               decNumberLn(&dresult, &doperand0, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+       case 'q':
+               if (operand0 < 0) {
+                       strcat(error_msg, CALC_MSG_INVALID_SQUARE);
+                       return TRUE;
+               }
+               decNumberSquareRoot(&dresult, &doperand0, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+       case 's':
+               tmp_ret = sin(operand0 * RADIAN_FACTOR);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+       case 'c':
+               tmp_ret = cos(operand0 * RADIAN_FACTOR);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+       case 't':
+               if (FLOAT_EQUAL(fmod(operand0, 180), 90) || FLOAT_EQUAL(fmod(operand0, 180), -90))      //revise by bfl
+               {
+                       return TRUE;
+               }
+               tmp_ret = tan(operand0 * RADIAN_FACTOR);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+       case 'l':
+               if (operand0 < 0) {
+                       strcat(error_msg, CALC_MSG_INVALID_LOG);
+                       return TRUE;
+               } else if (FLOAT_EQUAL(operand0, 0)) {
+                       strcat(error_msg, CALC_MSG_INVALID_LOG);
+                       return TRUE;
+               }
+               set.emax = 999999;
+               set.emin = -999999;
+               decNumberLog10(&dresult, &doperand0, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+       case 'b':
+               tmp_ret = fabs(operand0);
+               snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+
+       case '2':
+               decNumberFromString(&doperand1, "2", &set);
+               decNumberPower(&dresult, &doperand1, &doperand0, &set);
+               decNumberToString(&dresult, dec_result);
+               strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
+               if (!__calculator_check_overflow
+                   (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
+                    error_msg)) {
+                       return TRUE;
+               }
+               break;
+
+       default:
+               break;
+       }
+       /*CALCULATOR_GET_NODE_DATA(node)->tmp_result *=
+           CALCULATOR_GET_NODE_DATA(node)->negative_flag;
+       CALCULATOR_GET_NODE_DATA(node)->negative_flag = 1;*/
+
+       return FALSE;
+}
+
+/**
+* @describe
+*
+*
+* @param    tree
+* @param    result
+* @param    error_msg
+* @return    gboolean
+* @exception
+*/
+static gboolean
+__calculator_calculate_exec(GNode * tree, double **result, char *error_msg)
+{
+       guint depth = 0;
+       depth = g_node_max_height(tree);
+
+       if (depth < 1) {
+               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+               return FALSE;   //break the recursion
+       } else if (depth == 1) {
+               **result = atof(CALCULATOR_GET_NODE_DATA(tree)->tmp_result);
+               **result *= CALCULATOR_GET_NODE_DATA(tree)->negative_flag;
+               return TRUE;
+       }
+       g_node_traverse(tree,
+                       G_POST_ORDER,
+                       G_TRAVERSE_NON_LEAFS,
+                       depth,
+                       __calculator_calculate_exec_traverse_func,
+                       (gpointer) error_msg);
+
+       if (strlen(error_msg) > 0) {
+               return FALSE;
+       } else {
+               **result = atof(CALCULATOR_GET_NODE_DATA(tree)->tmp_result);
+       }
+       return TRUE;
+}
+
+/**
+* @describe
+*
+*
+* @param    tmp_result
+* @return    gboolean
+* @exception
+*/
+
+#if 0
+
+/*
+bool calculator_calculate_truncate_result(double* tmp_result)
+{
+
+       return TRUE;
+}
+*/
+#endif
+
+/**
+* @describe
+*
+*
+* @param    szInputString
+* @return    int
+* @exception
+*/
+int calculator_get_open_braket(const char *szInputString)
+{
+       int nReversIndex = strlen(szInputString) - 1;
+       int nOpenCnt = 0;
+       int nCloseCnt = 0;
+
+       while (nReversIndex >= 0) {
+               if (szInputString[nReversIndex] == '(') {
+                       nOpenCnt++;
+               } else if (szInputString[nReversIndex] == ')') {
+                       nCloseCnt++;
+               }
+               nReversIndex--;
+       }
+       return (nOpenCnt - nCloseCnt);
+}
+
+/**
+* @describe
+*
+*
+* @param    szInput
+* @param    [out]pDigitCnt : count of digit before point(.)
+* @param    [out]pPointCnt: count of digit after point(.)
+* @return    int
+* @exception
+*/
+bool calculator_get_digits_number(char *szInput, int *pDigitCnt, int *pPointCnt)
+{
+       int nLen = strlen(szInput);
+       int nIndex;
+
+       int nTempCnt = 0;
+       int nTempCntb = 0;
+
+       *pDigitCnt = 0;
+       *pPointCnt = 0;
+
+       if (nLen > 0) {
+               for (nIndex = nLen - 1; nIndex >= 0; nIndex--) {
+                       if (isdigit(szInput[nIndex])) {
+                               nTempCnt++;
+                       } else if (szInput[nIndex] == decimal_ch) {
+                               *pPointCnt = nTempCnt;
+                               nTempCnt = 0;
+                               break;
+                       }
+               }
+               for (nIndex = 0; nIndex < nLen; nIndex++) {
+                       if (isdigit(szInput[nIndex])) {
+                               nTempCntb++;
+                       } else if (szInput[nIndex] == decimal_ch) {
+                               *pDigitCnt = nTempCntb;
+                               break;
+                       }
+               }
+               //*pDigitCnt = nTempCntb;
+       }
+       return true;
+}
+
+/**
+* @describe
+*
+*
+* @param    str
+* @param    error_msg
+* @return    bool
+* @exception
+*/
+bool calculator_expression_length_check(char *str, char *error_msg)
+{
+       int is_digit = 0, has_dot = 0;
+       int idx = 0, nCount = 0, nDigitCnt = 0, nPointCnt = 0;
+       char *p = NULL;
+       char c;
+
+#if 0
+/*
+
+       if(strlen(str) > CALCULATOR_MAX_INPUT_DIGIT_NUMBER_POR)
+       {
+               strcat(error_msg, CALC_MSG_MAX_INPUT);
+               return FALSE;
+       }
+*/
+#endif
+
+       p = str;
+       while (idx < strlen(str)) {
+               c = p[idx];
+
+               if (isdigit(c)) {
+                       if (is_digit == 0) {
+                               is_digit = 1;
+
+                               nDigitCnt = 1;
+                               nCount = 1;
+                       } else {
+                               nCount++;
+                               if (nCount > MAX_NUM_LENGTH) {
+                                       strcat(error_msg, CALC_MSG_MAX_DIGIT);
+                                       return FALSE;
+                               }
+
+                               if (has_dot == 0) {
+                                       nDigitCnt++;
+                               } else {
+                                       nPointCnt++;
+
+#if 0                          //YangQ
+                                       /*
+                                          if(nPointCnt > CALCULATORUI_MAX_INPUT_DECIMALS)
+                                          {
+                                          strcat(error_msg, CALC_MSG_MAX_DEC_DIGIT);
+                                          PTAG;
+                                          return FALSE;
+                                          }
+                                        */
+#endif
+                               }
+                       }
+               }
+               else if (c == decimal_ch) {
+                       if (has_dot == 1) {
+                               return FALSE;
+                       } else {
+                               has_dot = 1;
+                       }
+               } else {
+                       if (is_digit == 1) {
+                               is_digit = 0;
+                               has_dot = 0;
+                               nCount = 0;
+                               nDigitCnt = 0;
+                               nPointCnt = 0;
+                       }
+               }
+
+               idx++;
+       }
+
+       return TRUE;
+
+}
+
+/**
+* @describe
+*
+*
+* @param    string
+* @param    result
+* @param    error_msg
+* @return    bool
+* @exception
+*/
+bool calculator_calculate(gchar * string, gdouble * result, char *error_msg)
+{
+#if 1                          //YangQ add.
+       string_replace(string, "E+", "x10^");
+       string_replace(string, "E-", "x0.1^");
+#endif
+       GNode *tree = NULL;
+       int end_idx = 0;
+
+       memset(error_msg, 0, sizeof(error_msg));
+       memset(g_stack, 0, sizeof(g_stack));
+       oper_num = 0;
+
+       strncpy(g_stack, string, MAX_EXPRESSION_LENGTH - 1);
+       g_stack[MAX_EXPRESSION_LENGTH - 1] = '\0';
+
+       char *digit = "0123456789pe";
+       if (strcspn(g_stack, digit) == strlen(g_stack)) {       /* no digit in expression */
+               strcat(error_msg, CALC_MSG_SYNTAX_ERROR);
+               return FALSE;
+       }
+
+       if (!calculator_expression_length_check(g_stack, error_msg)) {
+               return FALSE;
+       }
+       if (!__calculator_calculate_formula_scan(g_stack, &end_idx, error_msg)) {
+               return FALSE;
+       }
+
+       if (!__calculator_calculate_formula_parse
+           (result, &tree, g_stack, end_idx, error_msg)) {
+               if (tree != NULL) {
+                       __calculator_tree_destroy_all(&tree);
+               } else {
+                       LOGD("current tree is null\n");
+               }
+               return FALSE;
+       }
+       if (!__calculator_calculate_exec(tree, &result, error_msg)) {
+               if (tree != NULL) {
+                       __calculator_tree_destroy_all(&tree);
+               }
+               return FALSE;
+       }
+       if (!__calculator_check_overflow(*result, error_msg)) {
+               if (tree != NULL) {
+                       __calculator_tree_destroy_all(&tree);
+               }
+               return FALSE;
+       }
+
+       if (tree != NULL)
+               __calculator_tree_destroy_all(&tree);
+       oper_num = 0;
+       return TRUE;
+}
diff --git a/theme/src/decnumber/decContext.c b/theme/src/decnumber/decContext.c
new file mode 100644 (file)
index 0000000..5ff92a7
--- /dev/null
@@ -0,0 +1,478 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Context module                                             */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2009.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for handling arithmetic         */
+/* context structures.                                                */
+/* ------------------------------------------------------------------ */
+
+#include <string.h>            // for strcmp
+#include <stdio.h>             // for printf if DECCHECK
+#include "decContext.h"                // context and base types
+#include "decNumberLocal.h"    // decNumber local types, etc.
+
+/* compile-time endian tester [assumes sizeof(Int)>1] */
+static const Int mfcone = 1;   // constant 1
+static const Flag *mfctop = (const Flag *)&mfcone;     // -> top byte
+#define LITEND *mfctop         // named flag; 1=little-endian
+
+/* ------------------------------------------------------------------ */
+/* round-for-reround digits                                           */
+/* ------------------------------------------------------------------ */
+const uByte DECSTICKYTAB[10] = { 1, 1, 2, 3, 4, 6, 6, 7, 8, 9 };       /* used if sticky */
+
+/* ------------------------------------------------------------------ */
+/* Powers of ten (powers[n]==10**n, 0<=n<=9)                          */
+/* ------------------------------------------------------------------ */
+const uInt DECPOWERS[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
+       10000000, 100000000, 1000000000
+};
+
+/* ------------------------------------------------------------------ */
+/* decContextClearStatus -- clear bits in current status              */
+/*                                                                    */
+/*  context is the context structure to be queried                    */
+/*  mask indicates the bits to be cleared (the status bit that        */
+/*    corresponds to each 1 bit in the mask is cleared)               */
+/*  returns context                                                   */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextClearStatus(decContext * context, uInt mask)
+{
+       context->status &= ~mask;
+       return context;
+}                              // decContextClearStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextDefault -- initialize a context structure                */
+/*                                                                    */
+/*  context is the structure to be initialized                        */
+/*  kind selects the required set of default values, one of:          */
+/*      DEC_INIT_BASE       -- select ANSI X3-274 defaults            */
+/*      DEC_INIT_DECIMAL32  -- select IEEE 754 defaults, 32-bit       */
+/*      DEC_INIT_DECIMAL64  -- select IEEE 754 defaults, 64-bit       */
+/*      DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit      */
+/*      For any other value a valid context is returned, but with     */
+/*      Invalid_operation set in the status field.                    */
+/*  returns a context structure with the appropriate initial values.  */
+/* ------------------------------------------------------------------ */
+decContext *decContextDefault(decContext * context, Int kind)
+{
+       // set defaults...
+       context->digits = 9;    // 9 digits
+       context->emax = DEC_MAX_EMAX;   // 9-digit exponents
+       context->emin = DEC_MIN_EMIN;   // .. balanced
+       context->round = DEC_ROUND_HALF_UP;     // 0.5 rises
+       context->traps = DEC_Errors;    // all but informational
+       context->status = 0;    // cleared
+       context->clamp = 0;     // no clamping
+#if DECSUBSET
+       context->extended = 0;  // cleared
+#endif
+       switch (kind) {
+       case DEC_INIT_BASE:
+               // [use defaults]
+               break;
+       case DEC_INIT_DECIMAL32:
+               context->digits = 7;    // digits
+               context->emax = 96;     // Emax
+               context->emin = -95;    // Emin
+               context->round = DEC_ROUND_HALF_EVEN;   // 0.5 to nearest even
+               context->traps = 0;     // no traps set
+               context->clamp = 1;     // clamp exponents
+#if DECSUBSET
+               context->extended = 1;  // set
+#endif
+               break;
+       case DEC_INIT_DECIMAL64:
+               context->digits = 16;   // digits
+               context->emax = 384;    // Emax
+               context->emin = -383;   // Emin
+               context->round = DEC_ROUND_HALF_EVEN;   // 0.5 to nearest even
+               context->traps = 0;     // no traps set
+               context->clamp = 1;     // clamp exponents
+#if DECSUBSET
+               context->extended = 1;  // set
+#endif
+               break;
+       case DEC_INIT_DECIMAL128:
+               context->digits = 34;   // digits
+               context->emax = 6144;   // Emax
+               context->emin = -6143;  // Emin
+               context->round = DEC_ROUND_HALF_EVEN;   // 0.5 to nearest even
+               context->traps = 0;     // no traps set
+               context->clamp = 1;     // clamp exponents
+#if DECSUBSET
+               context->extended = 1;  // set
+#endif
+               break;
+
+       default:                // invalid Kind
+               // use defaults, and ..
+               decContextSetStatus(context, DEC_Invalid_operation);    // trap
+       }
+
+       return context;
+}                              // decContextDefault
+
+/* ------------------------------------------------------------------ */
+/* decContextGetRounding -- return current rounding mode              */
+/*                                                                    */
+/*  context is the context structure to be queried                    */
+/*  returns the rounding mode                                         */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+enum rounding decContextGetRounding(decContext * context)
+{
+       return context->round;
+}                              // decContextGetRounding
+
+/* ------------------------------------------------------------------ */
+/* decContextGetStatus -- return current status                       */
+/*                                                                    */
+/*  context is the context structure to be queried                    */
+/*  returns status                                                    */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+uInt decContextGetStatus(decContext * context)
+{
+       return context->status;
+}                              // decContextGetStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextRestoreStatus -- restore bits in current status          */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  newstatus is the source for the bits to be restored               */
+/*  mask indicates the bits to be restored (the status bit that       */
+/*    corresponds to each 1 bit in the mask is set to the value of    */
+/*    the correspnding bit in newstatus)                              */
+/*  returns context                                                   */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextRestoreStatus(decContext * context,
+                                   uInt newstatus, uInt mask)
+{
+       context->status &= ~mask;       // clear the selected bits
+       context->status |= (mask & newstatus);  // or in the new bits
+       return context;
+}                              // decContextRestoreStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextSaveStatus -- save bits in current status                */
+/*                                                                    */
+/*  context is the context structure to be queried                    */
+/*  mask indicates the bits to be saved (the status bits that         */
+/*    correspond to each 1 bit in the mask are saved)                 */
+/*  returns the AND of the mask and the current status                */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+uInt decContextSaveStatus(decContext * context, uInt mask)
+{
+       return context->status & mask;
+}                              // decContextSaveStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextSetRounding -- set current rounding mode                 */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  newround is the value which will replace the current mode         */
+/*  returns context                                                   */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetRounding(decContext * context, enum rounding newround)
+{
+       context->round = newround;
+       return context;
+}                              // decContextSetRounding
+
+/* ------------------------------------------------------------------ */
+/* decContextSetStatus -- set status and raise trap if appropriate    */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  status  is the DEC_ exception code                                */
+/*  returns the context structure                                     */
+/*                                                                    */
+/* Control may never return from this routine, if there is a signal   */
+/* handler and it takes a long jump.                                  */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetStatus(decContext * context, uInt status)
+{
+       context->status |= status;
+       if (status & context->traps)
+               raise(SIGFPE);
+       return context;
+}                              // decContextSetStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextSetStatusFromString -- set status from a string + trap   */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  string is a string exactly equal to one that might be returned    */
+/*            by decContextStatusToString                             */
+/*                                                                    */
+/*  The status bit corresponding to the string is set, and a trap     */
+/*  is raised if appropriate.                                         */
+/*                                                                    */
+/*  returns the context structure, unless the string is equal to      */
+/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
+/*    returned.                                                       */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetStatusFromString(decContext * context,
+                                         const char *string)
+{
+       if (strcmp(string, DEC_Condition_CS) == 0)
+               return decContextSetStatus(context, DEC_Conversion_syntax);
+       if (strcmp(string, DEC_Condition_DZ) == 0)
+               return decContextSetStatus(context, DEC_Division_by_zero);
+       if (strcmp(string, DEC_Condition_DI) == 0)
+               return decContextSetStatus(context, DEC_Division_impossible);
+       if (strcmp(string, DEC_Condition_DU) == 0)
+               return decContextSetStatus(context, DEC_Division_undefined);
+       if (strcmp(string, DEC_Condition_IE) == 0)
+               return decContextSetStatus(context, DEC_Inexact);
+       if (strcmp(string, DEC_Condition_IS) == 0)
+               return decContextSetStatus(context, DEC_Insufficient_storage);
+       if (strcmp(string, DEC_Condition_IC) == 0)
+               return decContextSetStatus(context, DEC_Invalid_context);
+       if (strcmp(string, DEC_Condition_IO) == 0)
+               return decContextSetStatus(context, DEC_Invalid_operation);
+#if DECSUBSET
+       if (strcmp(string, DEC_Condition_LD) == 0)
+               return decContextSetStatus(context, DEC_Lost_digits);
+#endif
+       if (strcmp(string, DEC_Condition_OV) == 0)
+               return decContextSetStatus(context, DEC_Overflow);
+       if (strcmp(string, DEC_Condition_PA) == 0)
+               return decContextSetStatus(context, DEC_Clamped);
+       if (strcmp(string, DEC_Condition_RO) == 0)
+               return decContextSetStatus(context, DEC_Rounded);
+       if (strcmp(string, DEC_Condition_SU) == 0)
+               return decContextSetStatus(context, DEC_Subnormal);
+       if (strcmp(string, DEC_Condition_UN) == 0)
+               return decContextSetStatus(context, DEC_Underflow);
+       if (strcmp(string, DEC_Condition_ZE) == 0)
+               return context;
+       return NULL;            // Multiple status, or unknown
+}                              // decContextSetStatusFromString
+
+/* ------------------------------------------------------------------ */
+/* decContextSetStatusFromStringQuiet -- set status from a string     */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  string is a string exactly equal to one that might be returned    */
+/*            by decContextStatusToString                             */
+/*                                                                    */
+/*  The status bit corresponding to the string is set; no trap is     */
+/*  raised.                                                           */
+/*                                                                    */
+/*  returns the context structure, unless the string is equal to      */
+/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
+/*    returned.                                                       */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetStatusFromStringQuiet(decContext * context,
+                                              const char *string)
+{
+       if (strcmp(string, DEC_Condition_CS) == 0)
+               return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
+       if (strcmp(string, DEC_Condition_DZ) == 0)
+               return decContextSetStatusQuiet(context, DEC_Division_by_zero);
+       if (strcmp(string, DEC_Condition_DI) == 0)
+               return decContextSetStatusQuiet(context,
+                                               DEC_Division_impossible);
+       if (strcmp(string, DEC_Condition_DU) == 0)
+               return decContextSetStatusQuiet(context,
+                                               DEC_Division_undefined);
+       if (strcmp(string, DEC_Condition_IE) == 0)
+               return decContextSetStatusQuiet(context, DEC_Inexact);
+       if (strcmp(string, DEC_Condition_IS) == 0)
+               return decContextSetStatusQuiet(context,
+                                               DEC_Insufficient_storage);
+       if (strcmp(string, DEC_Condition_IC) == 0)
+               return decContextSetStatusQuiet(context, DEC_Invalid_context);
+       if (strcmp(string, DEC_Condition_IO) == 0)
+               return decContextSetStatusQuiet(context, DEC_Invalid_operation);
+#if DECSUBSET
+       if (strcmp(string, DEC_Condition_LD) == 0)
+               return decContextSetStatusQuiet(context, DEC_Lost_digits);
+#endif
+       if (strcmp(string, DEC_Condition_OV) == 0)
+               return decContextSetStatusQuiet(context, DEC_Overflow);
+       if (strcmp(string, DEC_Condition_PA) == 0)
+               return decContextSetStatusQuiet(context, DEC_Clamped);
+       if (strcmp(string, DEC_Condition_RO) == 0)
+               return decContextSetStatusQuiet(context, DEC_Rounded);
+       if (strcmp(string, DEC_Condition_SU) == 0)
+               return decContextSetStatusQuiet(context, DEC_Subnormal);
+       if (strcmp(string, DEC_Condition_UN) == 0)
+               return decContextSetStatusQuiet(context, DEC_Underflow);
+       if (strcmp(string, DEC_Condition_ZE) == 0)
+               return context;
+       return NULL;            // Multiple status, or unknown
+}                              // decContextSetStatusFromStringQuiet
+
+/* ------------------------------------------------------------------ */
+/* decContextSetStatusQuiet -- set status without trap                */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  status  is the DEC_ exception code                                */
+/*  returns the context structure                                     */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextSetStatusQuiet(decContext * context, uInt status)
+{
+       context->status |= status;
+       return context;
+}                              // decContextSetStatusQuiet
+
+/* ------------------------------------------------------------------ */
+/* decContextStatusToString -- convert status flags to a string       */
+/*                                                                    */
+/*  context is a context with valid status field                      */
+/*                                                                    */
+/*  returns a constant string describing the condition.  If multiple  */
+/*    (or no) flags are set, a generic constant message is returned.  */
+/* ------------------------------------------------------------------ */
+const char *decContextStatusToString(const decContext * context)
+{
+       Int status = context->status;
+
+       // test the five IEEE first, as some of the others are ambiguous when
+       // DECEXTFLAG=0
+       if (status == DEC_Invalid_operation)
+               return DEC_Condition_IO;
+       if (status == DEC_Division_by_zero)
+               return DEC_Condition_DZ;
+       if (status == DEC_Overflow)
+               return DEC_Condition_OV;
+       if (status == DEC_Underflow)
+               return DEC_Condition_UN;
+       if (status == DEC_Inexact)
+               return DEC_Condition_IE;
+
+       if (status == DEC_Division_impossible)
+               return DEC_Condition_DI;
+       if (status == DEC_Division_undefined)
+               return DEC_Condition_DU;
+       if (status == DEC_Rounded)
+               return DEC_Condition_RO;
+       if (status == DEC_Clamped)
+               return DEC_Condition_PA;
+       if (status == DEC_Subnormal)
+               return DEC_Condition_SU;
+       if (status == DEC_Conversion_syntax)
+               return DEC_Condition_CS;
+       if (status == DEC_Insufficient_storage)
+               return DEC_Condition_IS;
+       if (status == DEC_Invalid_context)
+               return DEC_Condition_IC;
+#if DECSUBSET
+       if (status == DEC_Lost_digits)
+               return DEC_Condition_LD;
+#endif
+       if (status == 0)
+               return DEC_Condition_ZE;
+       return DEC_Condition_MU;        // Multiple errors
+}                              // decContextStatusToString
+
+/* ------------------------------------------------------------------ */
+/* decContextTestEndian -- test whether DECLITEND is set correctly    */
+/*                                                                    */
+/*  quiet is 1 to suppress message; 0 otherwise                       */
+/*  returns 0 if DECLITEND is correct                                 */
+/*          1 if DECLITEND is incorrect and should be 1               */
+/*         -1 if DECLITEND is incorrect and should be 0               */
+/*                                                                    */
+/* A message is displayed if the return value is not 0 and quiet==0.  */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+Int decContextTestEndian(Flag quiet)
+{
+       Int res = 0;            // optimist
+       uInt dle = (uInt) DECLITEND;    // unsign
+       if (dle > 1)
+               dle = 1;        // ensure 0 or 1
+
+       if (LITEND != DECLITEND) {
+               if (!quiet) {   // always refer to this
+#if DECPRINT
+                       const char *adj;
+                       if (LITEND)
+                               adj = "little";
+                       else
+                               adj = "big";
+                       printf
+                           ("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
+                            DECLITEND, adj);
+#endif
+               }
+               res = (Int) LITEND - dle;
+       }
+       return res;
+}                              // decContextTestEndian
+
+/* ------------------------------------------------------------------ */
+/* decContextTestSavedStatus -- test bits in saved status             */
+/*                                                                    */
+/*  oldstatus is the status word to be tested                         */
+/*  mask indicates the bits to be tested (the oldstatus bits that     */
+/*    correspond to each 1 bit in the mask are tested)                */
+/*  returns 1 if any of the tested bits are 1, or 0 otherwise         */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+uInt decContextTestSavedStatus(uInt oldstatus, uInt mask)
+{
+       return (oldstatus & mask) != 0;
+}                              // decContextTestSavedStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextTestStatus -- test bits in current status                */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  mask indicates the bits to be tested (the status bits that        */
+/*    correspond to each 1 bit in the mask are tested)                */
+/*  returns 1 if any of the tested bits are 1, or 0 otherwise         */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+uInt decContextTestStatus(decContext * context, uInt mask)
+{
+       return (context->status & mask) != 0;
+}                              // decContextTestStatus
+
+/* ------------------------------------------------------------------ */
+/* decContextZeroStatus -- clear all status bits                      */
+/*                                                                    */
+/*  context is the context structure to be updated                    */
+/*  returns context                                                   */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decContext *decContextZeroStatus(decContext * context)
+{
+       context->status = 0;
+       return context;
+}                              // decContextZeroStatus
diff --git a/theme/src/decnumber/decContext.h b/theme/src/decnumber/decContext.h
new file mode 100644 (file)
index 0000000..2a8550a
--- /dev/null
@@ -0,0 +1,255 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Context module header                                      */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2010.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+/*                                                                    */
+/* Context variables must always have valid values:                   */
+/*                                                                    */
+/*  status   -- [any bits may be cleared, but not set, by user]       */
+/*  round    -- must be one of the enumerated rounding modes          */
+/*                                                                    */
+/* The following variables are implied for fixed size formats (i.e.,  */
+/* they are ignored) but should still be set correctly in case used   */
+/* with decNumber functions:                                          */
+/*                                                                    */
+/*  clamp    -- must be either 0 or 1                                 */
+/*  digits   -- must be in the range 1 through 999999999              */
+/*  emax     -- must be in the range 0 through 999999999              */
+/*  emin     -- must be in the range 0 through -999999999             */
+/*  extended -- must be either 0 or 1 [present only if DECSUBSET]     */
+/*  traps    -- only defined bits may be set                          */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+
+#if !defined(DECCONTEXT)
+#define DECCONTEXT
+#define DECCNAME     "decContext"      /* Short name */
+#define DECCFULLNAME "Decimal Context Descriptor"      /* Verbose name */
+#define DECCAUTHOR   "Mike Cowlishaw"  /* Who to blame */
+
+#if !defined(int32_t)
+#include <stdint.h>            /* C99 standard integers           */
+#endif
+#include <stdio.h>             /* for printf, etc.                */
+#include <signal.h>            /* for traps                       */
+
+  /* Extended flags setting -- set this to 0 to use only IEEE flags   */
+#if !defined(DECEXTFLAG)
+#define DECEXTFLAG 1           /* 1=enable extended flags         */
+#endif
+
+  /* Conditional code flag -- set this to 0 for best performance      */
+#if !defined(DECSUBSET)
+#define DECSUBSET  0           /* 1=enable subset arithmetic      */
+#endif
+
+  /* Context for operations, with associated constants                */
+enum rounding {
+       DEC_ROUND_CEILING,      /* round towards +infinity         */
+       DEC_ROUND_UP,           /* round away from 0               */
+       DEC_ROUND_HALF_UP,      /* 0.5 rounds up                   */
+       DEC_ROUND_HALF_EVEN,    /* 0.5 rounds to nearest even      */
+       DEC_ROUND_HALF_DOWN,    /* 0.5 rounds down                 */
+       DEC_ROUND_DOWN,         /* round towards 0 (truncate)      */
+       DEC_ROUND_FLOOR,        /* round towards -infinity         */
+       DEC_ROUND_05UP,         /* round for reround               */
+       DEC_ROUND_MAX           /* enum must be less than this     */
+};
+#define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
+
+typedef struct {
+       int32_t digits;         /* working precision               */
+       int32_t emax;           /* maximum positive exponent       */
+       int32_t emin;           /* minimum negative exponent       */
+       enum rounding round;    /* rounding mode                   */
+       uint32_t traps;         /* trap-enabler flags              */
+       uint32_t status;        /* status flags                    */
+       uint8_t clamp;          /* flag: apply IEEE exponent clamp */
+#if DECSUBSET
+       uint8_t extended;       /* flag: special-values allowed    */
+#endif
+} decContext;
+
+  /* Maxima and Minima for context settings                           */
+#define DEC_MAX_DIGITS 999999999
+#define DEC_MIN_DIGITS         1
+#define DEC_MAX_EMAX   999999999
+#define DEC_MIN_EMAX           0
+#define DEC_MAX_EMIN           0
+#define DEC_MIN_EMIN  -999999999
+#define DEC_MAX_MATH      999999       /* max emax, etc., for math funcs. */
+
+  /* Classifications for decimal numbers, aligned with 754 (note that */
+  /* 'normal' and 'subnormal' are meaningful only with a decContext   */
+  /* or a fixed size format).                                         */
+enum decClass {
+       DEC_CLASS_SNAN,
+       DEC_CLASS_QNAN,
+       DEC_CLASS_NEG_INF,
+       DEC_CLASS_NEG_NORMAL,
+       DEC_CLASS_NEG_SUBNORMAL,
+       DEC_CLASS_NEG_ZERO,
+       DEC_CLASS_POS_ZERO,
+       DEC_CLASS_POS_SUBNORMAL,
+       DEC_CLASS_POS_NORMAL,
+       DEC_CLASS_POS_INF
+};
+  /* Strings for the decClasses */
+#define DEC_ClassString_SN  "sNaN"
+#define DEC_ClassString_QN  "NaN"
+#define DEC_ClassString_NI  "-Infinity"
+#define DEC_ClassString_NN  "-Normal"
+#define DEC_ClassString_NS  "-Subnormal"
+#define DEC_ClassString_NZ  "-Zero"
+#define DEC_ClassString_PZ  "+Zero"
+#define DEC_ClassString_PS  "+Subnormal"
+#define DEC_ClassString_PN  "+Normal"
+#define DEC_ClassString_PI  "+Infinity"
+#define DEC_ClassString_UN  "Invalid"
+
+  /* Trap-enabler and Status flags (exceptional conditions), and      */
+  /* their names.  The top byte is reserved for internal use          */
+#if DECEXTFLAG
+    /* Extended flags */
+#define DEC_Conversion_syntax    0x00000001
+#define DEC_Division_by_zero     0x00000002
+#define DEC_Division_impossible  0x00000004
+#define DEC_Division_undefined   0x00000008
+#define DEC_Insufficient_storage 0x00000010    /* [when malloc fails]  */
+#define DEC_Inexact              0x00000020
+#define DEC_Invalid_context      0x00000040
+#define DEC_Invalid_operation    0x00000080
+#if DECSUBSET
+#define DEC_Lost_digits          0x00000100
+#endif
+#define DEC_Overflow             0x00000200
+#define DEC_Clamped              0x00000400
+#define DEC_Rounded              0x00000800
+#define DEC_Subnormal            0x00001000
+#define DEC_Underflow            0x00002000
+#else
+    /* IEEE flags only */
+#define DEC_Conversion_syntax    0x00000010
+#define DEC_Division_by_zero     0x00000002
+#define DEC_Division_impossible  0x00000010
+#define DEC_Division_undefined   0x00000010
+#define DEC_Insufficient_storage 0x00000010    /* [when malloc fails]  */
+#define DEC_Inexact              0x00000001
+#define DEC_Invalid_context      0x00000010
+#define DEC_Invalid_operation    0x00000010
+#if DECSUBSET
+#define DEC_Lost_digits          0x00000000
+#endif
+#define DEC_Overflow             0x00000008
+#define DEC_Clamped              0x00000000
+#define DEC_Rounded              0x00000000
+#define DEC_Subnormal            0x00000000
+#define DEC_Underflow            0x00000004
+#endif
+
+  /* IEEE 754 groupings for the flags                                 */
+  /* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal    */
+  /* are not in IEEE 754]                                             */
+#define DEC_IEEE_754_Division_by_zero  (DEC_Division_by_zero)
+#if DECSUBSET
+#define DEC_IEEE_754_Inexact           (DEC_Inexact | DEC_Lost_digits)
+#else
+#define DEC_IEEE_754_Inexact           (DEC_Inexact)
+#endif
+#define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax |     \
+                                          DEC_Division_impossible |   \
+                                          DEC_Division_undefined |    \
+                                          DEC_Insufficient_storage |  \
+                                          DEC_Invalid_context |       \
+                                          DEC_Invalid_operation)
+#define DEC_IEEE_754_Overflow          (DEC_Overflow)
+#define DEC_IEEE_754_Underflow         (DEC_Underflow)
+
+  /* flags which are normally errors (result is qNaN, infinite, or 0) */
+#define DEC_Errors (DEC_IEEE_754_Division_by_zero |                 \
+                      DEC_IEEE_754_Invalid_operation |                \
+                      DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)
+  /* flags which cause a result to become qNaN                        */
+#define DEC_NaNs    DEC_IEEE_754_Invalid_operation
+
+  /* flags which are normally for information only (finite results)   */
+#if DECSUBSET
+#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact    \
+                          | DEC_Lost_digits)
+#else
+#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
+#endif
+
+  /* IEEE 854 names (for compatibility with older decNumber versions) */
+#define DEC_IEEE_854_Division_by_zero  DEC_IEEE_754_Division_by_zero
+#define DEC_IEEE_854_Inexact           DEC_IEEE_754_Inexact
+#define DEC_IEEE_854_Invalid_operation DEC_IEEE_754_Invalid_operation
+#define DEC_IEEE_854_Overflow          DEC_IEEE_754_Overflow
+#define DEC_IEEE_854_Underflow         DEC_IEEE_754_Underflow
+
+  /* Name strings for the exceptional conditions                      */
+#define DEC_Condition_CS "Conversion syntax"
+#define DEC_Condition_DZ "Division by zero"
+#define DEC_Condition_DI "Division impossible"
+#define DEC_Condition_DU "Division undefined"
+#define DEC_Condition_IE "Inexact"
+#define DEC_Condition_IS "Insufficient storage"
+#define DEC_Condition_IC "Invalid context"
+#define DEC_Condition_IO "Invalid operation"
+#if DECSUBSET
+#define DEC_Condition_LD "Lost digits"
+#endif
+#define DEC_Condition_OV "Overflow"
+#define DEC_Condition_PA "Clamped"
+#define DEC_Condition_RO "Rounded"
+#define DEC_Condition_SU "Subnormal"
+#define DEC_Condition_UN "Underflow"
+#define DEC_Condition_ZE "No status"
+#define DEC_Condition_MU "Multiple status"
+#define DEC_Condition_Length 21        /* length of the longest string,   */
+                                  /* including terminator            */
+
+  /* Initialization descriptors, used by decContextDefault            */
+#define DEC_INIT_BASE         0
+#define DEC_INIT_DECIMAL32   32
+#define DEC_INIT_DECIMAL64   64
+#define DEC_INIT_DECIMAL128 128
+  /* Synonyms */
+#define DEC_INIT_DECSINGLE  DEC_INIT_DECIMAL32
+#define DEC_INIT_DECDOUBLE  DEC_INIT_DECIMAL64
+#define DEC_INIT_DECQUAD    DEC_INIT_DECIMAL128
+
+  /* decContext routines                                              */
+extern decContext *decContextClearStatus(decContext *, uint32_t);
+extern decContext *decContextDefault(decContext *, int32_t);
+extern enum rounding decContextGetRounding(decContext *);
+extern uint32_t decContextGetStatus(decContext *);
+extern decContext *decContextRestoreStatus(decContext *, uint32_t, uint32_t);
+extern uint32_t decContextSaveStatus(decContext *, uint32_t);
+extern decContext *decContextSetRounding(decContext *, enum rounding);
+extern decContext *decContextSetStatus(decContext *, uint32_t);
+extern decContext *decContextSetStatusFromString(decContext *, const char *);
+extern decContext *decContextSetStatusFromStringQuiet(decContext *,
+                                                     const char *);
+extern decContext *decContextSetStatusQuiet(decContext *, uint32_t);
+extern const char *decContextStatusToString(const decContext *);
+extern int32_t decContextTestEndian(uint8_t);
+extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
+extern uint32_t decContextTestStatus(decContext *, uint32_t);
+extern decContext *decContextZeroStatus(decContext *);
+
+#endif
diff --git a/theme/src/decnumber/decNumber.c b/theme/src/decnumber/decNumber.c
new file mode 100644 (file)
index 0000000..a769132
--- /dev/null
@@ -0,0 +1,8983 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Number arithmetic module                                   */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2009.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for arbitrary-precision General */
+/* Decimal Arithmetic as defined in the specification which may be    */
+/* found on the General Decimal Arithmetic pages.  It implements both */
+/* the full ('extended') arithmetic and the simpler ('subset')        */
+/* arithmetic.                                                        */
+/*                                                                    */
+/* Usage notes:                                                       */
+/*                                                                    */
+/* 1. This code is ANSI C89 except:                                   */
+/*                                                                    */
+/*    a) C99 line comments (double forward slash) are used.  (Most C  */
+/*       compilers accept these.  If yours does not, a simple script  */
+/*       can be used to convert them to ANSI C comments.)             */
+/*                                                                    */
+/*    b) Types from C99 stdint.h are used.  If you do not have this   */
+/*       header file, see the User's Guide section of the decNumber   */
+/*       documentation; this lists the necessary definitions.         */
+/*                                                                    */
+/*    c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and       */
+/*       uint64_t types may be used.  To avoid these, set DECUSE64=0  */
+/*       and DECDPUN<=4 (see documentation).                          */
+/*                                                                    */
+/*    The code also conforms to C99 restrictions; in particular,      */
+/*    strict aliasing rules are observed.                             */
+/*                                                                    */
+/* 2. The decNumber format which this library uses is optimized for   */
+/*    efficient processing of relatively short numbers; in particular */
+/*    it allows the use of fixed sized structures and minimizes copy  */
+/*    and move operations.  It does, however, support arbitrary       */
+/*    precision (up to 999,999,999 digits) and arbitrary exponent     */
+/*    range (Emax in the range 0 through 999,999,999 and Emin in the  */
+/*    range -999,999,999 through 0).  Mathematical functions (for     */
+/*    example decNumberExp) as identified below are restricted more   */
+/*    tightly: digits, emax, and -emin in the context must be <=      */
+/*    DEC_MAX_MATH (999999), and their operand(s) must be within      */
+/*    these bounds.                                                   */
+/*                                                                    */
+/* 3. Logical functions are further restricted; their operands must   */
+/*    be finite, positive, have an exponent of zero, and all digits   */
+/*    must be either 0 or 1.  The result will only contain digits     */
+/*    which are 0 or 1 (and will have exponent=0 and a sign of 0).    */
+/*                                                                    */
+/* 4. Operands to operator functions are never modified unless they   */
+/*    are also specified to be the result number (which is always     */
+/*    permitted).  Other than that case, operands must not overlap.   */
+/*                                                                    */
+/* 5. Error handling: the type of the error is ORed into the status   */
+/*    flags in the current context (decContext structure).  The       */
+/*    SIGFPE signal is then raised if the corresponding trap-enabler  */
+/*    flag in the decContext is set (is 1).                           */
+/*                                                                    */
+/*    It is the responsibility of the caller to clear the status      */
+/*    flags as required.                                              */
+/*                                                                    */
+/*    The result of any routine which returns a number will always    */
+/*    be a valid number (which may be a special value, such as an     */
+/*    Infinity or NaN).                                               */
+/*                                                                    */
+/* 6. The decNumber format is not an exchangeable concrete            */
+/*    representation as it comprises fields which may be machine-     */
+/*    dependent (packed or unpacked, or special length, for example). */
+/*    Canonical conversions to and from strings are provided; other   */
+/*    conversions are available in separate modules.                  */
+/*                                                                    */
+/* 7. Normally, input operands are assumed to be valid.  Set DECCHECK */
+/*    to 1 for extended operand checking (including NULL operands).   */
+/*    Results are undefined if a badly-formed structure (or a NULL    */
+/*    pointer to a structure) is provided, though with DECCHECK       */
+/*    enabled the operator routines are protected against exceptions. */
+/*    (Except if the result pointer is NULL, which is unrecoverable.) */
+/*                                                                    */
+/*    However, the routines will never cause exceptions if they are   */
+/*    given well-formed operands, even if the value of the operands   */
+/*    is inappropriate for the operation and DECCHECK is not set.     */
+/*    (Except for SIGFPE, as and where documented.)                   */
+/*                                                                    */
+/* 8. Subset arithmetic is available only if DECSUBSET is set to 1.   */
+/* ------------------------------------------------------------------ */
+/* Implementation notes for maintenance of this module:               */
+/*                                                                    */
+/* 1. Storage leak protection:  Routines which use malloc are not     */
+/*    permitted to use return for fastpath or error exits (i.e.,      */
+/*    they follow strict structured programming conventions).         */
+/*    Instead they have a do{}while(0); construct surrounding the     */
+/*    code which is protected -- break may be used to exit this.      */
+/*    Other routines can safely use the return statement inline.      */
+/*                                                                    */
+/*    Storage leak accounting can be enabled using DECALLOC.          */
+/*                                                                    */
+/* 2. All loops use the for(;;) construct.  Any do construct does     */
+/*    not loop; it is for allocation protection as just described.    */
+/*                                                                    */
+/* 3. Setting status in the context must always be the very last      */
+/*    action in a routine, as non-0 status may raise a trap and hence */
+/*    the call to set status may not return (if the handler uses long */
+/*    jump).  Therefore all cleanup must be done first.  In general,  */
+/*    to achieve this status is accumulated and is only applied just  */
+/*    before return by calling decContextSetStatus (via decStatus).   */
+/*                                                                    */
+/*    Routines which allocate storage cannot, in general, use the     */
+/*    'top level' routines which could cause a non-returning          */
+/*    transfer of control.  The decXxxxOp routines are safe (do not   */
+/*    call decStatus even if traps are set in the context) and should */
+/*    be used instead (they are also a little faster).                */
+/*                                                                    */
+/* 4. Exponent checking is minimized by allowing the exponent to      */
+/*    grow outside its limits during calculations, provided that      */
+/*    the decFinalize function is called later.  Multiplication and   */
+/*    division, and intermediate calculations in exponentiation,      */
+/*    require more careful checks because of the risk of 31-bit       */
+/*    overflow (the most negative valid exponent is -1999999997, for  */
+/*    a 999999999-digit number with adjusted exponent of -999999999). */
+/*                                                                    */
+/* 5. Rounding is deferred until finalization of results, with any    */
+/*    'off to the right' data being represented as a single digit     */
+/*    residue (in the range -1 through 9).  This avoids any double-   */
+/*    rounding when more than one shortening takes place (for         */
+/*    example, when a result is subnormal).                           */
+/*                                                                    */
+/* 6. The digits count is allowed to rise to a multiple of DECDPUN    */
+/*    during many operations, so whole Units are handled and exact    */
+/*    accounting of digits is not needed.  The correct digits value   */
+/*    is found by decGetDigits, which accounts for leading zeros.     */
+/*    This must be called before any rounding if the number of digits */
+/*    is not known exactly.                                           */
+/*                                                                    */
+/* 7. The multiply-by-reciprocal 'trick' is used for partitioning     */
+/*    numbers up to four digits, using appropriate constants.  This   */
+/*    is not useful for longer numbers because overflow of 32 bits    */
+/*    would lead to 4 multiplies, which is almost as expensive as     */
+/*    a divide (unless a floating-point or 64-bit multiply is         */
+/*    assumed to be available).                                       */
+/*                                                                    */
+/* 8. Unusual abbreviations that may be used in the commentary:       */
+/*      lhs -- left hand side (operand, of an operation)              */
+/*      lsd -- least significant digit (of coefficient)               */
+/*      lsu -- least significant Unit (of coefficient)                */
+/*      msd -- most significant digit (of coefficient)                */
+/*      msi -- most significant item (in an array)                    */
+/*      msu -- most significant Unit (of coefficient)                 */
+/*      rhs -- right hand side (operand, of an operation)             */
+/*      +ve -- positive                                               */
+/*      -ve -- negative                                               */
+/*      **  -- raise to the power                                     */
+/* ------------------------------------------------------------------ */
+
+#include <stdlib.h>            // for malloc, free, etc.
+#include <stdio.h>             // for printf [if needed]
+#include <string.h>            // for strcpy
+#include <ctype.h>             // for lower
+#include "decNumber.h"         // base number library
+#include "decNumberLocal.h"    // decNumber local types, etc.
+
+/* Constants */
+// Public lookup table used by the D2U macro
+const uByte d2utable[DECMAXD2U + 1] = D2UTABLE;
+
+#define DECVERB     1          // set to 1 for verbose DECCHECK
+#define powers      DECPOWERS  // old internal name
+
+// Local constants
+#define DIVIDE      0x80       // Divide operators
+#define REMAINDER   0x40       // ..
+#define DIVIDEINT   0x20       // ..
+#define REMNEAR     0x10       // ..
+#define COMPARE     0x01       // Compare operators
+#define COMPMAX     0x02       // ..
+#define COMPMIN     0x03       // ..
+#define COMPTOTAL   0x04       // ..
+#define COMPNAN     0x05       // .. [NaN processing]
+#define COMPSIG     0x06       // .. [signaling COMPARE]
+#define COMPMAXMAG  0x07       // ..
+#define COMPMINMAG  0x08       // ..
+
+#define DEC_sNaN     0x40000000        // local status: sNaN signal
+#define BADINT  (Int)0x80000000        // most-negative Int; error indicator
+// Next two indicate an integer >= 10**6, and its parity (bottom bit)
+#define BIGEVEN (Int)0x80000002
+#define BIGODD  (Int)0x80000003
+
+static Unit uarrone[1] = { 1 };        // Unit array of 1, used for incrementing
+
+/* Granularity-dependent code */
+#if DECDPUN<=4
+#define eInt  Int              // extended integer
+#define ueInt uInt             // unsigned extended integer
+  // Constant multipliers for divide-by-power-of five using reciprocal
+  // multiply, after removing powers of 2 by shifting, and final shift
+  // of 17 [we only need up to **4]
+static const uInt multies[] = { 131073, 26215, 5243, 1049, 210 };
+
+  // QUOT10 -- macro to return the quotient of unit u divided by 10**n
+#define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
+#else
+  // For DECDPUN>4 non-ANSI-89 64-bit types are needed.
+#if !DECUSE64
+#error decNumber.c: DECUSE64 must be 1 when DECDPUN>4
+#endif
+#define eInt  Long             // extended integer
+#define ueInt uLong            // unsigned extended integer
+#endif
+
+/* Local routines */
+static decNumber *decAddOp(decNumber *, const decNumber *, const decNumber *,
+                          decContext *, uByte, uInt *);
+static Flag decBiStr(const char *, const char *, const char *);
+static uInt decCheckMath(const decNumber *, decContext *, uInt *);
+static void decApplyRound(decNumber *, decContext *, Int, uInt *);
+static Int decCompare(const decNumber * lhs, const decNumber * rhs, Flag);
+static decNumber *decCompareOp(decNumber *, const decNumber *,
+                              const decNumber *, decContext *, Flag, uInt *);
+static void decCopyFit(decNumber *, const decNumber *, decContext *,
+                      Int *, uInt *);
+static decNumber *decDecap(decNumber *, Int);
+static decNumber *decDivideOp(decNumber *, const decNumber *,
+                             const decNumber *, decContext *, Flag, uInt *);
+static decNumber *decExpOp(decNumber *, const decNumber *,
+                          decContext *, uInt *);
+static void decFinalize(decNumber *, decContext *, Int *, uInt *);
+static Int decGetDigits(Unit *, Int);
+static Int decGetInt(const decNumber *);
+static decNumber *decLnOp(decNumber *, const decNumber *, decContext *, uInt *);
+static decNumber *decMultiplyOp(decNumber *, const decNumber *,
+                               const decNumber *, decContext *, uInt *);
+static decNumber *decNaNs(decNumber *, const decNumber *,
+                         const decNumber *, decContext *, uInt *);
+static decNumber *decQuantizeOp(decNumber *, const decNumber *,
+                               const decNumber *, decContext *, Flag, uInt *);
+static void decReverse(Unit *, Unit *);
+static void decSetCoeff(decNumber *, decContext *, const Unit *,
+                       Int, Int *, uInt *);
+static void decSetMaxValue(decNumber *, decContext *);
+static void decSetOverflow(decNumber *, decContext *, uInt *);
+static void decSetSubnormal(decNumber *, decContext *, Int *, uInt *);
+static Int decShiftToLeast(Unit *, Int, Int);
+static Int decShiftToMost(Unit *, Int, Int);
+static void decStatus(decNumber *, uInt, decContext *);
+static void decToString(const decNumber *, char[], Flag);
+static decNumber *decTrim(decNumber *, decContext *, Flag, Flag, Int *);
+static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
+                        Unit *, Int);
+static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+
+#if !DECSUBSET
+/* decFinish == decFinalize when no subset arithmetic needed */
+#define decFinish(a,b,c,d) decFinalize(a,b,c,d)
+#else
+static void decFinish(decNumber *, decContext *, Int *, uInt *);
+static decNumber *decRoundOperand(const decNumber *, decContext *, uInt *);
+#endif
+
+/* Local macros */
+// masked special-values bits
+#define SPECIALARG  (rhs->bits & DECSPECIAL)
+#define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)
+
+/* Diagnostic macros, etc. */
+#if DECALLOC
+// Handle malloc/free accounting.  If enabled, our accountable routines
+// are used; otherwise the code just goes straight to the system malloc
+// and free routines.
+#define malloc(a) decMalloc(a)
+#define free(a) decFree(a)
+#define DECFENCE 0x5a          // corruption detector
+// 'Our' malloc and free:
+static void *decMalloc(size_t);
+static void decFree(void *);
+uInt decAllocBytes = 0;                // count of bytes allocated
+// Note that DECALLOC code only checks for storage buffer overflow.
+// To check for memory leaks, the decAllocBytes variable must be
+// checked to be 0 at appropriate times (e.g., after the test
+// harness completes a set of tests).  This checking may be unreliable
+// if the testing is done in a multi-thread environment.
+#endif
+
+#if DECCHECK
+// Optional checking routines.  Enabling these means that decNumber
+// and decContext operands to operator routines are checked for
+// correctness.  This roughly doubles the execution time of the
+// fastest routines (and adds 600+ bytes), so should not normally be
+// used in 'production'.
+// decCheckInexact is used to check that inexact results have a full
+// complement of digits (where appropriate -- this is not the case
+// for Quantize, for example)
+#define DECUNRESU ((decNumber *)(void *)0xffffffff)
+#define DECUNUSED ((const decNumber *)(void *)0xffffffff)
+#define DECUNCONT ((decContext *)(void *)(0xffffffff))
+static Flag decCheckOperands(decNumber *, const decNumber *,
+                            const decNumber *, decContext *);
+static Flag decCheckNumber(const decNumber *);
+static void decCheckInexact(const decNumber *, decContext *);
+#endif
+
+#if DECTRACE || DECCHECK
+// Optional trace/debugging routines (may or may not be used)
+void decNumberShow(const decNumber *); // displays the components of a number
+static void decDumpAr(char, const Unit *, Int);
+#endif
+
+/* ================================================================== */
+/* Conversions                                                        */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* from-int32 -- conversion from Int or uInt                          */
+/*                                                                    */
+/*  dn is the decNumber to receive the integer                        */
+/*  in or uin is the integer to be converted                          */
+/*  returns dn                                                        */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberFromInt32(decNumber * dn, Int in)
+{
+       uInt unsig;
+       if (in >= 0)
+               unsig = in;
+       else {                  // negative (possibly BADINT)
+               if (in == BADINT)
+                       unsig = (uInt) 1073741824 *2;   // special case
+               else
+                       unsig = -in;    // invert
+       }
+       // in is now positive
+       decNumberFromUInt32(dn, unsig);
+       if (in < 0)
+               dn->bits = DECNEG;      // sign needed
+       return dn;
+}                              // decNumberFromInt32
+
+decNumber *decNumberFromUInt32(decNumber * dn, uInt uin)
+{
+       Unit *up;               // work pointer
+       decNumberZero(dn);      // clean
+       if (uin == 0)
+               return dn;      // [or decGetDigits bad call]
+       for (up = dn->lsu; uin > 0; up++) {
+               *up = (Unit) (uin % (DECDPUNMAX + 1));
+               uin = uin / (DECDPUNMAX + 1);
+       }
+       dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
+       return dn;
+}                              // decNumberFromUInt32
+
+/* ------------------------------------------------------------------ */
+/* to-int32 -- conversion to Int or uInt                              */
+/*                                                                    */
+/*  dn is the decNumber to convert                                    */
+/*  set is the context for reporting errors                           */
+/*  returns the converted decNumber, or 0 if Invalid is set           */
+/*                                                                    */
+/* Invalid is set if the decNumber does not have exponent==0 or if    */
+/* it is a NaN, Infinite, or out-of-range.                            */
+/* ------------------------------------------------------------------ */
+Int decNumberToInt32(const decNumber * dn, decContext * set)
+{
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set))
+               return 0;
+#endif
+
+       // special or too many digits, or bad exponent
+       if (dn->bits & DECSPECIAL || dn->digits > 10 || dn->exponent != 0) ;    // bad
+       else {                  // is a finite integer with 10 or fewer digits
+               Int d;          // work
+               const Unit *up; // ..
+               uInt hi = 0, lo;        // ..
+               up = dn->lsu;   // -> lsu
+               lo = *up;       // get 1 to 9 digits
+#if DECDPUN>1                  // split to higher
+               hi = lo / 10;
+               lo = lo % 10;
+#endif
+               up++;
+               // collect remaining Units, if any, into hi
+               for (d = DECDPUN; d < dn->digits; up++, d += DECDPUN)
+                       hi += *up * powers[d - 1];
+               // now low has the lsd, hi the remainder
+               if (hi > 214748364 || (hi == 214748364 && lo > 7)) {    // out of range?
+                       // most-negative is a reprieve
+                       if (dn->bits & DECNEG && hi == 214748364 && lo == 8)
+                               return 0x80000000;
+                       // bad -- drop through
+               } else {        // in-range always
+                       Int i = X10(hi) + lo;
+                       if (dn->bits & DECNEG)
+                               return -i;
+                       return i;
+               }
+       }                       // integer
+       decContextSetStatus(set, DEC_Invalid_operation);        // [may not return]
+       return 0;
+}                              // decNumberToInt32
+
+uInt decNumberToUInt32(const decNumber * dn, decContext * set)
+{
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set))
+               return 0;
+#endif
+       // special or too many digits, or bad exponent, or negative (<0)
+       if (dn->bits & DECSPECIAL || dn->digits > 10 || dn->exponent != 0 || (dn->bits & DECNEG && !ISZERO(dn))) ;      // bad
+       else {                  // is a finite integer with 10 or fewer digits
+               Int d;          // work
+               const Unit *up; // ..
+               uInt hi = 0, lo;        // ..
+               up = dn->lsu;   // -> lsu
+               lo = *up;       // get 1 to 9 digits
+#if DECDPUN>1                  // split to higher
+               hi = lo / 10;
+               lo = lo % 10;
+#endif
+               up++;
+               // collect remaining Units, if any, into hi
+               for (d = DECDPUN; d < dn->digits; up++, d += DECDPUN)
+                       hi += *up * powers[d - 1];
+
+               // now low has the lsd, hi the remainder
+               if (hi > 429496729 || (hi == 429496729 && lo > 5)) ;    // no reprieve possible
+               else
+                       return X10(hi) + lo;
+       }                       // integer
+       decContextSetStatus(set, DEC_Invalid_operation);        // [may not return]
+       return 0;
+}                              // decNumberToUInt32
+
+/* ------------------------------------------------------------------ */
+/* to-scientific-string -- conversion to numeric string               */
+/* to-engineering-string -- conversion to numeric string              */
+/*                                                                    */
+/*   decNumberToString(dn, string);                                   */
+/*   decNumberToEngString(dn, string);                                */
+/*                                                                    */
+/*  dn is the decNumber to convert                                    */
+/*  string is the string where the result will be laid out            */
+/*                                                                    */
+/*  string must be at least dn->digits+14 characters long             */
+/*                                                                    */
+/*  No error is possible, and no status can be set.                   */
+/* ------------------------------------------------------------------ */
+char *decNumberToString(const decNumber * dn, char *string)
+{
+       decToString(dn, string, 0);
+       return string;
+}                              // DecNumberToString
+
+char *decNumberToEngString(const decNumber * dn, char *string)
+{
+       decToString(dn, string, 1);
+       return string;
+}                              // DecNumberToEngString
+
+/* ------------------------------------------------------------------ */
+/* to-number -- conversion from numeric string                        */
+/*                                                                    */
+/* decNumberFromString -- convert string to decNumber                 */
+/*   dn        -- the number structure to fill                        */
+/*   chars[]   -- the string to convert ('\0' terminated)             */
+/*   set       -- the context used for processing any error,          */
+/*                determining the maximum precision available         */
+/*                (set.digits), determining the maximum and minimum   */
+/*                exponent (set.emax and set.emin), determining if    */
+/*                extended values are allowed, and checking the       */
+/*                rounding mode if overflow occurs or rounding is     */
+/*                needed.                                             */
+/*                                                                    */
+/* The length of the coefficient and the size of the exponent are     */
+/* checked by this routine, so the correct error (Underflow or        */
+/* Overflow) can be reported or rounding applied, as necessary.       */
+/*                                                                    */
+/* If bad syntax is detected, the result will be a quiet NaN.         */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberFromString(decNumber * dn, const char chars[],
+                              decContext * set)
+{
+       Int exponent = 0;       // working exponent [assume 0]
+       uByte bits = 0;         // working flags [assume +ve]
+       Unit *res;              // where result will be built
+       Unit resbuff[SD2U(DECBUFFER + 9)];      // local buffer in case need temporary
+       // [+9 allows for ln() constants]
+       Unit *allocres = NULL;  // -> allocated result, iff allocated
+       Int d = 0;              // count of digits found in decimal part
+       const char *dotchar = NULL;     // where dot was found
+       const char *cfirst = chars;     // -> first character of decimal part
+       const char *last = NULL;        // -> last digit of decimal part
+       const char *c;          // work
+       Unit *up;               // ..
+#if DECDPUN>1
+       Int cut, out;           // ..
+#endif
+       Int residue;            // rounding residue
+       uInt status = 0;        // error code
+
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
+               return decNumberZero(dn);
+#endif
+
+       do {                    // status & malloc protection
+               for (c = chars;; c++) { // -> input character
+                       if (*c >= '0' && *c <= '9') {   // test for Arabic digit
+                               last = c;
+                               d++;    // count of real digits
+                               continue;       // still in decimal part
+                       }
+                       if (*c == '.' && dotchar == NULL) {     // first '.'
+                               dotchar = c;    // record offset into decimal part
+                               if (c == cfirst)
+                                       cfirst++;       // first digit must follow
+                               continue;
+                       }
+                       if (c == chars) {       // first in string...
+                               if (*c == '-') {        // valid - sign
+                                       cfirst++;
+                                       bits = DECNEG;
+                                       continue;
+                               }
+                               if (*c == '+') {        // valid + sign
+                                       cfirst++;
+                                       continue;
+                               }
+                       }
+                       // *c is not a digit, or a valid +, -, or '.'
+                       break;
+               }               // c
+
+               if (last == NULL) {     // no digits yet
+                       status = DEC_Conversion_syntax; // assume the worst
+                       if (*c == '\0')
+                               break;  // and no more to come...
+#if DECSUBSET
+                       // if subset then infinities and NaNs are not allowed
+                       if (!set->extended)
+                               break;  // hopeless
+#endif
+                       // Infinities and NaNs are possible, here
+                       if (dotchar != NULL)
+                               break;  // .. unless had a dot
+                       decNumberZero(dn);      // be optimistic
+                       if (decBiStr(c, "infinity", "INFINITY")
+                           || decBiStr(c, "inf", "INF")) {
+                               dn->bits = bits | DECINF;
+                               status = 0;     // is OK
+                               break;  // all done
+                       }
+                       // a NaN expected
+                       // 2003.09.10 NaNs are now permitted to have a sign
+                       dn->bits = bits | DECNAN;       // assume simple NaN
+                       if (*c == 's' || *c == 'S') {   // looks like an sNaN
+                               c++;
+                               dn->bits = bits | DECSNAN;
+                       }
+                       if (*c != 'n' && *c != 'N')
+                               break;  // check caseless "NaN"
+                       c++;
+                       if (*c != 'a' && *c != 'A')
+                               break;  // ..
+                       c++;
+                       if (*c != 'n' && *c != 'N')
+                               break;  // ..
+                       c++;
+                       // now either nothing, or nnnn payload, expected
+                       // -> start of integer and skip leading 0s [including plain 0]
+                       for (cfirst = c; *cfirst == '0';)
+                               cfirst++;
+                       if (*cfirst == '\0') {  // "NaN" or "sNaN", maybe with all 0s
+                               status = 0;     // it's good
+                               break;  // ..
+                       }
+                       // something other than 0s; setup last and d as usual [no dots]
+                       for (c = cfirst;; c++, d++) {
+                               if (*c < '0' || *c > '9')
+                                       break;  // test for Arabic digit
+                               last = c;
+                       }
+                       if (*c != '\0')
+                               break;  // not all digits
+                       if (d > set->digits - 1) {
+                               // [NB: payload in a decNumber can be full length unless
+                               // clamped, in which case can only be digits-1]
+                               if (set->clamp)
+                                       break;
+                               if (d > set->digits)
+                                       break;
+                       }       // too many digits?
+                       // good; drop through to convert the integer to coefficient
+                       status = 0;     // syntax is OK
+                       bits = dn->bits;        // for copy-back
+               }               // last==NULL
+
+               else if (*c != '\0') {  // more to process...
+                       // had some digits; exponent is only valid sequence now
+                       Flag nege;      // 1=negative exponent
+                       const char *firstexp;   // -> first significant exponent digit
+                       status = DEC_Conversion_syntax; // assume the worst
+                       if (*c != 'e' && *c != 'E')
+                               break;
+                       /* Found 'e' or 'E' -- now process explicit exponent */
+                       // 1998.07.11: sign no longer required
+                       nege = 0;
+                       c++;    // to (possible) sign
+                       if (*c == '-') {
+                               nege = 1;
+                               c++;
+                       } else if (*c == '+')
+                               c++;
+                       if (*c == '\0')
+                               break;
+
+                       for (; *c == '0' && *(c + 1) != '\0';)
+                               c++;    // strip insignificant zeros
+                       firstexp = c;   // save exponent digit place
+                       for (;; c++) {
+                               if (*c < '0' || *c > '9')
+                                       break;  // not a digit
+                               exponent =
+                                   X10(exponent) + (Int) * c - (Int) '0';
+                       }       // c
+                       // if not now on a '\0', *c must not be a digit
+                       if (*c != '\0')
+                               break;
+
+                       // (this next test must be after the syntax checks)
+                       // if it was too long the exponent may have wrapped, so check
+                       // carefully and set it to a certain overflow if wrap possible
+                       if (c >= firstexp + 9 + 1) {
+                               if (c > firstexp + 9 + 1 || *firstexp > '1')
+                                       exponent = DECNUMMAXE * 2;
+                               // [up to 1999999999 is OK, for example 1E-1000000998]
+                       }
+                       if (nege)
+                               exponent = -exponent;   // was negative
+                       status = 0;     // is OK
+               }               // stuff after digits
+
+               // Here when whole string has been inspected; syntax is good
+               // cfirst->first digit (never dot), last->last digit (ditto)
+
+               // strip leading zeros/dot [leave final 0 if all 0's]
+               if (*cfirst == '0') {   // [cfirst has stepped over .]
+                       for (c = cfirst; c < last; c++, cfirst++) {
+                               if (*c == '.')
+                                       continue;       // ignore dots
+                               if (*c != '0')
+                                       break;  // non-zero found
+                               d--;    // 0 stripped
+                       }       // c
+#if DECSUBSET
+                       // make a rapid exit for easy zeros if !extended
+                       if (*cfirst == '0' && !set->extended) {
+                               decNumberZero(dn);      // clean result
+                               break;  // [could be return]
+                       }
+#endif
+               }               // at least one leading 0
+
+               // Handle decimal point...
+               if (dotchar != NULL && dotchar < last)  // non-trailing '.' found?
+                       exponent -= (last - dotchar);   // adjust exponent
+               // [we can now ignore the .]
+
+               // OK, the digits string is good.  Assemble in the decNumber, or in
+               // a temporary units array if rounding is needed
+               if (d <= set->digits)
+                       res = dn->lsu;  // fits into supplied decNumber
+               else {          // rounding needed
+                       Int needbytes = D2U(d) * sizeof(Unit);  // bytes needed
+                       res = resbuff;  // assume use local buffer
+                       if (needbytes > (Int) sizeof(resbuff)) {        // too big for local
+                               allocres = (Unit *) malloc(needbytes);
+                               if (allocres == NULL) {
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               res = allocres;
+                       }
+               }
+               // res now -> number lsu, buffer, or allocated storage for Unit array
+
+               // Place the coefficient into the selected Unit array
+               // [this is often 70% of the cost of this function when DECDPUN>1]
+#if DECDPUN>1
+               out = 0;        // accumulator
+               up = res + D2U(d) - 1;  // -> msu
+               cut = d - (up - res) * DECDPUN; // digits in top unit
+               for (c = cfirst;; c++) {        // along the digits
+                       if (*c == '.')
+                               continue;       // ignore '.' [don't decrement cut]
+                       out = X10(out) + (Int) * c - (Int) '0';
+                       if (c == last)
+                               break;  // done [never get to trailing '.']
+                       cut--;
+                       if (cut > 0)
+                               continue;       // more for this unit
+                       *up = (Unit) out;       // write unit
+                       up--;   // prepare for unit below..
+                       cut = DECDPUN;  // ..
+                       out = 0;        // ..
+               }               // c
+               *up = (Unit) out;       // write lsu
+
+#else
+               // DECDPUN==1
+               up = res;       // -> lsu
+               for (c = last; c >= cfirst; c--) {      // over each character, from least
+                       if (*c == '.')
+                               continue;       // ignore . [don't step up]
+                       *up = (Unit) ((Int) * c - (Int) '0');
+                       up++;
+               }               // c
+#endif
+
+               dn->bits = bits;
+               dn->exponent = exponent;
+               dn->digits = d;
+
+               // if not in number (too long) shorten into the number
+               if (d > set->digits) {
+                       residue = 0;
+                       decSetCoeff(dn, set, res, d, &residue, &status);
+                       // always check for overflow or subnormal and round as needed
+                       decFinalize(dn, set, &residue, &status);
+               } else {        // no rounding, but may still have overflow or subnormal
+                       // [these tests are just for performance; finalize repeats them]
+                       if ((dn->exponent - 1 < set->emin - dn->digits)
+                           || (dn->exponent - 1 > set->emax - set->digits)) {
+                               residue = 0;
+                               decFinalize(dn, set, &residue, &status);
+                       }
+               }
+               // decNumberShow(dn);
+       } while (0);            // [for break]
+
+       if (allocres != NULL)
+               free(allocres); // drop any storage used
+       if (status != 0)
+               decStatus(dn, status, set);
+       return dn;
+}                              /* decNumberFromString */
+
+/* ================================================================== */
+/* Operators                                                          */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* decNumberAbs -- absolute value operator                            */
+/*                                                                    */
+/*   This computes C = abs(A)                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* See also decNumberCopyAbs for a quiet bitwise version of this.     */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* This has the same effect as decNumberPlus unless A is negative,    */
+/* in which case it has the same effect as decNumberMinus.            */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberAbs(decNumber * res, const decNumber * rhs,
+                       decContext * set)
+{
+       decNumber dzero;        // for 0
+       uInt status = 0;        // accumulator
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       decNumberZero(&dzero);  // set 0
+       dzero.exponent = rhs->exponent; // [no coefficient expansion]
+       decAddOp(res, &dzero, rhs, set, (uByte) (rhs->bits & DECNEG), &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberAbs
+
+/* ------------------------------------------------------------------ */
+/* decNumberAdd -- add two Numbers                                    */
+/*                                                                    */
+/*   This computes C = A + B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* This just calls the routine shared with Subtract                   */
+decNumber *decNumberAdd(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decAddOp(res, lhs, rhs, set, 0, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberAdd
+
+/* ------------------------------------------------------------------ */
+/* decNumberAnd -- AND two Numbers, digitwise                         */
+/*                                                                    */
+/*   This computes C = A & B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X&X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context (used for result length and error report)     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Logical function restrictions apply (see above); a NaN is          */
+/* returned with Invalid_operation if a restriction is violated.      */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberAnd(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       const Unit *ua, *ub;    // -> operands
+       const Unit *msua, *msub;        // -> operand msus
+       Unit *uc, *msuc;        // -> result and its msu
+       Int msudigs;            // digits in res msu
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       if (lhs->exponent != 0 || decNumberIsSpecial(lhs)
+           || decNumberIsNegative(lhs)
+           || rhs->exponent != 0 || decNumberIsSpecial(rhs)
+           || decNumberIsNegative(rhs)) {
+               decStatus(res, DEC_Invalid_operation, set);
+               return res;
+       }
+       // operands are valid
+       ua = lhs->lsu;          // bottom-up
+       ub = rhs->lsu;          // ..
+       uc = res->lsu;          // ..
+       msua = ua + D2U(lhs->digits) - 1;       // -> msu of lhs
+       msub = ub + D2U(rhs->digits) - 1;       // -> msu of rhs
+       msuc = uc + D2U(set->digits) - 1;       // -> msu of result
+       msudigs = MSUDIGITS(set->digits);       // [faster than remainder]
+       for (; uc <= msuc; ua++, ub++, uc++) {  // Unit loop
+               Unit a, b;      // extract units
+               if (ua > msua)
+                       a = 0;
+               else
+                       a = *ua;
+               if (ub > msub)
+                       b = 0;
+               else
+                       b = *ub;
+               *uc = 0;        // can now write back
+               if (a | b) {    // maybe 1 bits to examine
+                       Int i, j;
+                       *uc = 0;        // can now write back
+                       // This loop could be unrolled and/or use BIN2BCD tables
+                       for (i = 0; i < DECDPUN; i++) {
+                               if (a & b & 1)
+                                       *uc = *uc + (Unit) powers[i];   // effect AND
+                               j = a % 10;
+                               a = a / 10;
+                               j |= b % 10;
+                               b = b / 10;
+                               if (j > 1) {
+                                       decStatus(res, DEC_Invalid_operation,
+                                                 set);
+                                       return res;
+                               }
+                               if (uc == msuc && i == msudigs - 1)
+                                       break;  // just did final digit
+                       }       // each digit
+               }               // both OK
+       }                       // each unit
+       // [here uc-1 is the msu of the result]
+       res->digits = decGetDigits(res->lsu, uc - res->lsu);
+       res->exponent = 0;      // integer
+       res->bits = 0;          // sign=0
+       return res;             // [no status to set]
+}                              // decNumberAnd
+
+/* ------------------------------------------------------------------ */
+/* decNumberCompare -- compare two Numbers                            */
+/*                                                                    */
+/*   This computes C = A ? B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for one digit (or NaN).                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCompare(decNumber * res, const decNumber * lhs,
+                           const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPARE, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberCompare
+
+/* ------------------------------------------------------------------ */
+/* decNumberCompareSignal -- compare, signalling on all NaNs          */
+/*                                                                    */
+/*   This computes C = A ? B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for one digit (or NaN).                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCompareSignal(decNumber * res, const decNumber * lhs,
+                                 const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberCompareSignal
+
+/* ------------------------------------------------------------------ */
+/* decNumberCompareTotal -- compare two Numbers, using total ordering */
+/*                                                                    */
+/*   This computes C = A ? B, under total ordering                    */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for one digit; the result will always be one of  */
+/* -1, 0, or 1.                                                       */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCompareTotal(decNumber * res, const decNumber * lhs,
+                                const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberCompareTotal
+
+/* ------------------------------------------------------------------ */
+/* decNumberCompareTotalMag -- compare, total ordering of magnitudes  */
+/*                                                                    */
+/*   This computes C = |A| ? |B|, under total ordering                */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for one digit; the result will always be one of  */
+/* -1, 0, or 1.                                                       */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCompareTotalMag(decNumber * res, const decNumber * lhs,
+                                   const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       uInt needbytes;         // for space calculations
+       decNumber bufa[D2N(DECBUFFER + 1)];     // +1 in case DECBUFFER=0
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber bufb[D2N(DECBUFFER + 1)];
+       decNumber *allocbufb = NULL;    // -> allocated bufb, iff allocated
+       decNumber *a, *b;       // temporary pointers
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+               // if either is negative, take a copy and absolute
+               if (decNumberIsNegative(lhs)) { // lhs<0
+                       a = bufa;
+                       needbytes =
+                           sizeof(decNumber) + (D2U(lhs->digits) -
+                                                1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufa)) { // need malloc space
+                               allocbufa = (decNumber *) malloc(needbytes);
+                               if (allocbufa == NULL) {        // hopeless -- abandon
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               a = allocbufa;  // use the allocated space
+                       }
+                       decNumberCopy(a, lhs);  // copy content
+                       a->bits &= ~DECNEG;     // .. and clear the sign
+                       lhs = a;        // use copy from here on
+               }
+               if (decNumberIsNegative(rhs)) { // rhs<0
+                       b = bufb;
+                       needbytes =
+                           sizeof(decNumber) + (D2U(rhs->digits) -
+                                                1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufb)) { // need malloc space
+                               allocbufb = (decNumber *) malloc(needbytes);
+                               if (allocbufb == NULL) {        // hopeless -- abandon
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               b = allocbufb;  // use the allocated space
+                       }
+                       decNumberCopy(b, rhs);  // copy content
+                       b->bits &= ~DECNEG;     // .. and clear the sign
+                       rhs = b;        // use copy from here on
+               }
+               decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
+       } while (0);            // end protected
+
+       if (allocbufa != NULL)
+               free(allocbufa);        // drop any storage used
+       if (allocbufb != NULL)
+               free(allocbufb);        // ..
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberCompareTotalMag
+
+/* ------------------------------------------------------------------ */
+/* decNumberDivide -- divide one number by another                    */
+/*                                                                    */
+/*   This computes C = A / B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberDivide(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberDivide
+
+/* ------------------------------------------------------------------ */
+/* decNumberDivideInteger -- divide and return integer quotient       */
+/*                                                                    */
+/*   This computes C = A # B, where # is the integer divide operator  */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X#X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberDivideInteger(decNumber * res, const decNumber * lhs,
+                                 const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberDivideInteger
+
+/* ------------------------------------------------------------------ */
+/* decNumberExp -- exponentiation                                     */
+/*                                                                    */
+/*   This computes C = exp(A)                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* Finite results will always be full precision and Inexact, except   */
+/* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
+/*                                                                    */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+/* This is a wrapper for decExpOp which can handle the slightly wider */
+/* (double) range needed by Ln (which has to be able to calculate     */
+/* exp(-a) where a can be the tiniest number (Ntiny).                 */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberExp(decNumber * res, const decNumber * rhs,
+                       decContext * set)
+{
+       uInt status = 0;        // accumulator
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // Check restrictions; these restrictions ensure that if h=8 (see
+       // decExpOp) then the result will either overflow or underflow to 0.
+       // Other math functions restrict the input range, too, for inverses.
+       // If not violated then carry out the operation.
+       if (!decCheckMath(rhs, set, &status))
+               do {            // protect allocation
+#if DECSUBSET
+                       if (!set->extended) {
+                               // reduce operand and set lostDigits status, as needed
+                               if (rhs->digits > set->digits) {
+                                       allocrhs =
+                                           decRoundOperand(rhs, set, &status);
+                                       if (allocrhs == NULL)
+                                               break;
+                                       rhs = allocrhs;
+                               }
+                       }
+#endif
+                       decExpOp(res, rhs, set, &status);
+               } while (0);    // end protected
+
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // drop any storage used
+#endif
+       // apply significant status
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberExp
+
+/* ------------------------------------------------------------------ */
+/* decNumberFMA -- fused multiply add                                 */
+/*                                                                    */
+/*   This computes D = (A * B) + C with only one rounding             */
+/*                                                                    */
+/*   res is D, the result.  D may be A or B or C (e.g., X=FMA(X,X,X)) */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   fhs is C [far hand side]                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberFMA(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, const decNumber * fhs,
+                       decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decContext dcmul;       // context for the multiplication
+       uInt needbytes;         // for space calculations
+       decNumber bufa[D2N(DECBUFFER * 2 + 1)];
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *acc;         // accumulator pointer
+       decNumber dzero;        // work
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+       if (decCheckOperands(res, fhs, DECUNUSED, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {   // [undefined if subset]
+                       status |= DEC_Invalid_operation;
+                       break;
+               }
+#endif
+               // Check math restrictions [these ensure no overflow or underflow]
+               if ((!decNumberIsSpecial(lhs)
+                    && decCheckMath(lhs, set, &status))
+                   || (!decNumberIsSpecial(rhs)
+                       && decCheckMath(rhs, set, &status))
+                   || (!decNumberIsSpecial(fhs)
+                       && decCheckMath(fhs, set, &status)))
+                       break;
+               // set up context for multiply
+               dcmul = *set;
+               dcmul.digits = lhs->digits + rhs->digits;       // just enough
+               // [The above may be an over-estimate for subset arithmetic, but that's OK]
+               dcmul.emax = DEC_MAX_EMAX;      // effectively unbounded ..
+               dcmul.emin = DEC_MIN_EMIN;      // [thanks to Math restrictions]
+               // set up decNumber space to receive the result of the multiply
+               acc = bufa;     // may fit
+               needbytes =
+                   sizeof(decNumber) + (D2U(dcmul.digits) - 1) * sizeof(Unit);
+               if (needbytes > sizeof(bufa)) { // need malloc space
+                       allocbufa = (decNumber *) malloc(needbytes);
+                       if (allocbufa == NULL) {        // hopeless -- abandon
+                               status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       acc = allocbufa;        // use the allocated space
+               }
+               // multiply with extended range and necessary precision
+               //printf("emin=%ld\n", dcmul.emin);
+               decMultiplyOp(acc, lhs, rhs, &dcmul, &status);
+               // Only Invalid operation (from sNaN or Inf * 0) is possible in
+               // status; if either is seen than ignore fhs (in case it is
+               // another sNaN) and set acc to NaN unless we had an sNaN
+               // [decMultiplyOp leaves that to caller]
+               // Note sNaN has to go through addOp to shorten payload if
+               // necessary
+               if ((status & DEC_Invalid_operation) != 0) {
+                       if (!(status & DEC_sNaN)) {     // but be true invalid
+                               decNumberZero(res);     // acc not yet set
+                               res->bits = DECNAN;
+                               break;
+                       }
+                       decNumberZero(&dzero);  // make 0 (any non-NaN would do)
+                       fhs = &dzero;   // use that
+               }
+#if DECCHECK
+               else {          // multiply was OK
+                       if (status != 0)
+                               printf("Status=%08lx after FMA multiply\n",
+                                      (LI) status);
+               }
+#endif
+               // add the third operand and result -> res, and all is done
+               decAddOp(res, acc, fhs, set, 0, &status);
+       } while (0);            // end protected
+
+       if (allocbufa != NULL)
+               free(allocbufa);        // drop any storage used
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberFMA
+
+/* ------------------------------------------------------------------ */
+/* decNumberInvert -- invert a Number, digitwise                      */
+/*                                                                    */
+/*   This computes C = ~A                                             */
+/*                                                                    */
+/*   res is C, the result.  C may be A (e.g., X=~X)                   */
+/*   rhs is A                                                         */
+/*   set is the context (used for result length and error report)     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Logical function restrictions apply (see above); a NaN is          */
+/* returned with Invalid_operation if a restriction is violated.      */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberInvert(decNumber * res, const decNumber * rhs,
+                          decContext * set)
+{
+       const Unit *ua, *msua;  // -> operand and its msu
+       Unit *uc, *msuc;        // -> result and its msu
+       Int msudigs;            // digits in res msu
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       if (rhs->exponent != 0 || decNumberIsSpecial(rhs)
+           || decNumberIsNegative(rhs)) {
+               decStatus(res, DEC_Invalid_operation, set);
+               return res;
+       }
+       // operand is valid
+       ua = rhs->lsu;          // bottom-up
+       uc = res->lsu;          // ..
+       msua = ua + D2U(rhs->digits) - 1;       // -> msu of rhs
+       msuc = uc + D2U(set->digits) - 1;       // -> msu of result
+       msudigs = MSUDIGITS(set->digits);       // [faster than remainder]
+       for (; uc <= msuc; ua++, uc++) {        // Unit loop
+               Unit a;         // extract unit
+               Int i, j;       // work
+               if (ua > msua)
+                       a = 0;
+               else
+                       a = *ua;
+               *uc = 0;        // can now write back
+               // always need to examine all bits in rhs
+               // This loop could be unrolled and/or use BIN2BCD tables
+               for (i = 0; i < DECDPUN; i++) {
+                       if ((~a) & 1)
+                               *uc = *uc + (Unit) powers[i];   // effect INVERT
+                       j = a % 10;
+                       a = a / 10;
+                       if (j > 1) {
+                               decStatus(res, DEC_Invalid_operation, set);
+                               return res;
+                       }
+                       if (uc == msuc && i == msudigs - 1)
+                               break;  // just did final digit
+               }               // each digit
+       }                       // each unit
+       // [here uc-1 is the msu of the result]
+       res->digits = decGetDigits(res->lsu, uc - res->lsu);
+       res->exponent = 0;      // integer
+       res->bits = 0;          // sign=0
+       return res;             // [no status to set]
+}                              // decNumberInvert
+
+/* ------------------------------------------------------------------ */
+/* decNumberLn -- natural logarithm                                   */
+/*                                                                    */
+/*   This computes C = ln(A)                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Notable cases:                                                     */
+/*   A<0 -> Invalid                                                   */
+/*   A=0 -> -Infinity (Exact)                                         */
+/*   A=+Infinity -> +Infinity (Exact)                                 */
+/*   A=1 exactly -> 0 (Exact)                                         */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+/* This is a wrapper for decLnOp which can handle the slightly wider  */
+/* (+11) range needed by Ln, Log10, etc. (which may have to be able   */
+/* to calculate at p+e+2).                                            */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberLn(decNumber * res, const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // Check restrictions; this is a math function; if not violated
+       // then carry out the operation.
+       if (!decCheckMath(rhs, set, &status))
+               do {            // protect allocation
+#if DECSUBSET
+                       if (!set->extended) {
+                               // reduce operand and set lostDigits status, as needed
+                               if (rhs->digits > set->digits) {
+                                       allocrhs =
+                                           decRoundOperand(rhs, set, &status);
+                                       if (allocrhs == NULL)
+                                               break;
+                                       rhs = allocrhs;
+                               }
+                               // special check in subset for rhs=0
+                               if (ISZERO(rhs)) {      // +/- zeros -> error
+                                       status |= DEC_Invalid_operation;
+                                       break;
+                               }
+                       }       // extended=0
+#endif
+                       decLnOp(res, rhs, set, &status);
+               } while (0);    // end protected
+
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // drop any storage used
+#endif
+       // apply significant status
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberLn
+
+/* ------------------------------------------------------------------ */
+/* decNumberLogB - get adjusted exponent, by 754 rules                */
+/*                                                                    */
+/*   This computes C = adjustedexponent(A)                            */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context, used only for digits and status              */
+/*                                                                    */
+/* For an unrounded result, digits may need to be 10 (A might have    */
+/* 10**9 digits and an exponent of +999999999, or one digit and an    */
+/* exponent of -1999999999).                                          */
+/*                                                                    */
+/* This returns the adjusted exponent of A after (in theory) padding  */
+/* with zeros on the right to set->digits digits while keeping the    */
+/* same value.  The exponent is not limited by emin/emax.             */
+/*                                                                    */
+/* Notable cases:                                                     */
+/*   A<0 -> Use |A|                                                   */
+/*   A=0 -> -Infinity (Division by zero)                              */
+/*   A=Infinite -> +Infinity (Exact)                                  */
+/*   A=1 exactly -> 0 (Exact)                                         */
+/*   NaNs are propagated as usual                                     */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberLogB(decNumber * res, const decNumber * rhs,
+                        decContext * set)
+{
+       uInt status = 0;        // accumulator
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // NaNs as usual; Infinities return +Infinity; 0->oops
+       if (decNumberIsNaN(rhs))
+               decNaNs(res, rhs, NULL, set, &status);
+       else if (decNumberIsInfinite(rhs))
+               decNumberCopyAbs(res, rhs);
+       else if (decNumberIsZero(rhs)) {
+               decNumberZero(res);     // prepare for Infinity
+               res->bits = DECNEG | DECINF;    // -Infinity
+               status |= DEC_Division_by_zero; // as per 754
+       } else {                // finite non-zero
+               Int ae = rhs->exponent + rhs->digits - 1;       // adjusted exponent
+               if (set->digits >= 10)
+                       decNumberFromInt32(res, ae);    // lay it out
+               else {
+                       decNumber buft[D2N(10)];        // temporary number
+                       decNumber *t = buft;    // ..
+                       decNumberFromInt32(t, ae);      // lay it out
+                       decNumberPlus(res, t, set);     // round as necessary
+               }
+       }
+
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberLogB
+
+/* ------------------------------------------------------------------ */
+/* decNumberLog10 -- logarithm in base 10                             */
+/*                                                                    */
+/*   This computes C = log10(A)                                       */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Notable cases:                                                     */
+/*   A<0 -> Invalid                                                   */
+/*   A=0 -> -Infinity (Exact)                                         */
+/*   A=+Infinity -> +Infinity (Exact)                                 */
+/*   A=10**n (if n is an integer) -> n (Exact)                        */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+/* This calculates ln(A)/ln(10) using appropriate precision.  For     */
+/* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the      */
+/* requested digits and t is the number of digits in the exponent     */
+/* (maximum 6).  For ln(10) it is p + 3; this is often handled by the */
+/* fastpath in decLnOp.  The final division is done to the requested  */
+/* precision.                                                         */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberLog10(decNumber * res, const decNumber * rhs,
+                         decContext * set)
+{
+       uInt status = 0, ignore = 0;    // status accumulators
+       uInt needbytes;         // for space calculations
+       Int p;                  // working precision
+       Int t;                  // digits in exponent of A
+
+       // buffers for a and b working decimals
+       // (adjustment calculator, same size)
+       decNumber bufa[D2N(DECBUFFER + 2)];
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *a = bufa;    // temporary a
+       decNumber bufb[D2N(DECBUFFER + 2)];
+       decNumber *allocbufb = NULL;    // -> allocated bufb, iff allocated
+       decNumber *b = bufb;    // temporary b
+       decNumber bufw[D2N(10)];        // working 2-10 digit number
+       decNumber *w = bufw;    // ..
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+
+       decContext aset;        // working context
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // Check restrictions; this is a math function; if not violated
+       // then carry out the operation.
+       if (!decCheckMath(rhs, set, &status))
+               do {            // protect malloc
+#if DECSUBSET
+                       if (!set->extended) {
+                               // reduce operand and set lostDigits status, as needed
+                               if (rhs->digits > set->digits) {
+                                       allocrhs =
+                                           decRoundOperand(rhs, set, &status);
+                                       if (allocrhs == NULL)
+                                               break;
+                                       rhs = allocrhs;
+                               }
+                               // special check in subset for rhs=0
+                               if (ISZERO(rhs)) {      // +/- zeros -> error
+                                       status |= DEC_Invalid_operation;
+                                       break;
+                               }
+                       }       // extended=0
+#endif
+
+                       decContextDefault(&aset, DEC_INIT_DECIMAL64);   // clean context
+
+                       // handle exact powers of 10; only check if +ve finite
+                       if (!(rhs->bits & (DECNEG | DECSPECIAL))
+                           && !ISZERO(rhs)) {
+                               Int residue = 0;        // (no residue)
+                               uInt copystat = 0;      // clean status
+
+                               // round to a single digit...
+                               aset.digits = 1;
+                               decCopyFit(w, rhs, &aset, &residue, &copystat); // copy & shorten
+                               // if exact and the digit is 1, rhs is a power of 10
+                               if (!(copystat & DEC_Inexact) && w->lsu[0] == 1) {
+                                       // the exponent, conveniently, is the power of 10; making
+                                       // this the result needs a little care as it might not fit,
+                                       // so first convert it into the working number, and then move
+                                       // to res
+                                       decNumberFromInt32(w, w->exponent);
+                                       residue = 0;
+                                       decCopyFit(res, w, set, &residue, &status);     // copy & round
+                                       decFinish(res, set, &residue, &status); // cleanup/set flags
+                                       break;
+                               }       // not a power of 10
+                       }       // not a candidate for exact
+
+                       // simplify the information-content calculation to use 'total
+                       // number of digits in a, including exponent' as compared to the
+                       // requested digits, as increasing this will only rarely cost an
+                       // iteration in ln(a) anyway
+                       t = 6;  // it can never be >6
+
+                       // allocate space when needed...
+                       p = (rhs->digits + t >
+                            set->digits ? rhs->digits + t : set->digits) + 3;
+                       needbytes =
+                           sizeof(decNumber) + (D2U(p) - 1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufa)) { // need malloc space
+                               allocbufa = (decNumber *) malloc(needbytes);
+                               if (allocbufa == NULL) {        // hopeless -- abandon
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               a = allocbufa;  // use the allocated space
+                       }
+                       aset.digits = p;        // as calculated
+                       aset.emax = DEC_MAX_MATH;       // usual bounds
+                       aset.emin = -DEC_MAX_MATH;      // ..
+                       aset.clamp = 0; // and no concrete format
+                       decLnOp(a, rhs, &aset, &status);        // a=ln(rhs)
+
+                       // skip the division if the result so far is infinite, NaN, or
+                       // zero, or there was an error; note NaN from sNaN needs copy
+                       if (status & DEC_NaNs && !(status & DEC_sNaN))
+                               break;
+                       if (a->bits & DECSPECIAL || ISZERO(a)) {
+                               decNumberCopy(res, a);  // [will fit]
+                               break;
+                       }
+                       // for ln(10) an extra 3 digits of precision are needed
+                       p = set->digits + 3;
+                       needbytes =
+                           sizeof(decNumber) + (D2U(p) - 1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufb)) { // need malloc space
+                               allocbufb = (decNumber *) malloc(needbytes);
+                               if (allocbufb == NULL) {        // hopeless -- abandon
+                                       status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               b = allocbufb;  // use the allocated space
+                       }
+                       decNumberZero(w);       // set up 10...
+#if DECDPUN==1
+                       w->lsu[1] = 1;
+                       w->lsu[0] = 0;  // ..
+#else
+                       w->lsu[0] = 10; // ..
+#endif
+                       w->digits = 2;  // ..
+
+                       aset.digits = p;
+                       decLnOp(b, w, &aset, &ignore);  // b=ln(10)
+
+                       aset.digits = set->digits;      // for final divide
+                       decDivideOp(res, a, b, &aset, DIVIDE, &status); // into result
+               } while (0);    // [for break]
+
+       if (allocbufa != NULL)
+               free(allocbufa);        // drop any storage used
+       if (allocbufb != NULL)
+               free(allocbufb);        // ..
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+#endif
+       // apply significant status
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberLog10
+
+/* ------------------------------------------------------------------ */
+/* decNumberMax -- compare two Numbers and return the maximum         */
+/*                                                                    */
+/*   This computes C = A ? B, returning the maximum by 754 rules      */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMax(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMax
+
+/* ------------------------------------------------------------------ */
+/* decNumberMaxMag -- compare and return the maximum by magnitude     */
+/*                                                                    */
+/*   This computes C = A ? B, returning the maximum by 754 rules      */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMaxMag(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMaxMag
+
+/* ------------------------------------------------------------------ */
+/* decNumberMin -- compare two Numbers and return the minimum         */
+/*                                                                    */
+/*   This computes C = A ? B, returning the minimum by 754 rules      */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMin(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMin
+
+/* ------------------------------------------------------------------ */
+/* decNumberMinMag -- compare and return the minimum by magnitude     */
+/*                                                                    */
+/*   This computes C = A ? B, returning the minimum by 754 rules      */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMinMag(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMinMag
+
+/* ------------------------------------------------------------------ */
+/* decNumberMinus -- prefix minus operator                            */
+/*                                                                    */
+/*   This computes C = 0 - A                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* See also decNumberCopyNegate for a quiet bitwise version of this.  */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* Simply use AddOp for the subtract, which will do the necessary.    */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMinus(decNumber * res, const decNumber * rhs,
+                         decContext * set)
+{
+       decNumber dzero;
+       uInt status = 0;        // accumulator
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       decNumberZero(&dzero);  // make 0
+       dzero.exponent = rhs->exponent; // [no coefficient expansion]
+       decAddOp(res, &dzero, rhs, set, DECNEG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMinus
+
+/* ------------------------------------------------------------------ */
+/* decNumberNextMinus -- next towards -Infinity                       */
+/*                                                                    */
+/*   This computes C = A - infinitesimal, rounded towards -Infinity   */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* This is a generalization of 754 NextDown.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberNextMinus(decNumber * res, const decNumber * rhs,
+                             decContext * set)
+{
+       decNumber dtiny;        // constant
+       decContext workset = *set;      // work
+       uInt status = 0;        // accumulator
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // +Infinity is the special case
+       if ((rhs->bits & (DECINF | DECNEG)) == DECINF) {
+               decSetMaxValue(res, set);       // is +ve
+               // there is no status to set
+               return res;
+       }
+       decNumberZero(&dtiny);  // start with 0
+       dtiny.lsu[0] = 1;       // make number that is ..
+       dtiny.exponent = DEC_MIN_EMIN - 1;      // .. smaller than tiniest
+       workset.round = DEC_ROUND_FLOOR;
+       decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
+       status &= DEC_Invalid_operation | DEC_sNaN;     // only sNaN Invalid please
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberNextMinus
+
+/* ------------------------------------------------------------------ */
+/* decNumberNextPlus -- next towards +Infinity                        */
+/*                                                                    */
+/*   This computes C = A + infinitesimal, rounded towards +Infinity   */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* This is a generalization of 754 NextUp.                            */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberNextPlus(decNumber * res, const decNumber * rhs,
+                            decContext * set)
+{
+       decNumber dtiny;        // constant
+       decContext workset = *set;      // work
+       uInt status = 0;        // accumulator
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // -Infinity is the special case
+       if ((rhs->bits & (DECINF | DECNEG)) == (DECINF | DECNEG)) {
+               decSetMaxValue(res, set);
+               res->bits = DECNEG;     // negative
+               // there is no status to set
+               return res;
+       }
+       decNumberZero(&dtiny);  // start with 0
+       dtiny.lsu[0] = 1;       // make number that is ..
+       dtiny.exponent = DEC_MIN_EMIN - 1;      // .. smaller than tiniest
+       workset.round = DEC_ROUND_CEILING;
+       decAddOp(res, rhs, &dtiny, &workset, 0, &status);
+       status &= DEC_Invalid_operation | DEC_sNaN;     // only sNaN Invalid please
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberNextPlus
+
+/* ------------------------------------------------------------------ */
+/* decNumberNextToward -- next towards rhs                            */
+/*                                                                    */
+/*   This computes C = A +/- infinitesimal, rounded towards           */
+/*   +/-Infinity in the direction of B, as per 754-1985 nextafter     */
+/*   modified during revision but dropped from 754-2008.              */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B.                          */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* This is a generalization of 754-1985 NextAfter.                    */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberNextToward(decNumber * res, const decNumber * lhs,
+                              const decNumber * rhs, decContext * set)
+{
+       decNumber dtiny;        // constant
+       decContext workset = *set;      // work
+       Int result;             // ..
+       uInt status = 0;        // accumulator
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
+               decNaNs(res, lhs, rhs, set, &status);
+       } else {                // Is numeric, so no chance of sNaN Invalid, etc.
+               result = decCompare(lhs, rhs, 0);       // sign matters
+               if (result == BADINT)
+                       status |= DEC_Insufficient_storage;     // rare
+               else {          // valid compare
+                       if (result == 0)
+                               decNumberCopySign(res, lhs, rhs);       // easy
+                       else {  // differ: need NextPlus or NextMinus
+                               uByte sub;      // add or subtract
+                               if (result < 0) {       // lhs<rhs, do nextplus
+                                       // -Infinity is the special case
+                                       if ((lhs->bits & (DECINF | DECNEG)) ==
+                                           (DECINF | DECNEG)) {
+                                               decSetMaxValue(res, set);
+                                               res->bits = DECNEG;     // negative
+                                               return res;     // there is no status to set
+                                       }
+                                       workset.round = DEC_ROUND_CEILING;
+                                       sub = 0;        // add, please
+                               }       // plus
+                               else {  // lhs>rhs, do nextminus
+                                       // +Infinity is the special case
+                                       if ((lhs->bits & (DECINF | DECNEG)) ==
+                                           DECINF) {
+                                               decSetMaxValue(res, set);
+                                               return res;     // there is no status to set
+                                       }
+                                       workset.round = DEC_ROUND_FLOOR;
+                                       sub = DECNEG;   // subtract, please
+                               }       // minus
+                               decNumberZero(&dtiny);  // start with 0
+                               dtiny.lsu[0] = 1;       // make number that is ..
+                               dtiny.exponent = DEC_MIN_EMIN - 1;      // .. smaller than tiniest
+                               decAddOp(res, lhs, &dtiny, &workset, sub, &status);     // + or -
+                               // turn off exceptions if the result is a normal number
+                               // (including Nmin), otherwise let all status through
+                               if (decNumberIsNormal(res, set))
+                                       status = 0;
+                       }       // unequal
+               }               // compare OK
+       }                       // numeric
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberNextToward
+
+/* ------------------------------------------------------------------ */
+/* decNumberOr -- OR two Numbers, digitwise                           */
+/*                                                                    */
+/*   This computes C = A | B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X|X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context (used for result length and error report)     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Logical function restrictions apply (see above); a NaN is          */
+/* returned with Invalid_operation if a restriction is violated.      */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberOr(decNumber * res, const decNumber * lhs,
+                      const decNumber * rhs, decContext * set)
+{
+       const Unit *ua, *ub;    // -> operands
+       const Unit *msua, *msub;        // -> operand msus
+       Unit *uc, *msuc;        // -> result and its msu
+       Int msudigs;            // digits in res msu
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       if (lhs->exponent != 0 || decNumberIsSpecial(lhs)
+           || decNumberIsNegative(lhs)
+           || rhs->exponent != 0 || decNumberIsSpecial(rhs)
+           || decNumberIsNegative(rhs)) {
+               decStatus(res, DEC_Invalid_operation, set);
+               return res;
+       }
+       // operands are valid
+       ua = lhs->lsu;          // bottom-up
+       ub = rhs->lsu;          // ..
+       uc = res->lsu;          // ..
+       msua = ua + D2U(lhs->digits) - 1;       // -> msu of lhs
+       msub = ub + D2U(rhs->digits) - 1;       // -> msu of rhs
+       msuc = uc + D2U(set->digits) - 1;       // -> msu of result
+       msudigs = MSUDIGITS(set->digits);       // [faster than remainder]
+       for (; uc <= msuc; ua++, ub++, uc++) {  // Unit loop
+               Unit a, b;      // extract units
+               if (ua > msua)
+                       a = 0;
+               else
+                       a = *ua;
+               if (ub > msub)
+                       b = 0;
+               else
+                       b = *ub;
+               *uc = 0;        // can now write back
+               if (a | b) {    // maybe 1 bits to examine
+                       Int i, j;
+                       // This loop could be unrolled and/or use BIN2BCD tables
+                       for (i = 0; i < DECDPUN; i++) {
+                               if ((a | b) & 1)
+                                       *uc = *uc + (Unit) powers[i];   // effect OR
+                               j = a % 10;
+                               a = a / 10;
+                               j |= b % 10;
+                               b = b / 10;
+                               if (j > 1) {
+                                       decStatus(res, DEC_Invalid_operation,
+                                                 set);
+                                       return res;
+                               }
+                               if (uc == msuc && i == msudigs - 1)
+                                       break;  // just did final digit
+                       }       // each digit
+               }               // non-zero
+       }                       // each unit
+       // [here uc-1 is the msu of the result]
+       res->digits = decGetDigits(res->lsu, uc - res->lsu);
+       res->exponent = 0;      // integer
+       res->bits = 0;          // sign=0
+       return res;             // [no status to set]
+}                              // decNumberOr
+
+/* ------------------------------------------------------------------ */
+/* decNumberPlus -- prefix plus operator                              */
+/*                                                                    */
+/*   This computes C = 0 + A                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* See also decNumberCopy for a quiet bitwise version of this.        */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* This simply uses AddOp; Add will take fast path after preparing A. */
+/* Performance is a concern here, as this routine is often used to    */
+/* check operands and apply rounding and overflow/underflow testing.  */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberPlus(decNumber * res, const decNumber * rhs,
+                        decContext * set)
+{
+       decNumber dzero;
+       uInt status = 0;        // accumulator
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       decNumberZero(&dzero);  // make 0
+       dzero.exponent = rhs->exponent; // [no coefficient expansion]
+       decAddOp(res, &dzero, rhs, set, 0, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberPlus
+
+/* ------------------------------------------------------------------ */
+/* decNumberMultiply -- multiply two Numbers                          */
+/*                                                                    */
+/*   This computes C = A x B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberMultiply(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decMultiplyOp(res, lhs, rhs, set, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberMultiply
+
+/* ------------------------------------------------------------------ */
+/* decNumberPower -- raise a number to a power                        */
+/*                                                                    */
+/*   This computes C = A ** B                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X**X)        */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Mathematical function restrictions apply (see above); a NaN is     */
+/* returned with Invalid_operation if a restriction is violated.      */
+/*                                                                    */
+/* However, if 1999999997<=B<=999999999 and B is an integer then the  */
+/* restrictions on A and the context are relaxed to the usual bounds, */
+/* for compatibility with the earlier (integer power only) version    */
+/* of this function.                                                  */
+/*                                                                    */
+/* When B is an integer, the result may be exact, even if rounded.    */
+/*                                                                    */
+/* The final result is rounded according to the context; it will      */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberPower(decNumber * res, const decNumber * lhs,
+                         const decNumber * rhs, decContext * set)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       decNumber *allocdac = NULL;     // -> allocated acc buffer, iff used
+       decNumber *allocinv = NULL;     // -> allocated 1/x buffer, iff used
+       Int reqdigits = set->digits;    // requested DIGITS
+       Int n;                  // rhs in binary
+       Flag rhsint = 0;        // 1 if rhs is an integer
+       Flag useint = 0;        // 1 if can use integer calculation
+       Flag isoddint = 0;      // 1 if rhs is an integer and odd
+       Int i;                  // work
+#if DECSUBSET
+       Int dropped;            // ..
+#endif
+       uInt needbytes;         // buffer size needed
+       Flag seenbit;           // seen a bit while powering
+       Int residue = 0;        // rounding residue
+       uInt status = 0;        // accumulators
+       uByte bits = 0;         // result sign if errors
+       decContext aset;        // working context
+       decNumber dnOne;        // work value 1...
+       // local accumulator buffer [a decNumber, with digits+elength+1 digits]
+       decNumber dacbuff[D2N(DECBUFFER + 9)];
+       decNumber *dac = dacbuff;       // -> result accumulator
+       // same again for possible 1/lhs calculation
+       decNumber invbuff[D2N(DECBUFFER + 9)];
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {   // reduce operands and set status, as needed
+                       if (lhs->digits > reqdigits) {
+                               alloclhs = decRoundOperand(lhs, set, &status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > reqdigits) {
+                               allocrhs = decRoundOperand(rhs, set, &status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // handle NaNs and rhs Infinity (lhs infinity is harder)
+               if (SPECIALARGS) {
+                       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {       // NaNs
+                               decNaNs(res, lhs, rhs, set, &status);
+                               break;
+                       }
+                       if (decNumberIsInfinite(rhs)) { // rhs Infinity
+                               Flag rhsneg = rhs->bits & DECNEG;       // save rhs sign
+                               if (decNumberIsNegative(lhs)    // lhs<0
+                                   && !decNumberIsZero(lhs))   // ..
+                                       status |= DEC_Invalid_operation;
+                               else {  // lhs >=0
+                                       decNumberZero(&dnOne);  // set up 1
+                                       dnOne.lsu[0] = 1;
+                                       decNumberCompare(dac, lhs, &dnOne, set);        // lhs ? 1
+                                       decNumberZero(res);     // prepare for 0/1/Infinity
+                                       if (decNumberIsNegative(dac)) { // lhs<1
+                                               if (rhsneg)
+                                                       res->bits |= DECINF;    // +Infinity [else is +0]
+                                       } else if (dac->lsu[0] == 0) {  // lhs=1
+                                               // 1**Infinity is inexact, so return fully-padded 1.0000
+                                               Int shift = set->digits - 1;
+                                               *res->lsu = 1;  // was 0, make int 1
+                                               res->digits =
+                                                   decShiftToMost(res->lsu, 1,
+                                                                  shift);
+                                               res->exponent = -shift; // make 1.0000...
+                                               status |= DEC_Inexact | DEC_Rounded;    // deemed inexact
+                                       } else {        // lhs>1
+                                               if (!rhsneg)
+                                                       res->bits |= DECINF;    // +Infinity [else is +0]
+                                       }
+                               }       // lhs>=0
+                               break;
+                       }
+                       // [lhs infinity drops through]
+               }               // specials
+
+               // Original rhs may be an integer that fits and is in range
+               n = decGetInt(rhs);
+               if (n != BADINT) {      // it is an integer
+                       rhsint = 1;     // record the fact for 1**n
+                       isoddint = (Flag) n & 1;        // [works even if big]
+                       if (n != BIGEVEN && n != BIGODD)        // can use integer path?
+                               useint = 1;     // looks good
+               }
+
+               if (decNumberIsNegative(lhs)    // -x ..
+                   && isoddint)
+                       bits = DECNEG;  // .. to an odd power
+
+               // handle LHS infinity
+               if (decNumberIsInfinite(lhs)) { // [NaNs already handled]
+                       uByte rbits = rhs->bits;        // save
+                       decNumberZero(res);     // prepare
+                       if (n == 0)
+                               *res->lsu = 1;  // [-]Inf**0 => 1
+                       else {
+                               // -Inf**nonint -> error
+                               if (!rhsint && decNumberIsNegative(lhs)) {
+                                       status |= DEC_Invalid_operation;        // -Inf**nonint is error
+                                       break;
+                               }
+                               if (!(rbits & DECNEG))
+                                       bits |= DECINF; // was not a **-n
+                               // [otherwise will be 0 or -0]
+                               res->bits = bits;
+                       }
+                       break;
+               }
+               // similarly handle LHS zero
+               if (decNumberIsZero(lhs)) {
+                       if (n == 0) {   // 0**0 => Error
+#if DECSUBSET
+                               if (!set->extended) {   // [unless subset]
+                                       decNumberZero(res);
+                                       *res->lsu = 1;  // return 1
+                                       break;
+                               }
+#endif
+                               status |= DEC_Invalid_operation;
+                       } else {        // 0**x
+                               uByte rbits = rhs->bits;        // save
+                               if (rbits & DECNEG) {   // was a 0**(-n)
+#if DECSUBSET
+                                       if (!set->extended) {   // [bad if subset]
+                                               status |= DEC_Invalid_operation;
+                                               break;
+                                       }
+#endif
+                                       bits |= DECINF;
+                               }
+                               decNumberZero(res);     // prepare
+                               // [otherwise will be 0 or -0]
+                               res->bits = bits;
+                       }
+                       break;
+               }
+               // here both lhs and rhs are finite; rhs==0 is handled in the
+               // integer path.  Next handle the non-integer cases
+               if (!useint) {  // non-integral rhs
+                       // any -ve lhs is bad, as is either operand or context out of
+                       // bounds
+                       if (decNumberIsNegative(lhs)) {
+                               status |= DEC_Invalid_operation;
+                               break;
+                       }
+                       if (decCheckMath(lhs, set, &status)
+                           || decCheckMath(rhs, set, &status))
+                               break;  // variable status
+
+                       decContextDefault(&aset, DEC_INIT_DECIMAL64);   // clean context
+                       aset.emax = DEC_MAX_MATH;       // usual bounds
+                       aset.emin = -DEC_MAX_MATH;      // ..
+                       aset.clamp = 0; // and no concrete format
+
+                       // calculate the result using exp(ln(lhs)*rhs), which can
+                       // all be done into the accumulator, dac.  The precision needed
+                       // is enough to contain the full information in the lhs (which
+                       // is the total digits, including exponent), or the requested
+                       // precision, if larger, + 4; 6 is used for the exponent
+                       // maximum length, and this is also used when it is shorter
+                       // than the requested digits as it greatly reduces the >0.5 ulp
+                       // cases at little cost (because Ln doubles digits each
+                       // iteration so a few extra digits rarely causes an extra
+                       // iteration)
+                       aset.digits = MAXI(lhs->digits, set->digits) + 6 + 4;
+               }               // non-integer rhs
+
+               else {          // rhs is in-range integer
+                       if (n == 0) {   // x**0 = 1
+                               // (0**0 was handled above)
+                               decNumberZero(res);     // result=1
+                               *res->lsu = 1;  // ..
+                               break;
+                       }
+                       // rhs is a non-zero integer
+                       if (n < 0)
+                               n = -n; // use abs(n)
+
+                       aset = *set;    // clone the context
+                       aset.round = DEC_ROUND_HALF_EVEN;       // internally use balanced
+                       // calculate the working DIGITS
+                       aset.digits =
+                           reqdigits + (rhs->digits + rhs->exponent) + 2;
+#if DECSUBSET
+                       if (!set->extended)
+                               aset.digits--;  // use classic precision
+#endif
+                       // it's an error if this is more than can be handled
+                       if (aset.digits > DECNUMMAXP) {
+                               status |= DEC_Invalid_operation;
+                               break;
+                       }
+               }               // integer path
+
+               // aset.digits is the count of digits for the accumulator needed
+               // if accumulator is too long for local storage, then allocate
+               needbytes =
+                   sizeof(decNumber) + (D2U(aset.digits) - 1) * sizeof(Unit);
+               // [needbytes also used below if 1/lhs needed]
+               if (needbytes > sizeof(dacbuff)) {
+                       allocdac = (decNumber *) malloc(needbytes);
+                       if (allocdac == NULL) { // hopeless -- abandon
+                               status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       dac = allocdac; // use the allocated space
+               }
+               // here, aset is set up and accumulator is ready for use
+
+               if (!useint) {  // non-integral rhs
+                       // x ** y; special-case x=1 here as it will otherwise always
+                       // reduce to integer 1; decLnOp has a fastpath which detects
+                       // the case of x=1
+                       decLnOp(dac, lhs, &aset, &status);      // dac=ln(lhs)
+                       // [no error possible, as lhs 0 already handled]
+                       if (ISZERO(dac)) {      // x==1, 1.0, etc.
+                               // need to return fully-padded 1.0000 etc., but rhsint->1
+                               *dac->lsu = 1;  // was 0, make int 1
+                               if (!rhsint) {  // add padding
+                                       Int shift = set->digits - 1;
+                                       dac->digits =
+                                           decShiftToMost(dac->lsu, 1, shift);
+                                       dac->exponent = -shift; // make 1.0000...
+                                       status |= DEC_Inexact | DEC_Rounded;    // deemed inexact
+                               }
+                       } else {
+                               decMultiplyOp(dac, dac, rhs, &aset, &status);   // dac=dac*rhs
+                               decExpOp(dac, dac, &aset, &status);     // dac=exp(dac)
+                       }
+                       // and drop through for final rounding
+               }               // non-integer rhs
+
+               else {          // carry on with integer
+                       decNumberZero(dac);     // acc=1
+                       *dac->lsu = 1;  // ..
+
+                       // if a negative power the constant 1 is needed, and if not subset
+                       // invert the lhs now rather than inverting the result later
+                       if (decNumberIsNegative(rhs)) { // was a **-n [hence digits>0]
+                               decNumber *inv = invbuff;       // asssume use fixed buffer
+                               decNumberCopy(&dnOne, dac);     // dnOne=1;  [needed now or later]
+#if DECSUBSET
+                               if (set->extended) {    // need to calculate 1/lhs
+#endif
+                                       // divide lhs into 1, putting result in dac [dac=1/dac]
+                                       decDivideOp(dac, &dnOne, lhs, &aset,
+                                                   DIVIDE, &status);
+                                       // now locate or allocate space for the inverted lhs
+                                       if (needbytes > sizeof(invbuff)) {
+                                               allocinv = (decNumber *)
+                                                   malloc(needbytes);
+                                               if (allocinv == NULL) { // hopeless -- abandon
+                                                       status |=
+                                                           DEC_Insufficient_storage;
+                                                       break;
+                                               }
+                                               inv = allocinv; // use the allocated space
+                                       }
+                                       // [inv now points to big-enough buffer or allocated storage]
+                                       decNumberCopy(inv, dac);        // copy the 1/lhs
+                                       decNumberCopy(dac, &dnOne);     // restore acc=1
+                                       lhs = inv;      // .. and go forward with new lhs
+#if DECSUBSET
+                               }
+#endif
+                       }
+                       // Raise-to-the-power loop...
+                       seenbit = 0;    // set once a 1-bit is encountered
+                       for (i = 1;; i++) {     // for each bit [top bit ignored]
+                               // abandon if had overflow or terminal underflow
+                               if (status & (DEC_Overflow | DEC_Underflow)) {  // interesting?
+                                       if (status & DEC_Overflow
+                                           || ISZERO(dac))
+                                               break;
+                               }
+                               // [the following two lines revealed an optimizer bug in a C++
+                               // compiler, with symptom: 5**3 -> 25, when n=n+n was used]
+                               n = n << 1;     // move next bit to testable position
+                               if (n < 0) {    // top bit is set
+                                       seenbit = 1;    // OK, significant bit seen
+                                       decMultiplyOp(dac, dac, lhs, &aset, &status);   // dac=dac*x
+                               }
+                               if (i == 31)
+                                       break;  // that was the last bit
+                               if (!seenbit)
+                                       continue;       // no need to square 1
+                               decMultiplyOp(dac, dac, dac, &aset, &status);   // dac=dac*dac [square]
+                       }       /*i */// 32 bits
+
+                       // complete internal overflow or underflow processing
+                       if (status & (DEC_Overflow | DEC_Underflow)) {
+#if DECSUBSET
+                               // If subset, and power was negative, reverse the kind of -erflow
+                               // [1/x not yet done]
+                               if (!set->extended && decNumberIsNegative(rhs)) {
+                                       if (status & DEC_Overflow)
+                                               status ^=
+                                                   DEC_Overflow | DEC_Underflow
+                                                   | DEC_Subnormal;
+                                       else {  // trickier -- Underflow may or may not be set
+                                               status &= ~(DEC_Underflow | DEC_Subnormal);     // [one or both]
+                                               status |= DEC_Overflow;
+                                       }
+                               }
+#endif
+                               dac->bits = (dac->bits & ~DECNEG) | bits;       // force correct sign
+                               // round subnormals [to set.digits rather than aset.digits]
+                               // or set overflow result similarly as required
+                               decFinalize(dac, set, &residue, &status);
+                               decNumberCopy(res, dac);        // copy to result (is now OK length)
+                               break;
+                       }
+#if DECSUBSET
+                       if (!set->extended &&   // subset math
+                           decNumberIsNegative(rhs)) { // was a **-n [hence digits>0]
+                               // so divide result into 1 [dac=1/dac]
+                               decDivideOp(dac, &dnOne, dac, &aset, DIVIDE,
+                                           &status);
+                       }
+#endif
+               }               // rhs integer path
+
+               // reduce result to the requested length and copy to result
+               decCopyFit(res, dac, set, &residue, &status);
+               decFinish(res, set, &residue, &status); // final cleanup
+#if DECSUBSET
+               if (!set->extended)
+                       decTrim(res, set, 0, 1, &dropped);      // trailing zeros
+#endif
+       } while (0);            // end protected
+
+       if (allocdac != NULL)
+               free(allocdac); // drop any storage used
+       if (allocinv != NULL)
+               free(allocinv); // ..
+#if DECSUBSET
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+#endif
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberPower
+
+/* ------------------------------------------------------------------ */
+/* decNumberQuantize -- force exponent to requested value             */
+/*                                                                    */
+/*   This computes C = op(A, B), where op adjusts the coefficient     */
+/*   of C (by rounding or shifting) such that the exponent (-scale)   */
+/*   of C has exponent of B.  The numerical value of C will equal A,  */
+/*   except for the effects of any rounding that occurred.            */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B                           */
+/*   lhs is A, the number to adjust                                   */
+/*   rhs is B, the number with exponent to match                      */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Unless there is an error or the result is infinite, the exponent   */
+/* after the operation is guaranteed to be equal to that of B.        */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberQuantize(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decQuantizeOp(res, lhs, rhs, set, 1, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberQuantize
+
+/* ------------------------------------------------------------------ */
+/* decNumberReduce -- remove trailing zeros                           */
+/*                                                                    */
+/*   This computes C = 0 + A, and normalizes the result               */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+// Previously known as Normalize
+decNumber *decNumberNormalize(decNumber * res, const decNumber * rhs,
+                             decContext * set)
+{
+       return decNumberReduce(res, rhs, set);
+}                              // decNumberNormalize
+
+decNumber *decNumberReduce(decNumber * res, const decNumber * rhs,
+                          decContext * set)
+{
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+       uInt status = 0;        // as usual
+       Int residue = 0;        // as usual
+       Int dropped;            // work
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operand and set lostDigits status, as needed
+                       if (rhs->digits > set->digits) {
+                               allocrhs = decRoundOperand(rhs, set, &status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // Infinities copy through; NaNs need usual treatment
+               if (decNumberIsNaN(rhs)) {
+                       decNaNs(res, rhs, NULL, set, &status);
+                       break;
+               }
+               // reduce result to the requested length and copy to result
+               decCopyFit(res, rhs, set, &residue, &status);   // copy & round
+               decFinish(res, set, &residue, &status); // cleanup/set flags
+               decTrim(res, set, 1, 0, &dropped);      // normalize in place
+               // [may clamp]
+       } while (0);            // end protected
+
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+#endif
+       if (status != 0)
+               decStatus(res, status, set);    // then report status
+       return res;
+}                              // decNumberReduce
+
+/* ------------------------------------------------------------------ */
+/* decNumberRescale -- force exponent to requested value              */
+/*                                                                    */
+/*   This computes C = op(A, B), where op adjusts the coefficient     */
+/*   of C (by rounding or shifting) such that the exponent (-scale)   */
+/*   of C has the value B.  The numerical value of C will equal A,    */
+/*   except for the effects of any rounding that occurred.            */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B                           */
+/*   lhs is A, the number to adjust                                   */
+/*   rhs is B, the requested exponent                                 */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Unless there is an error or the result is infinite, the exponent   */
+/* after the operation is guaranteed to be equal to B.                */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberRescale(decNumber * res, const decNumber * lhs,
+                           const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decQuantizeOp(res, lhs, rhs, set, 0, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberRescale
+
+/* ------------------------------------------------------------------ */
+/* decNumberRemainder -- divide and return remainder                  */
+/*                                                                    */
+/*   This computes C = A % B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberRemainder(decNumber * res, const decNumber * lhs,
+                             const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberRemainder
+
+/* ------------------------------------------------------------------ */
+/* decNumberRemainderNear -- divide and return remainder from nearest */
+/*                                                                    */
+/*   This computes C = A % B, where % is the IEEE remainder operator  */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberRemainderNear(decNumber * res, const decNumber * lhs,
+                                 const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberRemainderNear
+
+/* ------------------------------------------------------------------ */
+/* decNumberRotate -- rotate the coefficient of a Number left/right   */
+/*                                                                    */
+/*   This computes C = A rot B  (in base ten and rotating set->digits */
+/*   digits).                                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=XrotX)       */
+/*   lhs is A                                                         */
+/*   rhs is B, the number of digits to rotate (-ve to right)          */
+/*   set is the context                                               */
+/*                                                                    */
+/* The digits of the coefficient of A are rotated to the left (if B   */
+/* is positive) or to the right (if B is negative) without adjusting  */
+/* the exponent or the sign of A.  If lhs->digits is less than        */
+/* set->digits the coefficient is padded with zeros on the left       */
+/* before the rotate.  Any leading zeros in the result are removed    */
+/* as usual.                                                          */
+/*                                                                    */
+/* B must be an integer (q=0) and in the range -set->digits through   */
+/* +set->digits.                                                      */
+/* C must have space for set->digits digits.                          */
+/* NaNs are propagated as usual.  Infinities are unaffected (but      */
+/* B must be valid).  No status is set unless B is invalid or an      */
+/* operand is an sNaN.                                                */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberRotate(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       Int rotate;             // rhs as an Int
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       // NaNs propagate as normal
+       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
+               decNaNs(res, lhs, rhs, set, &status);
+       // rhs must be an integer
+       else if (decNumberIsInfinite(rhs) || rhs->exponent != 0)
+               status = DEC_Invalid_operation;
+       else {                  // both numeric, rhs is an integer
+               rotate = decGetInt(rhs);        // [cannot fail]
+               if (rotate == BADINT    // something bad ..
+                   || rotate == BIGODD || rotate == BIGEVEN    // .. very big ..
+                   || abs(rotate) > set->digits)       // .. or out of range
+                       status = DEC_Invalid_operation;
+               else {          // rhs is OK
+                       decNumberCopy(res, lhs);
+                       // convert -ve rotate to equivalent positive rotation
+                       if (rotate < 0)
+                               rotate = set->digits + rotate;
+                       if (rotate != 0 && rotate != set->digits        // zero or full rotation
+                           && !decNumberIsInfinite(res)) {     // lhs was infinite
+                               // left-rotate to do; 0 < rotate < set->digits
+                               uInt units, shift;      // work
+                               uInt msudigits; // digits in result msu
+                               Unit *msu = res->lsu + D2U(res->digits) - 1;    // current msu
+                               Unit *msumax = res->lsu + D2U(set->digits) - 1; // rotation msu
+                               for (msu++; msu <= msumax; msu++)
+                                       *msu = 0;       // ensure high units=0
+                               res->digits = set->digits;      // now full-length
+                               msudigits = MSUDIGITS(res->digits);     // actual digits in msu
+
+                               // rotation here is done in-place, in three steps
+                               // 1. shift all to least up to one unit to unit-align final
+                               //    lsd [any digits shifted out are rotated to the left,
+                               //    abutted to the original msd (which may require split)]
+                               //
+                               //    [if there are no whole units left to rotate, the
+                               //    rotation is now complete]
+                               //
+                               // 2. shift to least, from below the split point only, so that
+                               //    the final msd is in the right place in its Unit [any
+                               //    digits shifted out will fit exactly in the current msu,
+                               //    left aligned, no split required]
+                               //
+                               // 3. rotate all the units by reversing left part, right
+                               //    part, and then whole
+                               //
+                               // example: rotate right 8 digits (2 units + 2), DECDPUN=3.
+                               //
+                               //   start: 00a bcd efg hij klm npq
+                               //
+                               //      1a  000 0ab cde fgh|ijk lmn [pq saved]
+                               //      1b  00p qab cde fgh|ijk lmn
+                               //
+                               //      2a  00p qab cde fgh|00i jkl [mn saved]
+                               //      2b  mnp qab cde fgh|00i jkl
+                               //
+                               //      3a  fgh cde qab mnp|00i jkl
+                               //      3b  fgh cde qab mnp|jkl 00i
+                               //      3c  00i jkl mnp qab cde fgh
+
+                               // Step 1: amount to shift is the partial right-rotate count
+                               rotate = set->digits - rotate;  // make it right-rotate
+                               units = rotate / DECDPUN;       // whole units to rotate
+                               shift = rotate % DECDPUN;       // left-over digits count
+                               if (shift > 0) {        // not an exact number of units
+                                       uInt save = res->lsu[0] % powers[shift];        // save low digit(s)
+                                       decShiftToLeast(res->lsu,
+                                                       D2U(res->digits),
+                                                       shift);
+                                       if (shift > msudigits) {        // msumax-1 needs >0 digits
+                                               uInt rem = save % powers[shift - msudigits];    // split save
+                                               *msumax = (Unit) (save / powers[shift - msudigits]);    // and insert
+                                               *(msumax - 1) = *(msumax - 1)
+                                                   + (Unit) (rem * powers[DECDPUN - (shift - msudigits)]);     // ..
+                                       } else {        // all fits in msumax
+                                               *msumax = *msumax + (Unit) (save * powers[msudigits - shift]);  // [maybe *1]
+                                       }
+                               }       // digits shift needed
+
+                               // If whole units to rotate...
+                               if (units > 0) {        // some to do
+                                       // Step 2: the units to touch are the whole ones in rotate,
+                                       //   if any, and the shift is DECDPUN-msudigits (which may be
+                                       //   0, again)
+                                       shift = DECDPUN - msudigits;
+                                       if (shift > 0) {        // not an exact number of units
+                                               uInt save = res->lsu[0] % powers[shift];        // save low digit(s)
+                                               decShiftToLeast(res->lsu, units,
+                                                               shift);
+                                               *msumax =
+                                                   *msumax +
+                                                   (Unit) (save *
+                                                           powers[msudigits]);
+                                       }       // partial shift needed
+
+                                       // Step 3: rotate the units array using triple reverse
+                                       // (reversing is easy and fast)
+                                       decReverse(res->lsu + units, msumax);   // left part
+                                       decReverse(res->lsu, res->lsu + units - 1);     // right part
+                                       decReverse(res->lsu, msumax);   // whole
+                               }       // whole units to rotate
+                               // the rotation may have left an undetermined number of zeros
+                               // on the left, so true length needs to be calculated
+                               res->digits =
+                                   decGetDigits(res->lsu,
+                                                msumax - res->lsu + 1);
+                       }       // rotate needed
+               }               // rhs OK
+       }                       // numerics
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberRotate
+
+/* ------------------------------------------------------------------ */
+/* decNumberSameQuantum -- test for equal exponents                   */
+/*                                                                    */
+/*   res is the result number, which will contain either 0 or 1       */
+/*   lhs is a number to test                                          */
+/*   rhs is the second (usually a pattern)                            */
+/*                                                                    */
+/* No errors are possible and no context is needed.                   */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberSameQuantum(decNumber * res, const decNumber * lhs,
+                               const decNumber * rhs)
+{
+       Unit ret = 0;           // return value
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, DECUNCONT))
+               return res;
+#endif
+
+       if (SPECIALARGS) {
+               if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs))
+                       ret = 1;
+               else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs))
+                       ret = 1;
+               // [anything else with a special gives 0]
+       } else if (lhs->exponent == rhs->exponent)
+               ret = 1;
+
+       decNumberZero(res);     // OK to overwrite an operand now
+       *res->lsu = ret;
+       return res;
+}                              // decNumberSameQuantum
+
+/* ------------------------------------------------------------------ */
+/* decNumberScaleB -- multiply by a power of 10                       */
+/*                                                                    */
+/* This computes C = A x 10**B where B is an integer (q=0) with       */
+/* maximum magnitude 2*(emax+digits)                                  */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B                           */
+/*   lhs is A, the number to adjust                                   */
+/*   rhs is B, the requested power of ten to use                      */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* The result may underflow or overflow.                              */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberScaleB(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set)
+{
+       Int reqexp;             // requested exponent change [B]
+       uInt status = 0;        // accumulator
+       Int residue;            // work
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       // Handle special values except lhs infinite
+       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
+               decNaNs(res, lhs, rhs, set, &status);
+       // rhs must be an integer
+       else if (decNumberIsInfinite(rhs) || rhs->exponent != 0)
+               status = DEC_Invalid_operation;
+       else {
+               // lhs is a number; rhs is a finite with q==0
+               reqexp = decGetInt(rhs);        // [cannot fail]
+               // maximum range is larger than getInt can handle, so this is
+               // more restrictive than the specification
+               if (reqexp == BADINT    // something bad ..
+                   || reqexp == BIGODD || reqexp == BIGEVEN    // it was huge
+                   || (abs(reqexp) + 1) / 2 > (set->digits + set->emax))       // .. or out of range
+                       status = DEC_Invalid_operation;
+               else {          // rhs is OK
+                       decNumberCopy(res, lhs);        // all done if infinite lhs
+                       if (!decNumberIsInfinite(res)) {        // prepare to scale
+                               Int exp = res->exponent;        // save for overflow test
+                               res->exponent += reqexp;        // adjust the exponent
+                               if (((exp ^ reqexp) >= 0)       // same sign ...
+                                   && ((exp ^ res->exponent) < 0)) {   // .. but result had different
+                                       // the calculation overflowed, so force right treatment
+                                       if (exp < 0)
+                                               res->exponent =
+                                                   DEC_MIN_EMIN -
+                                                   DEC_MAX_DIGITS;
+                                       else
+                                               res->exponent =
+                                                   DEC_MAX_EMAX + 1;
+                               }
+                               residue = 0;
+                               decFinalize(res, set, &residue, &status);       // final check
+                       }       // finite LHS
+               }               // rhs OK
+       }                       // rhs finite
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberScaleB
+
+/* ------------------------------------------------------------------ */
+/* decNumberShift -- shift the coefficient of a Number left or right  */
+/*                                                                    */
+/*   This computes C = A << B or C = A >> -B  (in base ten).          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X<<X)        */
+/*   lhs is A                                                         */
+/*   rhs is B, the number of digits to shift (-ve to right)           */
+/*   set is the context                                               */
+/*                                                                    */
+/* The digits of the coefficient of A are shifted to the left (if B   */
+/* is positive) or to the right (if B is negative) without adjusting  */
+/* the exponent or the sign of A.                                     */
+/*                                                                    */
+/* B must be an integer (q=0) and in the range -set->digits through   */
+/* +set->digits.                                                      */
+/* C must have space for set->digits digits.                          */
+/* NaNs are propagated as usual.  Infinities are unaffected (but      */
+/* B must be valid).  No status is set unless B is invalid or an      */
+/* operand is an sNaN.                                                */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberShift(decNumber * res, const decNumber * lhs,
+                         const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+       Int shift;              // rhs as an Int
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       // NaNs propagate as normal
+       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
+               decNaNs(res, lhs, rhs, set, &status);
+       // rhs must be an integer
+       else if (decNumberIsInfinite(rhs) || rhs->exponent != 0)
+               status = DEC_Invalid_operation;
+       else {                  // both numeric, rhs is an integer
+               shift = decGetInt(rhs); // [cannot fail]
+               if (shift == BADINT     // something bad ..
+                   || shift == BIGODD || shift == BIGEVEN      // .. very big ..
+                   || abs(shift) > set->digits)        // .. or out of range
+                       status = DEC_Invalid_operation;
+               else {          // rhs is OK
+                       decNumberCopy(res, lhs);
+                       if (shift != 0 && !decNumberIsInfinite(res)) {  // something to do
+                               if (shift > 0) {        // to left
+                                       if (shift == set->digits) {     // removing all
+                                               *res->lsu = 0;  // so place 0
+                                               res->digits = 1;        // ..
+                                       } else {        //
+                                               // first remove leading digits if necessary
+                                               if (res->digits + shift >
+                                                   set->digits) {
+                                                       decDecap(res,
+                                                                res->digits +
+                                                                shift -
+                                                                set->digits);
+                                                       // that updated res->digits; may have gone to 1 (for a
+                                                       // single digit or for zero
+                                               }
+                                               if (res->digits > 1 || *res->lsu)       // if non-zero..
+                                                       res->digits =
+                                                           decShiftToMost
+                                                           (res->lsu,
+                                                            res->digits,
+                                                            shift);
+                                       }       // partial left
+                               }       // left
+                               else {  // to right
+                                       if (-shift >= res->digits) {    // discarding all
+                                               *res->lsu = 0;  // so place 0
+                                               res->digits = 1;        // ..
+                                       } else {
+                                               decShiftToLeast(res->lsu,
+                                                               D2U
+                                                               (res->digits),
+                                                               -shift);
+                                               res->digits -= (-shift);
+                                       }
+                               }       // to right
+                       }       // non-0 non-Inf shift
+               }               // rhs OK
+       }                       // numerics
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberShift
+
+/* ------------------------------------------------------------------ */
+/* decNumberSquareRoot -- square root operator                        */
+/*                                                                    */
+/*   This computes C = squareroot(A)                                  */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+/* This uses the following varying-precision algorithm in:            */
+/*                                                                    */
+/*   Properly Rounded Variable Precision Square Root, T. E. Hull and  */
+/*   A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */
+/*   pp229-237, ACM, September 1985.                                  */
+/*                                                                    */
+/* The square-root is calculated using Newton's method, after which   */
+/* a check is made to ensure the result is correctly rounded.         */
+/*                                                                    */
+/* % [Reformatted original Numerical Turing source code follows.]     */
+/* function sqrt(x : real) : real                                     */
+/* % sqrt(x) returns the properly rounded approximation to the square */
+/* % root of x, in the precision of the calling environment, or it    */
+/* % fails if x < 0.                                                  */
+/* % t e hull and a abrham, august, 1984                              */
+/* if x <= 0 then                                                     */
+/*   if x < 0 then                                                    */
+/*     assert false                                                   */
+/*   else                                                             */
+/*     result 0                                                       */
+/*   end if                                                           */
+/* end if                                                             */
+/* var f := setexp(x, 0)  % fraction part of x   [0.1 <= x < 1]       */
+/* var e := getexp(x)     % exponent part of x                        */
+/* var approx : real                                                  */
+/* if e mod 2 = 0  then                                               */
+/*   approx := .259 + .819 * f   % approx to root of f                */
+/* else                                                               */
+/*   f := f/l0                   % adjustments                        */
+/*   e := e + 1                  %   for odd                          */
+/*   approx := .0819 + 2.59 * f  %   exponent                         */
+/* end if                                                             */
+/*                                                                    */
+/* var p:= 3                                                          */
+/* const maxp := currentprecision + 2                                 */
+/* loop                                                               */
+/*   p := min(2*p - 2, maxp)     % p = 4,6,10, . . . , maxp           */
+/*   precision p                                                      */
+/*   approx := .5 * (approx + f/approx)                               */
+/*   exit when p = maxp                                               */
+/* end loop                                                           */
+/*                                                                    */
+/* % approx is now within 1 ulp of the properly rounded square root   */
+/* % of f; to ensure proper rounding, compare squares of (approx -    */
+/* % l/2 ulp) and (approx + l/2 ulp) with f.                          */
+/* p := currentprecision                                              */
+/* begin                                                              */
+/*   precision p + 2                                                  */
+/*   const approxsubhalf := approx - setexp(.5, -p)                   */
+/*   if mulru(approxsubhalf, approxsubhalf) > f then                  */
+/*     approx := approx - setexp(.l, -p + 1)                          */
+/*   else                                                             */
+/*     const approxaddhalf := approx + setexp(.5, -p)                 */
+/*     if mulrd(approxaddhalf, approxaddhalf) < f then                */
+/*       approx := approx + setexp(.l, -p + 1)                        */
+/*     end if                                                         */
+/*   end if                                                           */
+/* end                                                                */
+/* result setexp(approx, e div 2)  % fix exponent                     */
+/* end sqrt                                                           */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberSquareRoot(decNumber * res, const decNumber * rhs,
+                              decContext * set)
+{
+       decContext workset, approxset;  // work contexts
+       decNumber dzero;        // used for constant zero
+       Int maxp;               // largest working precision
+       Int workp;              // working precision
+       Int residue = 0;        // rounding residue
+       uInt status = 0, ignore = 0;    // status accumulators
+       uInt rstatus;           // ..
+       Int exp;                // working exponent
+       Int ideal;              // ideal (preferred) exponent
+       Int needbytes;          // work
+       Int dropped;            // ..
+
+#if DECSUBSET
+       decNumber *allocrhs = NULL;     // non-NULL if rounded rhs allocated
+#endif
+       // buffer for f [needs +1 in case DECBUFFER 0]
+       decNumber buff[D2N(DECBUFFER + 1)];
+       // buffer for a [needs +2 to match likely maxp]
+       decNumber bufa[D2N(DECBUFFER + 2)];
+       // buffer for temporary, b [must be same size as a]
+       decNumber bufb[D2N(DECBUFFER + 2)];
+       decNumber *allocbuff = NULL;    // -> allocated buff, iff allocated
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *allocbufb = NULL;    // -> allocated bufb, iff allocated
+       decNumber *f = buff;    // reduced fraction
+       decNumber *a = bufa;    // approximation to result
+       decNumber *b = bufb;    // intermediate result
+       // buffer for temporary variable, up to 3 digits
+       decNumber buft[D2N(3)];
+       decNumber *t = buft;    // up-to-3-digit constant or work
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operand and set lostDigits status, as needed
+                       if (rhs->digits > set->digits) {
+                               allocrhs = decRoundOperand(rhs, set, &status);
+                               if (allocrhs == NULL)
+                                       break;
+                               // [Note: 'f' allocation below could reuse this buffer if
+                               // used, but as this is rare they are kept separate for clarity.]
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // handle infinities and NaNs
+               if (SPECIALARG) {
+                       if (decNumberIsInfinite(rhs)) { // an infinity
+                               if (decNumberIsNegative(rhs))
+                                       status |= DEC_Invalid_operation;
+                               else
+                                       decNumberCopy(res, rhs);        // +Infinity
+                       } else
+                               decNaNs(res, rhs, NULL, set, &status);  // a NaN
+                       break;
+               }
+               // calculate the ideal (preferred) exponent [floor(exp/2)]
+               // [It would be nicer to write: ideal=rhs->exponent>>1, but this
+               // generates a compiler warning.  Generated code is the same.]
+               ideal = (rhs->exponent & ~1) / 2;       // target
+
+               // handle zeros
+               if (ISZERO(rhs)) {
+                       decNumberCopy(res, rhs);        // could be 0 or -0
+                       res->exponent = ideal;  // use the ideal [safe]
+                       // use decFinish to clamp any out-of-range exponent, etc.
+                       decFinish(res, set, &residue, &status);
+                       break;
+               }
+               // any other -x is an oops
+               if (decNumberIsNegative(rhs)) {
+                       status |= DEC_Invalid_operation;
+                       break;
+               }
+               // space is needed for three working variables
+               //   f -- the same precision as the RHS, reduced to 0.01->0.99...
+               //   a -- Hull's approximation -- precision, when assigned, is
+               //        currentprecision+1 or the input argument precision,
+               //        whichever is larger (+2 for use as temporary)
+               //   b -- intermediate temporary result (same size as a)
+               // if any is too long for local storage, then allocate
+               workp = MAXI(set->digits + 1, rhs->digits);     // actual rounding precision
+               workp = MAXI(workp, 7); // at least 7 for low cases
+               maxp = workp + 2;       // largest working precision
+
+               needbytes =
+                   sizeof(decNumber) + (D2U(rhs->digits) - 1) * sizeof(Unit);
+               if (needbytes > (Int) sizeof(buff)) {
+                       allocbuff = (decNumber *) malloc(needbytes);
+                       if (allocbuff == NULL) {        // hopeless -- abandon
+                               status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       f = allocbuff;  // use the allocated space
+               }
+               // a and b both need to be able to hold a maxp-length number
+               needbytes = sizeof(decNumber) + (D2U(maxp) - 1) * sizeof(Unit);
+               if (needbytes > (Int) sizeof(bufa)) {   // [same applies to b]
+                       allocbufa = (decNumber *) malloc(needbytes);
+                       allocbufb = (decNumber *) malloc(needbytes);
+                       if (allocbufa == NULL || allocbufb == NULL) {   // hopeless
+                               status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       a = allocbufa;  // use the allocated spaces
+                       b = allocbufb;  // ..
+               }
+               // copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1
+               decNumberCopy(f, rhs);
+               exp = f->exponent + f->digits;  // adjusted to Hull rules
+               f->exponent = -(f->digits);     // to range
+
+               // set up working context
+               decContextDefault(&workset, DEC_INIT_DECIMAL64);
+               workset.emax = DEC_MAX_EMAX;
+               workset.emin = DEC_MIN_EMIN;
+
+               // [Until further notice, no error is possible and status bits
+               // (Rounded, etc.) should be ignored, not accumulated.]
+
+               // Calculate initial approximation, and allow for odd exponent
+               workset.digits = workp; // p for initial calculation
+               t->bits = 0;
+               t->digits = 3;
+               a->bits = 0;
+               a->digits = 3;
+               if ((exp & 1) == 0) {   // even exponent
+                       // Set t=0.259, a=0.819
+                       t->exponent = -3;
+                       a->exponent = -3;
+#if DECDPUN>=3
+                       t->lsu[0] = 259;
+                       a->lsu[0] = 819;
+#elif DECDPUN==2
+                       t->lsu[0] = 59;
+                       t->lsu[1] = 2;
+                       a->lsu[0] = 19;
+                       a->lsu[1] = 8;
+#else
+                       t->lsu[0] = 9;
+                       t->lsu[1] = 5;
+                       t->lsu[2] = 2;
+                       a->lsu[0] = 9;
+                       a->lsu[1] = 1;
+                       a->lsu[2] = 8;
+#endif
+               } else {        // odd exponent
+                       // Set t=0.0819, a=2.59
+                       f->exponent--;  // f=f/10
+                       exp++;  // e=e+1
+                       t->exponent = -4;
+                       a->exponent = -2;
+#if DECDPUN>=3
+                       t->lsu[0] = 819;
+                       a->lsu[0] = 259;
+#elif DECDPUN==2
+                       t->lsu[0] = 19;
+                       t->lsu[1] = 8;
+                       a->lsu[0] = 59;
+                       a->lsu[1] = 2;
+#else
+                       t->lsu[0] = 9;
+                       t->lsu[1] = 1;
+                       t->lsu[2] = 8;
+                       a->lsu[0] = 9;
+                       a->lsu[1] = 5;
+                       a->lsu[2] = 2;
+#endif
+               }
+
+               decMultiplyOp(a, a, f, &workset, &ignore);      // a=a*f
+               decAddOp(a, a, t, &workset, 0, &ignore);        // ..+t
+               // [a is now the initial approximation for sqrt(f), calculated with
+               // currentprecision, which is also a's precision.]
+
+               // the main calculation loop
+               decNumberZero(&dzero);  // make 0
+               decNumberZero(t);       // set t = 0.5
+               t->lsu[0] = 5;  // ..
+               t->exponent = -1;       // ..
+               workset.digits = 3;     // initial p
+               for (; workset.digits < maxp;) {
+                       // set p to min(2*p - 2, maxp)  [hence 3; or: 4, 6, 10, ... , maxp]
+                       workset.digits = MINI(workset.digits * 2 - 2, maxp);
+                       // a = 0.5 * (a + f/a)
+                       // [calculated at p then rounded to currentprecision]
+                       decDivideOp(b, f, a, &workset, DIVIDE, &ignore);        // b=f/a
+                       decAddOp(b, b, a, &workset, 0, &ignore);        // b=b+a
+                       decMultiplyOp(a, b, t, &workset, &ignore);      // a=b*0.5
+               }               // loop
+
+               // Here, 0.1 <= a < 1 [Hull], and a has maxp digits
+               // now reduce to length, etc.; this needs to be done with a
+               // having the correct exponent so as to handle subnormals
+               // correctly
+               approxset = *set;       // get emin, emax, etc.
+               approxset.round = DEC_ROUND_HALF_EVEN;
+               a->exponent += exp / 2; // set correct exponent
+               rstatus = 0;    // clear status
+               residue = 0;    // .. and accumulator
+               decCopyFit(a, a, &approxset, &residue, &rstatus);       // reduce (if needed)
+               decFinish(a, &approxset, &residue, &rstatus);   // clean and finalize
+
+               // Overflow was possible if the input exponent was out-of-range,
+               // in which case quit
+               if (rstatus & DEC_Overflow) {
+                       status = rstatus;       // use the status as-is
+                       decNumberCopy(res, a);  // copy to result
+                       break;
+               }
+               // Preserve status except Inexact/Rounded
+               status |= (rstatus & ~(DEC_Rounded | DEC_Inexact));
+
+               // Carry out the Hull correction
+               a->exponent -= exp / 2; // back to 0.1->1
+
+               // a is now at final precision and within 1 ulp of the properly
+               // rounded square root of f; to ensure proper rounding, compare
+               // squares of (a - l/2 ulp) and (a + l/2 ulp) with f.
+               // Here workset.digits=maxp and t=0.5, and a->digits determines
+               // the ulp
+               workset.digits--;       // maxp-1 is OK now
+               t->exponent = -a->digits - 1;   // make 0.5 ulp
+               decAddOp(b, a, t, &workset, DECNEG, &ignore);   // b = a - 0.5 ulp
+               workset.round = DEC_ROUND_UP;
+               decMultiplyOp(b, b, b, &workset, &ignore);      // b = mulru(b, b)
+               decCompareOp(b, f, b, &workset, COMPARE, &ignore);      // b ? f, reversed
+               if (decNumberIsNegative(b)) {   // f < b [i.e., b > f]
+                       // this is the more common adjustment, though both are rare
+                       t->exponent++;  // make 1.0 ulp
+                       t->lsu[0] = 1;  // ..
+                       decAddOp(a, a, t, &workset, DECNEG, &ignore);   // a = a - 1 ulp
+                       // assign to approx [round to length]
+                       approxset.emin -= exp / 2;      // adjust to match a
+                       approxset.emax -= exp / 2;
+                       decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+               } else {
+                       decAddOp(b, a, t, &workset, 0, &ignore);        // b = a + 0.5 ulp
+                       workset.round = DEC_ROUND_DOWN;
+                       decMultiplyOp(b, b, b, &workset, &ignore);      // b = mulrd(b, b)
+                       decCompareOp(b, b, f, &workset, COMPARE, &ignore);      // b ? f
+                       if (decNumberIsNegative(b)) {   // b < f
+                               t->exponent++;  // make 1.0 ulp
+                               t->lsu[0] = 1;  // ..
+                               decAddOp(a, a, t, &workset, 0, &ignore);        // a = a + 1 ulp
+                               // assign to approx [round to length]
+                               approxset.emin -= exp / 2;      // adjust to match a
+                               approxset.emax -= exp / 2;
+                               decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+                       }
+               }
+               // [no errors are possible in the above, and rounding/inexact during
+               // estimation are irrelevant, so status was not accumulated]
+
+               // Here, 0.1 <= a < 1  (still), so adjust back
+               a->exponent += exp / 2; // set correct exponent
+
+               // count droppable zeros [after any subnormal rounding] by
+               // trimming a copy
+               decNumberCopy(b, a);
+               decTrim(b, set, 1, 1, &dropped);        // [drops trailing zeros]
+
+               // Set Inexact and Rounded.  The answer can only be exact if
+               // it is short enough so that squaring it could fit in workp
+               // digits, so this is the only (relatively rare) condition that
+               // a careful check is needed
+               if (b->digits * 2 - 1 > workp) {        // cannot fit
+                       status |= DEC_Inexact | DEC_Rounded;
+               } else {        // could be exact/unrounded
+                       uInt mstatus = 0;       // local status
+                       decMultiplyOp(b, b, b, &workset, &mstatus);     // try the multiply
+                       if (mstatus & DEC_Overflow) {   // result just won't fit
+                               status |= DEC_Inexact | DEC_Rounded;
+                       } else {        // plausible
+                               decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus);   // b ? rhs
+                               if (!ISZERO(t))
+                                       status |= DEC_Inexact | DEC_Rounded;    // not equal
+                               else {  // is Exact
+                                       // here, dropped is the count of trailing zeros in 'a'
+                                       // use closest exponent to ideal...
+                                       Int todrop = ideal - a->exponent;       // most that can be dropped
+                                       if (todrop < 0)
+                                               status |= DEC_Rounded;  // ideally would add 0s
+                                       else {  // unrounded
+                                               // there are some to drop, but emax may not allow all
+                                               Int maxexp =
+                                                   set->emax - set->digits + 1;
+                                               Int maxdrop =
+                                                   maxexp - a->exponent;
+                                               if (todrop > maxdrop && set->clamp) {   // apply clamping
+                                                       todrop = maxdrop;
+                                                       status |= DEC_Clamped;
+                                               }
+                                               if (dropped < todrop) { // clamp to those available
+                                                       todrop = dropped;
+                                                       status |= DEC_Clamped;
+                                               }
+                                               if (todrop > 0) {       // have some to drop
+                                                       decShiftToLeast(a->lsu,
+                                                                       D2U
+                                                                       (a->digits),
+                                                                       todrop);
+                                                       a->exponent += todrop;  // maintain numerical value
+                                                       a->digits -= todrop;    // new length
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // double-check Underflow, as perhaps the result could not have
+               // been subnormal (initial argument too big), or it is now Exact
+               if (status & DEC_Underflow) {
+                       Int ae = rhs->exponent + rhs->digits - 1;       // adjusted exponent
+                       // check if truly subnormal
+#if DECEXTFLAG                 // DEC_Subnormal too
+                       if (ae >= set->emin * 2)
+                               status &= ~(DEC_Subnormal | DEC_Underflow);
+#else
+                       if (ae >= set->emin * 2)
+                               status &= ~DEC_Underflow;
+#endif
+                       // check if truly inexact
+                       if (!(status & DEC_Inexact))
+                               status &= ~DEC_Underflow;
+               }
+
+               decNumberCopy(res, a);  // a is now the result
+       } while (0);            // end protected
+
+       if (allocbuff != NULL)
+               free(allocbuff);        // drop any storage used
+       if (allocbufa != NULL)
+               free(allocbufa);        // ..
+       if (allocbufb != NULL)
+               free(allocbufb);        // ..
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+#endif
+       if (status != 0)
+               decStatus(res, status, set);    // then report status
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberSquareRoot
+
+/* ------------------------------------------------------------------ */
+/* decNumberSubtract -- subtract two Numbers                          */
+/*                                                                    */
+/*   This computes C = A - B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X-X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberSubtract(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs, decContext * set)
+{
+       uInt status = 0;        // accumulator
+
+       decAddOp(res, lhs, rhs, set, DECNEG, &status);
+       if (status != 0)
+               decStatus(res, status, set);
+#if DECCHECK
+       decCheckInexact(res, set);
+#endif
+       return res;
+}                              // decNumberSubtract
+
+/* ------------------------------------------------------------------ */
+/* decNumberToIntegralExact -- round-to-integral-value with InExact   */
+/* decNumberToIntegralValue -- round-to-integral-value                */
+/*                                                                    */
+/*   res is the result                                                */
+/*   rhs is input number                                              */
+/*   set is the context                                               */
+/*                                                                    */
+/* res must have space for any value of rhs.                          */
+/*                                                                    */
+/* This implements the IEEE special operators and therefore treats    */
+/* special values as valid.  For finite numbers it returns            */
+/* rescale(rhs, 0) if rhs->exponent is <0.                            */
+/* Otherwise the result is rhs (so no error is possible, except for   */
+/* sNaN).                                                             */
+/*                                                                    */
+/* The context is used for rounding mode and status after sNaN, but   */
+/* the digits setting is ignored.  The Exact version will signal      */
+/* Inexact if the result differs numerically from rhs; the other      */
+/* never signals Inexact.                                             */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberToIntegralExact(decNumber * res, const decNumber * rhs,
+                                   decContext * set)
+{
+       decNumber dn;
+       decContext workset;     // working context
+       uInt status = 0;        // accumulator
+
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       // handle infinities and NaNs
+       if (SPECIALARG) {
+               if (decNumberIsInfinite(rhs))
+                       decNumberCopy(res, rhs);        // an Infinity
+               else
+                       decNaNs(res, rhs, NULL, set, &status);  // a NaN
+       } else {                // finite
+               // have a finite number; no error possible (res must be big enough)
+               if (rhs->exponent >= 0)
+                       return decNumberCopy(res, rhs);
+               // that was easy, but if negative exponent there is work to do...
+               workset = *set; // clone rounding, etc.
+               workset.digits = rhs->digits;   // no length rounding
+               workset.traps = 0;      // no traps
+               decNumberZero(&dn);     // make a number with exponent 0
+               decNumberQuantize(res, rhs, &dn, &workset);
+               status |= workset.status;
+       }
+       if (status != 0)
+               decStatus(res, status, set);
+       return res;
+}                              // decNumberToIntegralExact
+
+decNumber *decNumberToIntegralValue(decNumber * res, const decNumber * rhs,
+                                   decContext * set)
+{
+       decContext workset = *set;      // working context
+       workset.traps = 0;      // no traps
+       decNumberToIntegralExact(res, rhs, &workset);
+       // this never affects set, except for sNaNs; NaN will have been set
+       // or propagated already, so no need to call decStatus
+       set->status |= workset.status & DEC_Invalid_operation;
+       return res;
+}                              // decNumberToIntegralValue
+
+/* ------------------------------------------------------------------ */
+/* decNumberXor -- XOR two Numbers, digitwise                         */
+/*                                                                    */
+/*   This computes C = A ^ B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X^X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context (used for result length and error report)     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Logical function restrictions apply (see above); a NaN is          */
+/* returned with Invalid_operation if a restriction is violated.      */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberXor(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set)
+{
+       const Unit *ua, *ub;    // -> operands
+       const Unit *msua, *msub;        // -> operand msus
+       Unit *uc, *msuc;        // -> result and its msu
+       Int msudigs;            // digits in res msu
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       if (lhs->exponent != 0 || decNumberIsSpecial(lhs)
+           || decNumberIsNegative(lhs)
+           || rhs->exponent != 0 || decNumberIsSpecial(rhs)
+           || decNumberIsNegative(rhs)) {
+               decStatus(res, DEC_Invalid_operation, set);
+               return res;
+       }
+       // operands are valid
+       ua = lhs->lsu;          // bottom-up
+       ub = rhs->lsu;          // ..
+       uc = res->lsu;          // ..
+       msua = ua + D2U(lhs->digits) - 1;       // -> msu of lhs
+       msub = ub + D2U(rhs->digits) - 1;       // -> msu of rhs
+       msuc = uc + D2U(set->digits) - 1;       // -> msu of result
+       msudigs = MSUDIGITS(set->digits);       // [faster than remainder]
+       for (; uc <= msuc; ua++, ub++, uc++) {  // Unit loop
+               Unit a, b;      // extract units
+               if (ua > msua)
+                       a = 0;
+               else
+                       a = *ua;
+               if (ub > msub)
+                       b = 0;
+               else
+                       b = *ub;
+               *uc = 0;        // can now write back
+               if (a | b) {    // maybe 1 bits to examine
+                       Int i, j;
+                       // This loop could be unrolled and/or use BIN2BCD tables
+                       for (i = 0; i < DECDPUN; i++) {
+                               if ((a ^ b) & 1)
+                                       *uc = *uc + (Unit) powers[i];   // effect XOR
+                               j = a % 10;
+                               a = a / 10;
+                               j |= b % 10;
+                               b = b / 10;
+                               if (j > 1) {
+                                       decStatus(res, DEC_Invalid_operation,
+                                                 set);
+                                       return res;
+                               }
+                               if (uc == msuc && i == msudigs - 1)
+                                       break;  // just did final digit
+                       }       // each digit
+               }               // non-zero
+       }                       // each unit
+       // [here uc-1 is the msu of the result]
+       res->digits = decGetDigits(res->lsu, uc - res->lsu);
+       res->exponent = 0;      // integer
+       res->bits = 0;          // sign=0
+       return res;             // [no status to set]
+}                              // decNumberXor
+
+/* ================================================================== */
+/* Utility routines                                                   */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* decNumberClass -- return the decClass of a decNumber               */
+/*   dn -- the decNumber to test                                      */
+/*   set -- the context to use for Emin                               */
+/*   returns the decClass enum                                        */
+/* ------------------------------------------------------------------ */
+enum decClass decNumberClass(const decNumber * dn, decContext * set)
+{
+       if (decNumberIsSpecial(dn)) {
+               if (decNumberIsQNaN(dn))
+                       return DEC_CLASS_QNAN;
+               if (decNumberIsSNaN(dn))
+                       return DEC_CLASS_SNAN;
+               // must be an infinity
+               if (decNumberIsNegative(dn))
+                       return DEC_CLASS_NEG_INF;
+               return DEC_CLASS_POS_INF;
+       }
+       // is finite
+       if (decNumberIsNormal(dn, set)) {       // most common
+               if (decNumberIsNegative(dn))
+                       return DEC_CLASS_NEG_NORMAL;
+               return DEC_CLASS_POS_NORMAL;
+       }
+       // is subnormal or zero
+       if (decNumberIsZero(dn)) {      // most common
+               if (decNumberIsNegative(dn))
+                       return DEC_CLASS_NEG_ZERO;
+               return DEC_CLASS_POS_ZERO;
+       }
+       if (decNumberIsNegative(dn))
+               return DEC_CLASS_NEG_SUBNORMAL;
+       return DEC_CLASS_POS_SUBNORMAL;
+}                              // decNumberClass
+
+/* ------------------------------------------------------------------ */
+/* decNumberClassToString -- convert decClass to a string             */
+/*                                                                    */
+/*  eclass is a valid decClass                                        */
+/*  returns a constant string describing the class (max 13+1 chars)   */
+/* ------------------------------------------------------------------ */
+const char *decNumberClassToString(enum decClass eclass)
+{
+       if (eclass == DEC_CLASS_POS_NORMAL)
+               return DEC_ClassString_PN;
+       if (eclass == DEC_CLASS_NEG_NORMAL)
+               return DEC_ClassString_NN;
+       if (eclass == DEC_CLASS_POS_ZERO)
+               return DEC_ClassString_PZ;
+       if (eclass == DEC_CLASS_NEG_ZERO)
+               return DEC_ClassString_NZ;
+       if (eclass == DEC_CLASS_POS_SUBNORMAL)
+               return DEC_ClassString_PS;
+       if (eclass == DEC_CLASS_NEG_SUBNORMAL)
+               return DEC_ClassString_NS;
+       if (eclass == DEC_CLASS_POS_INF)
+               return DEC_ClassString_PI;
+       if (eclass == DEC_CLASS_NEG_INF)
+               return DEC_ClassString_NI;
+       if (eclass == DEC_CLASS_QNAN)
+               return DEC_ClassString_QN;
+       if (eclass == DEC_CLASS_SNAN)
+               return DEC_ClassString_SN;
+       return DEC_ClassString_UN;      // Unknown
+}                              // decNumberClassToString
+
+/* ------------------------------------------------------------------ */
+/* decNumberCopy -- copy a number                                     */
+/*                                                                    */
+/*   dest is the target decNumber                                     */
+/*   src  is the source decNumber                                     */
+/*   returns dest                                                     */
+/*                                                                    */
+/* (dest==src is allowed and is a no-op)                              */
+/* All fields are updated as required.  This is a utility operation,  */
+/* so special values are unchanged and no error is possible.          */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCopy(decNumber * dest, const decNumber * src)
+{
+
+#if DECCHECK
+       if (src == NULL)
+               return decNumberZero(dest);
+#endif
+
+       if (dest == src)
+               return dest;    // no copy required
+
+       // Use explicit assignments here as structure assignment could copy
+       // more than just the lsu (for small DECDPUN).  This would not affect
+       // the value of the results, but could disturb test harness spill
+       // checking.
+       dest->bits = src->bits;
+       dest->exponent = src->exponent;
+       dest->digits = src->digits;
+       dest->lsu[0] = src->lsu[0];
+       if (src->digits > DECDPUN) {    // more Units to come
+               const Unit *smsup, *s;  // work
+               Unit *d;        // ..
+               // memcpy for the remaining Units would be safe as they cannot
+               // overlap.  However, this explicit loop is faster in short cases.
+               d = dest->lsu + 1;      // -> first destination
+               smsup = src->lsu + D2U(src->digits);    // -> source msu+1
+               for (s = src->lsu + 1; s < smsup; s++, d++)
+                       *d = *s;
+       }
+       return dest;
+}                              // decNumberCopy
+
+/* ------------------------------------------------------------------ */
+/* decNumberCopyAbs -- quiet absolute value operator                  */
+/*                                                                    */
+/*   This sets C = abs(A)                                             */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* No exception or error can occur; this is a quiet bitwise operation.*/
+/* See also decNumberAbs for a checking version of this.              */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCopyAbs(decNumber * res, const decNumber * rhs)
+{
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT))
+               return res;
+#endif
+       decNumberCopy(res, rhs);
+       res->bits &= ~DECNEG;   // turn off sign
+       return res;
+}                              // decNumberCopyAbs
+
+/* ------------------------------------------------------------------ */
+/* decNumberCopyNegate -- quiet negate value operator                 */
+/*                                                                    */
+/*   This sets C = negate(A)                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* No exception or error can occur; this is a quiet bitwise operation.*/
+/* See also decNumberMinus for a checking version of this.            */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCopyNegate(decNumber * res, const decNumber * rhs)
+{
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT))
+               return res;
+#endif
+       decNumberCopy(res, rhs);
+       res->bits ^= DECNEG;    // invert the sign
+       return res;
+}                              // decNumberCopyNegate
+
+/* ------------------------------------------------------------------ */
+/* decNumberCopySign -- quiet copy and set sign operator              */
+/*                                                                    */
+/*   This sets C = A with the sign of B                               */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* No exception or error can occur; this is a quiet bitwise operation.*/
+/* ------------------------------------------------------------------ */
+decNumber *decNumberCopySign(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs)
+{
+       uByte sign;             // rhs sign
+#if DECCHECK
+       if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT))
+               return res;
+#endif
+       sign = rhs->bits & DECNEG;      // save sign bit
+       decNumberCopy(res, lhs);
+       res->bits &= ~DECNEG;   // clear the sign
+       res->bits |= sign;      // set from rhs
+       return res;
+}                              // decNumberCopySign
+
+/* ------------------------------------------------------------------ */
+/* decNumberGetBCD -- get the coefficient in BCD8                     */
+/*   dn is the source decNumber                                       */
+/*   bcd is the uInt array that will receive dn->digits BCD bytes,    */
+/*     most-significant at offset 0                                   */
+/*   returns bcd                                                      */
+/*                                                                    */
+/* bcd must have at least dn->digits bytes.  No error is possible; if */
+/* dn is a NaN or Infinite, digits must be 1 and the coefficient 0.   */
+/* ------------------------------------------------------------------ */
+uByte *decNumberGetBCD(const decNumber * dn, uByte * bcd)
+{
+       uByte *ub = bcd + dn->digits - 1;       // -> lsd
+       const Unit *up = dn->lsu;       // Unit pointer, -> lsu
+
+#if DECDPUN==1                 // trivial simple copy
+       for (; ub >= bcd; ub--, up++)
+               *ub = *up;
+#else                          // chopping needed
+       uInt u = *up;           // work
+       uInt cut = DECDPUN;     // downcounter through unit
+       for (; ub >= bcd; ub--) {
+               *ub = (uByte) (u % 10); // [*6554 trick inhibits, here]
+               u = u / 10;
+               cut--;
+               if (cut > 0)
+                       continue;       // more in this unit
+               up++;
+               u = *up;
+               cut = DECDPUN;
+       }
+#endif
+       return bcd;
+}                              // decNumberGetBCD
+
+/* ------------------------------------------------------------------ */
+/* decNumberSetBCD -- set (replace) the coefficient from BCD8         */
+/*   dn is the target decNumber                                       */
+/*   bcd is the uInt array that will source n BCD bytes, most-        */
+/*     significant at offset 0                                        */
+/*   n is the number of digits in the source BCD array (bcd)          */
+/*   returns dn                                                       */
+/*                                                                    */
+/* dn must have space for at least n digits.  No error is possible;   */
+/* if dn is a NaN, or Infinite, or is to become a zero, n must be 1   */
+/* and bcd[0] zero.                                                   */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberSetBCD(decNumber * dn, const uByte * bcd, uInt n)
+{
+       Unit *up = dn->lsu + D2U(dn->digits) - 1;       // -> msu [target pointer]
+       const uByte *ub = bcd;  // -> source msd
+
+#if DECDPUN==1                 // trivial simple copy
+       for (; ub < bcd + n; ub++, up--)
+               *up = *ub;
+#else                          // some assembly needed
+       // calculate how many digits in msu, and hence first cut
+       Int cut = MSUDIGITS(n); // [faster than remainder]
+       for (; up >= dn->lsu; up--) {   // each Unit from msu
+               *up = 0;        // will take <=DECDPUN digits
+               for (; cut > 0; ub++, cut--)
+                       *up = X10(*up) + *ub;
+               cut = DECDPUN;  // next Unit has all digits
+       }
+#endif
+       dn->digits = n;         // set digit count
+       return dn;
+}                              // decNumberSetBCD
+
+/* ------------------------------------------------------------------ */
+/* decNumberIsNormal -- test normality of a decNumber                 */
+/*   dn is the decNumber to test                                      */
+/*   set is the context to use for Emin                               */
+/*   returns 1 if |dn| is finite and >=Nmin, 0 otherwise              */
+/* ------------------------------------------------------------------ */
+Int decNumberIsNormal(const decNumber * dn, decContext * set)
+{
+       Int ae;                 // adjusted exponent
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set))
+               return 0;
+#endif
+
+       if (decNumberIsSpecial(dn))
+               return 0;       // not finite
+       if (decNumberIsZero(dn))
+               return 0;       // not non-zero
+
+       ae = dn->exponent + dn->digits - 1;     // adjusted exponent
+       if (ae < set->emin)
+               return 0;       // is subnormal
+       return 1;
+}                              // decNumberIsNormal
+
+/* ------------------------------------------------------------------ */
+/* decNumberIsSubnormal -- test subnormality of a decNumber           */
+/*   dn is the decNumber to test                                      */
+/*   set is the context to use for Emin                               */
+/*   returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise    */
+/* ------------------------------------------------------------------ */
+Int decNumberIsSubnormal(const decNumber * dn, decContext * set)
+{
+       Int ae;                 // adjusted exponent
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set))
+               return 0;
+#endif
+
+       if (decNumberIsSpecial(dn))
+               return 0;       // not finite
+       if (decNumberIsZero(dn))
+               return 0;       // not non-zero
+
+       ae = dn->exponent + dn->digits - 1;     // adjusted exponent
+       if (ae < set->emin)
+               return 1;       // is subnormal
+       return 0;
+}                              // decNumberIsSubnormal
+
+/* ------------------------------------------------------------------ */
+/* decNumberTrim -- remove insignificant zeros                        */
+/*                                                                    */
+/*   dn is the number to trim                                         */
+/*   returns dn                                                       */
+/*                                                                    */
+/* All fields are updated as required.  This is a utility operation,  */
+/* so special values are unchanged and no error is possible.  The     */
+/* zeros are removed unconditionally.                                 */
+/* ------------------------------------------------------------------ */
+decNumber *decNumberTrim(decNumber * dn)
+{
+       Int dropped;            // work
+       decContext set;         // ..
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT))
+               return dn;
+#endif
+       decContextDefault(&set, DEC_INIT_BASE); // clamp=0
+       return decTrim(dn, &set, 0, 1, &dropped);
+}                              // decNumberTrim
+
+/* ------------------------------------------------------------------ */
+/* decNumberVersion -- return the name and version of this module     */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+const char *decNumberVersion(void)
+{
+       return DECVERSION;
+}                              // decNumberVersion
+
+/* ------------------------------------------------------------------ */
+/* decNumberZero -- set a number to 0                                 */
+/*                                                                    */
+/*   dn is the number to set, with space for one digit                */
+/*   returns dn                                                       */
+/*                                                                    */
+/* No error is possible.                                              */
+/* ------------------------------------------------------------------ */
+// Memset is not used as it is much slower in some environments.
+decNumber *decNumberZero(decNumber * dn)
+{
+
+#if DECCHECK
+       if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT))
+               return dn;
+#endif
+
+       dn->bits = 0;
+       dn->exponent = 0;
+       dn->digits = 1;
+       dn->lsu[0] = 0;
+       return dn;
+}                              // decNumberZero
+
+/* ================================================================== */
+/* Local routines                                                     */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* decToString -- lay out a number into a string                      */
+/*                                                                    */
+/*   dn     is the number to lay out                                  */
+/*   string is where to lay out the number                            */
+/*   eng    is 1 if Engineering, 0 if Scientific                      */
+/*                                                                    */
+/* string must be at least dn->digits+14 characters long              */
+/* No error is possible.                                              */
+/*                                                                    */
+/* Note that this routine can generate a -0 or 0.000.  These are      */
+/* never generated in subset to-number or arithmetic, but can occur   */
+/* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234).              */
+/* ------------------------------------------------------------------ */
+// If DECCHECK is enabled the string "?" is returned if a number is
+// invalid.
+static void decToString(const decNumber * dn, char *string, Flag eng)
+{
+       Int exp = dn->exponent; // local copy
+       Int e;                  // E-part value
+       Int pre;                // digits before the '.'
+       Int cut;                // for counting digits in a Unit
+       char *c = string;       // work [output pointer]
+       const Unit *up = dn->lsu + D2U(dn->digits) - 1; // -> msu [input pointer]
+       uInt u, pow;            // work
+
+#if DECCHECK
+       if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
+               strcpy(string, "?");
+               return;
+       }
+#endif
+
+       if (decNumberIsNegative(dn)) {  // Negatives get a minus
+               *c = '-';
+               c++;
+       }
+       if (dn->bits & DECSPECIAL) {    // Is a special value
+               if (decNumberIsInfinite(dn)) {
+                       strcpy(c, "Inf");
+                       strcpy(c + 3, "inity");
+                       return;
+               }
+               // a NaN
+               if (dn->bits & DECSNAN) {       // signalling NaN
+                       *c = 's';
+                       c++;
+               }
+               strcpy(c, "NaN");
+               c += 3;         // step past
+               // if not a clean non-zero coefficient, that's all there is in a
+               // NaN string
+               if (exp != 0 || (*dn->lsu == 0 && dn->digits == 1))
+                       return;
+               // [drop through to add integer]
+       }
+       // calculate how many digits in msu, and hence first cut
+       cut = MSUDIGITS(dn->digits);    // [faster than remainder]
+       cut--;                  // power of ten for digit
+
+       if (exp == 0) {         // simple integer [common fastpath]
+               for (; up >= dn->lsu; up--) {   // each Unit from msu
+                       u = *up;        // contains DECDPUN digits to lay out
+                       for (; cut >= 0; c++, cut--)
+                               TODIGIT(u, cut, c, pow);
+                       cut = DECDPUN - 1;      // next Unit has all digits
+               }
+               *c = '\0';      // terminate the string
+               return;
+       }
+
+       /* non-0 exponent -- assume plain form */
+       pre = dn->digits + exp; // digits before '.'
+       e = 0;                  // no E
+       if ((exp > 0) || (pre < -5)) {  // need exponential form
+               e = exp + dn->digits - 1;       // calculate E value
+               pre = 1;        // assume one digit before '.'
+               if (eng && (e != 0)) {  // engineering: may need to adjust
+                       Int adj;        // adjustment
+                       // The C remainder operator is undefined for negative numbers, so
+                       // a positive remainder calculation must be used here
+                       if (e < 0) {
+                               adj = (-e) % 3;
+                               if (adj != 0)
+                                       adj = 3 - adj;
+                       } else {        // e>0
+                               adj = e % 3;
+                       }
+                       e = e - adj;
+                       // if dealing with zero still produce an exponent which is a
+                       // multiple of three, as expected, but there will only be the
+                       // one zero before the E, still.  Otherwise note the padding.
+                       if (!ISZERO(dn))
+                               pre += adj;
+                       else {  // is zero
+                               if (adj != 0) { // 0.00Esnn needed
+                                       e = e + 3;
+                                       pre = -(2 - adj);
+                               }
+                       }       // zero
+               }               // eng
+       }                       // need exponent
+
+       /* lay out the digits of the coefficient, adding 0s and . as needed */
+       u = *up;
+       if (pre > 0) {          // xxx.xxx or xx00 (engineering) form
+               Int n = pre;
+               for (; pre > 0; pre--, c++, cut--) {
+                       if (cut < 0) {  // need new Unit
+                               if (up == dn->lsu)
+                                       break;  // out of input digits (pre>digits)
+                               up--;
+                               cut = DECDPUN - 1;
+                               u = *up;
+                       }
+                       TODIGIT(u, cut, c, pow);
+               }
+               if (n < dn->digits) {   // more to come, after '.'
+                       *c = '.';
+                       c++;
+                       for (;; c++, cut--) {
+                               if (cut < 0) {  // need new Unit
+                                       if (up == dn->lsu)
+                                               break;  // out of input digits
+                                       up--;
+                                       cut = DECDPUN - 1;
+                                       u = *up;
+                               }
+                               TODIGIT(u, cut, c, pow);
+                       }
+               } else
+                       for (; pre > 0; pre--, c++)
+                               *c = '0';       // 0 padding (for engineering) needed
+       } else {                // 0.xxx or 0.000xxx form
+               *c = '0';
+               c++;
+               *c = '.';
+               c++;
+               for (; pre < 0; pre++, c++)
+                       *c = '0';       // add any 0's after '.'
+               for (;; c++, cut--) {
+                       if (cut < 0) {  // need new Unit
+                               if (up == dn->lsu)
+                                       break;  // out of input digits
+                               up--;
+                               cut = DECDPUN - 1;
+                               u = *up;
+                       }
+                       TODIGIT(u, cut, c, pow);
+               }
+       }
+
+       /* Finally add the E-part, if needed.  It will never be 0, has a
+          base maximum and minimum of +999999999 through -999999999, but
+          could range down to -1999999998 for anormal numbers */
+       if (e != 0) {
+               Flag had = 0;   // 1=had non-zero
+               *c = 'E';
+               c++;
+               *c = '+';
+               c++;            // assume positive
+               u = e;          // ..
+               if (e < 0) {
+                       *(c - 1) = '-'; // oops, need -
+                       u = -e; // uInt, please
+               }
+               // lay out the exponent [_itoa or equivalent is not ANSI C]
+               for (cut = 9; cut >= 0; cut--) {
+                       TODIGIT(u, cut, c, pow);
+                       if (*c == '0' && !had)
+                               continue;       // skip leading zeros
+                       had = 1;        // had non-0
+                       c++;    // step for next
+               }               // cut
+       }
+       *c = '\0';              // terminate the string (all paths)
+       return;
+}                              // decToString
+
+/* ------------------------------------------------------------------ */
+/* decAddOp -- add/subtract operation                                 */
+/*                                                                    */
+/*   This computes C = A + B                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*   negate is DECNEG if rhs should be negated, or 0 otherwise        */
+/*   status accumulates status for the caller                         */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/* Inexact in status must be 0 for correct Exact zero sign in result  */
+/* ------------------------------------------------------------------ */
+/* If possible, the coefficient is calculated directly into C.        */
+/* However, if:                                                       */
+/*   -- a digits+1 calculation is needed because the numbers are      */
+/*      unaligned and span more than set->digits digits               */
+/*   -- a carry to digits+1 digits looks possible                     */
+/*   -- C is the same as A or B, and the result would destructively   */
+/*      overlap the A or B coefficient                                */
+/* then the result must be calculated into a temporary buffer.  In    */
+/* this case a local (stack) buffer is used if possible, and only if  */
+/* too long for that does malloc become the final resort.             */
+/*                                                                    */
+/* Misalignment is handled as follows:                                */
+/*   Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp.    */
+/*   BPad: Apply the padding by a combination of shifting (whole      */
+/*         units) and multiplication (part units).                    */
+/*                                                                    */
+/* Addition, especially x=x+1, is speed-critical.                     */
+/* The static buffer is larger than might be expected to allow for    */
+/* calls from higher-level funtions (notable exp).                    */
+/* ------------------------------------------------------------------ */
+static decNumber *decAddOp(decNumber * res, const decNumber * lhs,
+                          const decNumber * rhs, decContext * set,
+                          uByte negate, uInt * status)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       Int rhsshift;           // working shift (in Units)
+       Int maxdigits;          // longest logical length
+       Int mult;               // multiplier
+       Int residue;            // rounding accumulator
+       uByte bits;             // result bits
+       Flag diffsign;          // non-0 if arguments have different sign
+       Unit *acc;              // accumulator for result
+       Unit accbuff[SD2U(DECBUFFER * 2 + 20)]; // local buffer [*2+20 reduces many
+       // allocations when called from
+       // other operations, notable exp]
+       Unit *allocacc = NULL;  // -> allocated acc buffer, iff allocated
+       Int reqdigits = set->digits;    // local copy; requested DIGITS
+       Int padding;            // work
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > reqdigits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > reqdigits) {
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // note whether signs differ [used all paths]
+               diffsign = (Flag) ((lhs->bits ^ rhs->bits ^ negate) & DECNEG);
+
+               // handle infinities and NaNs
+               if (SPECIALARGS) {      // a special bit set
+                       if (SPECIALARGS & (DECSNAN | DECNAN))   // a NaN
+                               decNaNs(res, lhs, rhs, set, status);
+                       else {  // one or two infinities
+                               if (decNumberIsInfinite(lhs)) { // LHS is infinity
+                                       // two infinities with different signs is invalid
+                                       if (decNumberIsInfinite(rhs)
+                                           && diffsign) {
+                                               *status |=
+                                                   DEC_Invalid_operation;
+                                               break;
+                                       }
+                                       bits = lhs->bits & DECNEG;      // get sign from LHS
+                               } else
+                                       bits = (rhs->bits ^ negate) & DECNEG;   // RHS must be Infinity
+                               bits |= DECINF;
+                               decNumberZero(res);
+                               res->bits = bits;       // set +/- infinity
+                       }       // an infinity
+                       break;
+               }
+               // Quick exit for add 0s; return the non-0, modified as need be
+               if (ISZERO(lhs)) {
+                       Int adjust;     // work
+                       Int lexp = lhs->exponent;       // save in case LHS==RES
+                       bits = lhs->bits;       // ..
+                       residue = 0;    // clear accumulator
+                       decCopyFit(res, rhs, set, &residue, status);    // copy (as needed)
+                       res->bits ^= negate;    // flip if rhs was negated
+#if DECSUBSET
+                       if (set->extended) {    // exponents on zeros count
+#endif
+                               // exponent will be the lower of the two
+                               adjust = lexp - res->exponent;  // adjustment needed [if -ve]
+                               if (ISZERO(res)) {      // both 0: special IEEE 754 rules
+                                       if (adjust < 0)
+                                               res->exponent = lexp;   // set exponent
+                                       // 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0
+                                       if (diffsign) {
+                                               if (set->round !=
+                                                   DEC_ROUND_FLOOR)
+                                                       res->bits = 0;
+                                               else
+                                                       res->bits = DECNEG;     // preserve 0 sign
+                                       }
+                               } else {        // non-0 res
+                                       if (adjust < 0) {       // 0-padding needed
+                                               if ((res->digits - adjust) >
+                                                   set->digits) {
+                                                       adjust = res->digits - set->digits;     // to fit exactly
+                                                       *status |= DEC_Rounded; // [but exact]
+                                               }
+                                               res->digits =
+                                                   decShiftToMost(res->lsu,
+                                                                  res->digits,
+                                                                  -adjust);
+                                               res->exponent += adjust;        // set the exponent.
+                                       }
+                               }       // non-0 res
+#if DECSUBSET
+                       }       // extended
+#endif
+                       decFinish(res, set, &residue, status);  // clean and finalize
+                       break;
+               }
+
+               if (ISZERO(rhs)) {      // [lhs is non-zero]
+                       Int adjust;     // work
+                       Int rexp = rhs->exponent;       // save in case RHS==RES
+                       bits = rhs->bits;       // be clean
+                       residue = 0;    // clear accumulator
+                       decCopyFit(res, lhs, set, &residue, status);    // copy (as needed)
+#if DECSUBSET
+                       if (set->extended) {    // exponents on zeros count
+#endif
+                               // exponent will be the lower of the two
+                               // [0-0 case handled above]
+                               adjust = rexp - res->exponent;  // adjustment needed [if -ve]
+                               if (adjust < 0) {       // 0-padding needed
+                                       if ((res->digits - adjust) >
+                                           set->digits) {
+                                               adjust = res->digits - set->digits;     // to fit exactly
+                                               *status |= DEC_Rounded; // [but exact]
+                                       }
+                                       res->digits =
+                                           decShiftToMost(res->lsu,
+                                                          res->digits,
+                                                          -adjust);
+                                       res->exponent += adjust;        // set the exponent.
+                               }
+#if DECSUBSET
+                       }       // extended
+#endif
+                       decFinish(res, set, &residue, status);  // clean and finalize
+                       break;
+               }
+               // [NB: both fastpath and mainpath code below assume these cases
+               // (notably 0-0) have already been handled]
+
+               // calculate the padding needed to align the operands
+               padding = rhs->exponent - lhs->exponent;
+
+               // Fastpath cases where the numbers are aligned and normal, the RHS
+               // is all in one unit, no operand rounding is needed, and no carry,
+               // lengthening, or borrow is needed
+               if (padding == 0 && rhs->digits <= DECDPUN && rhs->exponent >= set->emin        // [some normals drop through]
+                   && rhs->exponent <= set->emax - set->digits + 1     // [could clamp]
+                   && rhs->digits <= reqdigits && lhs->digits <= reqdigits) {
+                       Int partial = *lhs->lsu;
+                       if (!diffsign) {        // adding
+                               partial += *rhs->lsu;
+                               if ((partial <= DECDPUNMAX)     // result fits in unit
+                                   && (lhs->digits >= DECDPUN ||       // .. and no digits-count change
+                                       partial < (Int) powers[lhs->digits])) { // ..
+                                       if (res != lhs)
+                                               decNumberCopy(res, lhs);        // not in place
+                                       *res->lsu = (Unit) partial;     // [copy could have overwritten RHS]
+                                       break;
+                               }
+                               // else drop out for careful add
+                       } else {        // signs differ
+                               partial -= *rhs->lsu;
+                               if (partial > 0) {      // no borrow needed, and non-0 result
+                                       if (res != lhs)
+                                               decNumberCopy(res, lhs);        // not in place
+                                       *res->lsu = (Unit) partial;
+                                       // this could have reduced digits [but result>0]
+                                       res->digits =
+                                           decGetDigits(res->lsu,
+                                                        D2U(res->digits));
+                                       break;
+                               }
+                               // else drop out for careful subtract
+                       }
+               }
+               // Now align (pad) the lhs or rhs so they can be added or
+               // subtracted, as necessary.  If one number is much larger than
+               // the other (that is, if in plain form there is a least one
+               // digit between the lowest digit of one and the highest of the
+               // other) padding with up to DIGITS-1 trailing zeros may be
+               // needed; then apply rounding (as exotic rounding modes may be
+               // affected by the residue).
+               rhsshift = 0;   // rhs shift to left (padding) in Units
+               bits = lhs->bits;       // assume sign is that of LHS
+               mult = 1;       // likely multiplier
+
+               // [if padding==0 the operands are aligned; no padding is needed]
+               if (padding != 0) {
+                       // some padding needed; always pad the RHS, as any required
+                       // padding can then be effected by a simple combination of
+                       // shifts and a multiply
+                       Flag swapped = 0;
+                       if (padding < 0) {      // LHS needs the padding
+                               const decNumber *t;
+                               padding = -padding;     // will be +ve
+                               bits = (uByte) (rhs->bits ^ negate);    // assumed sign is now that of RHS
+                               t = lhs;
+                               lhs = rhs;
+                               rhs = t;
+                               swapped = 1;
+                       }
+                       // If, after pad, rhs would be longer than lhs by digits+1 or
+                       // more then lhs cannot affect the answer, except as a residue,
+                       // so only need to pad up to a length of DIGITS+1.
+                       if (rhs->digits + padding > lhs->digits + reqdigits + 1) {
+                               // The RHS is sufficient
+                               // for residue use the relative sign indication...
+                               Int shift = reqdigits - rhs->digits;    // left shift needed
+                               residue = 1;    // residue for rounding
+                               if (diffsign)
+                                       residue = -residue;     // signs differ
+                               // copy, shortening if necessary
+                               decCopyFit(res, rhs, set, &residue, status);
+                               // if it was already shorter, then need to pad with zeros
+                               if (shift > 0) {
+                                       res->digits =
+                                           decShiftToMost(res->lsu,
+                                                          res->digits, shift);
+                                       res->exponent -= shift; // adjust the exponent.
+                               }
+                               // flip the result sign if unswapped and rhs was negated
+                               if (!swapped)
+                                       res->bits ^= negate;
+                               decFinish(res, set, &residue, status);  // done
+                               break;
+                       }
+                       // LHS digits may affect result
+                       rhsshift = D2U(padding + 1) - 1;        // this much by Unit shift ..
+                       mult = powers[padding - (rhsshift * DECDPUN)];  // .. this by multiplication
+               }               // padding needed
+
+               if (diffsign)
+                       mult = -mult;   // signs differ
+
+               // determine the longer operand
+               maxdigits = rhs->digits + padding;      // virtual length of RHS
+               if (lhs->digits > maxdigits)
+                       maxdigits = lhs->digits;
+
+               // Decide on the result buffer to use; if possible place directly
+               // into result.
+               acc = res->lsu; // assume add direct to result
+               // If destructive overlap, or the number is too long, or a carry or
+               // borrow to DIGITS+1 might be possible, a buffer must be used.
+               // [Might be worth more sophisticated tests when maxdigits==reqdigits]
+               if ((maxdigits >= reqdigits)    // is, or could be, too large
+                   || (res == rhs && rhsshift > 0)) {  // destructive overlap
+                       // buffer needed, choose it; units for maxdigits digits will be
+                       // needed, +1 Unit for carry or borrow
+                       Int need = D2U(maxdigits) + 1;
+                       acc = accbuff;  // assume use local buffer
+                       if (need * sizeof(Unit) > sizeof(accbuff)) {
+                               // printf("malloc add %ld %ld\n", need, sizeof(accbuff));
+                               allocacc = (Unit *) malloc(need * sizeof(Unit));
+                               if (allocacc == NULL) { // hopeless -- abandon
+                                       *status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               acc = allocacc;
+                       }
+               }
+
+               res->bits = (uByte) (bits & DECNEG);    // it's now safe to overwrite..
+               res->exponent = lhs->exponent;  // .. operands (even if aliased)
+
+#if DECTRACE
+               decDumpAr('A', lhs->lsu, D2U(lhs->digits));
+               decDumpAr('B', rhs->lsu, D2U(rhs->digits));
+               printf("  :h: %ld %ld\n", rhsshift, mult);
+#endif
+
+               // add [A+B*m] or subtract [A+B*(-m)]
+               res->digits = decUnitAddSub(lhs->lsu, D2U(lhs->digits),
+                                           rhs->lsu, D2U(rhs->digits),
+                                           rhsshift, acc, mult)
+                   * DECDPUN;  // [units -> digits]
+               if (res->digits < 0) {  // borrowed...
+                       res->digits = -res->digits;
+                       res->bits ^= DECNEG;    // flip the sign
+               }
+#if DECTRACE
+               decDumpAr('+', acc, D2U(res->digits));
+#endif
+
+               // If a buffer was used the result must be copied back, possibly
+               // shortening.  (If no buffer was used then the result must have
+               // fit, so can't need rounding and residue must be 0.)
+               residue = 0;    // clear accumulator
+               if (acc != res->lsu) {
+#if DECSUBSET
+                       if (set->extended) {    // round from first significant digit
+#endif
+                               // remove leading zeros that were added due to rounding up to
+                               // integral Units -- before the test for rounding.
+                               if (res->digits > reqdigits)
+                                       res->digits =
+                                           decGetDigits(acc, D2U(res->digits));
+                               decSetCoeff(res, set, acc, res->digits,
+                                           &residue, status);
+#if DECSUBSET
+                       } else {        // subset arithmetic rounds from original significant digit
+                               // May have an underestimate.  This only occurs when both
+                               // numbers fit in DECDPUN digits and are padding with a
+                               // negative multiple (-10, -100...) and the top digit(s) become
+                               // 0.  (This only matters when using X3.274 rules where the
+                               // leading zero could be included in the rounding.)
+                               if (res->digits < maxdigits) {
+                                       *(acc + D2U(res->digits)) = 0;  // ensure leading 0 is there
+                                       res->digits = maxdigits;
+                               } else {
+                                       // remove leading zeros that added due to rounding up to
+                                       // integral Units (but only those in excess of the original
+                                       // maxdigits length, unless extended) before test for rounding.
+                                       if (res->digits > reqdigits) {
+                                               res->digits =
+                                                   decGetDigits(acc,
+                                                                D2U
+                                                                (res->digits));
+                                               if (res->digits < maxdigits)
+                                                       res->digits = maxdigits;
+                                       }
+                               }
+                               decSetCoeff(res, set, acc, res->digits,
+                                           &residue, status);
+                               // Now apply rounding if needed before removing leading zeros.
+                               // This is safe because subnormals are not a possibility
+                               if (residue != 0) {
+                                       decApplyRound(res, set, residue,
+                                                     status);
+                                       residue = 0;    // did what needed to be done
+                               }
+                       }       // subset
+#endif
+               }               // used buffer
+
+               // strip leading zeros [these were left on in case of subset subtract]
+               res->digits = decGetDigits(res->lsu, D2U(res->digits));
+
+               // apply checks and rounding
+               decFinish(res, set, &residue, status);
+
+               // "When the sum of two operands with opposite signs is exactly
+               // zero, the sign of that sum shall be '+' in all rounding modes
+               // except round toward -Infinity, in which mode that sign shall be
+               // '-'."  [Subset zeros also never have '-', set by decFinish.]
+               if (ISZERO(res) && diffsign
+#if DECSUBSET
+                   && set->extended
+#endif
+                   && (*status & DEC_Inexact) == 0) {
+                       if (set->round == DEC_ROUND_FLOOR)
+                               res->bits |= DECNEG;    // sign -
+                       else
+                               res->bits &= ~DECNEG;   // sign +
+               }
+       } while (0);            // end protected
+
+       if (allocacc != NULL)
+               free(allocacc); // drop any storage used
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+       return res;
+}                              // decAddOp
+
+/* ------------------------------------------------------------------ */
+/* decDivideOp -- division operation                                  */
+/*                                                                    */
+/*  This routine performs the calculations for all four division      */
+/*  operators (divide, divideInteger, remainder, remainderNear).      */
+/*                                                                    */
+/*  C=A op B                                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*   op  is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively.    */
+/*   status is the usual accumulator                                  */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+/*   The underlying algorithm of this routine is the same as in the   */
+/*   1981 S/370 implementation, that is, non-restoring long division  */
+/*   with bi-unit (rather than bi-digit) estimation for each unit     */
+/*   multiplier.  In this pseudocode overview, complications for the  */
+/*   Remainder operators and division residues for exact rounding are */
+/*   omitted for clarity.                                             */
+/*                                                                    */
+/*     Prepare operands and handle special values                     */
+/*     Test for x/0 and then 0/x                                      */
+/*     Exp =Exp1 - Exp2                                               */
+/*     Exp =Exp +len(var1) -len(var2)                                 */
+/*     Sign=Sign1 * Sign2                                             */
+/*     Pad accumulator (Var1) to double-length with 0's (pad1)        */
+/*     Pad Var2 to same length as Var1                                */
+/*     msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round  */
+/*     have=0                                                         */
+/*     Do until (have=digits+1 OR residue=0)                          */
+/*       if exp<0 then if integer divide/residue then leave           */
+/*       this_unit=0                                                  */
+/*       Do forever                                                   */
+/*          compare numbers                                           */
+/*          if <0 then leave inner_loop                               */
+/*          if =0 then (* quick exit without subtract *) do           */
+/*             this_unit=this_unit+1; output this_unit                */
+/*             leave outer_loop; end                                  */
+/*          Compare lengths of numbers (mantissae):                   */
+/*          If same then tops2=msu2pair -- {units 1&2 of var2}        */
+/*                  else tops2=msu2plus -- {0, unit 1 of var2}        */
+/*          tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */
+/*          mult=tops1/tops2  -- Good and safe guess at divisor       */
+/*          if mult=0 then mult=1                                     */
+/*          this_unit=this_unit+mult                                  */
+/*          subtract                                                  */
+/*          end inner_loop                                            */
+/*        if have\=0 | this_unit\=0 then do                           */
+/*          output this_unit                                          */
+/*          have=have+1; end                                          */
+/*        var2=var2/10                                                */
+/*        exp=exp-1                                                   */
+/*        end outer_loop                                              */
+/*     exp=exp+1   -- set the proper exponent                         */
+/*     if have=0 then generate answer=0                               */
+/*     Return (Result is defined by Var1)                             */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+/* Two working buffers are needed during the division; one (digits+   */
+/* 1) to accumulate the result, and the other (up to 2*digits+1) for  */
+/* long subtractions.  These are acc and var1 respectively.           */
+/* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/
+/* The static buffers may be larger than might be expected to allow   */
+/* for calls from higher-level funtions (notable exp).                */
+/* ------------------------------------------------------------------ */
+static decNumber *decDivideOp(decNumber * res,
+                             const decNumber * lhs, const decNumber * rhs,
+                             decContext * set, Flag op, uInt * status)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       Unit accbuff[SD2U(DECBUFFER + DECDPUN + 10)];   // local buffer
+       Unit *acc = accbuff;    // -> accumulator array for result
+       Unit *allocacc = NULL;  // -> allocated buffer, iff allocated
+       Unit *accnext;          // -> where next digit will go
+       Int acclength;          // length of acc needed [Units]
+       Int accunits;           // count of units accumulated
+       Int accdigits;          // count of digits accumulated
+
+       Unit varbuff[SD2U(DECBUFFER * 2 + DECDPUN)];    // buffer for var1
+       Unit *var1 = varbuff;   // -> var1 array for long subtraction
+       Unit *varalloc = NULL;  // -> allocated buffer, iff used
+       Unit *msu1;             // -> msu of var1
+
+       const Unit *var2;       // -> var2 array
+       const Unit *msu2;       // -> msu of var2
+       Int msu2plus;           // msu2 plus one [does not vary]
+       eInt msu2pair;          // msu2 pair plus one [does not vary]
+
+       Int var1units, var2units;       // actual lengths
+       Int var2ulen;           // logical length (units)
+       Int var1initpad = 0;    // var1 initial padding (digits)
+       Int maxdigits;          // longest LHS or required acc length
+       Int mult;               // multiplier for subtraction
+       Unit thisunit;          // current unit being accumulated
+       Int residue;            // for rounding
+       Int reqdigits = set->digits;    // requested DIGITS
+       Int exponent;           // working exponent
+       Int maxexponent = 0;    // DIVIDE maximum exponent if unrounded
+       uByte bits;             // working sign
+       Unit *target;           // work
+       const Unit *source;     // ..
+       uInt const *pow;        // ..
+       Int shift, cut;         // ..
+#if DECSUBSET
+       Int dropped;            // work
+#endif
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > reqdigits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > reqdigits) {
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               bits = (lhs->bits ^ rhs->bits) & DECNEG;        // assumed sign for divisions
+
+               // handle infinities and NaNs
+               if (SPECIALARGS) {      // a special bit set
+                       if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
+                               decNaNs(res, lhs, rhs, set, status);
+                               break;
+                       }
+                       // one or two infinities
+                       if (decNumberIsInfinite(lhs)) { // LHS (dividend) is infinite
+                               if (decNumberIsInfinite(rhs) || // two infinities are invalid ..
+                                   op & (REMAINDER | REMNEAR)) {       // as is remainder of infinity
+                                       *status |= DEC_Invalid_operation;
+                                       break;
+                               }
+                               // [Note that infinity/0 raises no exceptions]
+                               decNumberZero(res);
+                               res->bits = bits | DECINF;      // set +/- infinity
+                               break;
+                       } else {        // RHS (divisor) is infinite
+                               residue = 0;
+                               if (op & (REMAINDER | REMNEAR)) {
+                                       // result is [finished clone of] lhs
+                                       decCopyFit(res, lhs, set, &residue,
+                                                  status);
+                               } else {        // a division
+                                       decNumberZero(res);
+                                       res->bits = bits;       // set +/- zero
+                                       // for DIVIDEINT the exponent is always 0.  For DIVIDE, result
+                                       // is a 0 with infinitely negative exponent, clamped to minimum
+                                       if (op & DIVIDE) {
+                                               res->exponent =
+                                                   set->emin - set->digits + 1;
+                                               *status |= DEC_Clamped;
+                                       }
+                               }
+                               decFinish(res, set, &residue, status);
+                               break;
+                       }
+               }
+               // handle 0 rhs (x/0)
+               if (ISZERO(rhs)) {      // x/0 is always exceptional
+                       if (ISZERO(lhs)) {
+                               decNumberZero(res);     // [after lhs test]
+                               *status |= DEC_Division_undefined;      // 0/0 will become NaN
+                       } else {
+                               decNumberZero(res);
+                               if (op & (REMAINDER | REMNEAR))
+                                       *status |= DEC_Invalid_operation;
+                               else {
+                                       *status |= DEC_Division_by_zero;        // x/0
+                                       res->bits = bits | DECINF;      // .. is +/- Infinity
+                               }
+                       }
+                       break;
+               }
+               // handle 0 lhs (0/x)
+               if (ISZERO(lhs)) {      // 0/x [x!=0]
+#if DECSUBSET
+                       if (!set->extended)
+                               decNumberZero(res);
+                       else {
+#endif
+                               if (op & DIVIDE) {
+                                       residue = 0;
+                                       exponent = lhs->exponent - rhs->exponent;       // ideal exponent
+                                       decNumberCopy(res, lhs);        // [zeros always fit]
+                                       res->bits = bits;       // sign as computed
+                                       res->exponent = exponent;       // exponent, too
+                                       decFinalize(res, set, &residue, status);        // check exponent
+                               } else if (op & DIVIDEINT) {
+                                       decNumberZero(res);     // integer 0
+                                       res->bits = bits;       // sign as computed
+                               } else {        // a remainder
+                                       exponent = rhs->exponent;       // [save in case overwrite]
+                                       decNumberCopy(res, lhs);        // [zeros always fit]
+                                       if (exponent < res->exponent)
+                                               res->exponent = exponent;       // use lower
+                               }
+#if DECSUBSET
+                       }
+#endif
+                       break;
+               }
+               // Precalculate exponent.  This starts off adjusted (and hence fits
+               // in 31 bits) and becomes the usual unadjusted exponent as the
+               // division proceeds.  The order of evaluation is important, here,
+               // to avoid wrap.
+               exponent =
+                   (lhs->exponent + lhs->digits) - (rhs->exponent +
+                                                    rhs->digits);
+
+               // If the working exponent is -ve, then some quick exits are
+               // possible because the quotient is known to be <1
+               // [for REMNEAR, it needs to be < -1, as -0.5 could need work]
+               if (exponent < 0 && !(op == DIVIDE)) {
+                       if (op & DIVIDEINT) {
+                               decNumberZero(res);     // integer part is 0
+#if DECSUBSET
+                               if (set->extended)
+#endif
+                                       res->bits = bits;       // set +/- zero
+                               break;
+                       }
+                       // fastpath remainders so long as the lhs has the smaller
+                       // (or equal) exponent
+                       if (lhs->exponent <= rhs->exponent) {
+                               if (op & REMAINDER || exponent < -1) {
+                                       // It is REMAINDER or safe REMNEAR; result is [finished
+                                       // clone of] lhs  (r = x - 0*y)
+                                       residue = 0;
+                                       decCopyFit(res, lhs, set, &residue,
+                                                  status);
+                                       decFinish(res, set, &residue, status);
+                                       break;
+                               }
+                               // [unsafe REMNEAR drops through]
+                       }
+               }               // fastpaths
+
+               /* Long (slow) division is needed; roll up the sleeves... */
+
+               // The accumulator will hold the quotient of the division.
+               // If it needs to be too long for stack storage, then allocate.
+               acclength = D2U(reqdigits + DECDPUN);   // in Units
+               if (acclength * sizeof(Unit) > sizeof(accbuff)) {
+                       // printf("malloc dvacc %ld units\n", acclength);
+                       allocacc = (Unit *) malloc(acclength * sizeof(Unit));
+                       if (allocacc == NULL) { // hopeless -- abandon
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       acc = allocacc; // use the allocated space
+               }
+               // var1 is the padded LHS ready for subtractions.
+               // If it needs to be too long for stack storage, then allocate.
+               // The maximum units needed for var1 (long subtraction) is:
+               // Enough for
+               //     (rhs->digits+reqdigits-1) -- to allow full slide to right
+               // or  (lhs->digits)             -- to allow for long lhs
+               // whichever is larger
+               //   +1                -- for rounding of slide to right
+               //   +1                -- for leading 0s
+               //   +1                -- for pre-adjust if a remainder or DIVIDEINT
+               // [Note: unused units do not participate in decUnitAddSub data]
+               maxdigits = rhs->digits + reqdigits - 1;
+               if (lhs->digits > maxdigits)
+                       maxdigits = lhs->digits;
+               var1units = D2U(maxdigits) + 2;
+               // allocate a guard unit above msu1 for REMAINDERNEAR
+               if (!(op & DIVIDE))
+                       var1units++;
+               if ((var1units + 1) * sizeof(Unit) > sizeof(varbuff)) {
+                       // printf("malloc dvvar %ld units\n", var1units+1);
+                       varalloc =
+                           (Unit *) malloc((var1units + 1) * sizeof(Unit));
+                       if (varalloc == NULL) { // hopeless -- abandon
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       var1 = varalloc;        // use the allocated space
+               }
+               // Extend the lhs and rhs to full long subtraction length.  The lhs
+               // is truly extended into the var1 buffer, with 0 padding, so a
+               // subtract in place is always possible.  The rhs (var2) has
+               // virtual padding (implemented by decUnitAddSub).
+               // One guard unit was allocated above msu1 for rem=rem+rem in
+               // REMAINDERNEAR.
+               msu1 = var1 + var1units - 1;    // msu of var1
+               source = lhs->lsu + D2U(lhs->digits) - 1;       // msu of input array
+               for (target = msu1; source >= lhs->lsu; source--, target--)
+                       *target = *source;
+               for (; target >= var1; target--)
+                       *target = 0;
+
+               // rhs (var2) is left-aligned with var1 at the start
+               var2ulen = var1units;   // rhs logical length (units)
+               var2units = D2U(rhs->digits);   // rhs actual length (units)
+               var2 = rhs->lsu;        // -> rhs array
+               msu2 = var2 + var2units - 1;    // -> msu of var2 [never changes]
+               // now set up the variables which will be used for estimating the
+               // multiplication factor.  If these variables are not exact, add
+               // 1 to make sure that the multiplier is never overestimated.
+               msu2plus = *msu2;       // it's value ..
+               if (var2units > 1)
+                       msu2plus++;     // .. +1 if any more
+               msu2pair = (eInt) * msu2 * (DECDPUNMAX + 1);    // top two pair ..
+               if (var2units > 1) {    // .. [else treat 2nd as 0]
+                       msu2pair += *(msu2 - 1);        // ..
+                       if (var2units > 2)
+                               msu2pair++;     // .. +1 if any more
+               }
+               // The calculation is working in units, which may have leading zeros,
+               // but the exponent was calculated on the assumption that they are
+               // both left-aligned.  Adjust the exponent to compensate: add the
+               // number of leading zeros in var1 msu and subtract those in var2 msu.
+               // [This is actually done by counting the digits and negating, as
+               // lead1=DECDPUN-digits1, and similarly for lead2.]
+               for (pow = &powers[1]; *msu1 >= *pow; pow++)
+                       exponent--;
+               for (pow = &powers[1]; *msu2 >= *pow; pow++)
+                       exponent++;
+
+               // Now, if doing an integer divide or remainder, ensure that
+               // the result will be Unit-aligned.  To do this, shift the var1
+               // accumulator towards least if need be.  (It's much easier to
+               // do this now than to reassemble the residue afterwards, if
+               // doing a remainder.)  Also ensure the exponent is not negative.
+               if (!(op & DIVIDE)) {
+                       Unit *u;        // work
+                       // save the initial 'false' padding of var1, in digits
+                       var1initpad = (var1units - D2U(lhs->digits)) * DECDPUN;
+                       // Determine the shift to do.
+                       if (exponent < 0)
+                               cut = -exponent;
+                       else
+                               cut = DECDPUN - exponent % DECDPUN;
+                       decShiftToLeast(var1, var1units, cut);
+                       exponent += cut;        // maintain numerical value
+                       var1initpad -= cut;     // .. and reduce padding
+                       // clean any most-significant units which were just emptied
+                       for (u = msu1; cut >= DECDPUN; cut -= DECDPUN, u--)
+                               *u = 0;
+               }               // align
+               else {          // is DIVIDE
+                       maxexponent = lhs->exponent - rhs->exponent;    // save
+                       // optimization: if the first iteration will just produce 0,
+                       // preadjust to skip it [valid for DIVIDE only]
+                       if (*msu1 < *msu2) {
+                               var2ulen--;     // shift down
+                               exponent -= DECDPUN;    // update the exponent
+                       }
+               }
+
+               // ---- start the long-division loops ------------------------------
+               accunits = 0;   // no units accumulated yet
+               accdigits = 0;  // .. or digits
+               accnext = acc + acclength - 1;  // -> msu of acc [NB: allows digits+1]
+               for (;;) {      // outer forever loop
+                       thisunit = 0;   // current unit assumed 0
+                       // find the next unit
+                       for (;;) {      // inner forever loop
+                               // strip leading zero units [from either pre-adjust or from
+                               // subtract last time around].  Leave at least one unit.
+                               for (; *msu1 == 0 && msu1 > var1; msu1--)
+                                       var1units--;
+
+                               if (var1units < var2ulen)
+                                       break;  // var1 too low for subtract
+                               if (var1units == var2ulen) {    // unit-by-unit compare needed
+                                       // compare the two numbers, from msu
+                                       const Unit *pv1, *pv2;
+                                       Unit v2;        // units to compare
+                                       pv2 = msu2;     // -> msu
+                                       for (pv1 = msu1;; pv1--, pv2--) {
+                                               // v1=*pv1 -- always OK
+                                               v2 = 0; // assume in padding
+                                               if (pv2 >= var2)
+                                                       v2 = *pv2;      // in range
+                                               if (*pv1 != v2)
+                                                       break;  // no longer the same
+                                               if (pv1 == var1)
+                                                       break;  // done; leave pv1 as is
+                                       }
+                                       // here when all inspected or a difference seen
+                                       if (*pv1 < v2)
+                                               break;  // var1 too low to subtract
+                                       if (*pv1 == v2) {       // var1 == var2
+                                               // reach here if var1 and var2 are identical; subtraction
+                                               // would increase digit by one, and the residue will be 0 so
+                                               // the calculation is done; leave the loop with residue=0.
+                                               thisunit++;     // as though subtracted
+                                               *var1 = 0;      // set var1 to 0
+                                               var1units = 1;  // ..
+                                               break;  // from inner
+                                       }       // var1 == var2
+                                       // *pv1>v2.  Prepare for real subtraction; the lengths are equal
+                                       // Estimate the multiplier (there's always a msu1-1)...
+                                       // Bring in two units of var2 to provide a good estimate.
+                                       mult =
+                                           (Int) (((eInt) * msu1 *
+                                                   (DECDPUNMAX + 1) + *(msu1 -
+                                                                        1)) /
+                                                  msu2pair);
+                               }       // lengths the same
+                               else {  // var1units > var2ulen, so subtraction is safe
+                                       // The var2 msu is one unit towards the lsu of the var1 msu,
+                                       // so only one unit for var2 can be used.
+                                       mult =
+                                           (Int) (((eInt) * msu1 *
+                                                   (DECDPUNMAX + 1) + *(msu1 -
+                                                                        1)) /
+                                                  msu2plus);
+                               }
+                               if (mult == 0)
+                                       mult = 1;       // must always be at least 1
+                               // subtraction needed; var1 is > var2
+                               thisunit = (Unit) (thisunit + mult);    // accumulate
+                               // subtract var1-var2, into var1; only the overlap needs
+                               // processing, as this is an in-place calculation
+                               shift = var2ulen - var2units;
+#if DECTRACE
+                               decDumpAr('1', &var1[shift], var1units - shift);
+                               decDumpAr('2', var2, var2units);
+                               printf("m=%ld\n", -mult);
+#endif
+                               decUnitAddSub(&var1[shift], var1units - shift,
+                                             var2, var2units, 0,
+                                             &var1[shift], -mult);
+#if DECTRACE
+                               decDumpAr('#', &var1[shift], var1units - shift);
+#endif
+                               // var1 now probably has leading zeros; these are removed at the
+                               // top of the inner loop.
+                       }       // inner loop
+
+                       // The next unit has been calculated in full; unless it's a
+                       // leading zero, add to acc
+                       if (accunits != 0 || thisunit != 0) {   // is first or non-zero
+                               *accnext = thisunit;    // store in accumulator
+                               // account exactly for the new digits
+                               if (accunits == 0) {
+                                       accdigits++;    // at least one
+                                       for (pow = &powers[1]; thisunit >= *pow;
+                                            pow++)
+                                               accdigits++;
+                               } else
+                                       accdigits += DECDPUN;
+                               accunits++;     // update count
+                               accnext--;      // ready for next
+                               if (accdigits > reqdigits)
+                                       break;  // have enough digits
+                       }
+                       // if the residue is zero, the operation is done (unless divide
+                       // or divideInteger and still not enough digits yet)
+                       if (*var1 == 0 && var1units == 1) {     // residue is 0
+                               if (op & (REMAINDER | REMNEAR))
+                                       break;
+                               if ((op & DIVIDE) && (exponent <= maxexponent))
+                                       break;
+                               // [drop through if divideInteger]
+                       }
+                       // also done enough if calculating remainder or integer
+                       // divide and just did the last ('units') unit
+                       if (exponent == 0 && !(op & DIVIDE))
+                               break;
+
+                       // to get here, var1 is less than var2, so divide var2 by the per-
+                       // Unit power of ten and go for the next digit
+                       var2ulen--;     // shift down
+                       exponent -= DECDPUN;    // update the exponent
+               }               // outer loop
+
+               // ---- division is complete ---------------------------------------
+               // here: acc      has at least reqdigits+1 of good results (or fewer
+               //                if early stop), starting at accnext+1 (its lsu)
+               //       var1     has any residue at the stopping point
+               //       accunits is the number of digits collected in acc
+               if (accunits == 0) {    // acc is 0
+                       accunits = 1;   // show have a unit ..
+                       accdigits = 1;  // ..
+                       *accnext = 0;   // .. whose value is 0
+               } else
+                       accnext++;      // back to last placed
+               // accnext now -> lowest unit of result
+
+               residue = 0;    // assume no residue
+               if (op & DIVIDE) {
+                       // record the presence of any residue, for rounding
+                       if (*var1 != 0 || var1units > 1)
+                               residue = 1;
+                       else {  // no residue
+                               // Had an exact division; clean up spurious trailing 0s.
+                               // There will be at most DECDPUN-1, from the final multiply,
+                               // and then only if the result is non-0 (and even) and the
+                               // exponent is 'loose'.
+#if DECDPUN>1
+                               Unit lsu = *accnext;
+                               if (!(lsu & 0x01) && (lsu != 0)) {
+                                       // count the trailing zeros
+                                       Int drop = 0;
+                                       for (;; drop++) {       // [will terminate because lsu!=0]
+                                               if (exponent >= maxexponent)
+                                                       break;  // don't chop real 0s
+#if DECDPUN<=4
+                                               if ((lsu - QUOT10(lsu, drop + 1)
+                                                    * powers[drop + 1]) != 0)
+                                                       break;  // found non-0 digit
+#else
+                                               if (lsu % powers[drop + 1] != 0)
+                                                       break;  // found non-0 digit
+#endif
+                                               exponent++;
+                                       }
+                                       if (drop > 0) {
+                                               accunits =
+                                                   decShiftToLeast(accnext,
+                                                                   accunits,
+                                                                   drop);
+                                               accdigits =
+                                                   decGetDigits(accnext,
+                                                                accunits);
+                                               accunits = D2U(accdigits);
+                                               // [exponent was adjusted in the loop]
+                                       }
+                               }       // neither odd nor 0
+#endif
+                       }       // exact divide
+               }               // divide
+               else {          /* op!=DIVIDE */
+
+                       // check for coefficient overflow
+                       if (accdigits + exponent > reqdigits) {
+                               *status |= DEC_Division_impossible;
+                               break;
+                       }
+                       if (op & (REMAINDER | REMNEAR)) {
+                               // [Here, the exponent will be 0, because var1 was adjusted
+                               // appropriately.]
+                               Int postshift;  // work
+                               Flag wasodd = 0;        // integer was odd
+                               Unit *quotlsu;  // for save
+                               Int quotdigits; // ..
+
+                               bits = lhs->bits;       // remainder sign is always as lhs
+
+                               // Fastpath when residue is truly 0 is worthwhile [and
+                               // simplifies the code below]
+                               if (*var1 == 0 && var1units == 1) {     // residue is 0
+                                       Int exp = lhs->exponent;        // save min(exponents)
+                                       if (rhs->exponent < exp)
+                                               exp = rhs->exponent;
+                                       decNumberZero(res);     // 0 coefficient
+#if DECSUBSET
+                                       if (set->extended)
+#endif
+                                               res->exponent = exp;    // .. with proper exponent
+                                       res->bits = (uByte) (bits & DECNEG);    // [cleaned]
+                                       decFinish(res, set, &residue, status);  // might clamp
+                                       break;
+                               }
+                               // note if the quotient was odd
+                               if (*accnext & 0x01)
+                                       wasodd = 1;     // acc is odd
+                               quotlsu = accnext;      // save in case need to reinspect
+                               quotdigits = accdigits; // ..
+
+                               // treat the residue, in var1, as the value to return, via acc
+                               // calculate the unused zero digits.  This is the smaller of:
+                               //   var1 initial padding (saved above)
+                               //   var2 residual padding, which happens to be given by:
+                               postshift =
+                                   var1initpad + exponent - lhs->exponent +
+                                   rhs->exponent;
+                               // [the 'exponent' term accounts for the shifts during divide]
+                               if (var1initpad < postshift)
+                                       postshift = var1initpad;
+
+                               // shift var1 the requested amount, and adjust its digits
+                               var1units =
+                                   decShiftToLeast(var1, var1units, postshift);
+                               accnext = var1;
+                               accdigits = decGetDigits(var1, var1units);
+                               accunits = D2U(accdigits);
+
+                               exponent = lhs->exponent;       // exponent is smaller of lhs & rhs
+                               if (rhs->exponent < exponent)
+                                       exponent = rhs->exponent;
+
+                               // Now correct the result if doing remainderNear; if it
+                               // (looking just at coefficients) is > rhs/2, or == rhs/2 and
+                               // the integer was odd then the result should be rem-rhs.
+                               if (op & REMNEAR) {
+                                       Int compare, tarunits;  // work
+                                       Unit *up;       // ..
+                                       // calculate remainder*2 into the var1 buffer (which has
+                                       // 'headroom' of an extra unit and hence enough space)
+                                       // [a dedicated 'double' loop would be faster, here]
+                                       tarunits =
+                                           decUnitAddSub(accnext, accunits,
+                                                         accnext, accunits, 0,
+                                                         accnext, 1);
+                                       // decDumpAr('r', accnext, tarunits);
+
+                                       // Here, accnext (var1) holds tarunits Units with twice the
+                                       // remainder's coefficient, which must now be compared to the
+                                       // RHS.  The remainder's exponent may be smaller than the RHS's.
+                                       compare =
+                                           decUnitCompare(accnext, tarunits,
+                                                          rhs->lsu,
+                                                          D2U(rhs->digits),
+                                                          rhs->exponent -
+                                                          exponent);
+                                       if (compare == BADINT) {        // deep trouble
+                                               *status |=
+                                                   DEC_Insufficient_storage;
+                                               break;
+                                       }
+                                       // now restore the remainder by dividing by two; the lsu
+                                       // is known to be even.
+                                       for (up = accnext;
+                                            up < accnext + tarunits; up++) {
+                                               Int half;       // half to add to lower unit
+                                               half = *up & 0x01;
+                                               *up /= 2;       // [shift]
+                                               if (!half)
+                                                       continue;
+                                               *(up - 1) +=
+                                                   (DECDPUNMAX + 1) / 2;
+                                       }
+                                       // [accunits still describes the original remainder length]
+
+                                       if (compare > 0 || (compare == 0 && wasodd)) {  // adjustment needed
+                                               Int exp, expunits, exprem;      // work
+                                               // This is effectively causing round-up of the quotient,
+                                               // so if it was the rare case where it was full and all
+                                               // nines, it would overflow and hence division-impossible
+                                               // should be raised
+                                               Flag allnines = 0;      // 1 if quotient all nines
+                                               if (quotdigits == reqdigits) {  // could be borderline
+                                                       for (up = quotlsu;;
+                                                            up++) {
+                                                               if (quotdigits >
+                                                                   DECDPUN) {
+                                                                       if (*up
+                                                                           !=
+                                                                           DECDPUNMAX)
+                                                                               break;  // non-nines
+                                                               } else {        // this is the last Unit
+                                                                       if (*up
+                                                                           ==
+                                                                           powers
+                                                                           [quotdigits]
+                                                                           - 1)
+                                                                               allnines
+                                                                                   =
+                                                                                   1;
+                                                                       break;
+                                                               }
+                                                               quotdigits -= DECDPUN;  // checked those digits
+                                                       }       // up
+                                               }       // borderline check
+                                               if (allnines) {
+                                                       *status |=
+                                                           DEC_Division_impossible;
+                                                       break;
+                                               }
+                                               // rem-rhs is needed; the sign will invert.  Again, var1
+                                               // can safely be used for the working Units array.
+                                               exp = rhs->exponent - exponent; // RHS padding needed
+                                               // Calculate units and remainder from exponent.
+                                               expunits = exp / DECDPUN;
+                                               exprem = exp % DECDPUN;
+                                               // subtract [A+B*(-m)]; the result will always be negative
+                                               accunits =
+                                                   -decUnitAddSub(accnext,
+                                                                  accunits,
+                                                                  rhs->lsu,
+                                                                  D2U
+                                                                  (rhs->digits),
+                                                                  expunits,
+                                                                  accnext,
+                                                                  -(Int)
+                                                                  powers
+                                                                  [exprem]);
+                                               accdigits = decGetDigits(accnext, accunits);    // count digits exactly
+                                               accunits = D2U(accdigits);      // and recalculate the units for copy
+                                               // [exponent is as for original remainder]
+                                               bits ^= DECNEG; // flip the sign
+                                       }
+                               }       // REMNEAR
+                       }       // REMAINDER or REMNEAR
+               }               // not DIVIDE
+
+               // Set exponent and bits
+               res->exponent = exponent;
+               res->bits = (uByte) (bits & DECNEG);    // [cleaned]
+
+               // Now the coefficient.
+               decSetCoeff(res, set, accnext, accdigits, &residue, status);
+
+               decFinish(res, set, &residue, status);  // final cleanup
+
+#if DECSUBSET
+               // If a divide then strip trailing zeros if subset [after round]
+               if (!set->extended && (op == DIVIDE))
+                       decTrim(res, set, 0, 1, &dropped);
+#endif
+       } while (0);            // end protected
+
+       if (varalloc != NULL)
+               free(varalloc); // drop any storage used
+       if (allocacc != NULL)
+               free(allocacc); // ..
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+       return res;
+}                              // decDivideOp
+
+/* ------------------------------------------------------------------ */
+/* decMultiplyOp -- multiplication operation                          */
+/*                                                                    */
+/*  This routine performs the multiplication C=A x B.                 */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X*X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*   status is the usual accumulator                                  */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+/* 'Classic' multiplication is used rather than Karatsuba, as the     */
+/* latter would give only a minor improvement for the short numbers   */
+/* expected to be handled most (and uses much more memory).           */
+/*                                                                    */
+/* There are two major paths here: the general-purpose ('old code')   */
+/* path which handles all DECDPUN values, and a fastpath version      */
+/* which is used if 64-bit ints are available, DECDPUN<=4, and more   */
+/* than two calls to decUnitAddSub would be made.                     */
+/*                                                                    */
+/* The fastpath version lumps units together into 8-digit or 9-digit  */
+/* chunks, and also uses a lazy carry strategy to minimise expensive  */
+/* 64-bit divisions.  The chunks are then broken apart again into     */
+/* units for continuing processing.  Despite this overhead, the       */
+/* fastpath can speed up some 16-digit operations by 10x (and much    */
+/* more for higher-precision calculations).                           */
+/*                                                                    */
+/* A buffer always has to be used for the accumulator; in the         */
+/* fastpath, buffers are also always needed for the chunked copies of */
+/* of the operand coefficients.                                       */
+/* Static buffers are larger than needed just for multiply, to allow  */
+/* for calls from other operations (notably exp).                     */
+/* ------------------------------------------------------------------ */
+#define FASTMUL (DECUSE64 && DECDPUN<5)
+static decNumber *decMultiplyOp(decNumber * res, const decNumber * lhs,
+                               const decNumber * rhs, decContext * set,
+                               uInt * status)
+{
+       Int accunits;           // Units of accumulator in use
+       Int exponent;           // work
+       Int residue = 0;        // rounding residue
+       uByte bits;             // result sign
+       Unit *acc;              // -> accumulator Unit array
+       Int needbytes;          // size calculator
+       void *allocacc = NULL;  // -> allocated accumulator, iff allocated
+       Unit accbuff[SD2U(DECBUFFER * 4 + 1)];  // buffer (+1 for DECBUFFER==0,
+       // *4 for calls from other operations)
+       const Unit *mer, *mermsup;      // work
+       Int madlength;          // Units in multiplicand
+       Int shift;              // Units to shift multiplicand by
+
+#if FASTMUL
+       // if DECDPUN is 1 or 3 work in base 10**9, otherwise
+       // (DECDPUN is 2 or 4) then work in base 10**8
+#if DECDPUN & 1                        // odd
+#define FASTBASE 1000000000    // base
+#define FASTDIGS          9    // digits in base
+#define FASTLAZY         18    // carry resolution point [1->18]
+#else
+#define FASTBASE  100000000
+#define FASTDIGS          8
+#define FASTLAZY       1844    // carry resolution point [1->1844]
+#endif
+       // three buffers are used, two for chunked copies of the operands
+       // (base 10**8 or base 10**9) and one base 2**64 accumulator with
+       // lazy carry evaluation
+       uInt zlhibuff[(DECBUFFER * 2 + 1) / 8 + 1];     // buffer (+1 for DECBUFFER==0)
+       uInt *zlhi = zlhibuff;  // -> lhs array
+       uInt *alloclhi = NULL;  // -> allocated buffer, iff allocated
+       uInt zrhibuff[(DECBUFFER * 2 + 1) / 8 + 1];     // buffer (+1 for DECBUFFER==0)
+       uInt *zrhi = zrhibuff;  // -> rhs array
+       uInt *allocrhi = NULL;  // -> allocated buffer, iff allocated
+       uLong zaccbuff[(DECBUFFER * 2 + 1) / 4 + 2];    // buffer (+1 for DECBUFFER==0)
+       // [allocacc is shared for both paths, as only one will run]
+       uLong *zacc = zaccbuff; // -> accumulator array for exact result
+#if DECDPUN==1
+       Int zoff;               // accumulator offset
+#endif
+       uInt *lip, *rip;        // item pointers
+       uInt *lmsi, *rmsi;      // most significant items
+       Int ilhs, irhs, iacc;   // item counts in the arrays
+       Int lazy;               // lazy carry counter
+       uLong lcarry;           // uLong carry
+       uInt carry;             // carry (NB not uLong)
+       Int count;              // work
+       const Unit *cup;        // ..
+       Unit *up;               // ..
+       uLong *lp;              // ..
+       Int p;                  // ..
+#endif
+
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // -> allocated buffer, iff allocated
+       decNumber *allocrhs = NULL;     // -> allocated buffer, iff allocated
+#endif
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       // precalculate result sign
+       bits = (uByte) ((lhs->bits ^ rhs->bits) & DECNEG);
+
+       // handle infinities and NaNs
+       if (SPECIALARGS) {      // a special bit set
+               if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
+                       decNaNs(res, lhs, rhs, set, status);
+                       return res;
+               }
+               // one or two infinities; Infinity * 0 is invalid
+               if (((lhs->bits & DECINF) == 0 && ISZERO(lhs))
+                   || ((rhs->bits & DECINF) == 0 && ISZERO(rhs))) {
+                       *status |= DEC_Invalid_operation;
+                       return res;
+               }
+               decNumberZero(res);
+               res->bits = bits | DECINF;      // infinity
+               return res;
+       }
+       // For best speed, as in DMSRCN [the original Rexx numerics
+       // module], use the shorter number as the multiplier (rhs) and
+       // the longer as the multiplicand (lhs) to minimise the number of
+       // adds (partial products)
+       if (lhs->digits < rhs->digits) {        // swap...
+               const decNumber *hold = lhs;
+               lhs = rhs;
+               rhs = hold;
+       }
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > set->digits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > set->digits) {
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+#if FASTMUL                    // fastpath can be used
+               // use the fast path if there are enough digits in the shorter
+               // operand to make the setup and takedown worthwhile
+#define NEEDTWO (DECDPUN*2)    // within two decUnitAddSub calls
+               if (rhs->digits > NEEDTWO) {    // use fastpath...
+                       // calculate the number of elements in each array
+                       ilhs = (lhs->digits + FASTDIGS - 1) / FASTDIGS; // [ceiling]
+                       irhs = (rhs->digits + FASTDIGS - 1) / FASTDIGS; // ..
+                       iacc = ilhs + irhs;
+
+                       // allocate buffers if required, as usual
+                       needbytes = ilhs * sizeof(uInt);
+                       if (needbytes > (Int) sizeof(zlhibuff)) {
+                               alloclhi = (uInt *) malloc(needbytes);
+                               zlhi = alloclhi;
+                       }
+                       needbytes = irhs * sizeof(uInt);
+                       if (needbytes > (Int) sizeof(zrhibuff)) {
+                               allocrhi = (uInt *) malloc(needbytes);
+                               zrhi = allocrhi;
+                       }
+                       // Allocating the accumulator space needs a special case when
+                       // DECDPUN=1 because when converting the accumulator to Units
+                       // after the multiplication each 8-byte item becomes 9 1-byte
+                       // units.  Therefore iacc extra bytes are needed at the front
+                       // (rounded up to a multiple of 8 bytes), and the uLong
+                       // accumulator starts offset the appropriate number of units
+                       // to the right to avoid overwrite during the unchunking.
+                       needbytes = iacc * sizeof(uLong);
+#if DECDPUN==1
+                       zoff = (iacc + 7) / 8;  // items to offset by
+                       needbytes += zoff * 8;
+#endif
+                       if (needbytes > (Int) sizeof(zaccbuff)) {
+                               allocacc = (uLong *) malloc(needbytes);
+                               zacc = (uLong *) allocacc;
+                       }
+                       if (zlhi == NULL || zrhi == NULL || zacc == NULL) {
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+
+                       acc = (Unit *) zacc;    // -> target Unit array
+#if DECDPUN==1
+                       zacc += zoff;   // start uLong accumulator to right
+#endif
+
+                       // assemble the chunked copies of the left and right sides
+                       for (count = lhs->digits, cup = lhs->lsu, lip = zlhi;
+                            count > 0; lip++)
+                               for (p = 0, *lip = 0; p < FASTDIGS && count > 0;
+                                    p += DECDPUN, cup++, count -= DECDPUN)
+                                       *lip += *cup * powers[p];
+                       lmsi = lip - 1; // save -> msi
+                       for (count = rhs->digits, cup = rhs->lsu, rip = zrhi;
+                            count > 0; rip++)
+                               for (p = 0, *rip = 0; p < FASTDIGS && count > 0;
+                                    p += DECDPUN, cup++, count -= DECDPUN)
+                                       *rip += *cup * powers[p];
+                       rmsi = rip - 1; // save -> msi
+
+                       // zero the accumulator
+                       for (lp = zacc; lp < zacc + iacc; lp++)
+                               *lp = 0;
+
+                       /* Start the multiplication */
+                       // Resolving carries can dominate the cost of accumulating the
+                       // partial products, so this is only done when necessary.
+                       // Each uLong item in the accumulator can hold values up to
+                       // 2**64-1, and each partial product can be as large as
+                       // (10**FASTDIGS-1)**2.  When FASTDIGS=9, this can be added to
+                       // itself 18.4 times in a uLong without overflowing, so during
+                       // the main calculation resolution is carried out every 18th
+                       // add -- every 162 digits.  Similarly, when FASTDIGS=8, the
+                       // partial products can be added to themselves 1844.6 times in
+                       // a uLong without overflowing, so intermediate carry
+                       // resolution occurs only every 14752 digits.  Hence for common
+                       // short numbers usually only the one final carry resolution
+                       // occurs.
+                       // (The count is set via FASTLAZY to simplify experiments to
+                       // measure the value of this approach: a 35% improvement on a
+                       // [34x34] multiply.)
+                       lazy = FASTLAZY;        // carry delay count
+                       for (rip = zrhi; rip <= rmsi; rip++) {  // over each item in rhs
+                               lp = zacc + (rip - zrhi);       // where to add the lhs
+                               for (lip = zlhi; lip <= lmsi; lip++, lp++) {    // over each item in lhs
+                                       *lp += (uLong) (*lip) * (*rip); // [this should in-line]
+                               }       // lip loop
+                               lazy--;
+                               if (lazy > 0 && rip != rmsi)
+                                       continue;
+                               lazy = FASTLAZY;        // reset delay count
+                               // spin up the accumulator resolving overflows
+                               for (lp = zacc; lp < zacc + iacc; lp++) {
+                                       if (*lp < FASTBASE)
+                                               continue;       // it fits
+                                       lcarry = *lp / FASTBASE;        // top part [slow divide]
+                                       // lcarry can exceed 2**32-1, so check again; this check
+                                       // and occasional extra divide (slow) is well worth it, as
+                                       // it allows FASTLAZY to be increased to 18 rather than 4
+                                       // in the FASTDIGS=9 case
+                                       if (lcarry < FASTBASE)
+                                               carry = (uInt) lcarry;  // [usual]
+                                       else {  // two-place carry [fairly rare]
+                                               uInt carry2 = (uInt) (lcarry / FASTBASE);       // top top part
+                                               *(lp + 2) += carry2;    // add to item+2
+                                               *lp -= ((uLong) FASTBASE * FASTBASE * carry2);  // [slow]
+                                               carry = (uInt) (lcarry - ((uLong) FASTBASE * carry2));  // [inline]
+                                       }
+                                       *(lp + 1) += carry;     // add to item above [inline]
+                                       *lp -= ((uLong) FASTBASE * carry);      // [inline]
+                               }       // carry resolution
+                       }       // rip loop
+
+                       // The multiplication is complete; time to convert back into
+                       // units.  This can be done in-place in the accumulator and in
+                       // 32-bit operations, because carries were resolved after the
+                       // final add.  This needs N-1 divides and multiplies for
+                       // each item in the accumulator (which will become up to N
+                       // units, where 2<=N<=9).
+                       for (lp = zacc, up = acc; lp < zacc + iacc; lp++) {
+                               uInt item = (uInt) * lp;        // decapitate to uInt
+                               for (p = 0; p < FASTDIGS - DECDPUN;
+                                    p += DECDPUN, up++) {
+                                       uInt part = item / (DECDPUNMAX + 1);
+                                       *up =
+                                           (Unit) (item -
+                                                   (part * (DECDPUNMAX + 1)));
+                                       item = part;
+                               }       // p
+                               *up = (Unit) item;
+                               up++;   // [final needs no division]
+                       }       // lp
+                       accunits = up - acc;    // count of units
+               } else {        // here to use units directly, without chunking ['old code']
+#endif
+
+                       // if accumulator will be too long for local storage, then allocate
+                       acc = accbuff;  // -> assume buffer for accumulator
+                       needbytes =
+                           (D2U(lhs->digits) +
+                            D2U(rhs->digits)) * sizeof(Unit);
+                       if (needbytes > (Int) sizeof(accbuff)) {
+                               allocacc = (Unit *) malloc(needbytes);
+                               if (allocacc == NULL) {
+                                       *status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               acc = (Unit *) allocacc;        // use the allocated space
+                       }
+
+                       /* Now the main long multiplication loop */
+                       // Unlike the equivalent in the IBM Java implementation, there
+                       // is no advantage in calculating from msu to lsu.  So, do it
+                       // by the book, as it were.
+                       // Each iteration calculates ACC=ACC+MULTAND*MULT
+                       accunits = 1;   // accumulator starts at '0'
+                       *acc = 0;       // .. (lsu=0)
+                       shift = 0;      // no multiplicand shift at first
+                       madlength = D2U(lhs->digits);   // this won't change
+                       mermsup = rhs->lsu + D2U(rhs->digits);  // -> msu+1 of multiplier
+
+                       for (mer = rhs->lsu; mer < mermsup; mer++) {
+                               // Here, *mer is the next Unit in the multiplier to use
+                               // If non-zero [optimization] add it...
+                               if (*mer != 0)
+                                       accunits =
+                                           decUnitAddSub(&acc[shift],
+                                                         accunits - shift,
+                                                         lhs->lsu, madlength,
+                                                         0, &acc[shift], *mer)
+                                           + shift;
+                               else {  // extend acc with a 0; it will be used shortly
+                                       *(acc + accunits) = 0;  // [this avoids length of <=0 later]
+                                       accunits++;
+                               }
+                               // multiply multiplicand by 10**DECDPUN for next Unit to left
+                               shift++;        // add this for 'logical length'
+                       }       // n
+#if FASTMUL
+               }               // unchunked units
+#endif
+               // common end-path
+#if DECTRACE
+               decDumpAr('*', acc, accunits);  // Show exact result
+#endif
+
+               // acc now contains the exact result of the multiplication,
+               // possibly with a leading zero unit; build the decNumber from
+               // it, noting if any residue
+               res->bits = bits;       // set sign
+               res->digits = decGetDigits(acc, accunits);      // count digits exactly
+
+               // There can be a 31-bit wrap in calculating the exponent.
+               // This can only happen if both input exponents are negative and
+               // both their magnitudes are large.  If there was a wrap, set a
+               // safe very negative exponent, from which decFinalize() will
+               // raise a hard underflow shortly.
+               exponent = lhs->exponent + rhs->exponent;       // calculate exponent
+               if (lhs->exponent < 0 && rhs->exponent < 0 && exponent > 0)
+                       exponent = -2 * DECNUMMAXE;     // force underflow
+               res->exponent = exponent;       // OK to overwrite now
+
+               // Set the coefficient.  If any rounding, residue records
+               decSetCoeff(res, set, acc, res->digits, &residue, status);
+               decFinish(res, set, &residue, status);  // final cleanup
+       } while (0);            // end protected
+
+       if (allocacc != NULL)
+               free(allocacc); // drop any storage used
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // ..
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+#if FASTMUL
+       if (allocrhi != NULL)
+               free(allocrhi); // ..
+       if (alloclhi != NULL)
+               free(alloclhi); // ..
+#endif
+       return res;
+}                              // decMultiplyOp
+
+/* ------------------------------------------------------------------ */
+/* decExpOp -- effect exponentiation                                  */
+/*                                                                    */
+/*   This computes C = exp(A)                                         */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits. status is updated but    */
+/* not set.                                                           */
+/*                                                                    */
+/* Restrictions:                                                      */
+/*                                                                    */
+/*   digits, emax, and -emin in the context must be less than         */
+/*   2*DEC_MAX_MATH (1999998), and the rhs must be within these       */
+/*   bounds or a zero.  This is an internal routine, so these         */
+/*   restrictions are contractual and not enforced.                   */
+/*                                                                    */
+/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/*                                                                    */
+/* Finite results will always be full precision and Inexact, except   */
+/* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
+/* ------------------------------------------------------------------ */
+/* This approach used here is similar to the algorithm described in   */
+/*                                                                    */
+/*   Variable Precision Exponential Function, T. E. Hull and          */
+/*   A. Abrham, ACM Transactions on Mathematical Software, Vol 12 #2, */
+/*   pp79-91, ACM, June 1986.                                         */
+/*                                                                    */
+/* with the main difference being that the iterations in the series   */
+/* evaluation are terminated dynamically (which does not require the  */
+/* extra variable-precision variables which are expensive in this     */
+/* context).                                                          */
+/*                                                                    */
+/* The error analysis in Hull & Abrham's paper applies except for the */
+/* round-off error accumulation during the series evaluation.  This   */
+/* code does not precalculate the number of iterations and so cannot  */
+/* use Horner's scheme.  Instead, the accumulation is done at double- */
+/* precision, which ensures that the additions of the terms are exact */
+/* and do not accumulate round-off (and any round-off errors in the   */
+/* terms themselves move 'to the right' faster than they can          */
+/* accumulate).  This code also extends the calculation by allowing,  */
+/* in the spirit of other decNumber operators, the input to be more   */
+/* precise than the result (the precision used is based on the more   */
+/* precise of the input or requested result).                         */
+/*                                                                    */
+/* Implementation notes:                                              */
+/*                                                                    */
+/* 1. This is separated out as decExpOp so it can be called from      */
+/*    other Mathematical functions (notably Ln) with a wider range    */
+/*    than normal.  In particular, it can handle the slightly wider   */
+/*    (double) range needed by Ln (which has to be able to calculate  */
+/*    exp(-x) where x can be the tiniest number (Ntiny).              */
+/*                                                                    */
+/* 2. Normalizing x to be <=0.1 (instead of <=1) reduces loop         */
+/*    iterations by appoximately a third with additional (although    */
+/*    diminishing) returns as the range is reduced to even smaller    */
+/*    fractions.  However, h (the power of 10 used to correct the     */
+/*    result at the end, see below) must be kept <=8 as otherwise     */
+/*    the final result cannot be computed.  Hence the leverage is a   */
+/*    sliding value (8-h), where potentially the range is reduced     */
+/*    more for smaller values.                                        */
+/*                                                                    */
+/*    The leverage that can be applied in this way is severely        */
+/*    limited by the cost of the raise-to-the power at the end,       */
+/*    which dominates when the number of iterations is small (less    */
+/*    than ten) or when rhs is short.  As an example, the adjustment  */
+/*    x**10,000,000 needs 31 multiplications, all but one full-width. */
+/*                                                                    */
+/* 3. The restrictions (especially precision) could be raised with    */
+/*    care, but the full decNumber range seems very hard within the   */
+/*    32-bit limits.                                                  */
+/*                                                                    */
+/* 4. The working precisions for the static buffers are twice the     */
+/*    obvious size to allow for calls from decNumberPower.            */
+/* ------------------------------------------------------------------ */
+decNumber *decExpOp(decNumber * res, const decNumber * rhs,
+                   decContext * set, uInt * status)
+{
+       uInt ignore = 0;        // working status
+       Int h;                  // adjusted exponent for 0.xxxx
+       Int p;                  // working precision
+       Int residue;            // rounding residue
+       uInt needbytes;         // for space calculations
+       const decNumber *x = rhs;       // (may point to safe copy later)
+       decContext aset, tset, dset;    // working contexts
+       Int comp;               // work
+
+       // the argument is often copied to normalize it, so (unusually) it
+       // is treated like other buffers, using DECBUFFER, +1 in case
+       // DECBUFFER is 0
+       decNumber bufr[D2N(DECBUFFER * 2 + 1)];
+       decNumber *allocrhs = NULL;     // non-NULL if rhs buffer allocated
+
+       // the working precision will be no more than set->digits+8+1
+       // so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER
+       // is 0 (and twice that for the accumulator)
+
+       // buffer for t, term (working precision plus)
+       decNumber buft[D2N(DECBUFFER * 2 + 9 + 1)];
+       decNumber *allocbuft = NULL;    // -> allocated buft, iff allocated
+       decNumber *t = buft;    // term
+       // buffer for a, accumulator (working precision * 2), at least 9
+       decNumber bufa[D2N(DECBUFFER * 4 + 18 + 1)];
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *a = bufa;    // accumulator
+       // decNumber for the divisor term; this needs at most 9 digits
+       // and so can be fixed size [16 so can use standard context]
+       decNumber bufd[D2N(16)];
+       decNumber *d = bufd;    // divisor
+       decNumber numone;       // constant 1
+
+#if DECCHECK
+       Int iterations = 0;     // for later sanity check
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+               if (SPECIALARG) {       // handle infinities and NaNs
+                       if (decNumberIsInfinite(rhs)) { // an infinity
+                               if (decNumberIsNegative(rhs))   // -Infinity -> +0
+                                       decNumberZero(res);
+                               else
+                                       decNumberCopy(res, rhs);        // +Infinity -> self
+                       } else
+                               decNaNs(res, rhs, NULL, set, status);   // a NaN
+                       break;
+               }
+
+               if (ISZERO(rhs)) {      // zeros -> exact 1
+                       decNumberZero(res);     // make clean 1
+                       *res->lsu = 1;  // ..
+                       break;
+               }               // [no status to set]
+
+               // e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path
+               // positive and negative tiny cases which will result in inexact
+               // 1.  This also allows the later add-accumulate to always be
+               // exact (because its length will never be more than twice the
+               // working precision).
+               // The comparator (tiny) needs just one digit, so use the
+               // decNumber d for it (reused as the divisor, etc., below); its
+               // exponent is such that if x is positive it will have
+               // set->digits-1 zeros between the decimal point and the digit,
+               // which is 4, and if x is negative one more zero there as the
+               // more precise result will be of the form 0.9999999 rather than
+               // 1.0000001.  Hence, tiny will be 0.0000004  if digits=7 and x>0
+               // or 0.00000004 if digits=7 and x<0.  If RHS not larger than
+               // this then the result will be 1.000000
+               decNumberZero(d);       // clean
+               *d->lsu = 4;    // set 4 ..
+               d->exponent = -set->digits;     // * 10**(-d)
+               if (decNumberIsNegative(rhs))
+                       d->exponent--;  // negative case
+               comp = decCompare(d, rhs, 1);   // signless compare
+               if (comp == BADINT) {
+                       *status |= DEC_Insufficient_storage;
+                       break;
+               }
+               if (comp >= 0) {        // rhs < d
+                       Int shift = set->digits - 1;
+                       decNumberZero(res);     // set 1
+                       *res->lsu = 1;  // ..
+                       res->digits = decShiftToMost(res->lsu, 1, shift);
+                       res->exponent = -shift; // make 1.0000...
+                       *status |= DEC_Inexact | DEC_Rounded;   // .. inexactly
+                       break;
+               }               // tiny
+
+               // set up the context to be used for calculating a, as this is
+               // used on both paths below
+               decContextDefault(&aset, DEC_INIT_DECIMAL64);
+               // accumulator bounds are as requested (could underflow)
+               aset.emax = set->emax;  // usual bounds
+               aset.emin = set->emin;  // ..
+               aset.clamp = 0; // and no concrete format
+
+               // calculate the adjusted (Hull & Abrham) exponent (where the
+               // decimal point is just to the left of the coefficient msd)
+               h = rhs->exponent + rhs->digits;
+               // if h>8 then 10**h cannot be calculated safely; however, when
+               // h=8 then exp(|rhs|) will be at least exp(1E+7) which is at
+               // least 6.59E+4342944, so (due to the restriction on Emax/Emin)
+               // overflow (or underflow to 0) is guaranteed -- so this case can
+               // be handled by simply forcing the appropriate excess
+               if (h > 8) {    // overflow/underflow
+                       // set up here so Power call below will over or underflow to
+                       // zero; set accumulator to either 2 or 0.02
+                       // [stack buffer for a is always big enough for this]
+                       decNumberZero(a);
+                       *a->lsu = 2;    // not 1 but < exp(1)
+                       if (decNumberIsNegative(rhs))
+                               a->exponent = -2;       // make 0.02
+                       h = 8;  // clamp so 10**h computable
+                       p = 9;  // set a working precision
+               } else {        // h<=8
+                       Int maxlever = (rhs->digits > 8 ? 1 : 0);
+                       // [could/should increase this for precisions >40 or so, too]
+
+                       // if h is 8, cannot normalize to a lower upper limit because
+                       // the final result will not be computable (see notes above),
+                       // but leverage can be applied whenever h is less than 8.
+                       // Apply as much as possible, up to a MAXLEVER digits, which
+                       // sets the tradeoff against the cost of the later a**(10**h).
+                       // As h is increased, the working precision below also
+                       // increases to compensate for the "constant digits at the
+                       // front" effect.
+                       Int lever = MINI(8 - h, maxlever);      // leverage attainable
+                       Int use = -rhs->digits - lever; // exponent to use for RHS
+                       h += lever;     // apply leverage selected
+                       if (h < 0) {    // clamp
+                               use += h;       // [may end up subnormal]
+                               h = 0;
+                       }
+                       // Take a copy of RHS if it needs normalization (true whenever x>=1)
+                       if (rhs->exponent != use) {
+                               decNumber *newrhs = bufr;       // assume will fit on stack
+                               needbytes =
+                                   sizeof(decNumber) + (D2U(rhs->digits) -
+                                                        1) * sizeof(Unit);
+                               if (needbytes > sizeof(bufr)) { // need malloc space
+                                       allocrhs =
+                                           (decNumber *) malloc(needbytes);
+                                       if (allocrhs == NULL) { // hopeless -- abandon
+                                               *status |=
+                                                   DEC_Insufficient_storage;
+                                               break;
+                                       }
+                                       newrhs = allocrhs;      // use the allocated space
+                               }
+                               decNumberCopy(newrhs, rhs);     // copy to safe space
+                               newrhs->exponent = use; // normalize; now <1
+                               x = newrhs;     // ready for use
+                               // decNumberShow(x);
+                       }
+                       // Now use the usual power series to evaluate exp(x).  The
+                       // series starts as 1 + x + x^2/2 ... so prime ready for the
+                       // third term by setting the term variable t=x, the accumulator
+                       // a=1, and the divisor d=2.
+
+                       // First determine the working precision.  From Hull & Abrham
+                       // this is set->digits+h+2.  However, if x is 'over-precise' we
+                       // need to allow for all its digits to potentially participate
+                       // (consider an x where all the excess digits are 9s) so in
+                       // this case use x->digits+h+2
+                       p = MAXI(x->digits, set->digits) + h + 2;       // [h<=8]
+
+                       // a and t are variable precision, and depend on p, so space
+                       // must be allocated for them if necessary
+
+                       // the accumulator needs to be able to hold 2p digits so that
+                       // the additions on the second and subsequent iterations are
+                       // sufficiently exact.
+                       needbytes =
+                           sizeof(decNumber) + (D2U(p * 2) - 1) * sizeof(Unit);
+                       if (needbytes > sizeof(bufa)) { // need malloc space
+                               allocbufa = (decNumber *) malloc(needbytes);
+                               if (allocbufa == NULL) {        // hopeless -- abandon
+                                       *status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               a = allocbufa;  // use the allocated space
+                       }
+                       // the term needs to be able to hold p digits (which is
+                       // guaranteed to be larger than x->digits, so the initial copy
+                       // is safe); it may also be used for the raise-to-power
+                       // calculation below, which needs an extra two digits
+                       needbytes =
+                           sizeof(decNumber) + (D2U(p + 2) - 1) * sizeof(Unit);
+                       if (needbytes > sizeof(buft)) { // need malloc space
+                               allocbuft = (decNumber *) malloc(needbytes);
+                               if (allocbuft == NULL) {        // hopeless -- abandon
+                                       *status |= DEC_Insufficient_storage;
+                                       break;
+                               }
+                               t = allocbuft;  // use the allocated space
+                       }
+
+                       decNumberCopy(t, x);    // term=x
+                       decNumberZero(a);
+                       *a->lsu = 1;    // accumulator=1
+                       decNumberZero(d);
+                       *d->lsu = 2;    // divisor=2
+                       decNumberZero(&numone);
+                       *numone.lsu = 1;        // constant 1 for increment
+
+                       // set up the contexts for calculating a, t, and d
+                       decContextDefault(&tset, DEC_INIT_DECIMAL64);
+                       dset = tset;
+                       // accumulator bounds are set above, set precision now
+                       aset.digits = p * 2;    // double
+                       // term bounds avoid any underflow or overflow
+                       tset.digits = p;
+                       tset.emin = DEC_MIN_EMIN;       // [emax is plenty]
+                       // [dset.digits=16, etc., are sufficient]
+
+                       // finally ready to roll
+                       for (;;) {
+#if DECCHECK
+                               iterations++;
+#endif
+                               // only the status from the accumulation is interesting
+                               // [but it should remain unchanged after first add]
+                               decAddOp(a, a, t, &aset, 0, status);    // a=a+t
+                               decMultiplyOp(t, t, x, &tset, &ignore); // t=t*x
+                               decDivideOp(t, t, d, &tset, DIVIDE, &ignore);   // t=t/d
+                               // the iteration ends when the term cannot affect the result,
+                               // if rounded to p digits, which is when its value is smaller
+                               // than the accumulator by p+1 digits.  There must also be
+                               // full precision in a.
+                               if (((a->digits + a->exponent) >=
+                                    (t->digits + t->exponent + p + 1))
+                                   && (a->digits >= p))
+                                       break;
+                               decAddOp(d, d, &numone, &dset, 0, &ignore);     // d=d+1
+                       }       // iterate
+
+#if DECCHECK
+                       // just a sanity check; comment out test to show always
+                       if (iterations > p + 3)
+                               printf
+                                   ("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
+                                    (LI) iterations, (LI) * status, (LI) p,
+                                    (LI) x->digits);
+#endif
+               }               // h<=8
+
+               // apply postconditioning: a=a**(10**h) -- this is calculated
+               // at a slightly higher precision than Hull & Abrham suggest
+               if (h > 0) {
+                       Int seenbit = 0;        // set once a 1-bit is seen
+                       Int i;  // counter
+                       Int n = powers[h];      // always positive
+                       aset.digits = p + 2;    // sufficient precision
+                       // avoid the overhead and many extra digits of decNumberPower
+                       // as all that is needed is the short 'multipliers' loop; here
+                       // accumulate the answer into t
+                       decNumberZero(t);
+                       *t->lsu = 1;    // acc=1
+                       for (i = 1;; i++) {     // for each bit [top bit ignored]
+                               // abandon if have had overflow or terminal underflow
+                               if (*status & (DEC_Overflow | DEC_Underflow)) { // interesting?
+                                       if (*status & DEC_Overflow || ISZERO(t))
+                                               break;
+                               }
+                               n = n << 1;     // move next bit to testable position
+                               if (n < 0) {    // top bit is set
+                                       seenbit = 1;    // OK, have a significant bit
+                                       decMultiplyOp(t, t, a, &aset, status);  // acc=acc*x
+                               }
+                               if (i == 31)
+                                       break;  // that was the last bit
+                               if (!seenbit)
+                                       continue;       // no need to square 1
+                               decMultiplyOp(t, t, t, &aset, status);  // acc=acc*acc [square]
+                       }       /*i */// 32 bits
+                       // decNumberShow(t);
+                       a = t;  // and carry on using t instead of a
+               }
+               // Copy and round the result to res
+               residue = 1;    // indicate dirt to right ..
+               if (ISZERO(a))
+                       residue = 0;    // .. unless underflowed to 0
+               aset.digits = set->digits;      // [use default rounding]
+               decCopyFit(res, a, &aset, &residue, status);    // copy & shorten
+               decFinish(res, set, &residue, status);  // cleanup/set flags
+       } while (0);            // end protected
+
+       if (allocrhs != NULL)
+               free(allocrhs); // drop any storage used
+       if (allocbufa != NULL)
+               free(allocbufa);        // ..
+       if (allocbuft != NULL)
+               free(allocbuft);        // ..
+       // [status is handled by caller]
+       return res;
+}                              // decExpOp
+
+/* ------------------------------------------------------------------ */
+/* Initial-estimate natural logarithm table                           */
+/*                                                                    */
+/*   LNnn -- 90-entry 16-bit table for values from .10 through .99.   */
+/*           The result is a 4-digit encode of the coefficient (c=the */
+/*           top 14 bits encoding 0-9999) and a 2-digit encode of the */
+/*           exponent (e=the bottom 2 bits encoding 0-3)              */
+/*                                                                    */
+/*           The resulting value is given by:                         */
+/*                                                                    */
+/*             v = -c * 10**(-e-3)                                    */
+/*                                                                    */
+/*           where e and c are extracted from entry k = LNnn[x-10]    */
+/*           where x is truncated (NB) into the range 10 through 99,  */
+/*           and then c = k>>2 and e = k&3.                           */
+/* ------------------------------------------------------------------ */
+const uShort LNnn[90] = { 9016, 8652, 8316, 8008, 7724, 7456, 7208,
+       6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312,
+       5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032,
+       39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
+       29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
+       22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
+       15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
+       10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801,
+       5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
+       10130, 6046, 20055
+};
+
+/* ------------------------------------------------------------------ */
+/* decLnOp -- effect natural logarithm                                */
+/*                                                                    */
+/*   This computes C = ln(A)                                          */
+/*                                                                    */
+/*   res is C, the result.  C may be A                                */
+/*   rhs is A                                                         */
+/*   set is the context; note that rounding mode has no effect        */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Notable cases:                                                     */
+/*   A<0 -> Invalid                                                   */
+/*   A=0 -> -Infinity (Exact)                                         */
+/*   A=+Infinity -> +Infinity (Exact)                                 */
+/*   A=1 exactly -> 0 (Exact)                                         */
+/*                                                                    */
+/* Restrictions (as for Exp):                                         */
+/*                                                                    */
+/*   digits, emax, and -emin in the context must be less than         */
+/*   DEC_MAX_MATH+11 (1000010), and the rhs must be within these      */
+/*   bounds or a zero.  This is an internal routine, so these         */
+/*   restrictions are contractual and not enforced.                   */
+/*                                                                    */
+/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
+/* almost always be correctly rounded, but may be up to 1 ulp in      */
+/* error in rare cases.                                               */
+/* ------------------------------------------------------------------ */
+/* The result is calculated using Newton's method, with each          */
+/* iteration calculating a' = a + x * exp(-a) - 1.  See, for example, */
+/* Epperson 1989.                                                     */
+/*                                                                    */
+/* The iteration ends when the adjustment x*exp(-a)-1 is tiny enough. */
+/* This has to be calculated at the sum of the precision of x and the */
+/* working precision.                                                 */
+/*                                                                    */
+/* Implementation notes:                                              */
+/*                                                                    */
+/* 1. This is separated out as decLnOp so it can be called from       */
+/*    other Mathematical functions (e.g., Log 10) with a wider range  */
+/*    than normal.  In particular, it can handle the slightly wider   */
+/*    (+9+2) range needed by a power function.                        */
+/*                                                                    */
+/* 2. The speed of this function is about 10x slower than exp, as     */
+/*    it typically needs 4-6 iterations for short numbers, and the    */
+/*    extra precision needed adds a squaring effect, twice.           */
+/*                                                                    */
+/* 3. Fastpaths are included for ln(10) and ln(2), up to length 40,   */
+/*    as these are common requests.  ln(10) is used by log10(x).      */
+/*                                                                    */
+/* 4. An iteration might be saved by widening the LNnn table, and     */
+/*    would certainly save at least one if it were made ten times     */
+/*    bigger, too (for truncated fractions 0.100 through 0.999).      */
+/*    However, for most practical evaluations, at least four or five  */
+/*    iterations will be neede -- so this would only speed up by      */
+/*    20-25% and that probably does not justify increasing the table  */
+/*    size.                                                           */
+/*                                                                    */
+/* 5. The static buffers are larger than might be expected to allow   */
+/*    for calls from decNumberPower.                                  */
+/* ------------------------------------------------------------------ */
+decNumber *decLnOp(decNumber * res, const decNumber * rhs,
+                  decContext * set, uInt * status)
+{
+       uInt ignore = 0;        // working status accumulator
+       uInt needbytes;         // for space calculations
+       Int residue;            // rounding residue
+       Int r;                  // rhs=f*10**r [see below]
+       Int p;                  // working precision
+       Int pp;                 // precision for iteration
+       Int t;                  // work
+
+       // buffers for a (accumulator, typically precision+2) and b
+       // (adjustment calculator, same size)
+       decNumber bufa[D2N(DECBUFFER + 12)];
+       decNumber *allocbufa = NULL;    // -> allocated bufa, iff allocated
+       decNumber *a = bufa;    // accumulator/work
+       decNumber bufb[D2N(DECBUFFER * 2 + 2)];
+       decNumber *allocbufb = NULL;    // -> allocated bufa, iff allocated
+       decNumber *b = bufb;    // adjustment/work
+
+       decNumber numone;       // constant 1
+       decNumber cmp;          // work
+       decContext aset, bset;  // working contexts
+
+#if DECCHECK
+       Int iterations = 0;     // for later sanity check
+       if (decCheckOperands(res, DECUNUSED, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+               if (SPECIALARG) {       // handle infinities and NaNs
+                       if (decNumberIsInfinite(rhs)) { // an infinity
+                               if (decNumberIsNegative(rhs))   // -Infinity -> error
+                                       *status |= DEC_Invalid_operation;
+                               else
+                                       decNumberCopy(res, rhs);        // +Infinity -> self
+                       } else
+                               decNaNs(res, rhs, NULL, set, status);   // a NaN
+                       break;
+               }
+
+               if (ISZERO(rhs)) {      // +/- zeros -> -Infinity
+                       decNumberZero(res);     // make clean
+                       res->bits = DECINF | DECNEG;    // set - infinity
+                       break;
+               }               // [no status to set]
+
+               // Non-zero negatives are bad...
+               if (decNumberIsNegative(rhs)) { // -x -> error
+                       *status |= DEC_Invalid_operation;
+                       break;
+               }
+               // Here, rhs is positive, finite, and in range
+
+               // lookaside fastpath code for ln(2) and ln(10) at common lengths
+               if (rhs->exponent == 0 && set->digits <= 40) {
+#if DECDPUN==1
+                       if (rhs->lsu[0] == 0 && rhs->lsu[1] == 1 && rhs->digits == 2) { // ln(10)
+#else
+                       if (rhs->lsu[0] == 10 && rhs->digits == 2) {    // ln(10)
+#endif
+                               aset = *set;
+                               aset.round = DEC_ROUND_HALF_EVEN;
+#define LN10 "2.302585092994045684017991454684364207601"
+                               decNumberFromString(res, LN10, &aset);
+                               *status |= (DEC_Inexact | DEC_Rounded); // is inexact
+                               break;
+                       }
+                       if (rhs->lsu[0] == 2 && rhs->digits == 1) {     // ln(2)
+                               aset = *set;
+                               aset.round = DEC_ROUND_HALF_EVEN;
+#define LN2 "0.6931471805599453094172321214581765680755"
+                               decNumberFromString(res, LN2, &aset);
+                               *status |= (DEC_Inexact | DEC_Rounded);
+                               break;
+                       }
+               }               // integer and short
+
+               // Determine the working precision.  This is normally the
+               // requested precision + 2, with a minimum of 9.  However, if
+               // the rhs is 'over-precise' then allow for all its digits to
+               // potentially participate (consider an rhs where all the excess
+               // digits are 9s) so in this case use rhs->digits+2.
+               p = MAXI(rhs->digits, MAXI(set->digits, 7)) + 2;
+
+               // Allocate space for the accumulator and the high-precision
+               // adjustment calculator, if necessary.  The accumulator must
+               // be able to hold p digits, and the adjustment up to
+               // rhs->digits+p digits.  They are also made big enough for 16
+               // digits so that they can be used for calculating the initial
+               // estimate.
+               needbytes =
+                   sizeof(decNumber) + (D2U(MAXI(p, 16)) - 1) * sizeof(Unit);
+               if (needbytes > sizeof(bufa)) { // need malloc space
+                       allocbufa = (decNumber *) malloc(needbytes);
+                       if (allocbufa == NULL) {        // hopeless -- abandon
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       a = allocbufa;  // use the allocated space
+               }
+               pp = p + rhs->digits;
+               needbytes =
+                   sizeof(decNumber) + (D2U(MAXI(pp, 16)) - 1) * sizeof(Unit);
+               if (needbytes > sizeof(bufb)) { // need malloc space
+                       allocbufb = (decNumber *) malloc(needbytes);
+                       if (allocbufb == NULL) {        // hopeless -- abandon
+                               *status |= DEC_Insufficient_storage;
+                               break;
+                       }
+                       b = allocbufb;  // use the allocated space
+               }
+               // Prepare an initial estimate in acc. Calculate this by
+               // considering the coefficient of x to be a normalized fraction,
+               // f, with the decimal point at far left and multiplied by
+               // 10**r.  Then, rhs=f*10**r and 0.1<=f<1, and
+               //   ln(x) = ln(f) + ln(10)*r
+               // Get the initial estimate for ln(f) from a small lookup
+               // table (see above) indexed by the first two digits of f,
+               // truncated.
+
+               decContextDefault(&aset, DEC_INIT_DECIMAL64);   // 16-digit extended
+               r = rhs->exponent + rhs->digits;        // 'normalised' exponent
+               decNumberFromInt32(a, r);       // a=r
+               decNumberFromInt32(b, 2302585); // b=ln(10) (2.302585)
+               b->exponent = -6;       //  ..
+               decMultiplyOp(a, a, b, &aset, &ignore); // a=a*b
+               // now get top two digits of rhs into b by simple truncate and
+               // force to integer
+               residue = 0;    // (no residue)
+               aset.digits = 2;
+               aset.round = DEC_ROUND_DOWN;
+               decCopyFit(b, rhs, &aset, &residue, &ignore);   // copy & shorten
+               b->exponent = 0;        // make integer
+               t = decGetInt(b);       // [cannot fail]
+               if (t < 10)
+                       t = X10(t);     // adjust single-digit b
+               t = LNnn[t - 10];       // look up ln(b)
+               decNumberFromInt32(b, t >> 2);  // b=ln(b) coefficient
+               b->exponent = -(t & 3) - 3;     // set exponent
+               b->bits = DECNEG;       // ln(0.10)->ln(0.99) always -ve
+               aset.digits = 16;
+               aset.round = DEC_ROUND_HALF_EVEN;       // restore
+               decAddOp(a, a, b, &aset, 0, &ignore);   // acc=a+b
+               // the initial estimate is now in a, with up to 4 digits correct.
+               // When rhs is at or near Nmax the estimate will be low, so we
+               // will approach it from below, avoiding overflow when calling exp.
+
+               decNumberZero(&numone);
+               *numone.lsu = 1;        // constant 1 for adjustment
+
+               // accumulator bounds are as requested (could underflow, but
+               // cannot overflow)
+               aset.emax = set->emax;
+               aset.emin = set->emin;
+               aset.clamp = 0; // no concrete format
+               // set up a context to be used for the multiply and subtract
+               bset = aset;
+               bset.emax = DEC_MAX_MATH * 2;   // use double bounds for the
+               bset.emin = -DEC_MAX_MATH * 2;  // adjustment calculation
+               // [see decExpOp call below]
+               // for each iteration double the number of digits to calculate,
+               // up to a maximum of p
+               pp = 9;         // initial precision
+               // [initially 9 as then the sequence starts 7+2, 16+2, and
+               // 34+2, which is ideal for standard-sized numbers]
+               aset.digits = pp;       // working context
+               bset.digits = pp + rhs->digits; // wider context
+               for (;;) {      // iterate
+#if DECCHECK
+                       iterations++;
+                       if (iterations > 24)
+                               break;  // consider 9 * 2**24
+#endif
+                       // calculate the adjustment (exp(-a)*x-1) into b.  This is a
+                       // catastrophic subtraction but it really is the difference
+                       // from 1 that is of interest.
+                       // Use the internal entry point to Exp as it allows the double
+                       // range for calculating exp(-a) when a is the tiniest subnormal.
+                       a->bits ^= DECNEG;      // make -a
+                       decExpOp(b, a, &bset, &ignore); // b=exp(-a)
+                       a->bits ^= DECNEG;      // restore sign of a
+                       // now multiply by rhs and subtract 1, at the wider precision
+                       decMultiplyOp(b, b, rhs, &bset, &ignore);       // b=b*rhs
+                       decAddOp(b, b, &numone, &bset, DECNEG, &ignore);        // b=b-1
+
+                       // the iteration ends when the adjustment cannot affect the
+                       // result by >=0.5 ulp (at the requested digits), which
+                       // is when its value is smaller than the accumulator by
+                       // set->digits+1 digits (or it is zero) -- this is a looser
+                       // requirement than for Exp because all that happens to the
+                       // accumulator after this is the final rounding (but note that
+                       // there must also be full precision in a, or a=0).
+
+                       if (decNumberIsZero(b) ||
+                           (a->digits + a->exponent) >=
+                           (b->digits + b->exponent + set->digits + 1)) {
+                               if (a->digits == p)
+                                       break;
+                               if (decNumberIsZero(a)) {
+                                       decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore);      // rhs=1 ?
+                                       if (cmp.lsu[0] == 0)
+                                               a->exponent = 0;        // yes, exact 0
+                                       else
+                                               *status |= (DEC_Inexact | DEC_Rounded); // no, inexact
+                                       break;
+                               }
+                               // force padding if adjustment has gone to 0 before full length
+                               if (decNumberIsZero(b))
+                                       b->exponent = a->exponent - p;
+                       }
+                       // not done yet ...
+                       decAddOp(a, a, b, &aset, 0, &ignore);   // a=a+b for next estimate
+                       if (pp == p)
+                               continue;       // precision is at maximum
+                       // lengthen the next calculation
+                       pp = pp * 2;    // double precision
+                       if (pp > p)
+                               pp = p; // clamp to maximum
+                       aset.digits = pp;       // working context
+                       bset.digits = pp + rhs->digits; // wider context
+               }               // Newton's iteration
+
+#if DECCHECK
+               // just a sanity check; remove the test to show always
+               if (iterations > 24)
+                       printf
+                           ("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
+                            (LI) iterations, (LI) * status, (LI) p,
+                            (LI) rhs->digits);
+#endif
+
+               // Copy and round the result to res
+               residue = 1;    // indicate dirt to right
+               if (ISZERO(a))
+                       residue = 0;    // .. unless underflowed to 0
+               aset.digits = set->digits;      // [use default rounding]
+               decCopyFit(res, a, &aset, &residue, status);    // copy & shorten
+               decFinish(res, set, &residue, status);  // cleanup/set flags
+       } while (0);            // end protected
+
+       if (allocbufa != NULL)
+               free(allocbufa);        // drop any storage used
+       if (allocbufb != NULL)
+               free(allocbufb);        // ..
+       // [status is handled by caller]
+       return res;
+}                              // decLnOp
+
+/* ------------------------------------------------------------------ */
+/* decQuantizeOp  -- force exponent to requested value                */
+/*                                                                    */
+/*   This computes C = op(A, B), where op adjusts the coefficient     */
+/*   of C (by rounding or shifting) such that the exponent (-scale)   */
+/*   of C has the value B or matches the exponent of B.               */
+/*   The numerical value of C will equal A, except for the effects of */
+/*   any rounding that occurred.                                      */
+/*                                                                    */
+/*   res is C, the result.  C may be A or B                           */
+/*   lhs is A, the number to adjust                                   */
+/*   rhs is B, the requested exponent                                 */
+/*   set is the context                                               */
+/*   quant is 1 for quantize or 0 for rescale                         */
+/*   status is the status accumulator (this can be called without     */
+/*          risk of control loss)                                     */
+/*                                                                    */
+/* C must have space for set->digits digits.                          */
+/*                                                                    */
+/* Unless there is an error or the result is infinite, the exponent   */
+/* after the operation is guaranteed to be that requested.            */
+/* ------------------------------------------------------------------ */
+static decNumber *decQuantizeOp(decNumber * res, const decNumber * lhs,
+                               const decNumber * rhs, decContext * set,
+                               Flag quant, uInt * status)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       const decNumber *inrhs = rhs;   // save original rhs
+       Int reqdigits = set->digits;    // requested DIGITS
+       Int reqexp;             // requested exponent [-scale]
+       Int residue = 0;        // rounding residue
+       Int etiny = set->emin - (reqdigits - 1);
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > reqdigits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL)
+                                       break;
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > reqdigits) {  // [this only checks lostDigits]
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL)
+                                       break;
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // Handle special values
+               if (SPECIALARGS) {
+                       // NaNs get usual processing
+                       if (SPECIALARGS & (DECSNAN | DECNAN))
+                               decNaNs(res, lhs, rhs, set, status);
+                       // one infinity but not both is bad
+                       else if ((lhs->bits ^ rhs->bits) & DECINF)
+                               *status |= DEC_Invalid_operation;
+                       // both infinity: return lhs
+                       else
+                               decNumberCopy(res, lhs);        // [nop if in place]
+                       break;
+               }
+               // set requested exponent
+               if (quant)
+                       reqexp = inrhs->exponent;       // quantize -- match exponents
+               else {          // rescale -- use value of rhs
+                       // Original rhs must be an integer that fits and is in range,
+                       // which could be from -1999999997 to +999999999, thanks to
+                       // subnormals
+                       reqexp = decGetInt(inrhs);      // [cannot fail]
+               }
+
+#if DECSUBSET
+               if (!set->extended)
+                       etiny = set->emin;      // no subnormals
+#endif
+
+               if (reqexp == BADINT    // bad (rescale only) or ..
+                   || reqexp == BIGODD || reqexp == BIGEVEN    // very big (ditto) or ..
+                   || (reqexp < etiny) // < lowest
+                   || (reqexp > set->emax)) {  // > emax
+                       *status |= DEC_Invalid_operation;
+                       break;
+               }
+               // the RHS has been processed, so it can be overwritten now if necessary
+               if (ISZERO(lhs)) {      // zero coefficient unchanged
+                       decNumberCopy(res, lhs);        // [nop if in place]
+                       res->exponent = reqexp; // .. just set exponent
+#if DECSUBSET
+                       if (!set->extended)
+                               res->bits = 0;  // subset specification; no -0
+#endif
+               } else {        // non-zero lhs
+                       Int adjust = reqexp - lhs->exponent;    // digit adjustment needed
+                       // if adjusted coefficient will definitely not fit, give up now
+                       if ((lhs->digits - adjust) > reqdigits) {
+                               *status |= DEC_Invalid_operation;
+                               break;
+                       }
+
+                       if (adjust > 0) {       // increasing exponent
+                               // this will decrease the length of the coefficient by adjust
+                               // digits, and must round as it does so
+                               decContext workset;     // work
+                               workset = *set; // clone rounding, etc.
+                               workset.digits = lhs->digits - adjust;  // set requested length
+                               // [note that the latter can be <1, here]
+                               decCopyFit(res, lhs, &workset, &residue, status);       // fit to result
+                               decApplyRound(res, &workset, residue, status);  // .. and round
+                               residue = 0;    // [used]
+                               // If just rounded a 999s case, exponent will be off by one;
+                               // adjust back (after checking space), if so.
+                               if (res->exponent > reqexp) {
+                                       // re-check needed, e.g., for quantize(0.9999, 0.001) under
+                                       // set->digits==3
+                                       if (res->digits == reqdigits) { // cannot shift by 1
+                                               *status &= ~(DEC_Inexact | DEC_Rounded);        // [clean these]
+                                               *status |=
+                                                   DEC_Invalid_operation;
+                                               break;
+                                       }
+                                       res->digits = decShiftToMost(res->lsu, res->digits, 1); // shift
+                                       res->exponent--;        // (re)adjust the exponent.
+                               }
+#if DECSUBSET
+                               if (ISZERO(res) && !set->extended)
+                                       res->bits = 0;  // subset; no -0
+#endif
+                       }       // increase
+                       else {  /* adjust<=0 */
+                               // decreasing or = exponent
+                               // this will increase the length of the coefficient by -adjust
+                               // digits, by adding zero or more trailing zeros; this is
+                               // already checked for fit, above
+                               decNumberCopy(res, lhs);        // [it will fit]
+                               // if padding needed (adjust<0), add it now...
+                               if (adjust < 0) {
+                                       res->digits =
+                                           decShiftToMost(res->lsu,
+                                                          res->digits,
+                                                          -adjust);
+                                       res->exponent += adjust;        // adjust the exponent
+                               }
+                       }       // decrease
+               }               // non-zero
+
+               // Check for overflow [do not use Finalize in this case, as an
+               // overflow here is a "don't fit" situation]
+               if (res->exponent > set->emax - res->digits + 1) {      // too big
+                       *status |= DEC_Invalid_operation;
+                       break;
+               } else {
+                       decFinalize(res, set, &residue, status);        // set subnormal flags
+                       *status &= ~DEC_Underflow;      // suppress Underflow [as per 754]
+               }
+       } while (0);            // end protected
+
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // drop any storage used
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+       return res;
+}                              // decQuantizeOp
+
+/* ------------------------------------------------------------------ */
+/* decCompareOp -- compare, min, or max two Numbers                   */
+/*                                                                    */
+/*   This computes C = A ? B and carries out one of four operations:  */
+/*     COMPARE    -- returns the signum (as a number) giving the      */
+/*                   result of a comparison unless one or both        */
+/*                   operands is a NaN (in which case a NaN results)  */
+/*     COMPSIG    -- as COMPARE except that a quiet NaN raises        */
+/*                   Invalid operation.                               */
+/*     COMPMAX    -- returns the larger of the operands, using the    */
+/*                   754 maxnum operation                             */
+/*     COMPMAXMAG -- ditto, comparing absolute values                 */
+/*     COMPMIN    -- the 754 minnum operation                         */
+/*     COMPMINMAG -- ditto, comparing absolute values                 */
+/*     COMTOTAL   -- returns the signum (as a number) giving the      */
+/*                   result of a comparison using 754 total ordering  */
+/*                                                                    */
+/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
+/*   lhs is A                                                         */
+/*   rhs is B                                                         */
+/*   set is the context                                               */
+/*   op  is the operation flag                                        */
+/*   status is the usual accumulator                                  */
+/*                                                                    */
+/* C must have space for one digit for COMPARE or set->digits for     */
+/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG.                       */
+/* ------------------------------------------------------------------ */
+/* The emphasis here is on speed for common cases, and avoiding       */
+/* coefficient comparison if possible.                                */
+/* ------------------------------------------------------------------ */
+decNumber *decCompareOp(decNumber * res, const decNumber * lhs,
+                       const decNumber * rhs, decContext * set,
+                       Flag op, uInt * status)
+{
+#if DECSUBSET
+       decNumber *alloclhs = NULL;     // non-NULL if rounded lhs allocated
+       decNumber *allocrhs = NULL;     // .., rhs
+#endif
+       Int result = 0;         // default result value
+       uByte merged;           // work
+
+#if DECCHECK
+       if (decCheckOperands(res, lhs, rhs, set))
+               return res;
+#endif
+
+       do {                    // protect allocated storage
+#if DECSUBSET
+               if (!set->extended) {
+                       // reduce operands and set lostDigits status, as needed
+                       if (lhs->digits > set->digits) {
+                               alloclhs = decRoundOperand(lhs, set, status);
+                               if (alloclhs == NULL) {
+                                       result = BADINT;
+                                       break;
+                               }
+                               lhs = alloclhs;
+                       }
+                       if (rhs->digits > set->digits) {
+                               allocrhs = decRoundOperand(rhs, set, status);
+                               if (allocrhs == NULL) {
+                                       result = BADINT;
+                                       break;
+                               }
+                               rhs = allocrhs;
+                       }
+               }
+#endif
+               // [following code does not require input rounding]
+
+               // If total ordering then handle differing signs 'up front'
+               if (op == COMPTOTAL) {  // total ordering
+                       if (decNumberIsNegative(lhs) &
+                           !decNumberIsNegative(rhs)) {
+                               result = -1;
+                               break;
+                       }
+                       if (!decNumberIsNegative(lhs) &
+                           decNumberIsNegative(rhs)) {
+                               result = +1;
+                               break;
+                       }
+               }
+               // handle NaNs specially; let infinities drop through
+               // This assumes sNaN (even just one) leads to NaN.
+               merged = (lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
+               if (merged) {   // a NaN bit set
+                       if (op == COMPARE) ;    // result will be NaN
+                       else if (op == COMPSIG) // treat qNaN as sNaN
+                               *status |= DEC_Invalid_operation | DEC_sNaN;
+                       else if (op == COMPTOTAL) {     // total ordering, always finite
+                               // signs are known to be the same; compute the ordering here
+                               // as if the signs are both positive, then invert for negatives
+                               if (!decNumberIsNaN(lhs))
+                                       result = -1;
+                               else if (!decNumberIsNaN(rhs))
+                                       result = +1;
+                               // here if both NaNs
+                               else if (decNumberIsSNaN(lhs)
+                                        && decNumberIsQNaN(rhs))
+                                       result = -1;
+                               else if (decNumberIsQNaN(lhs)
+                                        && decNumberIsSNaN(rhs))
+                                       result = +1;
+                               else {  // both NaN or both sNaN
+                                       // now it just depends on the payload
+                                       result =
+                                           decUnitCompare(lhs->lsu,
+                                                          D2U(lhs->digits),
+                                                          rhs->lsu,
+                                                          D2U(rhs->digits), 0);
+                                       // [Error not possible, as these are 'aligned']
+                               }       // both same NaNs
+                               if (decNumberIsNegative(lhs))
+                                       result = -result;
+                               break;
+                       }       // total order
+
+                       else if (merged & DECSNAN) ;    // sNaN -> qNaN
+                       else {  // here if MIN or MAX and one or two quiet NaNs
+                               // min or max -- 754 rules ignore single NaN
+                               if (!decNumberIsNaN(lhs)
+                                   || !decNumberIsNaN(rhs)) {
+                                       // just one NaN; force choice to be the non-NaN operand
+                                       op = COMPMAX;
+                                       if (lhs->bits & DECNAN)
+                                               result = -1;    // pick rhs
+                                       else
+                                               result = +1;    // pick lhs
+                                       break;
+                               }
+                       }       // max or min
+                       op = COMPNAN;   // use special path
+                       decNaNs(res, lhs, rhs, set, status);    // propagate NaN
+                       break;
+               }
+               // have numbers
+               if (op == COMPMAXMAG || op == COMPMINMAG)
+                       result = decCompare(lhs, rhs, 1);
+               else
+                       result = decCompare(lhs, rhs, 0);       // sign matters
+       } while (0);            // end protected
+
+       if (result == BADINT)
+               *status |= DEC_Insufficient_storage;    // rare
+       else {
+               if (op == COMPARE || op == COMPSIG || op == COMPTOTAL) {        // returning signum
+                       if (op == COMPTOTAL && result == 0) {
+                               // operands are numerically equal or same NaN (and same sign,
+                               // tested first); if identical, leave result 0
+                               if (lhs->exponent != rhs->exponent) {
+                                       if (lhs->exponent < rhs->exponent)
+                                               result = -1;
+                                       else
+                                               result = +1;
+                                       if (decNumberIsNegative(lhs))
+                                               result = -result;
+                               }       // lexp!=rexp
+                       }       // total-order by exponent
+                       decNumberZero(res);     // [always a valid result]
+                       if (result != 0) {      // must be -1 or +1
+                               *res->lsu = 1;
+                               if (result < 0)
+                                       res->bits = DECNEG;
+                       }
+               } else if (op == COMPNAN) ;     // special, drop through
+               else {          // MAX or MIN, non-NaN result
+                       Int residue = 0;        // rounding accumulator
+                       // choose the operand for the result
+                       const decNumber *choice;
+                       if (result == 0) {      // operands are numerically equal
+                               // choose according to sign then exponent (see 754)
+                               uByte slhs = (lhs->bits & DECNEG);
+                               uByte srhs = (rhs->bits & DECNEG);
+#if DECSUBSET
+                               if (!set->extended) {   // subset: force left-hand
+                                       op = COMPMAX;
+                                       result = +1;
+                               } else
+#endif
+                               if (slhs != srhs) {     // signs differ
+                                       if (slhs)
+                                               result = -1;    // rhs is max
+                                       else
+                                               result = +1;    // lhs is max
+                               } else if (slhs && srhs) {      // both negative
+                                       if (lhs->exponent < rhs->exponent)
+                                               result = +1;
+                                       else
+                                               result = -1;
+                                       // [if equal, use lhs, technically identical]
+                               } else {        // both positive
+                                       if (lhs->exponent > rhs->exponent)
+                                               result = +1;
+                                       else
+                                               result = -1;
+                                       // [ditto]
+                               }
+                       }       // numerically equal
+                       // here result will be non-0; reverse if looking for MIN
+                       if (op == COMPMIN || op == COMPMINMAG)
+                               result = -result;
+                       choice = (result > 0 ? lhs : rhs);      // choose
+                       // copy chosen to result, rounding if need be
+                       decCopyFit(res, choice, set, &residue, status);
+                       decFinish(res, set, &residue, status);
+               }
+       }
+#if DECSUBSET
+       if (allocrhs != NULL)
+               free(allocrhs); // free any storage used
+       if (alloclhs != NULL)
+               free(alloclhs); // ..
+#endif
+       return res;
+}                              // decCompareOp
+
+/* ------------------------------------------------------------------ */
+/* decCompare -- compare two decNumbers by numerical value            */
+/*                                                                    */
+/*  This routine compares A ? B without altering them.                */
+/*                                                                    */
+/*  Arg1 is A, a decNumber which is not a NaN                         */
+/*  Arg2 is B, a decNumber which is not a NaN                         */
+/*  Arg3 is 1 for a sign-independent compare, 0 otherwise             */
+/*                                                                    */
+/*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
+/*  (the only possible failure is an allocation error)                */
+/* ------------------------------------------------------------------ */
+static Int decCompare(const decNumber * lhs, const decNumber * rhs, Flag abs)
+{
+       Int result;             // result value
+       Int sigr;               // rhs signum
+       Int compare;            // work
+
+       result = 1;             // assume signum(lhs)
+       if (ISZERO(lhs))
+               result = 0;
+       if (abs) {
+               if (ISZERO(rhs))
+                       return result;  // LHS wins or both 0
+               // RHS is non-zero
+               if (result == 0)
+                       return -1;      // LHS is 0; RHS wins
+               // [here, both non-zero, result=1]
+       } else {                // signs matter
+               if (result && decNumberIsNegative(lhs))
+                       result = -1;
+               sigr = 1;       // compute signum(rhs)
+               if (ISZERO(rhs))
+                       sigr = 0;
+               else if (decNumberIsNegative(rhs))
+                       sigr = -1;
+               if (result > sigr)
+                       return +1;      // L > R, return 1
+               if (result < sigr)
+                       return -1;      // L < R, return -1
+               if (result == 0)
+                       return 0;       // both 0
+       }
+
+       // signums are the same; both are non-zero
+       if ((lhs->bits | rhs->bits) & DECINF) { // one or more infinities
+               if (decNumberIsInfinite(rhs)) {
+                       if (decNumberIsInfinite(lhs))
+                               result = 0;     // both infinite
+                       else
+                               result = -result;       // only rhs infinite
+               }
+               return result;
+       }
+       // must compare the coefficients, allowing for exponents
+       if (lhs->exponent > rhs->exponent) {    // LHS exponent larger
+               // swap sides, and sign
+               const decNumber *temp = lhs;
+               lhs = rhs;
+               rhs = temp;
+               result = -result;
+       }
+       compare = decUnitCompare(lhs->lsu, D2U(lhs->digits),
+                                rhs->lsu, D2U(rhs->digits),
+                                rhs->exponent - lhs->exponent);
+       if (compare != BADINT)
+               compare *= result;      // comparison succeeded
+       return compare;
+}                              // decCompare
+
+/* ------------------------------------------------------------------ */
+/* decUnitCompare -- compare two >=0 integers in Unit arrays          */
+/*                                                                    */
+/*  This routine compares A ? B*10**E where A and B are unit arrays   */
+/*  A is a plain integer                                              */
+/*  B has an exponent of E (which must be non-negative)               */
+/*                                                                    */
+/*  Arg1 is A first Unit (lsu)                                        */
+/*  Arg2 is A length in Units                                         */
+/*  Arg3 is B first Unit (lsu)                                        */
+/*  Arg4 is B length in Units                                         */
+/*  Arg5 is E (0 if the units are aligned)                            */
+/*                                                                    */
+/*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
+/*  (the only possible failure is an allocation error, which can      */
+/*  only occur if E!=0)                                               */
+/* ------------------------------------------------------------------ */
+static Int decUnitCompare(const Unit * a, Int alength,
+                         const Unit * b, Int blength, Int exp)
+{
+       Unit *acc;              // accumulator for result
+       Unit accbuff[SD2U(DECBUFFER * 2 + 1)];  // local buffer
+       Unit *allocacc = NULL;  // -> allocated acc buffer, iff allocated
+       Int accunits, need;     // units in use or needed for acc
+       const Unit *l, *r, *u;  // work
+       Int expunits, exprem, result;   // ..
+
+       if (exp == 0) {         // aligned; fastpath
+               if (alength > blength)
+                       return 1;
+               if (alength < blength)
+                       return -1;
+               // same number of units in both -- need unit-by-unit compare
+               l = a + alength - 1;
+               r = b + alength - 1;
+               for (; l >= a; l--, r--) {
+                       if (*l > *r)
+                               return 1;
+                       if (*l < *r)
+                               return -1;
+               }
+               return 0;       // all units match
+       }                       // aligned
+
+       // Unaligned.  If one is >1 unit longer than the other, padded
+       // approximately, then can return easily
+       if (alength > blength + (Int) D2U(exp))
+               return 1;
+       if (alength + 1 < blength + (Int) D2U(exp))
+               return -1;
+
+       // Need to do a real subtract.  For this, a result buffer is needed
+       // even though only the sign is of interest.  Its length needs
+       // to be the larger of alength and padded blength, +2
+       need = blength + D2U(exp);      // maximum real length of B
+       if (need < alength)
+               need = alength;
+       need += 2;
+       acc = accbuff;          // assume use local buffer
+       if (need * sizeof(Unit) > sizeof(accbuff)) {
+               allocacc = (Unit *) malloc(need * sizeof(Unit));
+               if (allocacc == NULL)
+                       return BADINT;  // hopeless -- abandon
+               acc = allocacc;
+       }
+       // Calculate units and remainder from exponent.
+       expunits = exp / DECDPUN;
+       exprem = exp % DECDPUN;
+       // subtract [A+B*(-m)]
+       accunits = decUnitAddSub(a, alength, b, blength, expunits, acc,
+                                -(Int) powers[exprem]);
+       // [UnitAddSub result may have leading zeros, even on zero]
+       if (accunits < 0)
+               result = -1;    // negative result
+       else {                  // non-negative result
+               // check units of the result before freeing any storage
+               for (u = acc; u < acc + accunits - 1 && *u == 0;)
+                       u++;
+               result = (*u == 0 ? 0 : +1);
+       }
+       // clean up and return the result
+       if (allocacc != NULL)
+               free(allocacc); // drop any storage used
+       return result;
+}                              // decUnitCompare
+
+/* ------------------------------------------------------------------ */
+/* decUnitAddSub -- add or subtract two >=0 integers in Unit arrays   */
+/*                                                                    */
+/*  This routine performs the calculation:                            */
+/*                                                                    */
+/*  C=A+(B*M)                                                         */
+/*                                                                    */
+/*  Where M is in the range -DECDPUNMAX through +DECDPUNMAX.          */
+/*                                                                    */
+/*  A may be shorter or longer than B.                                */
+/*                                                                    */
+/*  Leading zeros are not removed after a calculation.  The result is */
+/*  either the same length as the longer of A and B (adding any       */
+/*  shift), or one Unit longer than that (if a Unit carry occurred).  */
+/*                                                                    */
+/*  A and B content are not altered unless C is also A or B.          */
+/*  C may be the same array as A or B, but only if no zero padding is */
+/*  requested (that is, C may be B only if bshift==0).                */
+/*  C is filled from the lsu; only those units necessary to complete  */
+/*  the calculation are referenced.                                   */
+/*                                                                    */
+/*  Arg1 is A first Unit (lsu)                                        */
+/*  Arg2 is A length in Units                                         */
+/*  Arg3 is B first Unit (lsu)                                        */
+/*  Arg4 is B length in Units                                         */
+/*  Arg5 is B shift in Units  (>=0; pads with 0 units if positive)    */
+/*  Arg6 is C first Unit (lsu)                                        */
+/*  Arg7 is M, the multiplier                                         */
+/*                                                                    */
+/*  returns the count of Units written to C, which will be non-zero   */
+/*  and negated if the result is negative.  That is, the sign of the  */
+/*  returned Int is the sign of the result (positive for zero) and    */
+/*  the absolute value of the Int is the count of Units.              */
+/*                                                                    */
+/*  It is the caller's responsibility to make sure that C size is     */
+/*  safe, allowing space if necessary for a one-Unit carry.           */
+/*                                                                    */
+/*  This routine is severely performance-critical; *any* change here  */
+/*  must be measured (timed) to assure no performance degradation.    */
+/*  In particular, trickery here tends to be counter-productive, as   */
+/*  increased complexity of code hurts register optimizations on      */
+/*  register-poor architectures.  Avoiding divisions is nearly        */
+/*  always a Good Idea, however.                                      */
+/*                                                                    */
+/* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark  */
+/* (IBM Warwick, UK) for some of the ideas used in this routine.      */
+/* ------------------------------------------------------------------ */
+static Int decUnitAddSub(const Unit * a, Int alength,
+                        const Unit * b, Int blength, Int bshift,
+                        Unit * c, Int m)
+{
+       const Unit *alsu = a;   // A lsu [need to remember it]
+       Unit *clsu = c;         // C ditto
+       Unit *minC;             // low water mark for C
+       Unit *maxC;             // high water mark for C
+       eInt carry = 0;         // carry integer (could be Long)
+       Int add;                // work
+#if DECDPUN<=4                 // myriadal, millenary, etc.
+       Int est;                // estimated quotient
+#endif
+
+#if DECTRACE
+       if (alength < 1 || blength < 1)
+               printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength,
+                      blength, m);
+#endif
+
+       maxC = c + alength;     // A is usually the longer
+       minC = c + blength;     // .. and B the shorter
+       if (bshift != 0) {      // B is shifted; low As copy across
+               minC += bshift;
+               // if in place [common], skip copy unless there's a gap [rare]
+               if (a == c && bshift <= alength) {
+                       c += bshift;
+                       a += bshift;
+               } else
+                       for (; c < clsu + bshift; a++, c++) {   // copy needed
+                               if (a < alsu + alength)
+                                       *c = *a;
+                               else
+                                       *c = 0;
+                       }
+       }
+       if (minC > maxC) {      // swap
+               Unit *hold = minC;
+               minC = maxC;
+               maxC = hold;
+       }
+       // For speed, do the addition as two loops; the first where both A
+       // and B contribute, and the second (if necessary) where only one or
+       // other of the numbers contribute.
+       // Carry handling is the same (i.e., duplicated) in each case.
+       for (; c < minC; c++) {
+               carry += *a;
+               a++;
+               carry += ((eInt) * b) * m;      // [special-casing m=1/-1
+               b++;            // here is not a win]
+               // here carry is new Unit of digits; it could be +ve or -ve
+               if ((ueInt) carry <= DECDPUNMAX) {      // fastpath 0-DECDPUNMAX
+                       *c = (Unit) carry;
+                       carry = 0;
+                       continue;
+               }
+#if DECDPUN==4                 // use divide-by-multiply
+               if (carry >= 0) {
+                       est = (((ueInt) carry >> 11) * 53687) >> 18;
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                       carry = est;    // likely quotient [89%]
+                       if (*c < DECDPUNMAX + 1)
+                               continue;       // estimate was correct
+                       carry++;
+                       *c -= DECDPUNMAX + 1;
+                       continue;
+               }
+               // negative case
+               carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+               est = (((ueInt) carry >> 11) * 53687) >> 18;
+               *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+               carry = est - (DECDPUNMAX + 1); // correctly negative
+               if (*c < DECDPUNMAX + 1)
+                       continue;       // was OK
+               carry++;
+               *c -= DECDPUNMAX + 1;
+#elif DECDPUN==3
+               if (carry >= 0) {
+                       est = (((ueInt) carry >> 3) * 16777) >> 21;
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                       carry = est;    // likely quotient [99%]
+                       if (*c < DECDPUNMAX + 1)
+                               continue;       // estimate was correct
+                       carry++;
+                       *c -= DECDPUNMAX + 1;
+                       continue;
+               }
+               // negative case
+               carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+               est = (((ueInt) carry >> 3) * 16777) >> 21;
+               *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+               carry = est - (DECDPUNMAX + 1); // correctly negative
+               if (*c < DECDPUNMAX + 1)
+                       continue;       // was OK
+               carry++;
+               *c -= DECDPUNMAX + 1;
+#elif DECDPUN<=2
+               // Can use QUOT10 as carry <= 4 digits
+               if (carry >= 0) {
+                       est = QUOT10(carry, DECDPUN);
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                       carry = est;    // quotient
+                       continue;
+               }
+               // negative case
+               carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+               est = QUOT10(carry, DECDPUN);
+               *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+               carry = est - (DECDPUNMAX + 1); // correctly negative
+#else
+               // remainder operator is undefined if negative, so must test
+               if ((ueInt) carry < (DECDPUNMAX + 1) * 2) {     // fastpath carry +1
+                       *c = (Unit) (carry - (DECDPUNMAX + 1)); // [helps additions]
+                       carry = 1;
+                       continue;
+               }
+               if (carry >= 0) {
+                       *c = (Unit) (carry % (DECDPUNMAX + 1));
+                       carry = carry / (DECDPUNMAX + 1);
+                       continue;
+               }
+               // negative case
+               carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+               *c = (Unit) (carry % (DECDPUNMAX + 1));
+               carry = carry / (DECDPUNMAX + 1) - (DECDPUNMAX + 1);
+#endif
+       }                       // c
+
+       // now may have one or other to complete
+       // [pretest to avoid loop setup/shutdown]
+       if (c < maxC)
+               for (; c < maxC; c++) {
+                       if (a < alsu + alength) {       // still in A
+                               carry += *a;
+                               a++;
+                       } else {        // inside B
+                               carry += ((eInt) * b) * m;
+                               b++;
+                       }
+                       // here carry is new Unit of digits; it could be +ve or -ve and
+                       // magnitude up to DECDPUNMAX squared
+                       if ((ueInt) carry <= DECDPUNMAX) {      // fastpath 0-DECDPUNMAX
+                               *c = (Unit) carry;
+                               carry = 0;
+                               continue;
+                       }
+                       // result for this unit is negative or >DECDPUNMAX
+#if DECDPUN==4                 // use divide-by-multiply
+                       if (carry >= 0) {
+                               est = (((ueInt) carry >> 11) * 53687) >> 18;
+                               *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                               carry = est;    // likely quotient [79.7%]
+                               if (*c < DECDPUNMAX + 1)
+                                       continue;       // estimate was correct
+                               carry++;
+                               *c -= DECDPUNMAX + 1;
+                               continue;
+                       }
+                       // negative case
+                       carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+                       est = (((ueInt) carry >> 11) * 53687) >> 18;
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+                       carry = est - (DECDPUNMAX + 1); // correctly negative
+                       if (*c < DECDPUNMAX + 1)
+                               continue;       // was OK
+                       carry++;
+                       *c -= DECDPUNMAX + 1;
+#elif DECDPUN==3
+                       if (carry >= 0) {
+                               est = (((ueInt) carry >> 3) * 16777) >> 21;
+                               *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                               carry = est;    // likely quotient [99%]
+                               if (*c < DECDPUNMAX + 1)
+                                       continue;       // estimate was correct
+                               carry++;
+                               *c -= DECDPUNMAX + 1;
+                               continue;
+                       }
+                       // negative case
+                       carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+                       est = (((ueInt) carry >> 3) * 16777) >> 21;
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+                       carry = est - (DECDPUNMAX + 1); // correctly negative
+                       if (*c < DECDPUNMAX + 1)
+                               continue;       // was OK
+                       carry++;
+                       *c -= DECDPUNMAX + 1;
+#elif DECDPUN<=2
+                       if (carry >= 0) {
+                               est = QUOT10(carry, DECDPUN);
+                               *c = (Unit) (carry - est * (DECDPUNMAX + 1));   // remainder
+                               carry = est;    // quotient
+                               continue;
+                       }
+                       // negative case
+                       carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+                       est = QUOT10(carry, DECDPUN);
+                       *c = (Unit) (carry - est * (DECDPUNMAX + 1));
+                       carry = est - (DECDPUNMAX + 1); // correctly negative
+#else
+                       if ((ueInt) carry < (DECDPUNMAX + 1) * 2) {     // fastpath carry 1
+                               *c = (Unit) (carry - (DECDPUNMAX + 1));
+                               carry = 1;
+                               continue;
+                       }
+                       // remainder operator is undefined if negative, so must test
+                       if (carry >= 0) {
+                               *c = (Unit) (carry % (DECDPUNMAX + 1));
+                               carry = carry / (DECDPUNMAX + 1);
+                               continue;
+                       }
+                       // negative case
+                       carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1);     // make positive
+                       *c = (Unit) (carry % (DECDPUNMAX + 1));
+                       carry = carry / (DECDPUNMAX + 1) - (DECDPUNMAX + 1);
+#endif
+               }               // c
+
+       // OK, all A and B processed; might still have carry or borrow
+       // return number of Units in the result, negated if a borrow
+       if (carry == 0)
+               return c - clsu;        // no carry, so no more to do
+       if (carry > 0) {        // positive carry
+               *c = (Unit) carry;      // place as new unit
+               c++;            // ..
+               return c - clsu;
+       }
+       // -ve carry: it's a borrow; complement needed
+       add = 1;                // temporary carry...
+       for (c = clsu; c < maxC; c++) {
+               add = DECDPUNMAX + add - *c;
+               if (add <= DECDPUNMAX) {
+                       *c = (Unit) add;
+                       add = 0;
+               } else {
+                       *c = 0;
+                       add = 1;
+               }
+       }
+       // add an extra unit iff it would be non-zero
+#if DECTRACE
+       printf("UAS borrow: add %ld, carry %ld\n", add, carry);
+#endif
+       if ((add - carry - 1) != 0) {
+               *c = (Unit) (add - carry - 1);
+               c++;            // interesting, include it
+       }
+       return clsu - c;        // -ve result indicates borrowed
+}                              // decUnitAddSub
+
+/* ------------------------------------------------------------------ */
+/* decTrim -- trim trailing zeros or normalize                        */
+/*                                                                    */
+/*   dn is the number to trim or normalize                            */
+/*   set is the context to use to check for clamp                     */
+/*   all is 1 to remove all trailing zeros, 0 for just fraction ones  */
+/*   noclamp is 1 to unconditional (unclamped) trim                   */
+/*   dropped returns the number of discarded trailing zeros           */
+/*   returns dn                                                       */
+/*                                                                    */
+/* If clamp is set in the context then the number of zeros trimmed    */
+/* may be limited if the exponent is high.                            */
+/* All fields are updated as required.  This is a utility operation,  */
+/* so special values are unchanged and no error is possible.          */
+/* ------------------------------------------------------------------ */
+static decNumber *decTrim(decNumber * dn, decContext * set, Flag all,
+                         Flag noclamp, Int * dropped)
+{
+       Int d, exp;             // work
+       uInt cut;               // ..
+       Unit *up;               // -> current Unit
+
+#if DECCHECK
+       if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT))
+               return dn;
+#endif
+
+       *dropped = 0;           // assume no zeros dropped
+       if ((dn->bits & DECSPECIAL)     // fast exit if special ..
+           || (*dn->lsu & 0x01))
+               return dn;      // .. or odd
+       if (ISZERO(dn)) {       // .. or 0
+               dn->exponent = 0;       // (sign is preserved)
+               return dn;
+       }
+       // have a finite number which is even
+       exp = dn->exponent;
+       cut = 1;                // digit (1-DECDPUN) in Unit
+       up = dn->lsu;           // -> current Unit
+       for (d = 0; d < dn->digits - 1; d++) {  // [don't strip the final digit]
+               // slice by powers
+#if DECDPUN<=4
+               uInt quot = QUOT10(*up, cut);
+               if ((*up - quot * powers[cut]) != 0)
+                       break;  // found non-0 digit
+#else
+               if (*up % powers[cut] != 0)
+                       break;  // found non-0 digit
+#endif
+               // have a trailing 0
+               if (!all) {     // trimming
+                       // [if exp>0 then all trailing 0s are significant for trim]
+                       if (exp <= 0) { // if digit might be significant
+                               if (exp == 0)
+                                       break;  // then quit
+                               exp++;  // next digit might be significant
+                       }
+               }
+               cut++;          // next power
+               if (cut > DECDPUN) {    // need new Unit
+                       up++;
+                       cut = 1;
+               }
+       }                       // d
+       if (d == 0)
+               return dn;      // none to drop
+
+       // may need to limit drop if clamping
+       if (set->clamp && !noclamp) {
+               Int maxd = set->emax - set->digits + 1 - dn->exponent;
+               if (maxd <= 0)
+                       return dn;      // nothing possible
+               if (d > maxd)
+                       d = maxd;
+       }
+       // effect the drop
+       decShiftToLeast(dn->lsu, D2U(dn->digits), d);
+       dn->exponent += d;      // maintain numerical value
+       dn->digits -= d;        // new length
+       *dropped = d;           // report the count
+       return dn;
+}                              // decTrim
+
+/* ------------------------------------------------------------------ */
+/* decReverse -- reverse a Unit array in place                        */
+/*                                                                    */
+/*   ulo    is the start of the array                                 */
+/*   uhi    is the end of the array (highest Unit to include)         */
+/*                                                                    */
+/* The units ulo through uhi are reversed in place (if the number     */
+/* of units is odd, the middle one is untouched).  Note that the      */
+/* digit(s) in each unit are unaffected.                              */
+/* ------------------------------------------------------------------ */
+static void decReverse(Unit * ulo, Unit * uhi)
+{
+       Unit temp;
+       for (; ulo < uhi; ulo++, uhi--) {
+               temp = *ulo;
+               *ulo = *uhi;
+               *uhi = temp;
+       }
+       return;
+}                              // decReverse
+
+/* ------------------------------------------------------------------ */
+/* decShiftToMost -- shift digits in array towards most significant   */
+/*                                                                    */
+/*   uar    is the array                                              */
+/*   digits is the count of digits in use in the array                */
+/*   shift  is the number of zeros to pad with (least significant);   */
+/*     it must be zero or positive                                    */
+/*                                                                    */
+/*   returns the new length of the integer in the array, in digits    */
+/*                                                                    */
+/* No overflow is permitted (that is, the uar array must be known to  */
+/* be large enough to hold the result, after shifting).               */
+/* ------------------------------------------------------------------ */
+static Int decShiftToMost(Unit * uar, Int digits, Int shift)
+{
+       Unit *target, *source, *first;  // work
+       Int cut;                // odd 0's to add
+       uInt next;              // work
+
+       if (shift == 0)
+               return digits;  // [fastpath] nothing to do
+       if ((digits + shift) <= DECDPUN) {      // [fastpath] single-unit case
+               *uar = (Unit) (*uar * powers[shift]);
+               return digits + shift;
+       }
+
+       next = 0;               // all paths
+       source = uar + D2U(digits) - 1; // where msu comes from
+       target = source + D2U(shift);   // where upper part of first cut goes
+       cut = DECDPUN - MSUDIGITS(shift);       // where to slice
+       if (cut == 0) {         // unit-boundary case
+               for (; source >= uar; source--, target--)
+                       *target = *source;
+       } else {
+               first = uar + D2U(digits + shift) - 1;  // where msu of source will end up
+               for (; source >= uar; source--, target--) {
+                       // split the source Unit and accumulate remainder for next
+#if DECDPUN<=4
+                       uInt quot = QUOT10(*source, cut);
+                       uInt rem = *source - quot * powers[cut];
+                       next += quot;
+#else
+                       uInt rem = *source % powers[cut];
+                       next += *source / powers[cut];
+#endif
+                       if (target <= first)
+                               *target = (Unit) next;  // write to target iff valid
+                       next = rem * powers[DECDPUN - cut];     // save remainder for next Unit
+               }
+       }                       // shift-move
+
+       // propagate any partial unit to one below and clear the rest
+       for (; target >= uar; target--) {
+               *target = (Unit) next;
+               next = 0;
+       }
+       return digits + shift;
+}                              // decShiftToMost
+
+/* ------------------------------------------------------------------ */
+/* decShiftToLeast -- shift digits in array towards least significant */
+/*                                                                    */
+/*   uar   is the array                                               */
+/*   units is length of the array, in units                           */
+/*   shift is the number of digits to remove from the lsu end; it     */
+/*     must be zero or positive and <= than units*DECDPUN.            */
+/*                                                                    */
+/*   returns the new length of the integer in the array, in units     */
+/*                                                                    */
+/* Removed digits are discarded (lost).  Units not required to hold   */
+/* the final result are unchanged.                                    */
+/* ------------------------------------------------------------------ */
+static Int decShiftToLeast(Unit * uar, Int units, Int shift)
+{
+       Unit *target, *up;      // work
+       Int cut, count;         // work
+       Int quot, rem;          // for division
+
+       if (shift == 0)
+               return units;   // [fastpath] nothing to do
+       if (shift == units * DECDPUN) { // [fastpath] little to do
+               *uar = 0;       // all digits cleared gives zero
+               return 1;       // leaves just the one
+       }
+
+       target = uar;           // both paths
+       cut = MSUDIGITS(shift);
+       if (cut == DECDPUN) {   // unit-boundary case; easy
+               up = uar + D2U(shift);
+               for (; up < uar + units; target++, up++)
+                       *target = *up;
+               return target - uar;
+       }
+       // messier
+       up = uar + D2U(shift - cut);    // source; correct to whole Units
+       count = units * DECDPUN - shift;        // the maximum new length
+#if DECDPUN<=4
+       quot = QUOT10(*up, cut);
+#else
+       quot = *up / powers[cut];
+#endif
+       for (;; target++) {
+               *target = (Unit) quot;
+               count -= (DECDPUN - cut);
+               if (count <= 0)
+                       break;
+               up++;
+               quot = *up;
+#if DECDPUN<=4
+               quot = QUOT10(quot, cut);
+               rem = *up - quot * powers[cut];
+#else
+               rem = quot % powers[cut];
+               quot = quot / powers[cut];
+#endif
+               *target = (Unit) (*target + rem * powers[DECDPUN - cut]);
+               count -= cut;
+               if (count <= 0)
+                       break;
+       }
+       return target - uar + 1;
+}                              // decShiftToLeast
+
+#if DECSUBSET
+/* ------------------------------------------------------------------ */
+/* decRoundOperand -- round an operand  [used for subset only]        */
+/*                                                                    */
+/*   dn is the number to round (dn->digits is > set->digits)          */
+/*   set is the relevant context                                      */
+/*   status is the status accumulator                                 */
+/*                                                                    */
+/*   returns an allocated decNumber with the rounded result.          */
+/*                                                                    */
+/* lostDigits and other status may be set by this.                    */
+/*                                                                    */
+/* Since the input is an operand, it must not be modified.            */
+/* Instead, return an allocated decNumber, rounded as required.       */
+/* It is the caller's responsibility to free the allocated storage.   */
+/*                                                                    */
+/* If no storage is available then the result cannot be used, so NULL */
+/* is returned.                                                       */
+/* ------------------------------------------------------------------ */
+static decNumber *decRoundOperand(const decNumber * dn, decContext * set,
+                                 uInt * status)
+{
+       decNumber *res;         // result structure
+       uInt newstatus = 0;     // status from round
+       Int residue = 0;        // rounding accumulator
+
+       // Allocate storage for the returned decNumber, big enough for the
+       // length specified by the context
+       res = (decNumber *) malloc(sizeof(decNumber)
+                                  + (D2U(set->digits) - 1) * sizeof(Unit));
+       if (res == NULL) {
+               *status |= DEC_Insufficient_storage;
+               return NULL;
+       }
+       decCopyFit(res, dn, set, &residue, &newstatus);
+       decApplyRound(res, set, residue, &newstatus);
+
+       // If that set Inexact then "lost digits" is raised...
+       if (newstatus & DEC_Inexact)
+               newstatus |= DEC_Lost_digits;
+       *status |= newstatus;
+       return res;
+}                              // decRoundOperand
+#endif
+
+/* ------------------------------------------------------------------ */
+/* decCopyFit -- copy a number, truncating the coefficient if needed  */
+/*                                                                    */
+/*   dest is the target decNumber                                     */
+/*   src  is the source decNumber                                     */
+/*   set is the context [used for length (digits) and rounding mode]  */
+/*   residue is the residue accumulator                               */
+/*   status contains the current status to be updated                 */
+/*                                                                    */
+/* (dest==src is allowed and will be a no-op if fits)                 */
+/* All fields are updated as required.                                */
+/* ------------------------------------------------------------------ */
+static void decCopyFit(decNumber * dest, const decNumber * src,
+                      decContext * set, Int * residue, uInt * status)
+{
+       dest->bits = src->bits;
+       dest->exponent = src->exponent;
+       decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
+}                              // decCopyFit
+
+/* ------------------------------------------------------------------ */
+/* decSetCoeff -- set the coefficient of a number                     */
+/*                                                                    */
+/*   dn    is the number whose coefficient array is to be set.        */
+/*         It must have space for set->digits digits                  */
+/*   set   is the context [for size]                                  */
+/*   lsu   -> lsu of the source coefficient [may be dn->lsu]          */
+/*   len   is digits in the source coefficient [may be dn->digits]    */
+/*   residue is the residue accumulator.  This has values as in       */
+/*         decApplyRound, and will be unchanged unless the            */
+/*         target size is less than len.  In this case, the           */
+/*         coefficient is truncated and the residue is updated to     */
+/*         reflect the previous residue and the dropped digits.       */
+/*   status is the status accumulator, as usual                       */
+/*                                                                    */
+/* The coefficient may already be in the number, or it can be an      */
+/* external intermediate array.  If it is in the number, lsu must ==  */
+/* dn->lsu and len must == dn->digits.                                */
+/*                                                                    */
+/* Note that the coefficient length (len) may be < set->digits, and   */
+/* in this case this merely copies the coefficient (or is a no-op     */
+/* if dn->lsu==lsu).                                                  */
+/*                                                                    */
+/* Note also that (only internally, from decQuantizeOp and            */
+/* decSetSubnormal) the value of set->digits may be less than one,    */
+/* indicating a round to left.  This routine handles that case        */
+/* correctly; caller ensures space.                                   */
+/*                                                                    */
+/* dn->digits, dn->lsu (and as required), and dn->exponent are        */
+/* updated as necessary.   dn->bits (sign) is unchanged.              */
+/*                                                                    */
+/* DEC_Rounded status is set if any digits are discarded.             */
+/* DEC_Inexact status is set if any non-zero digits are discarded, or */
+/*                       incoming residue was non-0 (implies rounded) */
+/* ------------------------------------------------------------------ */
+// mapping array: maps 0-9 to canonical residues, so that a residue
+// can be adjusted in the range [-1, +1] and achieve correct rounding
+//                             0  1  2  3  4  5  6  7  8  9
+static const uByte resmap[10] = { 0, 3, 3, 3, 3, 5, 7, 7, 7, 7 };
+
+static void decSetCoeff(decNumber * dn, decContext * set, const Unit * lsu,
+                       Int len, Int * residue, uInt * status)
+{
+       Int discard;            // number of digits to discard
+       uInt cut;               // cut point in Unit
+       const Unit *up;         // work
+       Unit *target;           // ..
+       Int count;              // ..
+#if DECDPUN<=4
+       uInt temp;              // ..
+#endif
+
+       discard = len - set->digits;    // digits to discard
+       if (discard <= 0) {     // no digits are being discarded
+               if (dn->lsu != lsu) {   // copy needed
+                       // copy the coefficient array to the result number; no shift needed
+                       count = len;    // avoids D2U
+                       up = lsu;
+                       for (target = dn->lsu; count > 0;
+                            target++, up++, count -= DECDPUN)
+                               *target = *up;
+                       dn->digits = len;       // set the new length
+               }
+               // dn->exponent and residue are unchanged, record any inexactitude
+               if (*residue != 0)
+                       *status |= (DEC_Inexact | DEC_Rounded);
+               return;
+       }
+       // some digits must be discarded ...
+       dn->exponent += discard;        // maintain numerical value
+       *status |= DEC_Rounded; // accumulate Rounded status
+       if (*residue > 1)
+               *residue = 1;   // previous residue now to right, so reduce
+
+       if (discard > len) {    // everything, +1, is being discarded
+               // guard digit is 0
+               // residue is all the number [NB could be all 0s]
+               if (*residue <= 0) {    // not already positive
+                       count = len;    // avoids D2U
+                       for (up = lsu; count > 0; up++, count -= DECDPUN)
+                               if (*up != 0) { // found non-0
+                                       *residue = 1;
+                                       break;  // no need to check any others
+                               }
+               }
+               if (*residue != 0)
+                       *status |= DEC_Inexact; // record inexactitude
+               *dn->lsu = 0;   // coefficient will now be 0
+               dn->digits = 1; // ..
+               return;
+       }                       // total discard
+
+       // partial discard [most common case]
+       // here, at least the first (most significant) discarded digit exists
+
+       // spin up the number, noting residue during the spin, until get to
+       // the Unit with the first discarded digit.  When reach it, extract
+       // it and remember its position
+       count = 0;
+       for (up = lsu;; up++) {
+               count += DECDPUN;
+               if (count >= discard)
+                       break;  // full ones all checked
+               if (*up != 0)
+                       *residue = 1;
+       }                       // up
+
+       // here up -> Unit with first discarded digit
+       cut = discard - (count - DECDPUN) - 1;
+       if (cut == DECDPUN - 1) {       // unit-boundary case (fast)
+               Unit half = (Unit) powers[DECDPUN] >> 1;
+               // set residue directly
+               if (*up >= half) {
+                       if (*up > half)
+                               *residue = 7;
+                       else
+                               *residue += 5;  // add sticky bit
+               } else {        // <half
+                       if (*up != 0)
+                               *residue = 3;   // [else is 0, leave as sticky bit]
+               }
+               if (set->digits <= 0) { // special for Quantize/Subnormal :-(
+                       *dn->lsu = 0;   // .. result is 0
+                       dn->digits = 1; // ..
+               } else {        // shift to least
+                       count = set->digits;    // now digits to end up with
+                       dn->digits = count;     // set the new length
+                       up++;   // move to next
+                       // on unit boundary, so shift-down copy loop is simple
+                       for (target = dn->lsu; count > 0;
+                            target++, up++, count -= DECDPUN)
+                               *target = *up;
+               }
+       }                       // unit-boundary case
+
+       else {                  // discard digit is in low digit(s), and not top digit
+               uInt discard1;  // first discarded digit
+               uInt quot, rem; // for divisions
+               if (cut == 0)
+                       quot = *up;     // is at bottom of unit
+               else {          /* cut>0 */
+                       // it's not at bottom of unit
+#if DECDPUN<=4
+                       quot = QUOT10(*up, cut);
+                       rem = *up - quot * powers[cut];
+#else
+                       rem = *up % powers[cut];
+                       quot = *up / powers[cut];
+#endif
+                       if (rem != 0)
+                               *residue = 1;
+               }
+               // discard digit is now at bottom of quot
+#if DECDPUN<=4
+               temp = (quot * 6554) >> 16;     // fast /10
+               // Vowels algorithm here not a win (9 instructions)
+               discard1 = quot - X10(temp);
+               quot = temp;
+#else
+               discard1 = quot % 10;
+               quot = quot / 10;
+#endif
+               // here, discard1 is the guard digit, and residue is everything
+               // else [use mapping array to accumulate residue safely]
+               *residue += resmap[discard1];
+               cut++;          // update cut
+               // here: up -> Unit of the array with bottom digit
+               //       cut is the division point for each Unit
+               //       quot holds the uncut high-order digits for the current unit
+               if (set->digits <= 0) { // special for Quantize/Subnormal :-(
+                       *dn->lsu = 0;   // .. result is 0
+                       dn->digits = 1; // ..
+               } else {        // shift to least needed
+                       count = set->digits;    // now digits to end up with
+                       dn->digits = count;     // set the new length
+                       // shift-copy the coefficient array to the result number
+                       for (target = dn->lsu;; target++) {
+                               *target = (Unit) quot;
+                               count -= (DECDPUN - cut);
+                               if (count <= 0)
+                                       break;
+                               up++;
+                               quot = *up;
+#if DECDPUN<=4
+                               quot = QUOT10(quot, cut);
+                               rem = *up - quot * powers[cut];
+#else
+                               rem = quot % powers[cut];
+                               quot = quot / powers[cut];
+#endif
+                               *target =
+                                   (Unit) (*target +
+                                           rem * powers[DECDPUN - cut]);
+                               count -= cut;
+                               if (count <= 0)
+                                       break;
+                       }       // shift-copy loop
+               }               // shift to least
+       }                       // not unit boundary
+
+       if (*residue != 0)
+               *status |= DEC_Inexact; // record inexactitude
+       return;
+}                              // decSetCoeff
+
+/* ------------------------------------------------------------------ */
+/* decApplyRound -- apply pending rounding to a number                */
+/*                                                                    */
+/*   dn    is the number, with space for set->digits digits           */
+/*   set   is the context [for size and rounding mode]                */
+/*   residue indicates pending rounding, being any accumulated        */
+/*         guard and sticky information.  It may be:                  */
+/*         6-9: rounding digit is >5                                  */
+/*         5:   rounding digit is exactly half-way                    */
+/*         1-4: rounding digit is <5 and >0                           */
+/*         0:   the coefficient is exact                              */
+/*        -1:   as 1, but the hidden digits are subtractive, that     */
+/*              is, of the opposite sign to dn.  In this case the     */
+/*              coefficient must be non-0.  This case occurs when     */
+/*              subtracting a small number (which can be reduced to   */
+/*              a sticky bit); see decAddOp.                          */
+/*   status is the status accumulator, as usual                       */
+/*                                                                    */
+/* This routine applies rounding while keeping the length of the      */
+/* coefficient constant.  The exponent and status are unchanged       */
+/* except if:                                                         */
+/*                                                                    */
+/*   -- the coefficient was increased and is all nines (in which      */
+/*      case Overflow could occur, and is handled directly here so    */
+/*      the caller does not need to re-test for overflow)             */
+/*                                                                    */
+/*   -- the coefficient was decreased and becomes all nines (in which */
+/*      case Underflow could occur, and is also handled directly).    */
+/*                                                                    */
+/* All fields in dn are updated as required.                          */
+/*                                                                    */
+/* ------------------------------------------------------------------ */
+static void decApplyRound(decNumber * dn, decContext * set, Int residue,
+                         uInt * status)
+{
+       Int bump;               // 1 if coefficient needs to be incremented
+       // -1 if coefficient needs to be decremented
+
+       if (residue == 0)
+               return;         // nothing to apply
+
+       bump = 0;               // assume a smooth ride
+
+       // now decide whether, and how, to round, depending on mode
+       switch (set->round) {
+       case DEC_ROUND_05UP:{   // round zero or five up (for reround)
+                       // This is the same as DEC_ROUND_DOWN unless there is a
+                       // positive residue and the lsd of dn is 0 or 5, in which case
+                       // it is bumped; when residue is <0, the number is therefore
+                       // bumped down unless the final digit was 1 or 6 (in which
+                       // case it is bumped down and then up -- a no-op)
+                       Int lsd5 = *dn->lsu % 5;        // get lsd and quintate
+                       if (residue < 0 && lsd5 != 1)
+                               bump = -1;
+                       else if (residue > 0 && lsd5 == 0)
+                               bump = 1;
+                       // [bump==1 could be applied directly; use common path for clarity]
+                       break;
+               }               // r-05
+
+       case DEC_ROUND_DOWN:{
+                       // no change, except if negative residue
+                       if (residue < 0)
+                               bump = -1;
+                       break;
+               }               // r-d
+
+       case DEC_ROUND_HALF_DOWN:{
+                       if (residue > 5)
+                               bump = 1;
+                       break;
+               }               // r-h-d
+
+       case DEC_ROUND_HALF_EVEN:{
+                       if (residue > 5)
+                               bump = 1;       // >0.5 goes up
+                       else if (residue == 5) {        // exactly 0.5000...
+                               // 0.5 goes up iff [new] lsd is odd
+                               if (*dn->lsu & 0x01)
+                                       bump = 1;
+                       }
+                       break;
+               }               // r-h-e
+
+       case DEC_ROUND_HALF_UP:{
+                       if (residue >= 5)
+                               bump = 1;
+                       break;
+               }               // r-h-u
+
+       case DEC_ROUND_UP:{
+                       if (residue > 0)
+                               bump = 1;
+                       break;
+               }               // r-u
+
+       case DEC_ROUND_CEILING:{
+                       // same as _UP for positive numbers, and as _DOWN for negatives
+                       // [negative residue cannot occur on 0]
+                       if (decNumberIsNegative(dn)) {
+                               if (residue < 0)
+                                       bump = -1;
+                       } else {
+                               if (residue > 0)
+                                       bump = 1;
+                       }
+                       break;
+               }               // r-c
+
+       case DEC_ROUND_FLOOR:{
+                       // same as _UP for negative numbers, and as _DOWN for positive
+                       // [negative residue cannot occur on 0]
+                       if (!decNumberIsNegative(dn)) {
+                               if (residue < 0)
+                                       bump = -1;
+                       } else {
+                               if (residue > 0)
+                                       bump = 1;
+                       }
+                       break;
+               }               // r-f
+
+       default:{               // e.g., DEC_ROUND_MAX
+                       *status |= DEC_Invalid_context;
+#if DECTRACE || (DECCHECK && DECVERB)
+                       printf("Unknown rounding mode: %d\n", set->round);
+#endif
+                       break;
+               }
+       }                       // switch
+
+       // now bump the number, up or down, if need be
+       if (bump == 0)
+               return;         // no action required
+
+       // Simply use decUnitAddSub unless bumping up and the number is
+       // all nines.  In this special case set to 100... explicitly
+       // and adjust the exponent by one (as otherwise could overflow
+       // the array)
+       // Similarly handle all-nines result if bumping down.
+       if (bump > 0) {
+               Unit *up;       // work
+               uInt count = dn->digits;        // digits to be checked
+               for (up = dn->lsu;; up++) {
+                       if (count <= DECDPUN) {
+                               // this is the last Unit (the msu)
+                               if (*up != powers[count] - 1)
+                                       break;  // not still 9s
+                               // here if it, too, is all nines
+                               *up = (Unit) powers[count - 1]; // here 999 -> 100 etc.
+                               for (up = up - 1; up >= dn->lsu; up--)
+                                       *up = 0;        // others all to 0
+                               dn->exponent++; // and bump exponent
+                               // [which, very rarely, could cause Overflow...]
+                               if ((dn->exponent + dn->digits) > set->emax + 1) {
+                                       decSetOverflow(dn, set, status);
+                               }
+                               return; // done
+                       }
+                       // a full unit to check, with more to come
+                       if (*up != DECDPUNMAX)
+                               break;  // not still 9s
+                       count -= DECDPUN;
+               }               // up
+       }                       // bump>0
+       else {                  // -1
+               // here checking for a pre-bump of 1000... (leading 1, all
+               // other digits zero)
+               Unit *up, *sup; // work
+               uInt count = dn->digits;        // digits to be checked
+               for (up = dn->lsu;; up++) {
+                       if (count <= DECDPUN) {
+                               // this is the last Unit (the msu)
+                               if (*up != powers[count - 1])
+                                       break;  // not 100..
+                               // here if have the 1000... case
+                               sup = up;       // save msu pointer
+                               *up = (Unit) powers[count] - 1; // here 100 in msu -> 999
+                               // others all to all-nines, too
+                               for (up = up - 1; up >= dn->lsu; up--)
+                                       *up = (Unit) powers[DECDPUN] - 1;
+                               dn->exponent--; // and bump exponent
+
+                               // iff the number was at the subnormal boundary (exponent=etiny)
+                               // then the exponent is now out of range, so it will in fact get
+                               // clamped to etiny and the final 9 dropped.
+                               // printf(">> emin=%d exp=%d sdig=%d\n", set->emin,
+                               //        dn->exponent, set->digits);
+                               if (dn->exponent + 1 ==
+                                   set->emin - set->digits + 1) {
+                                       if (count == 1 && dn->digits == 1)
+                                               *sup = 0;       // here 9 -> 0[.9]
+                                       else {
+                                               *sup = (Unit) powers[count - 1] - 1;    // here 999.. in msu -> 99..
+                                               dn->digits--;
+                                       }
+                                       dn->exponent++;
+                                       *status |=
+                                           DEC_Underflow | DEC_Subnormal |
+                                           DEC_Inexact | DEC_Rounded;
+                               }
+                               return; // done
+                       }
+                       // a full unit to check, with more to come
+                       if (*up != 0)
+                               break;  // not still 0s
+                       count -= DECDPUN;
+               }               // up
+
+       }                       // bump<0
+
+       // Actual bump needed.  Do it.
+       decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
+}                              // decApplyRound
+
+#if DECSUBSET
+/* ------------------------------------------------------------------ */
+/* decFinish -- finish processing a number                            */
+/*                                                                    */
+/*   dn is the number                                                 */
+/*   set is the context                                               */
+/*   residue is the rounding accumulator (as in decApplyRound)        */
+/*   status is the accumulator                                        */
+/*                                                                    */
+/* This finishes off the current number by:                           */
+/*    1. If not extended:                                             */
+/*       a. Converting a zero result to clean '0'                     */
+/*       b. Reducing positive exponents to 0, if would fit in digits  */
+/*    2. Checking for overflow and subnormals (always)                */
+/* Note this is just Finalize when no subset arithmetic.              */
+/* All fields are updated as required.                                */
+/* ------------------------------------------------------------------ */
+static void decFinish(decNumber * dn, decContext * set, Int * residue,
+                     uInt * status)
+{
+       if (!set->extended) {
+               if ISZERO
+                       (dn) {  // value is zero
+                       dn->exponent = 0;       // clean exponent ..
+                       dn->bits = 0;   // .. and sign
+                       return; // no error possible
+                       }
+               if (dn->exponent >= 0) {        // non-negative exponent
+                       // >0; reduce to integer if possible
+                       if (set->digits >= (dn->exponent + dn->digits)) {
+                               dn->digits =
+                                   decShiftToMost(dn->lsu, dn->digits,
+                                                  dn->exponent);
+                               dn->exponent = 0;
+                       }
+               }
+       }                       // !extended
+
+       decFinalize(dn, set, residue, status);
+}                              // decFinish
+#endif
+
+/* ------------------------------------------------------------------ */
+/* decFinalize -- final check, clamp, and round of a number           */
+/*                                                                    */
+/*   dn is the number                                                 */
+/*   set is the context                                               */
+/*   residue is the rounding accumulator (as in decApplyRound)        */
+/*   status is the status accumulator                                 */
+/*                                                                    */
+/* This finishes off the current number by checking for subnormal     */
+/* results, applying any pending rounding, checking for overflow,     */
+/* and applying any clamping.                                         */
+/* Underflow and overflow conditions are raised as appropriate.       */
+/* All fields are updated as required.                                */
+/* ------------------------------------------------------------------ */
+static void decFinalize(decNumber * dn, decContext * set, Int * residue,
+                       uInt * status)
+{
+       Int shift;              // shift needed if clamping
+       Int tinyexp = set->emin - dn->digits + 1;       // precalculate subnormal boundary
+
+       // Must be careful, here, when checking the exponent as the
+       // adjusted exponent could overflow 31 bits [because it may already
+       // be up to twice the expected].
+
+       // First test for subnormal.  This must be done before any final
+       // round as the result could be rounded to Nmin or 0.
+       if (dn->exponent <= tinyexp) {  // prefilter
+               Int comp;
+               decNumber nmin;
+               // A very nasty case here is dn == Nmin and residue<0
+               if (dn->exponent < tinyexp) {
+                       // Go handle subnormals; this will apply round if needed.
+                       decSetSubnormal(dn, set, residue, status);
+                       return;
+               }
+               // Equals case: only subnormal if dn=Nmin and negative residue
+               decNumberZero(&nmin);
+               nmin.lsu[0] = 1;
+               nmin.exponent = set->emin;
+               comp = decCompare(dn, &nmin, 1);        // (signless compare)
+               if (comp == BADINT) {   // oops
+                       *status |= DEC_Insufficient_storage;    // abandon...
+                       return;
+               }
+               if (*residue < 0 && comp == 0) {        // neg residue and dn==Nmin
+                       decApplyRound(dn, set, *residue, status);       // might force down
+                       decSetSubnormal(dn, set, residue, status);
+                       return;
+               }
+       }
+       // now apply any pending round (this could raise overflow).
+       if (*residue != 0)
+               decApplyRound(dn, set, *residue, status);
+
+       // Check for overflow [redundant in the 'rare' case] or clamp
+       if (dn->exponent <= set->emax - set->digits + 1)
+               return;         // neither needed
+
+       // here when might have an overflow or clamp to do
+       if (dn->exponent > set->emax - dn->digits + 1) {        // too big
+               decSetOverflow(dn, set, status);
+               return;
+       }
+       // here when the result is normal but in clamp range
+       if (!set->clamp)
+               return;
+
+       // here when need to apply the IEEE exponent clamp (fold-down)
+       shift = dn->exponent - (set->emax - set->digits + 1);
+
+       // shift coefficient (if non-zero)
+       if (!ISZERO(dn)) {
+               dn->digits = decShiftToMost(dn->lsu, dn->digits, shift);
+       }
+       dn->exponent -= shift;  // adjust the exponent to match
+       *status |= DEC_Clamped; // and record the dirty deed
+       return;
+}                              // decFinalize
+
+/* ------------------------------------------------------------------ */
+/* decSetOverflow -- set number to proper overflow value              */
+/*                                                                    */
+/*   dn is the number (used for sign [only] and result)               */
+/*   set is the context [used for the rounding mode, etc.]            */
+/*   status contains the current status to be updated                 */
+/*                                                                    */
+/* This sets the sign of a number and sets its value to either        */
+/* Infinity or the maximum finite value, depending on the sign of     */
+/* dn and the rounding mode, following IEEE 754 rules.                */
+/* ------------------------------------------------------------------ */
+static void decSetOverflow(decNumber * dn, decContext * set, uInt * status)
+{
+       Flag needmax = 0;       // result is maximum finite value
+       uByte sign = dn->bits & DECNEG; // clean and save sign bit
+
+       if (ISZERO(dn)) {       // zero does not overflow magnitude
+               Int emax = set->emax;   // limit value
+               if (set->clamp)
+                       emax -= set->digits - 1;        // lower if clamping
+               if (dn->exponent > emax) {      // clamp required
+                       dn->exponent = emax;
+                       *status |= DEC_Clamped;
+               }
+               return;
+       }
+
+       decNumberZero(dn);
+       switch (set->round) {
+       case DEC_ROUND_DOWN:{
+                       needmax = 1;    // never Infinity
+                       break;
+               }               // r-d
+       case DEC_ROUND_05UP:{
+                       needmax = 1;    // never Infinity
+                       break;
+               }               // r-05
+       case DEC_ROUND_CEILING:{
+                       if (sign)
+                               needmax = 1;    // Infinity if non-negative
+                       break;
+               }               // r-c
+       case DEC_ROUND_FLOOR:{
+                       if (!sign)
+                               needmax = 1;    // Infinity if negative
+                       break;
+               }               // r-f
+       default:
+               break;          // Infinity in all other cases
+       }
+       if (needmax) {
+               decSetMaxValue(dn, set);
+               dn->bits = sign;        // set sign
+       } else
+               dn->bits = sign | DECINF;       // Value is +/-Infinity
+       *status |= DEC_Overflow | DEC_Inexact | DEC_Rounded;
+}                              // decSetOverflow
+
+/* ------------------------------------------------------------------ */
+/* decSetMaxValue -- set number to +Nmax (maximum normal value)       */
+/*                                                                    */
+/*   dn is the number to set                                          */
+/*   set is the context [used for digits and emax]                    */
+/*                                                                    */
+/* This sets the number to the maximum positive value.                */
+/* ------------------------------------------------------------------ */
+static void decSetMaxValue(decNumber * dn, decContext * set)
+{
+       Unit *up;               // work
+       Int count = set->digits;        // nines to add
+       dn->digits = count;
+       // fill in all nines to set maximum value
+       for (up = dn->lsu;; up++) {
+               if (count > DECDPUN)
+                       *up = DECDPUNMAX;       // unit full o'nines
+               else {          // this is the msu
+                       *up = (Unit) (powers[count] - 1);
+                       break;
+               }
+               count -= DECDPUN;       // filled those digits
+       }                       // up
+       dn->bits = 0;           // + sign
+       dn->exponent = set->emax - set->digits + 1;
+}                              // decSetMaxValue
+
+/* ------------------------------------------------------------------ */
+/* decSetSubnormal -- process value whose exponent is <Emin           */
+/*                                                                    */
+/*   dn is the number (used as input as well as output; it may have   */
+/*         an allowed subnormal value, which may need to be rounded)  */
+/*   set is the context [used for the rounding mode]                  */
+/*   residue is any pending residue                                   */
+/*   status contains the current status to be updated                 */
+/*                                                                    */
+/* If subset mode, set result to zero and set Underflow flags.        */
+/*                                                                    */
+/* Value may be zero with a low exponent; this does not set Subnormal */
+/* but the exponent will be clamped to Etiny.                         */
+/*                                                                    */
+/* Otherwise ensure exponent is not out of range, and round as        */
+/* necessary.  Underflow is set if the result is Inexact.             */
+/* ------------------------------------------------------------------ */
+static void decSetSubnormal(decNumber * dn, decContext * set, Int * residue,
+                           uInt * status)
+{
+       decContext workset;     // work
+       Int etiny, adjust;      // ..
+
+#if DECSUBSET
+       // simple set to zero and 'hard underflow' for subset
+       if (!set->extended) {
+               decNumberZero(dn);
+               // always full overflow
+               *status |=
+                   DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
+               return;
+       }
+#endif
+
+       // Full arithmetic -- allow subnormals, rounded to minimum exponent
+       // (Etiny) if needed
+       etiny = set->emin - (set->digits - 1);  // smallest allowed exponent
+
+       if ISZERO
+               (dn) {          // value is zero
+               // residue can never be non-zero here
+#if DECCHECK
+               if (*residue != 0) {
+                       printf("++ Subnormal 0 residue %ld\n", (LI) * residue);
+                       *status |= DEC_Invalid_operation;
+               }
+#endif
+               if (dn->exponent < etiny) {     // clamp required
+                       dn->exponent = etiny;
+                       *status |= DEC_Clamped;
+               }
+               return;
+               }
+
+       *status |= DEC_Subnormal;       // have a non-zero subnormal
+       adjust = etiny - dn->exponent;  // calculate digits to remove
+       if (adjust <= 0) {      // not out of range; unrounded
+               // residue can never be non-zero here, except in the Nmin-residue
+               // case (which is a subnormal result), so can take fast-path here
+               // it may already be inexact (from setting the coefficient)
+               if (*status & DEC_Inexact)
+                       *status |= DEC_Underflow;
+               return;
+       }
+       // adjust>0, so need to rescale the result so exponent becomes Etiny
+       // [this code is similar to that in rescale]
+       workset = *set;         // clone rounding, etc.
+       workset.digits = dn->digits - adjust;   // set requested length
+       workset.emin -= adjust; // and adjust emin to match
+       // [note that the latter can be <1, here, similar to Rescale case]
+       decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
+       decApplyRound(dn, &workset, *residue, status);
+
+       // Use 754 default rule: Underflow is set iff Inexact
+       // [independent of whether trapped]
+       if (*status & DEC_Inexact)
+               *status |= DEC_Underflow;
+
+       // if rounded up a 999s case, exponent will be off by one; adjust
+       // back if so [it will fit, because it was shortened earlier]
+       if (dn->exponent > etiny) {
+               dn->digits = decShiftToMost(dn->lsu, dn->digits, 1);
+               dn->exponent--; // (re)adjust the exponent.
+       }
+       // if rounded to zero, it is by definition clamped...
+       if (ISZERO(dn))
+               *status |= DEC_Clamped;
+}                              // decSetSubnormal
+
+/* ------------------------------------------------------------------ */
+/* decCheckMath - check entry conditions for a math function          */
+/*                                                                    */
+/*   This checks the context and the operand                          */
+/*                                                                    */
+/*   rhs is the operand to check                                      */
+/*   set is the context to check                                      */
+/*   status is unchanged if both are good                             */
+/*                                                                    */
+/* returns non-zero if status is changed, 0 otherwise                 */
+/*                                                                    */
+/* Restrictions enforced:                                             */
+/*                                                                    */
+/*   digits, emax, and -emin in the context must be less than         */
+/*   DEC_MAX_MATH (999999), and A must be within these bounds if      */
+/*   non-zero.  Invalid_operation is set in the status if a           */
+/*   restriction is violated.                                         */
+/* ------------------------------------------------------------------ */
+static uInt decCheckMath(const decNumber * rhs, decContext * set, uInt * status)
+{
+       uInt save = *status;    // record
+       if (set->digits > DEC_MAX_MATH
+           || set->emax > DEC_MAX_MATH || -set->emin > DEC_MAX_MATH)
+               *status |= DEC_Invalid_context;
+       else if ((rhs->digits > DEC_MAX_MATH
+                 || rhs->exponent + rhs->digits > DEC_MAX_MATH + 1
+                 || rhs->exponent + rhs->digits < 2 * (1 - DEC_MAX_MATH))
+                && !ISZERO(rhs))
+               *status |= DEC_Invalid_operation;
+       return (*status != save);
+}                              // decCheckMath
+
+/* ------------------------------------------------------------------ */
+/* decGetInt -- get integer from a number                             */
+/*                                                                    */
+/*   dn is the number [which will not be altered]                     */
+/*                                                                    */
+/*   returns one of:                                                  */
+/*     BADINT if there is a non-zero fraction                         */
+/*     the converted integer                                          */
+/*     BIGEVEN if the integer is even and magnitude > 2*10**9         */
+/*     BIGODD  if the integer is odd  and magnitude > 2*10**9         */
+/*                                                                    */
+/* This checks and gets a whole number from the input decNumber.      */
+/* The sign can be determined from dn by the caller when BIGEVEN or   */
+/* BIGODD is returned.                                                */
+/* ------------------------------------------------------------------ */
+static Int decGetInt(const decNumber * dn)
+{
+       Int theInt;             // result accumulator
+       const Unit *up;         // work
+       Int got;                // digits (real or not) processed
+       Int ilength = dn->digits + dn->exponent;        // integral length
+       Flag neg = decNumberIsNegative(dn);     // 1 if -ve
+
+       // The number must be an integer that fits in 10 digits
+       // Assert, here, that 10 is enough for any rescale Etiny
+#if DEC_MAX_EMAX > 999999999
+#error GetInt may need updating [for Emax]
+#endif
+#if DEC_MIN_EMIN < -999999999
+#error GetInt may need updating [for Emin]
+#endif
+       if (ISZERO(dn))
+               return 0;       // zeros are OK, with any exponent
+
+       up = dn->lsu;           // ready for lsu
+       theInt = 0;             // ready to accumulate
+       if (dn->exponent >= 0) {        // relatively easy
+               // no fractional part [usual]; allow for positive exponent
+               got = dn->exponent;
+       } else {                // -ve exponent; some fractional part to check and discard
+               Int count = -dn->exponent;      // digits to discard
+               // spin up whole units until reach the Unit with the unit digit
+               for (; count >= DECDPUN; up++) {
+                       if (*up != 0)
+                               return BADINT;  // non-zero Unit to discard
+                       count -= DECDPUN;
+               }
+               if (count == 0)
+                       got = 0;        // [a multiple of DECDPUN]
+               else {          // [not multiple of DECDPUN]
+                       Int rem;        // work
+                       // slice off fraction digits and check for non-zero
+#if DECDPUN<=4
+                       theInt = QUOT10(*up, count);
+                       rem = *up - theInt * powers[count];
+#else
+                       rem = *up % powers[count];      // slice off discards
+                       theInt = *up / powers[count];
+#endif
+                       if (rem != 0)
+                               return BADINT;  // non-zero fraction
+                       // it looks good
+                       got = DECDPUN - count;  // number of digits so far
+                       up++;   // ready for next
+               }
+       }
+       // now it's known there's no fractional part
+
+       // tricky code now, to accumulate up to 9.3 digits
+       if (got == 0) {
+               theInt = *up;
+               got += DECDPUN;
+               up++;
+       }                       // ensure lsu is there
+
+       if (ilength < 11) {
+               Int save = theInt;
+               // collect any remaining unit(s)
+               for (; got < ilength; up++) {
+                       theInt += *up * powers[got];
+                       got += DECDPUN;
+               }
+               if (ilength == 10) {    // need to check for wrap
+                       if (theInt / (Int) powers[got - DECDPUN] !=
+                           (Int) * (up - 1))
+                               ilength = 11;
+                       // [that test also disallows the BADINT result case]
+                       else if (neg && theInt > 1999999997)
+                               ilength = 11;
+                       else if (!neg && theInt > 999999999)
+                               ilength = 11;
+                       if (ilength == 11)
+                               theInt = save;  // restore correct low bit
+               }
+       }
+
+       if (ilength > 10) {     // too big
+               if (theInt & 1)
+                       return BIGODD;  // bottom bit 1
+               return BIGEVEN; // bottom bit 0
+       }
+
+       if (neg)
+               theInt = -theInt;       // apply sign
+       return theInt;
+}                              // decGetInt
+
+/* ------------------------------------------------------------------ */
+/* decDecap -- decapitate the coefficient of a number                 */
+/*                                                                    */
+/*   dn   is the number to be decapitated                             */
+/*   drop is the number of digits to be removed from the left of dn;  */
+/*     this must be <= dn->digits (if equal, the coefficient is       */
+/*     set to 0)                                                      */
+/*                                                                    */
+/* Returns dn; dn->digits will be <= the initial digits less drop     */
+/* (after removing drop digits there may be leading zero digits       */
+/* which will also be removed).  Only dn->lsu and dn->digits change.  */
+/* ------------------------------------------------------------------ */
+static decNumber *decDecap(decNumber * dn, Int drop)
+{
+       Unit *msu;              // -> target cut point
+       Int cut;                // work
+       if (drop >= dn->digits) {       // losing the whole thing
+#if DECCHECK
+               if (drop > dn->digits)
+                       printf("decDecap called with drop>digits [%ld>%ld]\n",
+                              (LI) drop, (LI) dn->digits);
+#endif
+               dn->lsu[0] = 0;
+               dn->digits = 1;
+               return dn;
+       }
+       msu = dn->lsu + D2U(dn->digits - drop) - 1;     // -> likely msu
+       cut = MSUDIGITS(dn->digits - drop);     // digits to be in use in msu
+       if (cut != DECDPUN)
+               *msu %= powers[cut];    // clear left digits
+       // that may have left leading zero digits, so do a proper count...
+       dn->digits = decGetDigits(dn->lsu, msu - dn->lsu + 1);
+       return dn;
+}                              // decDecap
+
+/* ------------------------------------------------------------------ */
+/* decBiStr -- compare string with pairwise options                   */
+/*                                                                    */
+/*   targ is the string to compare                                    */
+/*   str1 is one of the strings to compare against (length may be 0)  */
+/*   str2 is the other; it must be the same length as str1            */
+/*                                                                    */
+/*   returns 1 if strings compare equal, (that is, it is the same     */
+/*   length as str1 and str2, and each character of targ is in either */
+/*   str1 or str2 in the corresponding position), or 0 otherwise      */
+/*                                                                    */
+/* This is used for generic caseless compare, including the awkward   */
+/* case of the Turkish dotted and dotless Is.  Use as (for example):  */
+/*   if (decBiStr(test, "mike", "MIKE")) ...                          */
+/* ------------------------------------------------------------------ */
+static Flag decBiStr(const char *targ, const char *str1, const char *str2)
+{
+       for (;; targ++, str1++, str2++) {
+               if (*targ != *str1 && *targ != *str2)
+                       return 0;
+               // *targ has a match in one (or both, if terminator)
+               if (*targ == '\0')
+                       break;
+       }                       // forever
+       return 1;
+}                              // decBiStr
+
+/* ------------------------------------------------------------------ */
+/* decNaNs -- handle NaN operand or operands                          */
+/*                                                                    */
+/*   res     is the result number                                     */
+/*   lhs     is the first operand                                     */
+/*   rhs     is the second operand, or NULL if none                   */
+/*   context is used to limit payload length                          */
+/*   status  contains the current status                              */
+/*   returns res in case convenient                                   */
+/*                                                                    */
+/* Called when one or both operands is a NaN, and propagates the      */
+/* appropriate result to res.  When an sNaN is found, it is changed   */
+/* to a qNaN and Invalid operation is set.                            */
+/* ------------------------------------------------------------------ */
+static decNumber *decNaNs(decNumber * res, const decNumber * lhs,
+                         const decNumber * rhs, decContext * set,
+                         uInt * status)
+{
+       // This decision tree ends up with LHS being the source pointer,
+       // and status updated if need be
+       if (lhs->bits & DECSNAN)
+               *status |= DEC_Invalid_operation | DEC_sNaN;
+       else if (rhs == NULL) ;
+       else if (rhs->bits & DECSNAN) {
+               lhs = rhs;
+               *status |= DEC_Invalid_operation | DEC_sNaN;
+       } else if (lhs->bits & DECNAN) ;
+       else
+               lhs = rhs;
+
+       // propagate the payload
+       if (lhs->digits <= set->digits)
+               decNumberCopy(res, lhs);        // easy
+       else {                  // too long
+               const Unit *ul;
+               Unit *ur, *uresp1;
+               // copy safe number of units, then decapitate
+               res->bits = lhs->bits;  // need sign etc.
+               uresp1 = res->lsu + D2U(set->digits);
+               for (ur = res->lsu, ul = lhs->lsu; ur < uresp1; ur++, ul++)
+                       *ur = *ul;
+               res->digits = D2U(set->digits) * DECDPUN;
+               // maybe still too long
+               if (res->digits > set->digits)
+                       decDecap(res, res->digits - set->digits);
+       }
+
+       res->bits &= ~DECSNAN;  // convert any sNaN to NaN, while
+       res->bits |= DECNAN;    // .. preserving sign
+       res->exponent = 0;      // clean exponent
+       // [coefficient was copied/decapitated]
+       return res;
+}                              // decNaNs
+
+/* ------------------------------------------------------------------ */
+/* decStatus -- apply non-zero status                                 */
+/*                                                                    */
+/*   dn     is the number to set if error                             */
+/*   status contains the current status (not yet in context)          */
+/*   set    is the context                                            */
+/*                                                                    */
+/* If the status is an error status, the number is set to a NaN,      */
+/* unless the error was an overflow, divide-by-zero, or underflow,    */
+/* in which case the number will have already been set.               */
+/*                                                                    */
+/* The context status is then updated with the new status.  Note that */
+/* this may raise a signal, so control may never return from this     */
+/* routine (hence resources must be recovered before it is called).   */
+/* ------------------------------------------------------------------ */
+static void decStatus(decNumber * dn, uInt status, decContext * set)
+{
+       if (status & DEC_NaNs) {        // error status -> NaN
+               // if cause was an sNaN, clear and propagate [NaN is already set up]
+               if (status & DEC_sNaN)
+                       status &= ~DEC_sNaN;
+               else {
+                       decNumberZero(dn);      // other error: clean throughout
+                       dn->bits = DECNAN;      // and make a quiet NaN
+               }
+       }
+       decContextSetStatus(set, status);       // [may not return]
+       return;
+}                              // decStatus
+
+/* ------------------------------------------------------------------ */
+/* decGetDigits -- count digits in a Units array                      */
+/*                                                                    */
+/*   uar is the Unit array holding the number (this is often an       */
+/*          accumulator of some sort)                                 */
+/*   len is the length of the array in units [>=1]                    */
+/*                                                                    */
+/*   returns the number of (significant) digits in the array          */
+/*                                                                    */
+/* All leading zeros are excluded, except the last if the array has   */
+/* only zero Units.                                                   */
+/* ------------------------------------------------------------------ */
+// This may be called twice during some operations.
+static Int decGetDigits(Unit * uar, Int len)
+{
+       Unit *up = uar + (len - 1);     // -> msu
+       Int digits = (len - 1) * DECDPUN + 1;   // possible digits excluding msu
+#if DECDPUN>4
+       uInt const *pow;        // work
+#endif
+       // (at least 1 in final msu)
+#if DECCHECK
+       if (len < 1)
+               printf("decGetDigits called with len<1 [%ld]\n", (LI) len);
+#endif
+
+       for (; up >= uar; up--) {
+               if (*up == 0) { // unit is all 0s
+                       if (digits == 1)
+                               break;  // a zero has one digit
+                       digits -= DECDPUN;      // adjust for 0 unit
+                       continue;
+               }
+               // found the first (most significant) non-zero Unit
+#if DECDPUN>1                  // not done yet
+               if (*up < 10)
+                       break;  // is 1-9
+               digits++;
+#if DECDPUN>2                  // not done yet
+               if (*up < 100)
+                       break;  // is 10-99
+               digits++;
+#if DECDPUN>3                  // not done yet
+               if (*up < 1000)
+                       break;  // is 100-999
+               digits++;
+#if DECDPUN>4                  // count the rest ...
+               for (pow = &powers[4]; *up >= *pow; pow++)
+                       digits++;
+#endif
+#endif
+#endif
+#endif
+               break;
+       }                       // up
+       return digits;
+}                              // decGetDigits
+
+#if DECTRACE | DECCHECK
+/* ------------------------------------------------------------------ */
+/* decNumberShow -- display a number [debug aid]                      */
+/*   dn is the number to show                                         */
+/*                                                                    */
+/* Shows: sign, exponent, coefficient (msu first), digits             */
+/*    or: sign, special-value                                         */
+/* ------------------------------------------------------------------ */
+// this is public so other modules can use it
+void decNumberShow(const decNumber * dn)
+{
+       const Unit *up;         // work
+       uInt u, d;              // ..
+       Int cut;                // ..
+       char isign = '+';       // main sign
+       if (dn == NULL) {
+               printf("NULL\n");
+               return;
+       }
+       if (decNumberIsNegative(dn))
+               isign = '-';
+       printf(" >> %c ", isign);
+       if (dn->bits & DECSPECIAL) {    // Is a special value
+               if (decNumberIsInfinite(dn))
+                       printf("Infinity");
+               else {          // a NaN
+                       if (dn->bits & DECSNAN)
+                               printf("sNaN"); // signalling NaN
+                       else
+                               printf("NaN");
+               }
+               // if coefficient and exponent are 0, no more to do
+               if (dn->exponent == 0 && dn->digits == 1 && *dn->lsu == 0) {
+                       printf("\n");
+                       return;
+               }
+               // drop through to report other information
+               printf(" ");
+       }
+       // now carefully display the coefficient
+       up = dn->lsu + D2U(dn->digits) - 1;     // msu
+       printf("%ld", (LI) * up);
+       for (up = up - 1; up >= dn->lsu; up--) {
+               u = *up;
+               printf(":");
+               for (cut = DECDPUN - 1; cut >= 0; cut--) {
+                       d = u / powers[cut];
+                       u -= d * powers[cut];
+                       printf("%ld", (LI) d);
+               }               // cut
+       }                       // up
+       if (dn->exponent != 0) {
+               char esign = '+';
+               if (dn->exponent < 0)
+                       esign = '-';
+               printf(" E%c%ld", esign, (LI) abs(dn->exponent));
+       }
+       printf(" [%ld]\n", (LI) dn->digits);
+}                              // decNumberShow
+#endif
+
+#if DECTRACE || DECCHECK
+/* ------------------------------------------------------------------ */
+/* decDumpAr -- display a unit array [debug/check aid]                */
+/*   name is a single-character tag name                              */
+/*   ar   is the array to display                                     */
+/*   len  is the length of the array in Units                         */
+/* ------------------------------------------------------------------ */
+static void decDumpAr(char name, const Unit * ar, Int len)
+{
+       Int i;
+       const char *spec;
+#if DECDPUN==9
+       spec = "%09d ";
+#elif DECDPUN==8
+       spec = "%08d ";
+#elif DECDPUN==7
+       spec = "%07d ";
+#elif DECDPUN==6
+       spec = "%06d ";
+#elif DECDPUN==5
+       spec = "%05d ";
+#elif DECDPUN==4
+       spec = "%04d ";
+#elif DECDPUN==3
+       spec = "%03d ";
+#elif DECDPUN==2
+       spec = "%02d ";
+#else
+       spec = "%d ";
+#endif
+       printf("  :%c: ", name);
+       for (i = len - 1; i >= 0; i--) {
+               if (i == len - 1)
+                       printf("%ld ", (LI) ar[i]);
+               else
+                       printf(spec, ar[i]);
+       }
+       printf("\n");
+       return;
+}
+#endif
+
+#if DECCHECK
+/* ------------------------------------------------------------------ */
+/* decCheckOperands -- check operand(s) to a routine                  */
+/*   res is the result structure (not checked; it will be set to      */
+/*          quiet NaN if error found (and it is not NULL))            */
+/*   lhs is the first operand (may be DECUNRESU)                      */
+/*   rhs is the second (may be DECUNUSED)                             */
+/*   set is the context (may be DECUNCONT)                            */
+/*   returns 0 if both operands, and the context are clean, or 1      */
+/*     otherwise (in which case the context will show an error,       */
+/*     unless NULL).  Note that res is not cleaned; caller should     */
+/*     handle this so res=NULL case is safe.                          */
+/* The caller is expected to abandon immediately if 1 is returned.    */
+/* ------------------------------------------------------------------ */
+static Flag decCheckOperands(decNumber * res, const decNumber * lhs,
+                            const decNumber * rhs, decContext * set)
+{
+       Flag bad = 0;
+       if (set == NULL) {      // oops; hopeless
+#if DECTRACE || DECVERB
+               printf("Reference to context is NULL.\n");
+#endif
+               bad = 1;
+               return 1;
+       } else if (set != DECUNCONT
+                  && (set->digits < 1 || set->round >= DEC_ROUND_MAX)) {
+               bad = 1;
+#if DECTRACE || DECVERB
+               printf("Bad context [digits=%ld round=%ld].\n",
+                      (LI) set->digits, (LI) set->round);
+#endif
+       } else {
+               if (res == NULL) {
+                       bad = 1;
+#if DECTRACE
+                       // this one not DECVERB as standard tests include NULL
+                       printf("Reference to result is NULL.\n");
+#endif
+               }
+               if (!bad && lhs != DECUNUSED)
+                       bad = (decCheckNumber(lhs));
+               if (!bad && rhs != DECUNUSED)
+                       bad = (decCheckNumber(rhs));
+       }
+       if (bad) {
+               if (set != DECUNCONT)
+                       decContextSetStatus(set, DEC_Invalid_operation);
+               if (res != DECUNRESU && res != NULL) {
+                       decNumberZero(res);
+                       res->bits = DECNAN;     // qNaN
+               }
+       }
+       return bad;
+}                              // decCheckOperands
+
+/* ------------------------------------------------------------------ */
+/* decCheckNumber -- check a number                                   */
+/*   dn is the number to check                                        */
+/*   returns 0 if the number is clean, or 1 otherwise                 */
+/*                                                                    */
+/* The number is considered valid if it could be a result from some   */
+/* operation in some valid context.                                   */
+/* ------------------------------------------------------------------ */
+static Flag decCheckNumber(const decNumber * dn)
+{
+       const Unit *up;         // work
+       uInt maxuint;           // ..
+       Int ae, d, digits;      // ..
+       Int emin, emax;         // ..
+
+       if (dn == NULL) {       // hopeless
+#if DECTRACE
+               // this one not DECVERB as standard tests include NULL
+               printf("Reference to decNumber is NULL.\n");
+#endif
+               return 1;
+       }
+       // check special values
+       if (dn->bits & DECSPECIAL) {
+               if (dn->exponent != 0) {
+#if DECTRACE || DECVERB
+                       printf
+                           ("Exponent %ld (not 0) for a special value [%02x].\n",
+                            (LI) dn->exponent, dn->bits);
+#endif
+                       return 1;
+               }
+               // 2003.09.08: NaNs may now have coefficients, so next tests Inf only
+               if (decNumberIsInfinite(dn)) {
+                       if (dn->digits != 1) {
+#if DECTRACE || DECVERB
+                               printf("Digits %ld (not 1) for an infinity.\n",
+                                      (LI) dn->digits);
+#endif
+                               return 1;
+                       }
+                       if (*dn->lsu != 0) {
+#if DECTRACE || DECVERB
+                               printf("LSU %ld (not 0) for an infinity.\n",
+                                      (LI) * dn->lsu);
+#endif
+                               decDumpAr('I', dn->lsu, D2U(dn->digits));
+                               return 1;
+                       }
+               }               // Inf
+               // 2002.12.26: negative NaNs can now appear through proposed IEEE
+               //             concrete formats (decimal64, etc.).
+               return 0;
+       }
+       // check the coefficient
+       if (dn->digits < 1 || dn->digits > DECNUMMAXP) {
+#if DECTRACE || DECVERB
+               printf("Digits %ld in number.\n", (LI) dn->digits);
+#endif
+               return 1;
+       }
+
+       d = dn->digits;
+
+       for (up = dn->lsu; d > 0; up++) {
+               if (d > DECDPUN)
+                       maxuint = DECDPUNMAX;
+               else {          // reached the msu
+                       maxuint = powers[d] - 1;
+                       if (dn->digits > 1 && *up < powers[d - 1]) {
+#if DECTRACE || DECVERB
+                               printf("Leading 0 in number.\n");
+                               decNumberShow(dn);
+#endif
+                               return 1;
+                       }
+               }
+               if (*up > maxuint) {
+#if DECTRACE || DECVERB
+                       printf
+                           ("Bad Unit [%08lx] in %ld-digit number at offset %ld [maxuint %ld].\n",
+                            (LI) * up, (LI) dn->digits, (LI) (up - dn->lsu),
+                            (LI) maxuint);
+#endif
+                       return 1;
+               }
+               d -= DECDPUN;
+       }
+
+       // check the exponent.  Note that input operands can have exponents
+       // which are out of the set->emin/set->emax and set->digits range
+       // (just as they can have more digits than set->digits).
+       ae = dn->exponent + dn->digits - 1;     // adjusted exponent
+       emax = DECNUMMAXE;
+       emin = DECNUMMINE;
+       digits = DECNUMMAXP;
+       if (ae < emin - (digits - 1)) {
+#if DECTRACE || DECVERB
+               printf("Adjusted exponent underflow [%ld].\n", (LI) ae);
+               decNumberShow(dn);
+#endif
+               return 1;
+       }
+       if (ae > +emax) {
+#if DECTRACE || DECVERB
+               printf("Adjusted exponent overflow [%ld].\n", (LI) ae);
+               decNumberShow(dn);
+#endif
+               return 1;
+       }
+
+       return 0;               // it's OK
+}                              // decCheckNumber
+
+/* ------------------------------------------------------------------ */
+/* decCheckInexact -- check a normal finite inexact result has digits */
+/*   dn is the number to check                                        */
+/*   set is the context (for status and precision)                    */
+/*   sets Invalid operation, etc., if some digits are missing         */
+/* [this check is not made for DECSUBSET compilation or when          */
+/* subnormal is not set]                                              */
+/* ------------------------------------------------------------------ */
+static void decCheckInexact(const decNumber * dn, decContext * set)
+{
+#if !DECSUBSET && DECEXTFLAG
+       if ((set->status & (DEC_Inexact | DEC_Subnormal)) == DEC_Inexact
+           && (set->digits != dn->digits) && !(dn->bits & DECSPECIAL)) {
+#if DECTRACE || DECVERB
+               printf("Insufficient digits [%ld] on normal Inexact result.\n",
+                      (LI) dn->digits);
+               decNumberShow(dn);
+#endif
+               decContextSetStatus(set, DEC_Invalid_operation);
+       }
+#else
+       // next is a noop for quiet compiler
+       if (dn != NULL && dn->digits == 0)
+               set->status |= DEC_Invalid_operation;
+#endif
+       return;
+}                              // decCheckInexact
+#endif
+
+#if DECALLOC
+#undef malloc
+#undef free
+/* ------------------------------------------------------------------ */
+/* decMalloc -- accountable allocation routine                        */
+/*   n is the number of bytes to allocate                             */
+/*                                                                    */
+/* Semantics is the same as the stdlib malloc routine, but bytes      */
+/* allocated are accounted for globally, and corruption fences are    */
+/* added before and after the 'actual' storage.                       */
+/* ------------------------------------------------------------------ */
+/* This routine allocates storage with an extra twelve bytes; 8 are   */
+/* at the start and hold:                                             */
+/*   0-3 the original length requested                                */
+/*   4-7 buffer corruption detection fence (DECFENCE, x4)             */
+/* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */
+/* ------------------------------------------------------------------ */
+static void *decMalloc(size_t n)
+{
+       uInt size = n + 12;     // true size
+       void *alloc;            // -> allocated storage
+       uByte *b, *b0;          // work
+       uInt uiwork;            // for macros
+
+       alloc = malloc(size);   // -> allocated storage
+       if (alloc == NULL)
+               return NULL;    // out of strorage
+       b0 = (uByte *) alloc;   // as bytes
+       decAllocBytes += n;     // account for storage
+       UBFROMUI(alloc, n);     // save n
+       // printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n);
+       for (b = b0 + 4; b < b0 + 8; b++)
+               *b = DECFENCE;
+       for (b = b0 + n + 8; b < b0 + n + 12; b++)
+               *b = DECFENCE;
+       return b0 + 8;          // -> play area
+}                              // decMalloc
+
+/* ------------------------------------------------------------------ */
+/* decFree -- accountable free routine                                */
+/*   alloc is the storage to free                                     */
+/*                                                                    */
+/* Semantics is the same as the stdlib malloc routine, except that    */
+/* the global storage accounting is updated and the fences are        */
+/* checked to ensure that no routine has written 'out of bounds'.     */
+/* ------------------------------------------------------------------ */
+/* This routine first checks that the fences have not been corrupted. */
+/* It then frees the storage using the 'truw' storage address (that   */
+/* is, offset by 8).                                                  */
+/* ------------------------------------------------------------------ */
+static void decFree(void *alloc)
+{
+       uInt n;                 // original length
+       uByte *b, *b0;          // work
+       uInt uiwork;            // for macros
+
+       if (alloc == NULL)
+               return;         // allowed; it's a nop
+       b0 = (uByte *) alloc;   // as bytes
+       b0 -= 8;                // -> true start of storage
+       n = UBTOUI(b0);         // lift length
+       for (b = b0 + 4; b < b0 + 8; b++)
+               if (*b != DECFENCE)
+                       printf
+                           ("=== Corrupt byte [%02x] at offset %d from %ld ===\n",
+                            *b, b - b0 - 8, (LI) b0);
+       for (b = b0 + n + 8; b < b0 + n + 12; b++)
+               if (*b != DECFENCE)
+                       printf
+                           ("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n",
+                            *b, b - b0 - 8, (LI) b0, (LI) n);
+       free(b0);               // drop the storage
+       decAllocBytes -= n;     // account for storage
+       // printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n);
+}                              // decFree
+
+#define malloc(a) decMalloc(a)
+#define free(a) decFree(a)
+#endif
diff --git a/theme/src/decnumber/decNumber.h b/theme/src/decnumber/decNumber.h
new file mode 100644 (file)
index 0000000..cf0975d
--- /dev/null
@@ -0,0 +1,210 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Number arithmetic module header                            */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2010.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+
+#if !defined(DECNUMBER)
+#define DECNUMBER
+#define DECNAME     "decNumber"        /* Short name */
+#define DECFULLNAME "Decimal Number Module"    /* Verbose name */
+#define DECAUTHOR   "Mike Cowlishaw"   /* Who to blame */
+
+#if !defined(DECCONTEXT)
+#include "decContext.h"
+#endif
+
+  /* Bit settings for decNumber.bits                                  */
+#define DECNEG    0x80         /* Sign; 1=negative, 0=positive or zero */
+#define DECINF    0x40         /* 1=Infinity                           */
+#define DECNAN    0x20         /* 1=NaN                                */
+#define DECSNAN   0x10         /* 1=sNaN                               */
+  /* The remaining bits are reserved; they must be 0                  */
+#define DECSPECIAL (DECINF|DECNAN|DECSNAN)     /* any special value     */
+
+  /* Define the decNumber data structure.  The size and shape of the  */
+  /* units array in the structure is determined by the following      */
+  /* constant.  This must not be changed without recompiling the      */
+  /* decNumber library modules. */
+
+#define DECDPUN 3              /* DECimal Digits Per UNit [must be >0  */
+                             /* and <10; 3 or powers of 2 are best]. */
+
+  /* DECNUMDIGITS is the default number of digits that can be held in */
+  /* the structure.  If undefined, 1 is assumed and it is assumed     */
+  /* that the structure will be immediately followed by extra space,  */
+  /* as required.  DECNUMDIGITS is always >0.                         */
+#if !defined(DECNUMDIGITS)
+#define DECNUMDIGITS 1
+#endif
+
+  /* The size (integer data type) of each unit is determined by the   */
+  /* number of digits it will hold.                                   */
+#if   DECDPUN<=2
+#define decNumberUnit uint8_t
+#elif DECDPUN<=4
+#define decNumberUnit uint16_t
+#else
+#define decNumberUnit uint32_t
+#endif
+  /* The number of units needed is ceil(DECNUMDIGITS/DECDPUN)         */
+#define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)
+
+  /* The data structure... */
+typedef struct {
+       int32_t digits;         /* Count of digits in the coefficient; >0    */
+       int32_t exponent;       /* Unadjusted exponent, unbiased, in         */
+       /* range: -1999999997 through 999999999      */
+       uint8_t bits;           /* Indicator bits (see above)                */
+       /* Coefficient, from least significant unit  */
+       decNumberUnit lsu[DECNUMUNITS];
+} decNumber;
+
+  /* Notes:                                                           */
+  /* 1. If digits is > DECDPUN then there will one or more            */
+  /*    decNumberUnits immediately following the first element of lsu. */
+  /*    These contain the remaining (more significant) digits of the  */
+  /*    number, and may be in the lsu array, or may be guaranteed by  */
+  /*    some other mechanism (such as being contained in another      */
+  /*    structure, or being overlaid on dynamically allocated         */
+  /*    storage).                                                     */
+  /*                                                                  */
+  /*    Each integer of the coefficient (except potentially the last) */
+  /*    contains DECDPUN digits (e.g., a value in the range 0 through */
+  /*    99999999 if DECDPUN is 8, or 0 through 999 if DECDPUN is 3).  */
+  /*                                                                  */
+  /* 2. A decNumber converted to a string may need up to digits+14    */
+  /*    characters.  The worst cases (non-exponential and exponential */
+  /*    formats) are -0.00000{9...}# and -9.{9...}E+999999999#        */
+  /*    (where # is '\0')                                             */
+
+  /* ---------------------------------------------------------------- */
+  /* decNumber public functions and macros                            */
+  /* ---------------------------------------------------------------- */
+  /* Conversions                                                      */
+decNumber *decNumberFromInt32(decNumber *, int32_t);
+decNumber *decNumberFromUInt32(decNumber *, uint32_t);
+decNumber *decNumberFromString(decNumber *, const char *, decContext *);
+char *decNumberToString(const decNumber *, char *);
+char *decNumberToEngString(const decNumber *, char *);
+uint32_t decNumberToUInt32(const decNumber *, decContext *);
+int32_t decNumberToInt32(const decNumber *, decContext *);
+uint8_t *decNumberGetBCD(const decNumber *, uint8_t *);
+decNumber *decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
+
+  /* Operators and elementary functions                               */
+decNumber *decNumberAbs(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberAdd(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+decNumber *decNumberAnd(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+decNumber *decNumberCompare(decNumber *, const decNumber *, const decNumber *,
+                           decContext *);
+decNumber *decNumberCompareSignal(decNumber *, const decNumber *,
+                                 const decNumber *, decContext *);
+decNumber *decNumberCompareTotal(decNumber *, const decNumber *,
+                                const decNumber *, decContext *);
+decNumber *decNumberCompareTotalMag(decNumber *, const decNumber *,
+                                   const decNumber *, decContext *);
+decNumber *decNumberDivide(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberDivideInteger(decNumber *, const decNumber *,
+                                 const decNumber *, decContext *);
+decNumber *decNumberExp(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberFMA(decNumber *, const decNumber *, const decNumber *,
+                       const decNumber *, decContext *);
+decNumber *decNumberInvert(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberLn(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberLogB(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberLog10(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberMax(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+decNumber *decNumberMaxMag(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberMin(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+decNumber *decNumberMinMag(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberMinus(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberMultiply(decNumber *, const decNumber *, const decNumber *,
+                            decContext *);
+decNumber *decNumberNormalize(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberOr(decNumber *, const decNumber *, const decNumber *,
+                      decContext *);
+decNumber *decNumberPlus(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberPower(decNumber *, const decNumber *, const decNumber *,
+                         decContext *);
+decNumber *decNumberQuantize(decNumber *, const decNumber *, const decNumber *,
+                            decContext *);
+decNumber *decNumberReduce(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberRemainder(decNumber *, const decNumber *, const decNumber *,
+                             decContext *);
+decNumber *decNumberRemainderNear(decNumber *, const decNumber *,
+                                 const decNumber *, decContext *);
+decNumber *decNumberRescale(decNumber *, const decNumber *, const decNumber *,
+                           decContext *);
+decNumber *decNumberRotate(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberSameQuantum(decNumber *, const decNumber *,
+                               const decNumber *);
+decNumber *decNumberScaleB(decNumber *, const decNumber *, const decNumber *,
+                          decContext *);
+decNumber *decNumberShift(decNumber *, const decNumber *, const decNumber *,
+                         decContext *);
+decNumber *decNumberSquareRoot(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberSubtract(decNumber *, const decNumber *, const decNumber *,
+                            decContext *);
+decNumber *decNumberToIntegralExact(decNumber *, const decNumber *,
+                                   decContext *);
+decNumber *decNumberToIntegralValue(decNumber *, const decNumber *,
+                                   decContext *);
+decNumber *decNumberXor(decNumber *, const decNumber *, const decNumber *,
+                       decContext *);
+
+  /* Utilities                                                        */
+enum decClass decNumberClass(const decNumber *, decContext *);
+const char *decNumberClassToString(enum decClass);
+decNumber *decNumberCopy(decNumber *, const decNumber *);
+decNumber *decNumberCopyAbs(decNumber *, const decNumber *);
+decNumber *decNumberCopyNegate(decNumber *, const decNumber *);
+decNumber *decNumberCopySign(decNumber *, const decNumber *, const decNumber *);
+decNumber *decNumberNextMinus(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberNextPlus(decNumber *, const decNumber *, decContext *);
+decNumber *decNumberNextToward(decNumber *, const decNumber *,
+                              const decNumber *, decContext *);
+decNumber *decNumberTrim(decNumber *);
+const char *decNumberVersion(void);
+decNumber *decNumberZero(decNumber *);
+
+  /* Functions for testing decNumbers (normality depends on context)  */
+int32_t decNumberIsNormal(const decNumber *, decContext *);
+int32_t decNumberIsSubnormal(const decNumber *, decContext *);
+
+  /* Macros for testing decNumber *dn                                 */
+#define decNumberIsCanonical(dn) (1)   /* All decNumbers are saintly */
+#define decNumberIsFinite(dn)    (((dn)->bits&DECSPECIAL)==0)
+#define decNumberIsInfinite(dn)  (((dn)->bits&DECINF)!=0)
+#define decNumberIsNaN(dn)       (((dn)->bits&(DECNAN|DECSNAN))!=0)
+#define decNumberIsNegative(dn)  (((dn)->bits&DECNEG)!=0)
+#define decNumberIsQNaN(dn)      (((dn)->bits&(DECNAN))!=0)
+#define decNumberIsSNaN(dn)      (((dn)->bits&(DECSNAN))!=0)
+#define decNumberIsSpecial(dn)   (((dn)->bits&DECSPECIAL)!=0)
+#define decNumberIsZero(dn)      (*(dn)->lsu==0 \
+                                    && (dn)->digits==1 \
+                                    && (((dn)->bits&DECSPECIAL)==0))
+#define decNumberRadix(dn)       (10)
+
+#endif
diff --git a/theme/src/decnumber/decNumberLocal.h b/theme/src/decnumber/decNumberLocal.h
new file mode 100644 (file)
index 0000000..00146ec
--- /dev/null
@@ -0,0 +1,753 @@
+/* ------------------------------------------------------------------ */
+/* decNumber package local type, tuning, and macro definitions        */
+/* ------------------------------------------------------------------ */
+/* Copyright (c) IBM Corporation, 2000, 2010.  All rights reserved.   */
+/*                                                                    */
+/* This software is made available under the terms of the             */
+/* ICU License -- ICU 1.8.1 and later.                                */
+/*                                                                    */
+/* The description and User's Guide ("The decNumber C Library") for   */
+/* this software is called decNumber.pdf.  This document is           */
+/* available, together with arithmetic and format specifications,     */
+/* testcases, and Web links, on the General Decimal Arithmetic page.  */
+/*                                                                    */
+/* Please send comments, suggestions, and corrections to the author:  */
+/*   mfc@uk.ibm.com                                                   */
+/*   Mike Cowlishaw, IBM Fellow                                       */
+/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
+/* ------------------------------------------------------------------ */
+/* This header file is included by all modules in the decNumber       */
+/* library, and contains local type definitions, tuning parameters,   */
+/* etc.  It should not need to be used by application programs.       */
+/* decNumber.h or one of decDouble (etc.) must be included first.     */
+/* ------------------------------------------------------------------ */
+
+#if !defined(DECNUMBERLOC)
+#define DECNUMBERLOC
+#define DECVERSION    "decNumber 3.68" /* Package Version [16 max.] */
+#define DECNLAUTHOR   "Mike Cowlishaw" /* Who to blame */
+
+#include <stdlib.h>            /* for abs                              */
+#include <string.h>            /* for memset, strcpy                   */
+
+  /* Conditional code flag -- set this to match hardware platform     */
+#if !defined(DECLITEND)
+#define DECLITEND 1            /* 1=little-endian, 0=big-endian        */
+#endif
+
+  /* Conditional code flag -- set this to 1 for best performance      */
+#if !defined(DECUSE64)
+#define DECUSE64  1            /* 1=use int64s, 0=int32 & smaller only */
+#endif
+
+  /* Conditional code flag -- set this to 0 to exclude printf calls   */
+#if !defined(DECPRINT)
+#define DECPRINT  1            /* 1=allow printf calls; 0=no printf    */
+#endif
+
+  /* Conditional check flags -- set these to 0 for best performance   */
+#if !defined(DECCHECK)
+#define DECCHECK  0            /* 1 to enable robust checking          */
+#endif
+#if !defined(DECALLOC)
+#define DECALLOC  0            /* 1 to enable memory accounting        */
+#endif
+#if !defined(DECTRACE)
+#define DECTRACE  0            /* 1 to trace certain internals, etc.   */
+#endif
+
+  /* Tuning parameter for decNumber (arbitrary precision) module      */
+#if !defined(DECBUFFER)
+#define DECBUFFER 36           /* Size basis for local buffers.  This  */
+                             /* should be a common maximum precision */
+                             /* rounded up to a multiple of 4; must  */
+                             /* be zero or positive.                 */
+#endif
+
+  /* ---------------------------------------------------------------- */
+  /* Check parameter dependencies                                     */
+  /* ---------------------------------------------------------------- */
+#if DECCHECK & !DECPRINT
+#error DECCHECK needs DECPRINT to be useful
+#endif
+#if DECALLOC & !DECPRINT
+#error DECALLOC needs DECPRINT to be useful
+#endif
+#if DECTRACE & !DECPRINT
+#error DECTRACE needs DECPRINT to be useful
+#endif
+
+  /* ---------------------------------------------------------------- */
+  /* Definitions for all modules (general-purpose)                    */
+  /* ---------------------------------------------------------------- */
+
+  /* Local names for common types -- for safety, decNumber modules do */
+  /* not use int or long directly.                                    */
+#define Flag   uint8_t
+#define Byte   int8_t
+#define uByte  uint8_t
+#define Short  int16_t
+#define uShort uint16_t
+#define Int    int32_t
+#define uInt   uint32_t
+#define Unit   decNumberUnit
+#if DECUSE64
+#define Long   int64_t
+#define uLong  uint64_t
+#endif
+
+  /* Development-use definitions                                      */
+typedef long int LI;           /* for printf arguments only            */
+#define DECNOINT  0            /* 1 to check no internal use of 'int'  */
+                             /*   or stdint types                    */
+#if DECNOINT
+    /* if these interfere with your C includes, do not set DECNOINT   */
+#define int     ?              /* enable to ensure that plain C 'int'  */
+#define long    ??             /* .. or 'long' types are not used      */
+#endif
+
+  /* Shared lookup tables                                             */
+extern const uByte DECSTICKYTAB[10];   /* re-round digits if sticky  */
+extern const uInt DECPOWERS[10];       /* powers of ten table        */
+  /* The following are included from decDPD.h                         */
+extern const uShort DPD2BIN[1024];     /* DPD -> 0-999               */
+extern const uShort BIN2DPD[1000];     /* 0-999 -> DPD               */
+extern const uInt DPD2BINK[1024];      /* DPD -> 0-999000            */
+extern const uInt DPD2BINM[1024];      /* DPD -> 0-999000000         */
+extern const uByte DPD2BCD8[4096];     /* DPD -> ddd + len           */
+extern const uByte BIN2BCD8[4000];     /* 0-999 -> ddd + len         */
+extern const uShort BCD2DPD[2458];     /* 0-0x999 -> DPD (0x999=2457) */
+
+  /* LONGMUL32HI -- set w=(u*v)>>32, where w, u, and v are uInts      */
+  /* (that is, sets w to be the high-order word of the 64-bit result; */
+  /* the low-order word is simply u*v.)                               */
+  /* This version is derived from Knuth via Hacker's Delight;         */
+  /* it seems to optimize better than some others tried               */
+#define LONGMUL32HI(w, u, v) {             \
+    uInt u0, u1, v0, v1, w0, w1, w2, t;      \
+    u0=u & 0xffff; u1=u>>16;                 \
+    v0=v & 0xffff; v1=v>>16;                 \
+    w0=u0*v0;                                \
+    t=u1*v0 + (w0>>16);                      \
+    w1=t & 0xffff; w2=t>>16;                 \
+    w1=u0*v1 + w1;                           \
+    (w)=u1*v1 + w2 + (w1>>16);}
+
+  /* ROUNDUP -- round an integer up to a multiple of n                */
+#define ROUNDUP(i, n) ((((i)+(n)-1)/n)*n)
+#define ROUNDUP4(i)   (((i)+3)&~3)     /* special for n=4            */
+
+  /* ROUNDDOWN -- round an integer down to a multiple of n            */
+#define ROUNDDOWN(i, n) (((i)/n)*n)
+#define ROUNDDOWN4(i)   ((i)&~3)       /* special for n=4            */
+
+  /* References to multi-byte sequences under different sizes; these  */
+  /* require locally declared variables, but do not violate strict    */
+  /* aliasing or alignment (as did the UINTAT simple cast to uInt).   */
+  /* Variables needed are uswork, uiwork, etc. [so do not use at same */
+  /* level in an expression, e.g., UBTOUI(x)==UBTOUI(y) may fail].    */
+
+  /* Return a uInt, etc., from bytes starting at a char* or uByte*    */
+#define UBTOUS(b)  (memcpy((void *)&uswork, b, 2), uswork)
+#define UBTOUI(b)  (memcpy((void *)&uiwork, b, 4), uiwork)
+
+  /* Store a uInt, etc., into bytes starting at a char* or uByte*.    */
+  /* Returns i, evaluated, for convenience; has to use uiwork because */
+  /* i may be an expression.                                          */
+#define UBFROMUS(b, i)  (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork)
+#define UBFROMUI(b, i)  (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork)
+
+  /* X10 and X100 -- multiply integer i by 10 or 100                  */
+  /* [shifts are usually faster than multiply; could be conditional]  */
+#define X10(i)  (((i)<<1)+((i)<<3))
+#define X100(i) (((i)<<2)+((i)<<5)+((i)<<6))
+
+  /* MAXI and MINI -- general max & min (not in ANSI) for integers    */
+#define MAXI(x,y) ((x)<(y)?(y):(x))
+#define MINI(x,y) ((x)>(y)?(y):(x))
+
+  /* Useful constants                                                 */
+#define BILLION      1000000000        /* 10**9                 */
+  /* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC       */
+#define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')
+
+  /* ---------------------------------------------------------------- */
+  /* Definitions for arbitary-precision modules (only valid after     */
+  /* decNumber.h has been included)                                   */
+  /* ---------------------------------------------------------------- */
+
+  /* Limits and constants                                             */
+#define DECNUMMAXP 999999999   /* maximum precision code can handle  */
+#define DECNUMMAXE 999999999   /* maximum adjusted exponent ditto    */
+#define DECNUMMINE -999999999  /* minimum adjusted exponent ditto    */
+#if (DECNUMMAXP != DEC_MAX_DIGITS)
+#error Maximum digits mismatch
+#endif
+#if (DECNUMMAXE != DEC_MAX_EMAX)
+#error Maximum exponent mismatch
+#endif
+#if (DECNUMMINE != DEC_MIN_EMIN)
+#error Minimum exponent mismatch
+#endif
+
+  /* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN       */
+  /* digits, and D2UTABLE -- the initializer for the D2U table        */
+#if   DECDPUN==1
+#define DECDPUNMAX 9
+#define D2UTABLE {0,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}
+#elif DECDPUN==2
+#define DECDPUNMAX 99
+#define D2UTABLE {0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,  \
+                      11,11,12,12,13,13,14,14,15,15,16,16,17,17,18, \
+                      18,19,19,20,20,21,21,22,22,23,23,24,24,25}
+#elif DECDPUN==3
+#define DECDPUNMAX 999
+#define D2UTABLE {0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,  \
+                      8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13, \
+                      13,14,14,14,15,15,15,16,16,16,17}
+#elif DECDPUN==4
+#define DECDPUNMAX 9999
+#define D2UTABLE {0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,  \
+                      6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11, \
+                      11,11,11,12,12,12,12,13}
+#elif DECDPUN==5
+#define DECDPUNMAX 99999
+#define D2UTABLE {0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,  \
+                      5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,  \
+                      9,9,10,10,10,10}
+#elif DECDPUN==6
+#define DECDPUNMAX 999999
+#define D2UTABLE {0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,  \
+                      4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,  \
+                      8,8,8,8,8,9}
+#elif DECDPUN==7
+#define DECDPUNMAX 9999999
+#define D2UTABLE {0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,  \
+                      4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,  \
+                      7,7,7,7,7,7}
+#elif DECDPUN==8
+#define DECDPUNMAX 99999999
+#define D2UTABLE {0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,  \
+                      3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,  \
+                      6,6,6,6,6,7}
+#elif DECDPUN==9
+#define DECDPUNMAX 999999999
+#define D2UTABLE {0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,  \
+                      3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,  \
+                      5,5,6,6,6,6}
+#elif defined(DECDPUN)
+#error DECDPUN must be in the range 1-9
+#endif
+
+  /* ----- Shared data (in decNumber.c) ----- */
+  /* Public lookup table used by the D2U macro (see below)            */
+#define DECMAXD2U 49
+extern const uByte d2utable[DECMAXD2U + 1];
+
+  /* ----- Macros ----- */
+  /* ISZERO -- return true if decNumber dn is a zero                  */
+  /* [performance-critical in some situations]                        */
+#define ISZERO(dn) decNumberIsZero(dn) /* now just a local name */
+
+  /* D2U -- return the number of Units needed to hold d digits        */
+  /* (runtime version, with table lookaside for small d)              */
+#if DECDPUN==8
+#define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+7)>>3))
+#elif DECDPUN==4
+#define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+3)>>2))
+#else
+#define D2U(d) ((d)<=DECMAXD2U?d2utable[d]:((d)+DECDPUN-1)/DECDPUN)
+#endif
+  /* SD2U -- static D2U macro (for compile-time calculation)          */
+#define SD2U(d) (((d)+DECDPUN-1)/DECDPUN)
+
+  /* MSUDIGITS -- returns digits in msu, from digits, calculated      */
+  /* using D2U                                                        */
+#define MSUDIGITS(d) ((d)-(D2U(d)-1)*DECDPUN)
+
+  /* D2N -- return the number of decNumber structs that would be      */
+  /* needed to contain that number of digits (and the initial         */
+  /* decNumber struct) safely.  Note that one Unit is included in the */
+  /* initial structure.  Used for allocating space that is aligned on */
+  /* a decNumber struct boundary. */
+#define D2N(d) \
+    ((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
+
+  /* TODIGIT -- macro to remove the leading digit from the unsigned   */
+  /* integer u at column cut (counting from the right, LSD=0) and     */
+  /* place it as an ASCII character into the character pointed to by  */
+  /* c.  Note that cut must be <= 9, and the maximum value for u is   */
+  /* 2,000,000,000 (as is needed for negative exponents of            */
+  /* subnormals).  The unsigned integer pow is used as a temporary    */
+  /* variable. */
+#define TODIGIT(u, cut, c, pow) {       \
+    *(c)='0';                             \
+    pow=DECPOWERS[cut]*2;                 \
+    if ((u)>pow) {                        \
+      pow*=4;                             \
+      if ((u)>=pow) {(u)-=pow; *(c)+=8;}  \
+      pow/=2;                             \
+      if ((u)>=pow) {(u)-=pow; *(c)+=4;}  \
+      pow/=2;                             \
+      }                                   \
+    if ((u)>=pow) {(u)-=pow; *(c)+=2;}    \
+    pow/=2;                               \
+    if ((u)>=pow) {(u)-=pow; *(c)+=1;}    \
+    }
+
+  /* ---------------------------------------------------------------- */
+  /* Definitions for fixed-precision modules (only valid after        */
+  /* decSingle.h, decDouble.h, or decQuad.h has been included)        */
+  /* ---------------------------------------------------------------- */
+
+  /* bcdnum -- a structure describing a format-independent finite     */
+  /* number, whose coefficient is a string of bcd8 uBytes             */
+typedef struct {
+       uByte *msd;             /* -> most significant digit            */
+       uByte *lsd;             /* -> least ditto                       */
+       uInt sign;              /* 0=positive, DECFLOAT_Sign=negative   */
+       Int exponent;           /* Unadjusted signed exponent (q), or   */
+       /* DECFLOAT_NaN etc. for a special      */
+} bcdnum;
+
+  /* Test if exponent or bcdnum exponent must be a special, etc.      */
+#define EXPISSPECIAL(exp) ((exp)>=DECFLOAT_MinSp)
+#define EXPISINF(exp) (exp==DECFLOAT_Inf)
+#define EXPISNAN(exp) (exp==DECFLOAT_qNaN || exp==DECFLOAT_sNaN)
+#define NUMISSPECIAL(num) (EXPISSPECIAL((num)->exponent))
+
+  /* Refer to a 32-bit word or byte in a decFloat (df) by big-endian  */
+  /* (array) notation (the 0 word or byte contains the sign bit),     */
+  /* automatically adjusting for endianness; similarly address a word */
+  /* in the next-wider format (decFloatWider, or dfw)                 */
+#define DECWORDS  (DECBYTES/4)
+#define DECWWORDS (DECWBYTES/4)
+#if DECLITEND
+#define DFBYTE(df, off)   ((df)->bytes[DECBYTES-1-(off)])
+#define DFWORD(df, off)   ((df)->words[DECWORDS-1-(off)])
+#define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
+#else
+#define DFBYTE(df, off)   ((df)->bytes[off])
+#define DFWORD(df, off)   ((df)->words[off])
+#define DFWWORD(dfw, off) ((dfw)->words[off])
+#endif
+
+  /* Tests for sign or specials, directly on DECFLOATs                */
+#define DFISSIGNED(df)  ((DFWORD(df, 0)&0x80000000)!=0)
+#define DFISSPECIAL(df) ((DFWORD(df, 0)&0x78000000)==0x78000000)
+#define DFISINF(df)     ((DFWORD(df, 0)&0x7c000000)==0x78000000)
+#define DFISNAN(df)     ((DFWORD(df, 0)&0x7c000000)==0x7c000000)
+#define DFISQNAN(df)    ((DFWORD(df, 0)&0x7e000000)==0x7c000000)
+#define DFISSNAN(df)    ((DFWORD(df, 0)&0x7e000000)==0x7e000000)
+
+  /* Shared lookup tables                                             */
+extern const uInt DECCOMBMSD[64];      /* Combination field -> MSD   */
+extern const uInt DECCOMBFROM[48];     /* exp+msd -> Combination     */
+
+  /* Private generic (utility) routine                                */
+#if DECCHECK || DECTRACE
+extern void decShowNum(const bcdnum *, const char *);
+#endif
+
+  /* Format-dependent macros and constants                            */
+#if defined(DECPMAX)
+
+    /* Useful constants                                               */
+#define DECPMAX9  (ROUNDUP(DECPMAX, 9)/9)      /* 'Pmax' in 10**9s    */
+    /* Top words for a zero                                           */
+#define SINGLEZERO   0x22500000
+#define DOUBLEZERO   0x22380000
+#define QUADZERO     0x22080000
+    /* [ZEROWORD is defined to be one of these in the DFISZERO macro] */
+
+    /* Format-dependent common tests:                                 */
+    /*   DFISZERO   -- test for (any) zero                            */
+    /*   DFISCCZERO -- test for coefficient continuation being zero   */
+    /*   DFISCC01   -- test for coefficient contains only 0s and 1s   */
+    /*   DFISINT    -- test for finite and exponent q=0               */
+    /*   DFISUINT01 -- test for sign=0, finite, exponent q=0, and     */
+    /*                 MSD=0 or 1                                     */
+    /*   ZEROWORD is also defined here.                               */
+    /*                                                                */
+    /* In DFISZERO the first test checks the least-significant word   */
+    /* (most likely to be non-zero); the penultimate tests MSD and    */
+    /* DPDs in the signword, and the final test excludes specials and */
+    /* MSD>7.  DFISINT similarly has to allow for the two forms of    */
+    /* MSD codes.  DFISUINT01 only has to allow for one form of MSD   */
+    /* code.                                                          */
+#if DECPMAX==7
+#define ZEROWORD SINGLEZERO
+      /* [test macros not needed except for Zero]                     */
+#define DFISZERO(df)  ((DFWORD(df, 0)&0x1c0fffff)==0         \
+                          && (DFWORD(df, 0)&0x60000000)!=0x60000000)
+#elif DECPMAX==16
+#define ZEROWORD DOUBLEZERO
+#define DFISZERO(df)  ((DFWORD(df, 1)==0                     \
+                          && (DFWORD(df, 0)&0x1c03ffff)==0         \
+                          && (DFWORD(df, 0)&0x60000000)!=0x60000000))
+#define DFISINT(df) ((DFWORD(df, 0)&0x63fc0000)==0x22380000  \
+                         ||(DFWORD(df, 0)&0x7bfc0000)==0x6a380000)
+#define DFISUINT01(df) ((DFWORD(df, 0)&0xfbfc0000)==0x22380000)
+#define DFISCCZERO(df) (DFWORD(df, 1)==0                     \
+                          && (DFWORD(df, 0)&0x0003ffff)==0)
+#define DFISCC01(df)  ((DFWORD(df, 0)&~0xfffc9124)==0        \
+                          && (DFWORD(df, 1)&~0x49124491)==0)
+#elif DECPMAX==34
+#define ZEROWORD QUADZERO
+#define DFISZERO(df)  ((DFWORD(df, 3)==0                     \
+                          &&  DFWORD(df, 2)==0                     \
+                          &&  DFWORD(df, 1)==0                     \
+                          && (DFWORD(df, 0)&0x1c003fff)==0         \
+                          && (DFWORD(df, 0)&0x60000000)!=0x60000000))
+#define DFISINT(df) ((DFWORD(df, 0)&0x63ffc000)==0x22080000  \
+                         ||(DFWORD(df, 0)&0x7bffc000)==0x6a080000)
+#define DFISUINT01(df) ((DFWORD(df, 0)&0xfbffc000)==0x22080000)
+#define DFISCCZERO(df) (DFWORD(df, 3)==0                     \
+                          &&  DFWORD(df, 2)==0                     \
+                          &&  DFWORD(df, 1)==0                     \
+                          && (DFWORD(df, 0)&0x00003fff)==0)
+
+#define DFISCC01(df)   ((DFWORD(df, 0)&~0xffffc912)==0       \
+                          &&  (DFWORD(df, 1)&~0x44912449)==0       \
+                          &&  (DFWORD(df, 2)&~0x12449124)==0       \
+                          &&  (DFWORD(df, 3)&~0x49124491)==0)
+#endif
+
+    /* Macros to test if a certain 10 bits of a uInt or pair of uInts */
+    /* are a canonical declet [higher or lower bits are ignored].     */
+    /* declet is at offset 0 (from the right) in a uInt:              */
+#define CANONDPD(dpd) (((dpd)&0x300)==0 || ((dpd)&0x6e)!=0x6e)
+    /* declet is at offset k (a multiple of 2) in a uInt:             */
+#define CANONDPDOFF(dpd, k) (((dpd)&(0x300<<(k)))==0            \
+      || ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
+    /* declet is at offset k (a multiple of 2) in a pair of uInts:    */
+    /* [the top 2 bits will always be in the more-significant uInt]   */
+#define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0     \
+      || ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k)))                  \
+      || ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
+
+    /* Macro to test whether a full-length (length DECPMAX) BCD8      */
+    /* coefficient, starting at uByte u, is all zeros                 */
+    /* Test just the LSWord first, then the remainder as a sequence   */
+    /* of tests in order to avoid same-level use of UBTOUI            */
+#if DECPMAX==7
+#define ISCOEFFZERO(u) (                                      \
+           UBTOUI((u)+DECPMAX-4)==0                                 \
+        && UBTOUS((u)+DECPMAX-6)==0                                 \
+        && *(u)==0)
+#elif DECPMAX==16
+#define ISCOEFFZERO(u) (                                      \
+           UBTOUI((u)+DECPMAX-4)==0                                 \
+        && UBTOUI((u)+DECPMAX-8)==0                                 \
+        && UBTOUI((u)+DECPMAX-12)==0                                \
+        && UBTOUI(u)==0)
+#elif DECPMAX==34
+#define ISCOEFFZERO(u) (                                      \
+           UBTOUI((u)+DECPMAX-4)==0                                 \
+        && UBTOUI((u)+DECPMAX-8)==0                                 \
+        && UBTOUI((u)+DECPMAX-12)==0                                \
+        && UBTOUI((u)+DECPMAX-16)==0                                \
+        && UBTOUI((u)+DECPMAX-20)==0                                \
+        && UBTOUI((u)+DECPMAX-24)==0                                \
+        && UBTOUI((u)+DECPMAX-28)==0                                \
+        && UBTOUI((u)+DECPMAX-32)==0                                \
+        && UBTOUS(u)==0)
+#endif
+
+    /* Macros and masks for the sign, exponent continuation, and MSD  */
+    /* Get the sign as DECFLOAT_Sign or 0                             */
+#define GETSIGN(df) (DFWORD(df, 0)&0x80000000)
+    /* Get the exponent continuation from a decFloat *df as an Int    */
+#define GETECON(df) ((Int)((DFWORD((df), 0)&0x03ffffff)>>(32-6-DECECONL)))
+    /* Ditto, from the next-wider format                              */
+#define GETWECON(df) ((Int)((DFWWORD((df), 0)&0x03ffffff)>>(32-6-DECWECONL)))
+    /* Get the biased exponent similarly                              */
+#define GETEXP(df)  ((Int)(DECCOMBEXP[DFWORD((df), 0)>>26]+GETECON(df)))
+    /* Get the unbiased exponent similarly                            */
+#define GETEXPUN(df) ((Int)GETEXP(df)-DECBIAS)
+    /* Get the MSD similarly (as uInt)                                */
+#define GETMSD(df)   (DECCOMBMSD[DFWORD((df), 0)>>26])
+
+    /* Compile-time computes of the exponent continuation field masks */
+    /* full exponent continuation field:                              */
+#define ECONMASK ((0x03ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
+    /* same, not including its first digit (the qNaN/sNaN selector):  */
+#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
+
+    /* Macros to decode the coefficient in a finite decFloat *df into */
+    /* a BCD string (uByte *bcdin) of length DECPMAX uBytes.          */
+
+    /* In-line sequence to convert least significant 10 bits of uInt  */
+    /* dpd to three BCD8 digits starting at uByte u.  Note that an    */
+    /* extra byte is written to the right of the three digits because */
+    /* four bytes are moved at a time for speed; the alternative      */
+    /* macro moves exactly three bytes (usually slower).              */
+#define dpd2bcd8(u, dpd)  memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 4)
+#define dpd2bcd83(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 3)
+
+    /* Decode the declets.  After extracting each one, it is decoded  */
+    /* to BCD8 using a table lookup (also used for variable-length    */
+    /* decode).  Each DPD decode is 3 bytes BCD8 plus a one-byte      */
+    /* length which is not used, here).  Fixed-length 4-byte moves    */
+    /* are fast, however, almost everywhere, and so are used except   */
+    /* for the final three bytes (to avoid overrun).  The code below  */
+    /* is 36 instructions for Doubles and about 70 for Quads, even    */
+    /* on IA32.                                                       */
+
+    /* Two macros are defined for each format:                        */
+    /*   GETCOEFF extracts the coefficient of the current format      */
+    /*   GETWCOEFF extracts the coefficient of the next-wider format. */
+    /* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */
+
+#if DECPMAX==7
+#define GETCOEFF(df, bcd) {                          \
+      uInt sourhi=DFWORD(df, 0);                         \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>10);                       \
+      dpd2bcd83(bcd+4, sourhi);}
+#define GETWCOEFF(df, bcd) {                         \
+      uInt sourhi=DFWWORD(df, 0);                        \
+      uInt sourlo=DFWWORD(df, 1);                        \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>8);                        \
+      dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30));       \
+      dpd2bcd8(bcd+7, sourlo>>20);                       \
+      dpd2bcd8(bcd+10, sourlo>>10);                      \
+      dpd2bcd83(bcd+13, sourlo);}
+
+#elif DECPMAX==16
+#define GETCOEFF(df, bcd) {                          \
+      uInt sourhi=DFWORD(df, 0);                         \
+      uInt sourlo=DFWORD(df, 1);                         \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>8);                        \
+      dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30));       \
+      dpd2bcd8(bcd+7, sourlo>>20);                       \
+      dpd2bcd8(bcd+10, sourlo>>10);                      \
+      dpd2bcd83(bcd+13, sourlo);}
+#define GETWCOEFF(df, bcd) {                         \
+      uInt sourhi=DFWWORD(df, 0);                        \
+      uInt sourmh=DFWWORD(df, 1);                        \
+      uInt sourml=DFWWORD(df, 2);                        \
+      uInt sourlo=DFWWORD(df, 3);                        \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>4);                        \
+      dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26));     \
+      dpd2bcd8(bcd+7, sourmh>>16);                       \
+      dpd2bcd8(bcd+10, sourmh>>6);                       \
+      dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28));    \
+      dpd2bcd8(bcd+16, sourml>>18);                      \
+      dpd2bcd8(bcd+19, sourml>>8);                       \
+      dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30));    \
+      dpd2bcd8(bcd+25, sourlo>>20);                      \
+      dpd2bcd8(bcd+28, sourlo>>10);                      \
+      dpd2bcd83(bcd+31, sourlo);}
+
+#elif DECPMAX==34
+#define GETCOEFF(df, bcd) {                          \
+      uInt sourhi=DFWORD(df, 0);                         \
+      uInt sourmh=DFWORD(df, 1);                         \
+      uInt sourml=DFWORD(df, 2);                         \
+      uInt sourlo=DFWORD(df, 3);                         \
+      *(bcd)=(uByte)DECCOMBMSD[sourhi>>26];              \
+      dpd2bcd8(bcd+1, sourhi>>4);                        \
+      dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26));     \
+      dpd2bcd8(bcd+7, sourmh>>16);                       \
+      dpd2bcd8(bcd+10, sourmh>>6);                       \
+      dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28));    \
+      dpd2bcd8(bcd+16, sourml>>18);                      \
+      dpd2bcd8(bcd+19, sourml>>8);                       \
+      dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30));    \
+      dpd2bcd8(bcd+25, sourlo>>20);                      \
+      dpd2bcd8(bcd+28, sourlo>>10);                      \
+      dpd2bcd83(bcd+31, sourlo);}
+
+#define GETWCOEFF(df, bcd) {??}        /* [should never be used]       */
+#endif
+
+    /* Macros to decode the coefficient in a finite decFloat *df into */
+    /* a base-billion uInt array, with the least-significant          */
+    /* 0-999999999 'digit' at offset 0.                               */
+
+    /* Decode the declets.  After extracting each one, it is decoded  */
+    /* to binary using a table lookup.  Three tables are used; one    */
+    /* the usual DPD to binary, the other two pre-multiplied by 1000  */
+    /* and 1000000 to avoid multiplication during decode.  These      */
+    /* tables can also be used for multiplying up the MSD as the DPD  */
+    /* code for 0 through 9 is the identity.                          */
+#define DPD2BIN0 DPD2BIN       /* for prettier code             */
+
+#if DECPMAX==7
+#define GETCOEFFBILL(df, buf) {                           \
+      uInt sourhi=DFWORD(df, 0);                              \
+      (buf)[0]=DPD2BIN0[sourhi&0x3ff]                         \
+              +DPD2BINK[(sourhi>>10)&0x3ff]                   \
+              +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
+
+#elif DECPMAX==16
+#define GETCOEFFBILL(df, buf) {                           \
+      uInt sourhi, sourlo;                                    \
+      sourlo=DFWORD(df, 1);                                   \
+      (buf)[0]=DPD2BIN0[sourlo&0x3ff]                         \
+              +DPD2BINK[(sourlo>>10)&0x3ff]                   \
+              +DPD2BINM[(sourlo>>20)&0x3ff];                  \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[1]=DPD2BIN0[((sourhi<<2) | (sourlo>>30))&0x3ff]   \
+              +DPD2BINK[(sourhi>>8)&0x3ff]                    \
+              +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
+
+#elif DECPMAX==34
+#define GETCOEFFBILL(df, buf) {                           \
+      uInt sourhi, sourmh, sourml, sourlo;                    \
+      sourlo=DFWORD(df, 3);                                   \
+      (buf)[0]=DPD2BIN0[sourlo&0x3ff]                         \
+              +DPD2BINK[(sourlo>>10)&0x3ff]                   \
+              +DPD2BINM[(sourlo>>20)&0x3ff];                  \
+      sourml=DFWORD(df, 2);                                   \
+      (buf)[1]=DPD2BIN0[((sourml<<2) | (sourlo>>30))&0x3ff]   \
+              +DPD2BINK[(sourml>>8)&0x3ff]                    \
+              +DPD2BINM[(sourml>>18)&0x3ff];                  \
+      sourmh=DFWORD(df, 1);                                   \
+      (buf)[2]=DPD2BIN0[((sourmh<<4) | (sourml>>28))&0x3ff]   \
+              +DPD2BINK[(sourmh>>6)&0x3ff]                    \
+              +DPD2BINM[(sourmh>>16)&0x3ff];                  \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[3]=DPD2BIN0[((sourhi<<6) | (sourmh>>26))&0x3ff]   \
+              +DPD2BINK[(sourhi>>4)&0x3ff]                    \
+              +DPD2BINM[DECCOMBMSD[sourhi>>26]];}
+
+#endif
+
+    /* Macros to decode the coefficient in a finite decFloat *df into */
+    /* a base-thousand uInt array (of size DECLETS+1, to allow for    */
+    /* the MSD), with the least-significant 0-999 'digit' at offset 0. */
+
+    /* Decode the declets.  After extracting each one, it is decoded  */
+    /* to binary using a table lookup.                                */
+#if DECPMAX==7
+#define GETCOEFFTHOU(df, buf) {                           \
+      uInt sourhi=DFWORD(df, 0);                              \
+      (buf)[0]=DPD2BIN[sourhi&0x3ff];                         \
+      (buf)[1]=DPD2BIN[(sourhi>>10)&0x3ff];                   \
+      (buf)[2]=DECCOMBMSD[sourhi>>26];}
+
+#elif DECPMAX==16
+#define GETCOEFFTHOU(df, buf) {                           \
+      uInt sourhi, sourlo;                                    \
+      sourlo=DFWORD(df, 1);                                   \
+      (buf)[0]=DPD2BIN[sourlo&0x3ff];                         \
+      (buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff];                   \
+      (buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff];                   \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[3]=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff];   \
+      (buf)[4]=DPD2BIN[(sourhi>>8)&0x3ff];                    \
+      (buf)[5]=DECCOMBMSD[sourhi>>26];}
+
+#elif DECPMAX==34
+#define GETCOEFFTHOU(df, buf) {                           \
+      uInt sourhi, sourmh, sourml, sourlo;                    \
+      sourlo=DFWORD(df, 3);                                   \
+      (buf)[0]=DPD2BIN[sourlo&0x3ff];                         \
+      (buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff];                   \
+      (buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff];                   \
+      sourml=DFWORD(df, 2);                                   \
+      (buf)[3]=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff];   \
+      (buf)[4]=DPD2BIN[(sourml>>8)&0x3ff];                    \
+      (buf)[5]=DPD2BIN[(sourml>>18)&0x3ff];                   \
+      sourmh=DFWORD(df, 1);                                   \
+      (buf)[6]=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff];   \
+      (buf)[7]=DPD2BIN[(sourmh>>6)&0x3ff];                    \
+      (buf)[8]=DPD2BIN[(sourmh>>16)&0x3ff];                   \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff];   \
+      (buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff];                   \
+      (buf)[11]=DECCOMBMSD[sourhi>>26];}
+#endif
+
+    /* Macros to decode the coefficient in a finite decFloat *df and  */
+    /* add to a base-thousand uInt array (as for GETCOEFFTHOU).       */
+    /* After the addition then most significant 'digit' in the array  */
+    /* might have a value larger then 10 (with a maximum of 19).      */
+#if DECPMAX==7
+#define ADDCOEFFTHOU(df, buf) {                           \
+      uInt sourhi=DFWORD(df, 0);                              \
+      (buf)[0]+=DPD2BIN[sourhi&0x3ff];                        \
+      if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
+      (buf)[1]+=DPD2BIN[(sourhi>>10)&0x3ff];                  \
+      if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
+      (buf)[2]+=DECCOMBMSD[sourhi>>26];}
+
+#elif DECPMAX==16
+#define ADDCOEFFTHOU(df, buf) {                           \
+      uInt sourhi, sourlo;                                    \
+      sourlo=DFWORD(df, 1);                                   \
+      (buf)[0]+=DPD2BIN[sourlo&0x3ff];                        \
+      if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
+      (buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff];                  \
+      if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
+      (buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff];                  \
+      if (buf[2]>999) {buf[2]-=1000; buf[3]++;}               \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[3]+=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff];  \
+      if (buf[3]>999) {buf[3]-=1000; buf[4]++;}               \
+      (buf)[4]+=DPD2BIN[(sourhi>>8)&0x3ff];                   \
+      if (buf[4]>999) {buf[4]-=1000; buf[5]++;}               \
+      (buf)[5]+=DECCOMBMSD[sourhi>>26];}
+
+#elif DECPMAX==34
+#define ADDCOEFFTHOU(df, buf) {                           \
+      uInt sourhi, sourmh, sourml, sourlo;                    \
+      sourlo=DFWORD(df, 3);                                   \
+      (buf)[0]+=DPD2BIN[sourlo&0x3ff];                        \
+      if (buf[0]>999) {buf[0]-=1000; buf[1]++;}               \
+      (buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff];                  \
+      if (buf[1]>999) {buf[1]-=1000; buf[2]++;}               \
+      (buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff];                  \
+      if (buf[2]>999) {buf[2]-=1000; buf[3]++;}               \
+      sourml=DFWORD(df, 2);                                   \
+      (buf)[3]+=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff];  \
+      if (buf[3]>999) {buf[3]-=1000; buf[4]++;}               \
+      (buf)[4]+=DPD2BIN[(sourml>>8)&0x3ff];                   \
+      if (buf[4]>999) {buf[4]-=1000; buf[5]++;}               \
+      (buf)[5]+=DPD2BIN[(sourml>>18)&0x3ff];                  \
+      if (buf[5]>999) {buf[5]-=1000; buf[6]++;}               \
+      sourmh=DFWORD(df, 1);                                   \
+      (buf)[6]+=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff];  \
+      if (buf[6]>999) {buf[6]-=1000; buf[7]++;}               \
+      (buf)[7]+=DPD2BIN[(sourmh>>6)&0x3ff];                   \
+      if (buf[7]>999) {buf[7]-=1000; buf[8]++;}               \
+      (buf)[8]+=DPD2BIN[(sourmh>>16)&0x3ff];                  \
+      if (buf[8]>999) {buf[8]-=1000; buf[9]++;}               \
+      sourhi=DFWORD(df, 0);                                   \
+      (buf)[9]+=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff];  \
+      if (buf[9]>999) {buf[9]-=1000; buf[10]++;}              \
+      (buf)[10]+=DPD2BIN[(sourhi>>4)&0x3ff];                  \
+      if (buf[10]>999) {buf[10]-=1000; buf[11]++;}            \
+      (buf)[11]+=DECCOMBMSD[sourhi>>26];}
+#endif
+
+    /* Set a decFloat to the maximum positive finite number (Nmax)    */
+#if DECPMAX==7
+#define DFSETNMAX(df)            \
+      {DFWORD(df, 0)=0x77f3fcff;}
+#elif DECPMAX==16
+#define DFSETNMAX(df)            \
+      {DFWORD(df, 0)=0x77fcff3f;     \
+       DFWORD(df, 1)=0xcff3fcff;}
+#elif DECPMAX==34
+#define DFSETNMAX(df)            \
+      {DFWORD(df, 0)=0x77ffcff3;     \
+       DFWORD(df, 1)=0xfcff3fcf;     \
+       DFWORD(df, 2)=0xf3fcff3f;     \
+       DFWORD(df, 3)=0xcff3fcff;}
+#endif
+
+  /* [end of format-dependent macros and constants]                   */
+#endif
+
+#else
+#error decNumberLocal included more than once
+#endif