summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid McMackins II <contact@mcmackins.org>2017-05-22 11:46:38 -0500
committerDavid McMackins II <contact@mcmackins.org>2017-05-22 11:46:38 -0500
commit89b0dafe92ee723a69c1da1aaa2bbcb4551fab16 (patch)
treef0aefb744dfec45b6f74bbf7fe9d521eaed8829b
parentc0e14c93609fd436931caaf49d89fb6d2f2c6ea5 (diff)
Use new Delwink style
-rw-r--r--.gitignore1
-rw-r--r--Makefile38
-rw-r--r--README14
-rwxr-xr-xautogen.sh5
-rw-r--r--configure.ac23
-rwxr-xr-xmvobjs.sh4
-rw-r--r--src/button.h46
-rw-r--r--src/font.c242
-rw-r--r--src/font.h8
-rw-r--r--src/keys.c210
-rw-r--r--src/keys.h4
-rw-r--r--src/liberti.c597
-rw-r--r--src/log.c46
-rw-r--r--src/log.h12
-rw-r--r--src/mode_default.c497
-rw-r--r--src/mode_default.h6
-rw-r--r--src/point.h6
-rw-r--r--src/screen.c27
-rw-r--r--src/screen.h22
-rw-r--r--src/skin.c1240
-rw-r--r--src/skin.h32
-rw-r--r--src/state.c475
-rw-r--r--src/state.h56
-rw-r--r--src/tibchar.c618
-rw-r--r--src/tibchar.h196
-rw-r--r--src/tibdecode.c131
-rw-r--r--src/tibencode.c262
-rw-r--r--src/tiberr.h34
-rw-r--r--src/tibeval.c1287
-rw-r--r--src/tibeval.h24
-rw-r--r--src/tibexpr.c412
-rw-r--r--src/tibexpr.h37
-rw-r--r--src/tibfunction.c381
-rw-r--r--src/tibfunction.h14
-rw-r--r--src/tiblst.c156
-rw-r--r--src/tiblst.h28
-rw-r--r--src/tibtranscode.c1526
-rw-r--r--src/tibtranscode.h6
-rw-r--r--src/tibtype.c1929
-rw-r--r--src/tibtype.h76
-rw-r--r--src/tibvar.c182
-rw-r--r--src/tibvar.h16
-rw-r--r--src/util.c125
-rw-r--r--src/util.h14
44 files changed, 5558 insertions, 5507 deletions
diff --git a/.gitignore b/.gitignore
index 5e1df20..97b83fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,7 +32,6 @@ autom4te.cache
m4/
libtool
src/.dirstamp
-Makefile
Makefile.in
aclocal.m4
configure
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..d3b83fd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,38 @@
+CC=c99
+CFLAGS=-Wall -Wextra -Wunreachable-code -ftrapv -fPIC -g -D_POSIX_C_SOURCE=2 -D_REENTRANT -I/usr/include/SDL2
+CONFIG_LIBS=-lconfig
+GSL_LIBS=-lgsl -lgslcblas -lm
+PFXTREE_LIBS=-lpfxtree
+SDL2_LIBS=-lSDL2 -lSDL2_image
+PREFIX=/usr/local
+BINDIR=$(DESTDIR)$(PREFIX)/bin
+
+all: liberti tibencode tibdecode
+
+liberti_deps=src/colors.o src/font.o src/keys.o src/liberti.o src/log.o src/mode_default.o src/screen.o src/skin.o src/state.o libtib.a
+liberti: $(liberti_deps)
+ ./mvobjs.sh
+ $(CC) -o $@ $(liberti_deps) $(CONFIG_LIBS) $(GSL_LIBS) $(PFXTREE_LIBS) $(SDL2_LIBS)
+
+tibencode_deps=src/tibencode.o libtib.a
+tibencode: $(tibencode_deps)
+ ./mvobjs.sh
+ $(CC) -o $@ $(tibencode_deps) $(GSL_LIBS) $(PFXTREE_LIBS)
+
+tibdecode_deps=src/tibdecode.o libtib.a
+tibdecode: $(tibdecode_deps)
+ ./mvobjs.sh
+ $(CC) -o $@ $(tibdecode_deps) $(GSL_LIBS) $(PFXTREE_LIBS)
+
+libtib_deps=src/tibchar.o src/tiberr.o src/tibeval.o src/tibexpr.o src/tibfunction.o src/tiblst.o src/tibtranscode.o src/tibtype.o src/tibvar.o src/util.o
+libtib.a: $(libtib_deps)
+ ./mvobjs.sh
+ $(AR) rcs $@ $(libtib_deps)
+
+install: all
+ install -m755 liberti $(BINDIR)/liberti
+ install -m755 tibencode $(BINDIR)/tibencode
+ install -m755 tibdecode $(BINDIR)/tibdecode
+
+clean:
+ rm -f src/*.o *.a liberti tibencode tibdecode
diff --git a/README b/README
index 3c107e2..243ec9c 100644
--- a/README
+++ b/README
@@ -10,8 +10,8 @@ You must first satisfy the build dependencies of LiberTI.
| Library/Tool | Purpose |
|----------------------------|-----------------------------------------------|
-| GNU Autotools | Automatic build scripts |
-| C11 Compiler | (Prefer GCC or Clang) Source compilation |
+| POSIX Make | Build scripts |
+| C99 Compiler | (Prefer GCC or Clang) Source compilation |
| GNU Scientific Library | Complex math calculations and data structures |
| Simple DirectMedia Layer 2 | Graphics and threading |
| SDL2 Image | Image loading support |
@@ -21,16 +21,14 @@ You must first satisfy the build dependencies of LiberTI.
On Debian GNU/Linux and derivatives, you can install these with the following
command:
- # apt-get install build-essential autoconf automake libgsl0-dev \
- libsdl2-dev libsdl2-image-dev libconfig-dev
+ # apt-get install build-essential libgsl0-dev libsdl2-dev \
+ libsdl2-image-dev libconfig-dev
For libpfxtree, download the latest stable source from [Delwink's site][3], and
build/install according to the README inside.
After the dependencies are installed, you can build LiberTI as follows:
- $ ./autogen.sh
- $ ./configure
$ make
If you wish to install LiberTI to the system, you can run the following:
@@ -74,9 +72,7 @@ officially endorsed or supported by LibreCalc.
Hacking
-------
-We prefer the GNU coding style for C with a strict limit of 79 columns in the
-source code. Indentations are two spaces, and tab characters are eight
-spaces.
+Copy the style you see in the code. Do not use spaces for indentation.
To submit a patch, [submit your diff to Delwink][2], or use GitHub's pull
request system.
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755
index 5b883a6..0000000
--- a/autogen.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-set -e
-srcdir="$(dirname $0)"
-cd "$srcdir"
-autoreconf --install --force
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index 4363aa4..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,23 +0,0 @@
-AC_PREREQ([2.60])
-AC_INIT([liberti],[0.0.0],[support@delwink.com])
-
-AC_CONFIG_SRCDIR([src/liberti.c])
-AC_CONFIG_AUX_DIR([build-aux])
-AC_CONFIG_MACRO_DIR([m4])
-AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
-AM_SILENT_RULES([yes])
-AM_PROG_AR
-AC_PROG_RANLIB
-AC_PROG_CC
-
-PKG_CHECK_MODULES([gsl], [gsl])
-PKG_CHECK_MODULES([pfxtree], [pfxtree])
-PKG_CHECK_MODULES([sdl2], [sdl2])
-PKG_CHECK_MODULES([libconfig], [libconfig])
-
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([
- Makefile
-])
-AC_OUTPUT
diff --git a/mvobjs.sh b/mvobjs.sh
new file mode 100755
index 0000000..467ac53
--- /dev/null
+++ b/mvobjs.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+mv *.o src/ >/dev/null 2>&1
+exit 0
diff --git a/src/button.h b/src/button.h
index 21c5dca..4e7ebe9 100644
--- a/src/button.h
+++ b/src/button.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,41 +21,41 @@
#include "screen.h"
enum cursor_direction
- {
- UP = -16,
- DOWN = 16,
- LEFT = -1,
- RIGHT = 1
- };
+{
+ UP = -16,
+ DOWN = 16,
+ LEFT = -1,
+ RIGHT = 1
+};
enum button_action_type
- {
- CHANGE_MODES,
- CHAR_INSERT,
- CURSOR_MOVE,
- TOGGLE_2ND,
- TOGGLE_ALPHA,
- TOGGLE_INSERT
- };
+{
+ CHANGE_MODES,
+ CHAR_INSERT,
+ CURSOR_MOVE,
+ TOGGLE_2ND,
+ TOGGLE_ALPHA,
+ TOGGLE_INSERT
+};
union button_action
{
- int char_insert;
- enum cursor_direction cursor_move;
- enum screen_mode mode_open;
+ int char_insert;
+ enum cursor_direction cursor_move;
+ enum screen_mode mode_open;
};
struct button_action_set
{
- enum button_action_type type;
- union button_action which;
+ enum button_action_type type;
+ union button_action which;
};
struct button
{
- struct button_action_set actions[NUM_SCREEN_MODES][NUM_ACTION_STATES];
- struct point2d pos;
- struct point2d size;
+ struct button_action_set actions[NUM_SCREEN_MODES][NUM_ACTION_STATES];
+ struct point2d pos;
+ struct point2d size;
};
#endif
diff --git a/src/font.c b/src/font.c
index 973ab70..ce7c646 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -31,138 +31,138 @@ static bool tiles_init = false;
static SDL_Surface *tiles[NUM_TILES];
int
-font_init ()
+font_init()
{
- SDL_Surface *tileset;
-
- if (tiles_init)
- return 0;
-
- memset (tiles, 0, sizeof tiles);
-
- tileset = IMG_Load_RW (SDL_RWFromMem (FONT_PNG_DATA, FONT_PNG_SIZE), 1);
- if (!tileset)
- {
- critical ("Failed to load tileset: %s", SDL_GetError ());
- return TIB_EALLOC;
- }
-
- for (unsigned int i = 0; i < NUM_TILES; ++i)
- {
- tiles[i] = SDL_CreateRGBSurface (0, 6, 8, 32, 0, 0, 0, 0);
- if (!tiles[i])
- {
- critical ("Failed to alloc tile %u: %s", i, SDL_GetError ());
-
- for (unsigned int j = 0; j < i; ++j)
- SDL_FreeSurface (tiles[j]);
-
- return TIB_EALLOC;
- }
-
- SDL_Rect src = { i * 6, 0, 6, 8 };
- if (SDL_BlitSurface (tileset, &src, tiles[i], NULL))
- error ("Failed to blit tile %u: %s", i, SDL_GetError ());
- }
-
- SDL_FreeSurface (tileset);
- tiles_init = true;
- return 0;
+ SDL_Surface *tileset;
+
+ if (tiles_init)
+ return 0;
+
+ memset(tiles, 0, sizeof tiles);
+
+ tileset = IMG_Load_RW(SDL_RWFromMem(FONT_PNG_DATA, FONT_PNG_SIZE), 1);
+ if (!tileset)
+ {
+ critical("Failed to load tileset: %s", SDL_GetError());
+ return TIB_EALLOC;
+ }
+
+ for (unsigned int i = 0; i < NUM_TILES; ++i)
+ {
+ tiles[i] = SDL_CreateRGBSurface(0, 6, 8, 32, 0, 0, 0, 0);
+ if (!tiles[i])
+ {
+ critical("Failed to alloc tile %u: %s", i,
+ SDL_GetError());
+
+ for (unsigned int j = 0; j < i; ++j)
+ SDL_FreeSurface(tiles[j]);
+
+ return TIB_EALLOC;
+ }
+
+ SDL_Rect src = { i * 6, 0, 6, 8 };
+ if (SDL_BlitSurface(tileset, &src, tiles[i], NULL))
+ error("Failed to blit tile %u: %s", i, SDL_GetError());
+ }
+
+ SDL_FreeSurface(tileset);
+ tiles_init = true;
+ return 0;
}
void
-font_free ()
+font_free()
{
- if (tiles_init)
- for (unsigned int i = 0; i < NUM_TILES; ++i)
- SDL_FreeSurface (tiles[i]);
+ if (tiles_init)
+ for (unsigned int i = 0; i < NUM_TILES; ++i)
+ SDL_FreeSurface(tiles[i]);
- tiles_init = false;
+ tiles_init = false;
}
SDL_Surface *
-get_font_char (int c)
+get_font_char(int c)
{
- if (!tiles_init || c < 0)
- return NULL;
+ if (!tiles_init || c < 0)
+ return NULL;
- return tiles[c];
+ return tiles[c];
}
// generated from font.png
-unsigned char FONT_PNG_DATA[] =
- {
- 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
- 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x08, 0x03, 0x00, 0x00, 0x00, 0x08, 0xb3, 0xc4, 0x0e, 0x00, 0x00, 0x00,
- 0x06, 0x50, 0x4c, 0x54, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa5,
- 0xd9, 0x9f, 0xdd, 0x00, 0x00, 0x03, 0x12, 0x49, 0x44, 0x41, 0x54, 0x68,
- 0xde, 0xed, 0x5a, 0x81, 0x76, 0x9c, 0x30, 0x0c, 0x93, 0xff, 0xff, 0xa7,
- 0xf7, 0xda, 0x83, 0x20, 0xc9, 0x0e, 0x81, 0x5b, 0xdf, 0x8d, 0x6d, 0xf6,
- 0xbb, 0xa6, 0x94, 0xa3, 0xc1, 0x71, 0x82, 0x64, 0x2b, 0x20, 0xbe, 0x0d,
- 0x5f, 0x56, 0xb4, 0xbb, 0x21, 0xb5, 0x4f, 0x33, 0xbc, 0x1a, 0x8c, 0xf6,
- 0x75, 0x28, 0x2e, 0xd3, 0xaf, 0xeb, 0x83, 0xd8, 0xc2, 0x80, 0x71, 0x3c,
- 0x22, 0x43, 0xc7, 0x74, 0x7e, 0x3f, 0x81, 0xda, 0x45, 0x0e, 0x24, 0x5d,
- 0x39, 0x7a, 0xd6, 0x63, 0x99, 0x8b, 0x57, 0x33, 0x6e, 0xbc, 0x77, 0x41,
- 0x43, 0xa6, 0x63, 0x4c, 0xfb, 0x0c, 0x9e, 0x65, 0x0b, 0x9a, 0xb5, 0x34,
- 0xba, 0x11, 0x8d, 0xb4, 0x06, 0x50, 0x1c, 0xa5, 0x6f, 0xe0, 0xe7, 0xd2,
- 0x5c, 0x00, 0xef, 0xcc, 0xf8, 0xd5, 0x39, 0xd4, 0xf5, 0x90, 0xbe, 0xe3,
- 0x5e, 0xd5, 0x55, 0x70, 0x2b, 0x0b, 0x02, 0xd5, 0x14, 0xfe, 0xdc, 0x7a,
- 0x7e, 0xe6, 0x63, 0xd6, 0xf6, 0x8f, 0x19, 0x94, 0x00, 0xfc, 0x23, 0x20,
- 0x88, 0x27, 0x33, 0x40, 0x22, 0x80, 0x7d, 0x44, 0xdf, 0x7f, 0x62, 0x42,
- 0x63, 0xab, 0x01, 0x11, 0x98, 0x32, 0x5a, 0x0d, 0x04, 0x80, 0x61, 0x11,
- 0x1c, 0x82, 0x4f, 0x40, 0x73, 0x01, 0xbe, 0x29, 0xe0, 0xd2, 0x33, 0xdd,
- 0x79, 0x7c, 0x5e, 0xb7, 0xc2, 0xb5, 0x3e, 0xaf, 0xf8, 0xa0, 0x57, 0xa5,
- 0x38, 0x5f, 0x27, 0x00, 0x0c, 0xb6, 0xac, 0x62, 0x8d, 0x78, 0x6b, 0x59,
- 0xe1, 0xe6, 0x95, 0x60, 0xff, 0x43, 0x5d, 0x53, 0xa6, 0x50, 0x46, 0xaa,
- 0xa2, 0x1f, 0x16, 0x45, 0x78, 0x50, 0x7e, 0x7f, 0x25, 0x47, 0x33, 0x40,
- 0xdb, 0xa7, 0x09, 0x20, 0x76, 0xb8, 0x44, 0xf0, 0xc3, 0xba, 0x41, 0x28,
- 0x04, 0xcf, 0x1e, 0x4b, 0x00, 0xfb, 0x58, 0x18, 0x22, 0x8b, 0x87, 0x9f,
- 0xa8, 0x01, 0x27, 0x9d, 0x32, 0xf8, 0x87, 0x92, 0xc0, 0x91, 0xa7, 0x1b,
- 0x9a, 0x94, 0x04, 0x80, 0x23, 0xce, 0x0c, 0x7a, 0x20, 0x2f, 0xea, 0x5c,
- 0x3e, 0x0a, 0x1a, 0x88, 0x34, 0x3a, 0x70, 0x7f, 0x78, 0x9f, 0x00, 0xb6,
- 0x71, 0x29, 0xd5, 0x15, 0x29, 0xbb, 0x31, 0xc0, 0x16, 0x07, 0x49, 0x88,
- 0x8f, 0x35, 0x03, 0x1e, 0x51, 0x02, 0x59, 0xba, 0xdf, 0xf6, 0x4f, 0x51,
- 0x54, 0x2d, 0xfc, 0xbf, 0x74, 0xc7, 0x4b, 0x15, 0x4c, 0x01, 0xe4, 0xb0,
- 0x29, 0x03, 0x67, 0x3c, 0xbb, 0x1b, 0xf6, 0xd9, 0xd6, 0x15, 0x1d, 0xeb,
- 0x79, 0xbb, 0xe3, 0xbb, 0xc5, 0x03, 0xee, 0x16, 0xa9, 0x6d, 0x6d, 0x3f,
- 0x42, 0x00, 0xfc, 0xf0, 0x0b, 0xb0, 0x15, 0x02, 0xcb, 0x43, 0x07, 0x12,
- 0x5c, 0x01, 0x54, 0x19, 0x9f, 0xe2, 0x9f, 0x48, 0x3a, 0x11, 0x85, 0xf0,
- 0x65, 0x24, 0x01, 0xcd, 0xbb, 0x63, 0x00, 0x8d, 0xca, 0x44, 0x01, 0x24,
- 0x69, 0x61, 0x96, 0xe7, 0xa9, 0xec, 0x66, 0x40, 0xc5, 0x72, 0x50, 0x86,
- 0x18, 0x66, 0x19, 0x23, 0x14, 0x68, 0x0f, 0xec, 0x27, 0x79, 0xab, 0xa0,
- 0x09, 0xa3, 0xb7, 0xdb, 0xd5, 0x92, 0x92, 0x2d, 0xc8, 0x87, 0xf0, 0x75,
- 0x05, 0x4f, 0xa0, 0xd9, 0x8b, 0x8a, 0xc0, 0xa0, 0xfd, 0xdf, 0x20, 0x30,
- 0x14, 0x85, 0x86, 0xab, 0x53, 0xf0, 0x0a, 0x00, 0x46, 0xae, 0x28, 0x62,
- 0x55, 0x44, 0x0e, 0xa2, 0x34, 0xdd, 0x2c, 0x1e, 0x66, 0x02, 0x6c, 0x5b,
- 0xdb, 0x27, 0x25, 0x20, 0x59, 0xde, 0xb9, 0xf0, 0xc7, 0xc3, 0x09, 0xe0,
- 0x80, 0x48, 0x90, 0xe3, 0x95, 0x08, 0xad, 0x90, 0x87, 0xba, 0xa8, 0x10,
- 0xc0, 0xa2, 0x9a, 0x68, 0x3c, 0xa2, 0xf4, 0xf0, 0x87, 0x5d, 0xbb, 0xa8,
- 0x00, 0x5c, 0xd4, 0x59, 0x57, 0x00, 0x58, 0x56, 0x00, 0x04, 0x97, 0xd2,
- 0x03, 0x3c, 0xef, 0xe5, 0x1f, 0x50, 0x34, 0x50, 0x67, 0xfd, 0x15, 0x97,
- 0x8a, 0x64, 0x5d, 0xef, 0x46, 0x08, 0xa7, 0x1d, 0xd7, 0x28, 0x01, 0x78,
- 0x6e, 0xee, 0x59, 0x7c, 0xa8, 0x7c, 0x74, 0x89, 0xc0, 0xea, 0xdc, 0xff,
- 0xcc, 0x7f, 0xce, 0x1e, 0xea, 0xac, 0x3f, 0xc2, 0x2b, 0x80, 0x83, 0xe0,
- 0xf6, 0xea, 0x64, 0x42, 0x9c, 0xbc, 0x99, 0x52, 0xa6, 0x0b, 0x5d, 0x01,
- 0xb4, 0x3d, 0x8b, 0x00, 0xfe, 0x5e, 0x15, 0x52, 0xc5, 0x19, 0xc0, 0x75,
- 0xde, 0x58, 0xe6, 0xb6, 0x98, 0x68, 0xe0, 0x30, 0x11, 0xc8, 0x73, 0x4f,
- 0xbf, 0x16, 0x33, 0xe8, 0xa9, 0xb6, 0xd7, 0xef, 0xef, 0x01, 0x20, 0xef,
- 0x01, 0xcc, 0x7b, 0xb0, 0xaa, 0x65, 0x46, 0x00, 0x88, 0x89, 0xee, 0x1f,
- 0x67, 0xb0, 0xb4, 0x90, 0x9b, 0xd2, 0x1e, 0x09, 0xfb, 0x7f, 0x80, 0xe6,
- 0x99, 0x60, 0x15, 0x29, 0x21, 0x19, 0xc2, 0x64, 0x49, 0x60, 0x3e, 0xda,
- 0x15, 0x01, 0xd4, 0x27, 0xee, 0xb6, 0x15, 0x7d, 0x9e, 0x4c, 0x62, 0xb9,
- 0xaf, 0x86, 0xde, 0x02, 0x68, 0xfb, 0xa3, 0x04, 0x30, 0x79, 0x23, 0xe8,
- 0xd9, 0xc5, 0x69, 0x92, 0x80, 0xb8, 0xaa, 0x07, 0x8a, 0x27, 0xec, 0x04,
- 0x02, 0x00, 0xcf, 0x0d, 0x91, 0xde, 0xf3, 0x21, 0x11, 0x29, 0x24, 0xdd,
- 0xf4, 0x17, 0x67, 0x12, 0x8e, 0x5a, 0x4a, 0x0d, 0xa0, 0x90, 0x68, 0xe4,
- 0x2d, 0xa0, 0x94, 0x65, 0xf3, 0x5d, 0x38, 0xd7, 0x2e, 0xde, 0x02, 0x22,
- 0x55, 0x1b, 0x33, 0xc1, 0x8a, 0x77, 0x35, 0x18, 0xa0, 0xa7, 0x6f, 0x01,
- 0x25, 0xb9, 0x8c, 0x24, 0x2c, 0x11, 0xc1, 0x52, 0x64, 0xb2, 0xff, 0xcc,
- 0x9d, 0x53, 0xff, 0x19, 0x2b, 0x35, 0xfe, 0xbe, 0x2b, 0x13, 0xfa, 0x06,
- 0x14, 0x84, 0xd0, 0xa7, 0x4b, 0xb7, 0x5a, 0xe7, 0xa5, 0x50, 0xbf, 0x68,
- 0x39, 0x79, 0xd0, 0xe0, 0x79, 0x05, 0x30, 0x5b, 0x2d, 0x79, 0x05, 0xb6,
- 0xb5, 0x7d, 0x02, 0x37, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xfe, 0x27, 0xfb,
- 0x05, 0x36, 0xf6, 0x29, 0xcf, 0xfc, 0x99, 0x25, 0xd1, 0x00, 0x00, 0x00,
- 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
- };
+unsigned char FONT_PNG_DATA[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
+ 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x03, 0x00, 0x00, 0x00, 0x08, 0xb3, 0xc4, 0x0e, 0x00, 0x00, 0x00,
+ 0x06, 0x50, 0x4c, 0x54, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa5,
+ 0xd9, 0x9f, 0xdd, 0x00, 0x00, 0x03, 0x12, 0x49, 0x44, 0x41, 0x54, 0x68,
+ 0xde, 0xed, 0x5a, 0x81, 0x76, 0x9c, 0x30, 0x0c, 0x93, 0xff, 0xff, 0xa7,
+ 0xf7, 0xda, 0x83, 0x20, 0xc9, 0x0e, 0x81, 0x5b, 0xdf, 0x8d, 0x6d, 0xf6,
+ 0xbb, 0xa6, 0x94, 0xa3, 0xc1, 0x71, 0x82, 0x64, 0x2b, 0x20, 0xbe, 0x0d,
+ 0x5f, 0x56, 0xb4, 0xbb, 0x21, 0xb5, 0x4f, 0x33, 0xbc, 0x1a, 0x8c, 0xf6,
+ 0x75, 0x28, 0x2e, 0xd3, 0xaf, 0xeb, 0x83, 0xd8, 0xc2, 0x80, 0x71, 0x3c,
+ 0x22, 0x43, 0xc7, 0x74, 0x7e, 0x3f, 0x81, 0xda, 0x45, 0x0e, 0x24, 0x5d,
+ 0x39, 0x7a, 0xd6, 0x63, 0x99, 0x8b, 0x57, 0x33, 0x6e, 0xbc, 0x77, 0x41,
+ 0x43, 0xa6, 0x63, 0x4c, 0xfb, 0x0c, 0x9e, 0x65, 0x0b, 0x9a, 0xb5, 0x34,
+ 0xba, 0x11, 0x8d, 0xb4, 0x06, 0x50, 0x1c, 0xa5, 0x6f, 0xe0, 0xe7, 0xd2,
+ 0x5c, 0x00, 0xef, 0xcc, 0xf8, 0xd5, 0x39, 0xd4, 0xf5, 0x90, 0xbe, 0xe3,
+ 0x5e, 0xd5, 0x55, 0x70, 0x2b, 0x0b, 0x02, 0xd5, 0x14, 0xfe, 0xdc, 0x7a,
+ 0x7e, 0xe6, 0x63, 0xd6, 0xf6, 0x8f, 0x19, 0x94, 0x00, 0xfc, 0x23, 0x20,
+ 0x88, 0x27, 0x33, 0x40, 0x22, 0x80, 0x7d, 0x44, 0xdf, 0x7f, 0x62, 0x42,
+ 0x63, 0xab, 0x01, 0x11, 0x98, 0x32, 0x5a, 0x0d, 0x04, 0x80, 0x61, 0x11,
+ 0x1c, 0x82, 0x4f, 0x40, 0x73, 0x01, 0xbe, 0x29, 0xe0, 0xd2, 0x33, 0xdd,
+ 0x79, 0x7c, 0x5e, 0xb7, 0xc2, 0xb5, 0x3e, 0xaf, 0xf8, 0xa0, 0x57, 0xa5,
+ 0x38, 0x5f, 0x27, 0x00, 0x0c, 0xb6, 0xac, 0x62, 0x8d, 0x78, 0x6b, 0x59,
+ 0xe1, 0xe6, 0x95, 0x60, 0xff, 0x43, 0x5d, 0x53, 0xa6, 0x50, 0x46, 0xaa,
+ 0xa2, 0x1f, 0x16, 0x45, 0x78, 0x50, 0x7e, 0x7f, 0x25, 0x47, 0x33, 0x40,
+ 0xdb, 0xa7, 0x09, 0x20, 0x76, 0xb8, 0x44, 0xf0, 0xc3, 0xba, 0x41, 0x28,
+ 0x04, 0xcf, 0x1e, 0x4b, 0x00, 0xfb, 0x58, 0x18, 0x22, 0x8b, 0x87, 0x9f,
+ 0xa8, 0x01, 0x27, 0x9d, 0x32, 0xf8, 0x87, 0x92, 0xc0, 0x91, 0xa7, 0x1b,
+ 0x9a, 0x94, 0x04, 0x80, 0x23, 0xce, 0x0c, 0x7a, 0x20, 0x2f, 0xea, 0x5c,
+ 0x3e, 0x0a, 0x1a, 0x88, 0x34, 0x3a, 0x70, 0x7f, 0x78, 0x9f, 0x00, 0xb6,
+ 0x71, 0x29, 0xd5, 0x15, 0x29, 0xbb, 0x31, 0xc0, 0x16, 0x07, 0x49, 0x88,
+ 0x8f, 0x35, 0x03, 0x1e, 0x51, 0x02, 0x59, 0xba, 0xdf, 0xf6, 0x4f, 0x51,
+ 0x54, 0x2d, 0xfc, 0xbf, 0x74, 0xc7, 0x4b, 0x15, 0x4c, 0x01, 0xe4, 0xb0,
+ 0x29, 0x03, 0x67, 0x3c, 0xbb, 0x1b, 0xf6, 0xd9, 0xd6, 0x15, 0x1d, 0xeb,
+ 0x79, 0xbb, 0xe3, 0xbb, 0xc5, 0x03, 0xee, 0x16, 0xa9, 0x6d, 0x6d, 0x3f,
+ 0x42, 0x00, 0xfc, 0xf0, 0x0b, 0xb0, 0x15, 0x02, 0xcb, 0x43, 0x07, 0x12,
+ 0x5c, 0x01, 0x54, 0x19, 0x9f, 0xe2, 0x9f, 0x48, 0x3a, 0x11, 0x85, 0xf0,
+ 0x65, 0x24, 0x01, 0xcd, 0xbb, 0x63, 0x00, 0x8d, 0xca, 0x44, 0x01, 0x24,
+ 0x69, 0x61, 0x96, 0xe7, 0xa9, 0xec, 0x66, 0x40, 0xc5, 0x72, 0x50, 0x86,
+ 0x18, 0x66, 0x19, 0x23, 0x14, 0x68, 0x0f, 0xec, 0x27, 0x79, 0xab, 0xa0,
+ 0x09, 0xa3, 0xb7, 0xdb, 0xd5, 0x92, 0x92, 0x2d, 0xc8, 0x87, 0xf0, 0x75,
+ 0x05, 0x4f, 0xa0, 0xd9, 0x8b, 0x8a, 0xc0, 0xa0, 0xfd, 0xdf, 0x20, 0x30,
+ 0x14, 0x85, 0x86, 0xab, 0x53, 0xf0, 0x0a, 0x00, 0x46, 0xae, 0x28, 0x62,
+ 0x55, 0x44, 0x0e, 0xa2, 0x34, 0xdd, 0x2c, 0x1e, 0x66, 0x02, 0x6c, 0x5b,
+ 0xdb, 0x27, 0x25, 0x20, 0x59, 0xde, 0xb9, 0xf0, 0xc7, 0xc3, 0x09, 0xe0,
+ 0x80, 0x48, 0x90, 0xe3, 0x95, 0x08, 0xad, 0x90, 0x87, 0xba, 0xa8, 0x10,
+ 0xc0, 0xa2, 0x9a, 0x68, 0x3c, 0xa2, 0xf4, 0xf0, 0x87, 0x5d, 0xbb, 0xa8,
+ 0x00, 0x5c, 0xd4, 0x59, 0x57, 0x00, 0x58, 0x56, 0x00, 0x04, 0x97, 0xd2,
+ 0x03, 0x3c, 0xef, 0xe5, 0x1f, 0x50, 0x34, 0x50, 0x67, 0xfd, 0x15, 0x97,
+ 0x8a, 0x64, 0x5d, 0xef, 0x46, 0x08, 0xa7, 0x1d, 0xd7, 0x28, 0x01, 0x78,
+ 0x6e, 0xee, 0x59, 0x7c, 0xa8, 0x7c, 0x74, 0x89, 0xc0, 0xea, 0xdc, 0xff,
+ 0xcc, 0x7f, 0xce, 0x1e, 0xea, 0xac, 0x3f, 0xc2, 0x2b, 0x80, 0x83, 0xe0,
+ 0xf6, 0xea, 0x64, 0x42, 0x9c, 0xbc, 0x99, 0x52, 0xa6, 0x0b, 0x5d, 0x01,
+ 0xb4, 0x3d, 0x8b, 0x00, 0xfe, 0x5e, 0x15, 0x52, 0xc5, 0x19, 0xc0, 0x75,
+ 0xde, 0x58, 0xe6, 0xb6, 0x98, 0x68, 0xe0, 0x30, 0x11, 0xc8, 0x73, 0x4f,
+ 0xbf, 0x16, 0x33, 0xe8, 0xa9, 0xb6, 0xd7, 0xef, 0xef, 0x01, 0x20, 0xef,
+ 0x01, 0xcc, 0x7b, 0xb0, 0xaa, 0x65, 0x46, 0x00, 0x88, 0x89, 0xee, 0x1f,
+ 0x67, 0xb0, 0xb4, 0x90, 0x9b, 0xd2, 0x1e, 0x09, 0xfb, 0x7f, 0x80, 0xe6,
+ 0x99, 0x60, 0x15, 0x29, 0x21, 0x19, 0xc2, 0x64, 0x49, 0x60, 0x3e, 0xda,
+ 0x15, 0x01, 0xd4, 0x27, 0xee, 0xb6, 0x15, 0x7d, 0x9e, 0x4c, 0x62, 0xb9,
+ 0xaf, 0x86, 0xde, 0x02, 0x68, 0xfb, 0xa3, 0x04, 0x30, 0x79, 0x23, 0xe8,
+ 0xd9, 0xc5, 0x69, 0x92, 0x80, 0xb8, 0xaa, 0x07, 0x8a, 0x27, 0xec, 0x04,
+ 0x02, 0x00, 0xcf, 0x0d, 0x91, 0xde, 0xf3, 0x21, 0x11, 0x29, 0x24, 0xdd,
+ 0xf4, 0x17, 0x67, 0x12, 0x8e, 0x5a, 0x4a, 0x0d, 0xa0, 0x90, 0x68, 0xe4,
+ 0x2d, 0xa0, 0x94, 0x65, 0xf3, 0x5d, 0x38, 0xd7, 0x2e, 0xde, 0x02, 0x22,
+ 0x55, 0x1b, 0x33, 0xc1, 0x8a, 0x77, 0x35, 0x18, 0xa0, 0xa7, 0x6f, 0x01,
+ 0x25, 0xb9, 0x8c, 0x24, 0x2c, 0x11, 0xc1, 0x52, 0x64, 0xb2, 0xff, 0xcc,
+ 0x9d, 0x53, 0xff, 0x19, 0x2b, 0x35, 0xfe, 0xbe, 0x2b, 0x13, 0xfa, 0x06,
+ 0x14, 0x84, 0xd0, 0xa7, 0x4b, 0xb7, 0x5a, 0xe7, 0xa5, 0x50, 0xbf, 0x68,
+ 0x39, 0x79, 0xd0, 0xe0, 0x79, 0x05, 0x30, 0x5b, 0x2d, 0x79, 0x05, 0xb6,
+ 0xb5, 0x7d, 0x02, 0x37, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xfe, 0x27, 0xfb,
+ 0x05, 0x36, 0xf6, 0x29, 0xcf, 0xfc, 0x99, 0x25, 0xd1, 0x00, 0x00, 0x00,
+ 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
diff --git a/src/font.h b/src/font.h
index f735adf..26feda8 100644
--- a/src/font.h
+++ b/src/font.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,12 +21,12 @@
#include <SDL.h>
int
-font_init (void);
+font_init(void);
void
-font_free (void);
+font_free(void);
SDL_Surface *
-get_font_char (int c);
+get_font_char(int c);
#endif
diff --git a/src/keys.c b/src/keys.c
index b87a295..0b5e7d8 100644
--- a/src/keys.c
+++ b/src/keys.c
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -18,113 +18,113 @@
#include "keys.h"
#include "tibchar.h"
-static const SDL_Keycode UNCHANGED_RANGES[] =
- {
- SDLK_0, SDLK_9
- };
+static const SDL_Keycode UNCHANGED_RANGES[] = {
+ SDLK_0, SDLK_9
+};
-static const SDL_Keycode UNCHANGED[] =
- {
- SDLK_PERIOD,
- SDLK_MINUS,
- SDLK_SLASH,
+static const SDL_Keycode UNCHANGED[] = {
+ SDLK_PERIOD,
+ SDLK_MINUS,
+ SDLK_SLASH,
- SDLK_e,
- SDLK_i
- };
+ SDLK_e,
+ SDLK_i
+};
int
-normalize_keycode (SDL_Keycode code, SDL_Keymod mod)
+normalize_keycode(SDL_Keycode code, SDL_Keymod mod)
{
- if (mod & KMOD_CTRL)
- {
- switch (code)
- {
- case SDLK_a:
- return TIB_CHAR_ANS;
-
- case SDLK_d:
- return TIB_CHAR_DEGREE;
-
- case SDLK_e:
- return TIB_CHAR_EPOW10;
-
- case SDLK_p:
- return TIB_CHAR_PI;
- }
- }
- else if (mod & KMOD_SHIFT)
- {
- switch (code)
- {
- case SDLK_EQUALS:
- return '+';
-
- case SDLK_1:
- return '!';
-
- case SDLK_4:
- return TIB_CHAR_STO;
-
- case SDLK_6:
- return '^';
-
- case SDLK_8:
- return '*';
-
- case SDLK_9:
- return '(';
-
- case SDLK_0:
- return ')';
- }
- }
- else
- {
- switch (code)
- {
- case SDLK_KP_0:
- return '0';
-
- case SDLK_KP_PERIOD:
- return '.';
-
- case SDLK_KP_PLUS:
- return '+';
-
- case SDLK_KP_MINUS:
- return '-';
-
- case SDLK_KP_MULTIPLY:
- return '*';
-
- case SDLK_KP_DIVIDE:
- return '/';
-
- case SDLK_c:
- return TIB_CHAR_COS;
-
- case SDLK_s:
- return TIB_CHAR_SIN;
-
- case SDLK_t:
- return TIB_CHAR_TAN;
- }
- }
-
- for (unsigned int i = 0; i < (sizeof UNCHANGED_RANGES / sizeof (int)); ++i)
- if (code >= UNCHANGED_RANGES[i++] && code <= UNCHANGED_RANGES[i])
- return code;
-
- for (unsigned int i = 0; i < (sizeof UNCHANGED / sizeof (int)); ++i)
- if (code == UNCHANGED[i])
- return code;
-
- if (code >= SDLK_KP_1 && code <= SDLK_KP_9)
- return code - SDLK_KP_1 + '1';
-
- if (code >= SDLK_a && code <= SDLK_z)
- return code - SDLK_a + 'A';
-
- return 0;
+ if (mod & KMOD_CTRL)
+ {
+ switch (code)
+ {
+ case SDLK_a:
+ return TIB_CHAR_ANS;
+
+ case SDLK_d:
+ return TIB_CHAR_DEGREE;
+
+ case SDLK_e:
+ return TIB_CHAR_EPOW10;
+
+ case SDLK_p:
+ return TIB_CHAR_PI;
+ }
+ }
+ else if (mod & KMOD_SHIFT)
+ {
+ switch (code)
+ {
+ case SDLK_EQUALS:
+ return '+';
+
+ case SDLK_1:
+ return '!';
+
+ case SDLK_4:
+ return TIB_CHAR_STO;
+
+ case SDLK_6:
+ return '^';
+
+ case SDLK_8:
+ return '*';
+
+ case SDLK_9:
+ return '(';
+
+ case SDLK_0:
+ return ')';
+ }
+ }
+ else
+ {
+ switch (code)
+ {
+ case SDLK_KP_0:
+ return '0';
+
+ case SDLK_KP_PERIOD:
+ return '.';
+
+ case SDLK_KP_PLUS:
+ return '+';
+
+ case SDLK_KP_MINUS:
+ return '-';
+
+ case SDLK_KP_MULTIPLY:
+ return '*';
+
+ case SDLK_KP_DIVIDE:
+ return '/';
+
+ case SDLK_c:
+ return TIB_CHAR_COS;
+
+ case SDLK_s:
+ return TIB_CHAR_SIN;
+
+ case SDLK_t:
+ return TIB_CHAR_TAN;
+ }
+ }
+
+ for (unsigned int i = 0; i < (sizeof UNCHANGED_RANGES / sizeof(int));
+ ++i)
+ if (code >= UNCHANGED_RANGES[i++]
+ && code <= UNCHANGED_RANGES[i])
+ return code;
+
+ for (unsigned int i = 0; i < (sizeof UNCHANGED / sizeof(int)); ++i)
+ if (code == UNCHANGED[i])
+ return code;
+
+ if (code >= SDLK_KP_1 && code <= SDLK_KP_9)
+ return code - SDLK_KP_1 + '1';
+
+ if (code >= SDLK_a && code <= SDLK_z)
+ return code - SDLK_a + 'A';
+
+ return 0;
}
diff --git a/src/keys.h b/src/keys.h
index 63e3e44..256dd85 100644
--- a/src/keys.h
+++ b/src/keys.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,6 +21,6 @@
#include <SDL.h>
int
-normalize_keycode (SDL_Keycode code, SDL_Keymod mod);
+normalize_keycode(SDL_Keycode code, SDL_Keymod mod);
#endif
diff --git a/src/liberti.c b/src/liberti.c
index 89ea691..2bcc175 100644
--- a/src/liberti.c
+++ b/src/liberti.c
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -23,7 +23,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
-#include <getopt.h>
#include <wordexp.h>
#include "font.h"
@@ -33,342 +32,338 @@
#include "tibfunction.h"
#include "tibvar.h"
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-# define VERSION_STRING PACKAGE_VERSION
-# define PROG PACKAGE
-#else
-# define VERSION_STRING "custom build"
-# define PROG "liberti"
-#endif
+#define VERSION_STRING "0.0.0"
+#define PROG "liberti"
#define USAGE_INFO "USAGE: " PROG " [options]\n\n\
OPTIONS:\n\
-\t-d, --debug\tPrints extra activity while running\n\
-\t-h, --help\tPrints this help message and exits\n\
-\t-v, --version\tPrints version info and exits\n"
+\t-d\tPrints extra activity while running\n\
+\t-h\tPrints this help message and exits\n\
+\t-v\tPrints version info and exits\n"
#define VERSION_INFO "LiberTI " VERSION_STRING "\n\
-Copyright (C) 2015-2016 Delwink, LLC\n\
+Copyright (C) 2015-2017 Delwink, LLC\n\
License AGPLv3: GNU AGPL version 3 only <http://gnu.org/licenses/agpl.html>.\n\
This is libre software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n\n\
Written by David McMackins II."
#ifdef RUN_IN_PLACE
-# define USER_DIR "."
+#define USER_DIR "."
#else
-# define USER_DIR "~/.liberti"
+#define USER_DIR "~/.liberti"
#endif
#define USER_STATE_PATH "state.conf"
static Uint32
-timer (Uint32 interval, void *data)
+timer(Uint32 interval, void *data)
{
- SDL_Event event;
- SDL_UserEvent user;
+ SDL_Event event;
+ SDL_UserEvent user;
- user.type = SDL_USEREVENT;
- user.code = 0;
- user.data1 = data;
+ user.type = SDL_USEREVENT;
+ user.code = 0;
+ user.data1 = data;
- event.type = SDL_USEREVENT;
- event.user = user;
+ event.type = SDL_USEREVENT;
+ event.user = user;
- SDL_PushEvent (&event);
- return interval;
+ SDL_PushEvent(&event);
+ return interval;
}
static char *
-get_conf_path (const char *path)
+get_conf_path(const char *path)
{
- wordexp_t w;
- int rc = wordexp (USER_DIR, &w, 0);
- if (rc)
- return NULL;
-
- size_t len = strlen (w.we_wordv[0]) + strlen (path) + 2;
- char *out = malloc (len * sizeof (char));
- if (out)
- snprintf (out, len, "%s/%s", w.we_wordv[0], path);
-
- wordfree (&w);
- return out;
+ wordexp_t w;
+ int rc = wordexp(USER_DIR, &w, 0);
+ if (rc)
+ return NULL;
+
+ size_t len = strlen(w.we_wordv[0]) + strlen(path) + 2;
+ char *out = malloc(len * sizeof(char));
+ if (out)
+ snprintf(out, len, "%s/%s", w.we_wordv[0], path);
+
+ wordfree(&w);
+ return out;
}
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- bool user_dir_exists = false, state_file_exists = false, state_init = false;
- int rc = 0;
- SDL_TimerID timer_id = 0;
- SDL_Window *window = NULL;
- Skin *skin = NULL;
-
- char *skin_path = NULL, *state_path = NULL;
- Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
-
- struct option longopts[] =
- {
- {"debug", no_argument, 0, 'd'},
- {"fullscreen", no_argument, 0, 'f'},
- {"help", no_argument, 0, 'h'},
- {"skin", required_argument, 0, 's'},
- {"version", no_argument, 0, 'v'},
- {0, 0, 0, 0}
- };
-
- if (argc > 1)
- {
- int c;
- int longindex;
- while ((c = getopt_long (argc, argv, "dfhs:v", longopts, &longindex))
- != -1)
- {
- switch (c)
- {
- case 'd':
- debug_mode = true;
- break;
-
- case 'f':
- window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
- break;
-
- case 'h':
- puts (USAGE_INFO);
- return 0;
-
- case 's':
- skin_path = optarg;
- break;
-
- case 'v':
- puts (VERSION_INFO);
- return 0;
-
- case '?':
- return 1;
- }
- }
- }
-
- gsl_set_error_handler_off ();
-
- rc = SDL_Init (SDL_INIT_TIMER);
- if (rc)
- {
- critical ("Could not initialize SDL timer: %s", SDL_GetError ());
- goto end;
- }
-
- rc = SDL_VideoInit (NULL);
- if (rc)
- {
- critical ("Could not initialize SDL video: %s", SDL_GetError ());
- goto end;
- }
-
- rc = IMG_Init (IMG_INIT_PNG);
- if (rc != IMG_INIT_PNG)
- {
- critical ("Could not initialize PNG image library: %s", IMG_GetError ());
- rc = 1;
- goto end;
- }
-
- rc = font_init ();
- if (rc)
- goto end;
-
- rc = tib_keyword_init ();
- if (rc)
- {
- critical ("Could not initialize TI-BASIC keyword lookup tree: Error %d",
- rc);
- goto end;
- }
-
- rc = tib_var_init ();
- if (rc)
- {
- critical ("Could not initialize default variables: Error %d", rc);
- goto end;
- }
-
- rc = tib_registry_init ();
- if (rc)
- {
- critical ("Could not initialize function registry: Error %d", rc);
- goto end;
- }
-
- SDL_DisplayMode display_mode;
- rc = SDL_GetCurrentDisplayMode (0, &display_mode);
- if (rc)
- {
- critical ("Could not get screen information: %s", SDL_GetError ());
- goto end;
- }
-
- debug ("Screen resolution: %dx%d", display_mode.w, display_mode.h);
-
- {
- char *user_dir_path = get_conf_path ("");
- if (user_dir_path)
- {
- rc = mkdir (user_dir_path, 0755);
- free (user_dir_path);
- if (rc && EEXIST != errno)
- {
- warn ("Failed to create config directory: %s", strerror (errno));
- }
- else
- {
- user_dir_exists = true;
-
- state_path = get_conf_path (USER_STATE_PATH);
- if (state_path)
- {
- rc = access (state_path, F_OK);
- if (rc)
- {
- debug ("Can't open state file: %s", strerror (errno));
- info ("Loading empty state");
- }
- else
- {
- state_file_exists = true;
- info ("Loading state from %s", state_path);
- }
- }
- }
- }
- else
- {
- warn ("Could not determine config path");
- }
- }
-
- struct state state;
- rc = load_state (&state, state_file_exists ? state_path : NULL);
- if (rc)
- {
- critical ("Could not initialize calculator state. Error %d", rc);
- goto end;
- }
-
- state_init = true;
-
- timer_id = SDL_AddTimer (500, timer, &state);
- if (!timer_id)
- {
- critical ("Could not add blink timer: %s", SDL_GetError ());
- goto end;
- }
-
- skin = open_skin (skin_path, &state, (struct point2d) { 96, 64 });
- if (!skin)
- {
- critical ("Could not load skin");
- goto end;
- }
-
- window = SDL_CreateWindow ("LiberTI " VERSION_STRING,
- SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED,
- skin->size.x,
- skin->size.y,
- window_flags);
- if (!window)
- {
- critical ("Could not create window: %s", SDL_GetError ());
- goto end;
- }
-
- for (;;)
- {
- SDL_Surface *frame = Skin_get_frame (skin);
- if (frame)
- {
- SDL_Surface *screen = SDL_GetWindowSurface (window);
- SDL_BlitScaled (frame, NULL, screen, NULL);
- SDL_FreeSurface (frame);
- SDL_UpdateWindowSurface (window);
- }
-
- SDL_Event event;
- SDL_WaitEvent (NULL);
-
- while (SDL_PollEvent (&event))
- {
- switch (event.type)
- {
- case SDL_KEYDOWN:
- rc = Skin_input (skin, &event.key);
- if (rc)
- error ("Error %d processing key entry", rc);
- break;
-
- case SDL_USEREVENT:
- switch (event.user.code)
- {
- case 0:
- {
- struct state *state = event.user.data1;
- state->blink_state = !state->blink_state;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case SDL_QUIT:
- info ("Got SDL quit event");
- goto end;
-
- default:
- break;
- }
- }
- }
+ bool user_dir_exists = false, state_file_exists = false;
+ bool state_init = false;
+ int rc = 0;
+ SDL_TimerID timer_id = 0;
+ SDL_Window *window = NULL;
+ Skin *skin = NULL;
+
+ char *skin_path = NULL, *state_path = NULL;
+ Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
+
+ if (argc > 1)
+ {
+ int c;
+ while ((c = getopt(argc, argv, ":dfhs:v")) != -1)
+ {
+ switch (c)
+ {
+ case 'd':
+ debug_mode = true;
+ break;
+
+ case 'f':
+ window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
+ break;
+
+ case 'h':
+ puts(USAGE_INFO);
+ return 0;
+
+ case 's':
+ skin_path = optarg;
+ break;
+
+ case 'v':
+ puts(VERSION_INFO);
+ return 0;
+
+ case ':':
+ fprintf(stderr,
+ PROG ": option -%c requires an argument\n",
+ optopt);
+ // SPILLS OVER!
+
+ case '?':
+ return 1;
+ }
+ }
+ }
+
+ gsl_set_error_handler_off();
+
+ rc = SDL_Init(SDL_INIT_TIMER);
+ if (rc)
+ {
+ critical("Could not initialize SDL timer: %s", SDL_GetError());
+ goto end;
+ }
+
+ rc = SDL_VideoInit(NULL);
+ if (rc)
+ {
+ critical("Could not initialize SDL video: %s", SDL_GetError());
+ goto end;
+ }
+
+ rc = IMG_Init(IMG_INIT_PNG);
+ if (rc != IMG_INIT_PNG)
+ {
+ critical("Could not initialize PNG image library: %s",
+ IMG_GetError());
+ rc = 1;
+ goto end;
+ }
+
+ rc = font_init();
+ if (rc)
+ goto end;
+
+ rc = tib_keyword_init();
+ if (rc)
+ {
+ critical("Could not initialize TI-BASIC keyword lookup tree: Error %d",
+ rc);
+ goto end;
+ }
+
+ rc = tib_var_init();
+ if (rc)
+ {
+ critical("Could not initialize default variables: Error %d",
+ rc);
+ goto end;
+ }
+
+ rc = tib_registry_init();
+ if (rc)
+ {
+ critical("Could not initialize function registry: Error %d",
+ rc);
+ goto end;
+ }
+
+ SDL_DisplayMode display_mode;
+ rc = SDL_GetCurrentDisplayMode(0, &display_mode);
+ if (rc)
+ {
+ critical("Could not get screen information: %s",
+ SDL_GetError());
+ goto end;
+ }
+
+ debug("Screen resolution: %dx%d", display_mode.w, display_mode.h);
+
+ char *user_dir_path = get_conf_path("");
+ if (user_dir_path)
+ {
+ rc = mkdir(user_dir_path, 0755);
+ free(user_dir_path);
+ if (rc && EEXIST != errno)
+ {
+ warn("Failed to create config directory: %s",
+ strerror(errno));
+ }
+ else
+ {
+ user_dir_exists = true;
+
+ state_path = get_conf_path(USER_STATE_PATH);
+ if (state_path)
+ {
+ rc = access(state_path, F_OK);
+ if (rc)
+ {
+ debug("Can't open state file: %s",
+ strerror(errno));
+ info("Loading empty state");
+ }
+ else
+ {
+ state_file_exists = true;
+ info("Loading state from %s",
+ state_path);
+ }
+ }
+ }
+ }
+ else
+ {
+ warn("Could not determine config path");
+ }
+
+ struct state state;
+ rc = load_state(&state, state_file_exists ? state_path : NULL);
+ if (rc)
+ {
+ critical("Could not initialize calculator state. Error %d",
+ rc);
+ goto end;
+ }
+
+ state_init = true;
+
+ timer_id = SDL_AddTimer(500, timer, &state);
+ if (!timer_id)
+ {
+ critical("Could not add blink timer: %s", SDL_GetError());
+ goto end;
+ }
+
+ skin = open_skin(skin_path, &state, (struct point2d) { 96, 64 });
+ if (!skin)
+ {
+ critical("Could not load skin");
+ goto end;
+ }
+
+ window = SDL_CreateWindow("LiberTI " VERSION_STRING,
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ skin->size.x, skin->size.y, window_flags);
+ if (!window)
+ {
+ critical("Could not create window: %s", SDL_GetError());
+ goto end;
+ }
+
+ for (;;)
+ {
+ SDL_Surface *frame = Skin_get_frame(skin);
+ if (frame)
+ {
+ SDL_Surface *screen = SDL_GetWindowSurface(window);
+ SDL_BlitScaled(frame, NULL, screen, NULL);
+ SDL_FreeSurface(frame);
+ SDL_UpdateWindowSurface(window);
+ }
+
+ SDL_Event event;
+ SDL_WaitEvent(NULL);
+
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_KEYDOWN:
+ rc = Skin_input(skin, &event.key);
+ if (rc)
+ error("Error %d processing key entry",
+ rc);
+ break;
+
+ case SDL_USEREVENT:
+ switch (event.user.code)
+ {
+ case 0:
+ {
+ struct state *state =
+ event.user.data1;
+ state->blink_state =
+ !state->blink_state;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SDL_QUIT:
+ info("Got SDL quit event");
+ goto end;
+
+ default:
+ break;
+ }
+ }
+ }
end:
- if (timer_id)
- SDL_RemoveTimer (timer_id);
+ if (timer_id)
+ SDL_RemoveTimer(timer_id);
- SDL_Quit ();
- SDL_VideoQuit ();
- IMG_Quit ();
+ SDL_Quit();
+ SDL_VideoQuit();
+ IMG_Quit();
- font_free ();
- tib_keyword_free ();
- tib_registry_free ();
- tib_var_free ();
+ font_free();
+ tib_keyword_free();
+ tib_registry_free();
+ tib_var_free();
- if (state_init)
- {
- if (user_dir_exists && state_path)
- {
- errno = save_state (&state, state_path);
- if (errno)
- warn ("Failed to save state");
- }
+ if (state_init)
+ {
+ if (user_dir_exists && state_path)
+ {
+ errno = save_state(&state, state_path);
+ if (errno)
+ warn("Failed to save state");
+ }
- state_destroy (&state);
- }
+ state_destroy(&state);
+ }
- if (state_path)
- free (state_path);
+ if (state_path)
+ free(state_path);
- if (skin)
- free_skin (skin);
+ if (skin)
+ free_skin(skin);
- if (window)
- SDL_DestroyWindow (window);
+ if (window)
+ SDL_DestroyWindow(window);
- return !!rc;
+ return !!rc;
}
diff --git a/src/log.c b/src/log.c
index cf7c6ed..168ac31 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -23,46 +23,46 @@
bool debug_mode = false;
-#define log(FMT,FILE,PRE) \
- { \
- fputs (PRE, FILE); \
- va_list ap; \
- va_start (ap, FMT); \
- int n = vfprintf (FILE, FMT, ap); \
- va_end (ap); \
- fputc ('\n', FILE); \
- return n; \
- }
+#define log(FMT,FILE,PRE) \
+ { \
+ fputs(PRE, FILE); \
+ va_list ap; \
+ va_start(ap, FMT); \
+ int n = vfprintf(FILE, FMT, ap); \
+ va_end(ap); \
+ fputc('\n', FILE); \
+ return n; \
+ }
int
-info (const char *fmt, ...)
+info(const char *fmt, ...)
{
- log (fmt, stdout, "[info]: ");
+ log(fmt, stdout, "[info]: ");
}
int
-warn (const char *fmt, ...)
+warn(const char *fmt, ...)
{
- log (fmt, stdout, "[warn]: ");
+ log(fmt, stdout, "[warn]: ");
}
int
-error (const char *fmt, ...)
+error(const char *fmt, ...)
{
- log (fmt, stderr, "[error]: ");
+ log(fmt, stderr, "[error]: ");
}
int
-critical (const char *fmt, ...)
+critical(const char *fmt, ...)
{
- log (fmt, stderr, "[critical]: ");
+ log(fmt, stderr, "[critical]: ");
}
int
-debug (const char *fmt, ...)
+debug(const char *fmt, ...)
{
- if (!debug_mode)
- return 0;
+ if (!debug_mode)
+ return 0;
- log (fmt, stdout, "[debug]: ");
+ log(fmt, stdout, "[debug]: ");
}
diff --git a/src/log.h b/src/log.h
index 4bbe807..789c0f5 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2015 Delwink, LLC
+ * Copyright (C) 2015, 2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -23,18 +23,18 @@
extern bool debug_mode;
int
-info (const char *fmt, ...);
+info(const char *fmt, ...);
int
-warn (const char *fmt, ...);
+warn(const char *fmt, ...);
int
-error (const char *fmt, ...);
+error(const char *fmt, ...);
int
-critical (const char *fmt, ...);
+critical(const char *fmt, ...);
int
-debug (const char *fmt, ...);
+debug(const char *fmt, ...);
#endif
diff --git a/src/mode_default.c b/src/mode_default.c
index fe47654..76b3319 100644
--- a/src/mode_default.c
+++ b/src/mode_default.c
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -28,266 +28,275 @@
#include "util.h"
static SDL_Surface *
-render_line (const struct tib_expr *line, unsigned int *width)
+render_line(const struct tib_expr *line, unsigned int *width)
{
- int rc;
- char *s = get_expr_display_str (line);
- if (!s)
- {
- error ("Error converting expression to string");
- return NULL;
- }
-
- unsigned int len = strlen (s);
- SDL_Surface *parts[len + 1];
- parts[len] = get_font_char (' ');
-
- SDL_Rect pos;
- pos.x = 0;
- pos.y = 8;
-
- for (unsigned int i = 0; i < len; ++i)
- {
- SDL_Surface *part = get_font_char ((unsigned char) s[i]);
-
- pos.x += 6;
- if (pos.x >= 96)
- {
- pos.y += 8;
- pos.x = 6;
- }
-
- parts[i] = part;
- }
-
- SDL_Surface *final = SDL_CreateRGBSurface (0, 96, pos.y, 32, 0, 0, 0, 0);
- if (!final)
- {
- error ("Failed to initialize expression render surface: %s",
- SDL_GetError ());
- goto end;
- }
-
- SDL_LockSurface (final);
-
- rc = SDL_FillRect (final, NULL, SDL_MapRGB (final->format, 255, 255, 255));
- if (rc < 0)
- error ("Failed to set background of expression render surface: %s",
- SDL_GetError ());
-
- SDL_UnlockSurface (final);
-
- pos.x = 0;
- pos.y = 0;
- for (unsigned int i = 0; i <= len; ++i)
- {
- if (pos.x + 6 > 96)
- {
- pos.x = 0;
- pos.y += 8;
- }
-
- rc = SDL_BlitSurface (parts[i], NULL, final, &pos);
- if (rc < 0)
- {
- error ("Failed to blit expression portion: %s", SDL_GetError ());
- continue;
- }
-
- pos.x += 6;
- }
-
- *width = min (16, len) * 6;
+ int rc;
+ char *s = get_expr_display_str(line);
+ if (!s)
+ {
+ error("Error converting expression to string");
+ return NULL;
+ }
+
+ unsigned int len = strlen(s);
+ SDL_Surface *parts[len + 1];
+ parts[len] = get_font_char(' ');
+
+ SDL_Rect pos;
+ pos.x = 0;
+ pos.y = 8;
+
+ for (unsigned int i = 0; i < len; ++i)
+ {
+ SDL_Surface *part = get_font_char((unsigned char) s[i]);
+
+ pos.x += 6;
+ if (pos.x >= 96)
+ {
+ pos.y += 8;
+ pos.x = 6;
+ }
+
+ parts[i] = part;
+ }
+
+ SDL_Surface *final = SDL_CreateRGBSurface(0, 96, pos.y, 32, 0, 0, 0,
+ 0);
+ if (!final)
+ {
+ error("Failed to initialize expression render surface: %s",
+ SDL_GetError());
+ goto end;
+ }
+
+ SDL_LockSurface(final);
+
+ rc = SDL_FillRect(final, NULL,
+ SDL_MapRGB(final->format, 255, 255, 255));
+ if (rc < 0)
+ error("Failed to set background of expression render surface: %s",
+ SDL_GetError());
+
+ SDL_UnlockSurface(final);
+
+ pos.x = 0;
+ pos.y = 0;
+ for (unsigned int i = 0; i <= len; ++i)
+ {
+ if (pos.x + 6 > 96)
+ {
+ pos.x = 0;
+ pos.y += 8;
+ }
+
+ rc = SDL_BlitSurface(parts[i], NULL, final, &pos);
+ if (rc < 0)
+ {
+ error("Failed to blit expression portion: %s",
+ SDL_GetError());
+ continue;
+ }
+
+ pos.x += 6;
+ }
+
+ *width = min(16, len) * 6;
end:
- free (s);
- return final;
+ free(s);
+ return final;
}
static void
-draw_line (const struct tib_expr *line, SDL_Surface *final,
- unsigned int *height, bool right_align)
+draw_line(const struct tib_expr *line, SDL_Surface *final,
+ unsigned int *height, bool right_align)
{
- unsigned int width;
-
- SDL_Surface *line_render = render_line (line, &width);
- if (line_render)
- {
- SDL_Rect pos;
- if (right_align)
- pos.x = 96 - width;
- else
- pos.x = 0;
-
- *height += line_render->h;
- pos.y = 64 - *height;
-
- int rc = SDL_BlitSurface (line_render, NULL, final, &pos);
- if (rc < 0)
- error ("Failed to draw line on screen frame: %s", SDL_GetError ());
-
- SDL_FreeSurface (line_render);
- }
+ unsigned int width;
+
+ SDL_Surface *line_render = render_line(line, &width);
+ if (line_render)
+ {
+ SDL_Rect pos;
+ if (right_align)
+ pos.x = 96 - width;
+ else
+ pos.x = 0;
+
+ *height += line_render->h;
+ pos.y = 64 - *height;
+
+ int rc = SDL_BlitSurface(line_render, NULL, final, &pos);
+ if (rc < 0)
+ error("Failed to draw line on screen frame: %s",
+ SDL_GetError());
+
+ SDL_FreeSurface(line_render);
+ }
}
static void
-draw_cursor (const struct state *state, SDL_Surface *frame)
+draw_cursor(const struct state *state, SDL_Surface *frame)
{
- if (!state->blink_state)
- return;
-
- SDL_Keymod mod = SDL_GetModState ();
- int c = 1;
-
- if (state->insert_mode)
- c += 4;
-
- if (STATE_2ND == state->action_state || mod & KMOD_CTRL)
- ++c;
- else if (STATE_ALPHA == state->action_state || mod & KMOD_SHIFT)
- c += 2;
-
- int x = 0;
- for (int i = 0; i < state->entry_cursor; ++i)
- {
- const char *special = display_special_char (state->entry.data[i]);
- if (special)
- x += strlen (special);
- else
- ++x;
-
- if (x >= 16)
- x %= 16;
- }
-
- SDL_Rect pos = { .x = (6 * x), .y = (64 - 8) };
- SDL_Surface *tile = get_font_char (c);
-
- int rc = SDL_BlitSurface (tile, NULL, frame, &pos);
- if (rc < 0)
- error ("Failed to draw cursor on screen frame: %s", SDL_GetError ());
+ if (!state->blink_state)
+ return;
+
+ SDL_Keymod mod = SDL_GetModState();
+ int c = 1;
+
+ if (state->insert_mode)
+ c += 4;
+
+ if (STATE_2ND == state->action_state || mod & KMOD_CTRL)
+ ++c;
+ else if (STATE_ALPHA == state->action_state || mod & KMOD_SHIFT)
+ c += 2;
+
+ int x = 0;
+ for (int i = 0; i < state->entry_cursor; ++i)
+ {
+ const char *special =
+ display_special_char(state->entry.data[i]);
+
+ if (special)
+ x += strlen(special);
+ else
+ ++x;
+
+ x %= 16;
+ }
+
+ SDL_Rect pos = { .x = (6 * x), .y = (64 - 8) };
+ SDL_Surface *tile = get_font_char(c);
+
+ int rc = SDL_BlitSurface(tile, NULL, frame, &pos);
+ if (rc < 0)
+ error("Failed to draw cursor on screen frame: %s",
+ SDL_GetError());
}
SDL_Surface *
-default_draw (const struct screen *screen)
+default_draw(const struct screen *screen)
{
- int rc;
- SDL_Surface *final;
-
- final = SDL_CreateRGBSurface (0, 96, 64, 32, 0, 0, 0, 0);
- if (!final)
- {
- error ("Failed to initialize screen frame: %s", SDL_GetError ());
- return NULL;
- }
-
- rc = SDL_FillRect (final, NULL, SDL_MapRGB (final->format, 255, 255, 255));
- if (rc < 0)
- error ("Failed to fill screen frame with white background: %s",
- SDL_GetError ());
-
- struct state *state = screen->state;
- unsigned int height = 0;
- draw_line (&state->entry, final, &height, false);
- draw_cursor (state, final);
-
- for (int i = state->history_len - 1; i >= 0 && height < 64; --i)
- {
- draw_line (&state->history[i].answer_string, final, &height, true);
-
- if (height < 64)
- draw_line (&state->history[i].entry, final, &height, false);
- }
-
- return final;
+ int rc;
+ SDL_Surface *final;
+
+ final = SDL_CreateRGBSurface(0, 96, 64, 32, 0, 0, 0, 0);
+ if (!final)
+ {
+ error("Failed to initialize screen frame: %s", SDL_GetError());
+ return NULL;
+ }
+
+ rc = SDL_FillRect(final, NULL,
+ SDL_MapRGB(final->format, 255, 255, 255));
+ if (rc < 0)
+ error("Failed to fill screen frame with white background: %s",
+ SDL_GetError());
+
+ struct state *state = screen->state;
+ unsigned int height = 0;
+ draw_line(&state->entry, final, &height, false);
+ draw_cursor(state, final);
+
+ for (int i = state->history_len - 1; i >= 0 && height < 64; --i)
+ {
+ draw_line(&state->history[i].answer_string, final, &height,
+ true);
+
+ if (height < 64)
+ draw_line(&state->history[i].entry, final, &height,
+ false);
+ }
+
+ return final;
}
int
-default_input (struct screen *screen, SDL_KeyboardEvent *key)
+default_input(struct screen *screen, SDL_KeyboardEvent *key)
{
- struct state *state = screen->state;
- SDL_Keycode code = key->keysym.sym;
- SDL_Keymod mod = key->keysym.mod;
-
- switch (state->action_state)
- {
- case STATE_2ND:
- mod |= KMOD_LCTRL;
- break;
-
- case STATE_ALPHA:
- mod |= KMOD_LSHIFT;
- break;
-
- default:
- break;
- }
-
- switch (code)
- {
- case SDLK_BACKSPACE:
- if (!state->entry_cursor)
- return 0;
-
- --state->entry_cursor;
- // SPILLS OVER!
- case SDLK_DELETE:
- if (state->entry_cursor < state->entry.len)
- tib_expr_delete (&state->entry, state->entry_cursor);
- return 0;
-
- case SDLK_END:
- state->entry_cursor = state->entry.len;
- return 0;
-
- case SDLK_HOME:
- state->entry_cursor = 0;
- return 0;
-
- case SDLK_INSERT:
- state->insert_mode = !state->insert_mode;
- return 0;
-
- case SDLK_LEFT:
- entry_move_cursor (state, LEFT);
- return 0;
-
- case SDLK_RETURN:
- case SDLK_KP_ENTER:
- if (mod & KMOD_CTRL)
- {
- return entry_recall (state);
- }
- else
- {
- if (0 == state->entry.len)
- {
- int rc = entry_write (state, TIB_CHAR_ANS);
- if (rc)
- return rc;
- }
-
- return state_calc_entry (state);
- }
-
- case SDLK_RIGHT:
- entry_move_cursor (state, RIGHT);
- return 0;
- }
-
- int normal = normalize_keycode (code, mod);
- if (normal)
- {
- if (is_math_operator (normal) && 0 == state->entry.len
- && !(mod & KMOD_CTRL))
- {
- int rc = entry_write (state, TIB_CHAR_ANS);
- if (rc)
- return rc;
- }
-
- return entry_write (state, normal);
- }
-
- return 0;
+ struct state *state = screen->state;
+ SDL_Keycode code = key->keysym.sym;
+ SDL_Keymod mod = key->keysym.mod;
+
+ switch (state->action_state)
+ {
+ case STATE_2ND:
+ mod |= KMOD_LCTRL;
+ break;
+
+ case STATE_ALPHA:
+ mod |= KMOD_LSHIFT;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (code)
+ {
+ case SDLK_BACKSPACE:
+ if (!state->entry_cursor)
+ return 0;
+
+ --state->entry_cursor;
+ // SPILLS OVER!
+ case SDLK_DELETE:
+ if (state->entry_cursor < state->entry.len)
+ tib_expr_delete(&state->entry, state->entry_cursor);
+ return 0;
+
+ case SDLK_END:
+ state->entry_cursor = state->entry.len;
+ return 0;
+
+ case SDLK_HOME:
+ state->entry_cursor = 0;
+ return 0;
+
+ case SDLK_INSERT:
+ state->insert_mode = !state->insert_mode;
+ return 0;
+
+ case SDLK_LEFT:
+ entry_move_cursor(state, LEFT);
+ return 0;
+
+ case SDLK_RETURN:
+ case SDLK_KP_ENTER:
+ if (mod & KMOD_CTRL)
+ {
+ return entry_recall(state);
+ }
+ else
+ {
+ if (0 == state->entry.len)
+ {
+ int rc = entry_write(state, TIB_CHAR_ANS);
+ if (rc)
+ return rc;
+ }
+
+ return state_calc_entry(state);
+ }
+
+ case SDLK_RIGHT:
+ entry_move_cursor(state, RIGHT);
+ return 0;
+ }
+
+ int normal = normalize_keycode(code, mod);
+ if (normal)
+ {
+ if (is_math_operator(normal) && 0 == state->entry.len
+ && !(mod & KMOD_CTRL))
+ {
+ int rc = entry_write(state, TIB_CHAR_ANS);
+ if (rc)
+ return rc;
+ }
+
+ return entry_write(state, normal);
+ }
+
+ return 0;
}
diff --git a/src/mode_default.h b/src/mode_default.h
index 59caaed..d720978 100644
--- a/src/mode_default.h
+++ b/src/mode_default.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,9 +21,9 @@
#include "screen.h"
SDL_Surface *
-default_draw (const struct screen *screen);
+default_draw(const struct screen *screen);
int
-default_input (struct screen *screen, SDL_KeyboardEvent *key);
+default_input(struct screen *screen, SDL_KeyboardEvent *key);
#endif
diff --git a/src/point.h b/src/point.h
index 727521a..0ae4079 100644
--- a/src/point.h
+++ b/src/point.h
@@ -1,6 +1,6 @@
/*
* LiberTI - Libre TI calculator emulator designed for LibreCalc
- * Copyright (C) 2015 Delwink, LLC
+ * Copyright (C) 2015, 2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -20,8 +20,8 @@
struct point2d
{
- int x;
- int y;
+ int x;
+ int y;
};
#endif
diff --git a/src/screen.c b/src/screen.c
index d4b5ea8..ba04e8b 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -22,26 +22,25 @@
struct _screen_mode
{
- SDL_Surface * (*draw) (const struct screen *);
- int (*input) (struct screen *, SDL_KeyboardEvent *);
+ SDL_Surface *(*draw)(const struct screen *);
+ int (*input)(struct screen *, SDL_KeyboardEvent *);
};
-const struct _screen_mode SCREEN_MODES[NUM_SCREEN_MODES] =
- {
- {
- .draw = default_draw,
- .input = default_input
- }
- };
+const struct _screen_mode SCREEN_MODES[NUM_SCREEN_MODES] = {
+ {
+ .draw = default_draw,
+ .input = default_input
+ }
+};
SDL_Surface *
-screen_draw (const struct screen *screen)
+screen_draw(const struct screen *screen)
{
- return SCREEN_MODES[screen->mode].draw (screen);
+ return SCREEN_MODES[screen->mode].draw(screen);
}
int
-screen_input (struct screen *screen, SDL_KeyboardEvent *event)
+screen_input(struct screen *screen, SDL_KeyboardEvent *event)
{
- return SCREEN_MODES[screen->mode].input (screen, event);
+ return SCREEN_MODES[screen->mode].input(screen, event);
}
diff --git a/src/screen.h b/src/screen.h
index 5d6014f..627e5f6 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -24,25 +24,25 @@
#include "state.h"
enum screen_mode
- {
- DEFAULT_SCREEN_MODE,
- NUM_SCREEN_MODES
- };
+{
+ DEFAULT_SCREEN_MODE,
+ NUM_SCREEN_MODES
+};
struct screen
{
- struct state *state;
+ struct state *state;
- struct point2d pos;
- struct point2d size;
+ struct point2d pos;
+ struct point2d size;
- enum screen_mode mode;
+ enum screen_mode mode;
};
SDL_Surface *
-screen_draw (const struct screen *screen);
+screen_draw(const struct screen *screen);
int
-screen_input (struct screen *screen, SDL_KeyboardEvent *event);
+screen_input(struct screen *screen, SDL_KeyboardEvent *event);
#endif
diff --git a/src/skin.c b/src/skin.c
index 2d41ed7..c24f9e8 100644
--- a/src/skin.c
+++ b/src/skin.c
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -27,12 +27,12 @@
#include "tibchar.h"
#include "tiberr.h"
-#define DEFAULT_SKIN \
- "screens=({" \
- "mode=\"default\";" \
- "x=0;" \
- "y=0;" \
- "});"
+#define DEFAULT_SKIN \
+ "screens=({" \
+ "mode=\"default\";" \
+ "x=0;" \
+ "y=0;" \
+ "});"
#define DEFAULT_SCREEN_WIDTH (96)
#define DEFAULT_SCREEN_HEIGHT (64)
@@ -40,725 +40,737 @@
static PrefixTree *action_keywords = NULL;
static int
-mode_from_string (const char *s)
+mode_from_string(const char *s)
{
- if (0 == strcmp (s, "default"))
- return DEFAULT_SCREEN_MODE;
+ if (0 == strcmp(s, "default"))
+ return DEFAULT_SCREEN_MODE;
- return -1;
+ return -1;
}
static int
-add_screen (Skin *self, struct state *state, struct point2d pos,
- enum screen_mode mode, double scale)
+add_screen(Skin *self, struct state *state, struct point2d pos,
+ enum screen_mode mode, double scale)
{
- struct skin_screen_list *node = self->screens;
-
- if (scale <= 0)
- return TIB_EBADFILE;
-
- if (!node)
- {
- self->screens = malloc (sizeof (struct skin_screen_list));
- if (!self->screens)
- return TIB_EALLOC;
-
- node = self->screens;
- self->active_screen = &node->screen;
- }
- else
- {
- while (node->next)
- node = node->next;
-
- node->next = malloc (sizeof (struct skin_screen_list));
- if (!node->next)
- return TIB_EALLOC;
-
- node = node->next;
- }
-
- node->next = NULL;
- node->screen.state = state;
- node->screen.pos = pos;
- node->screen.size.x = DEFAULT_SCREEN_WIDTH * scale;
- node->screen.size.y = DEFAULT_SCREEN_HEIGHT * scale;
- node->screen.mode = mode;
-
- return 0;
+ struct skin_screen_list *node = self->screens;
+
+ if (scale <= 0)
+ return TIB_EBADFILE;
+
+ if (!node)
+ {
+ self->screens = malloc(sizeof(struct skin_screen_list));
+ if (!self->screens)
+ return TIB_EALLOC;
+
+ node = self->screens;
+ self->active_screen = &node->screen;
+ }
+ else
+ {
+ while (node->next)
+ node = node->next;
+
+ node->next = malloc(sizeof(struct skin_screen_list));
+ if (!node->next)
+ return TIB_EALLOC;
+
+ node = node->next;
+ }
+
+ node->next = NULL;
+ node->screen.state = state;
+ node->screen.pos = pos;
+ node->screen.size.x = DEFAULT_SCREEN_WIDTH * scale;
+ node->screen.size.y = DEFAULT_SCREEN_HEIGHT * scale;
+ node->screen.mode = mode;
+
+ return 0;
}
static char *
-skin_file_path (const char *root, const char *file)
+skin_file_path(const char *root, const char *file)
{
- size_t len = strlen (root) + strlen (file) + 2;
- char *full_path = malloc (len * sizeof (char));
- if (!full_path)
- return NULL;
+ size_t len = strlen(root) + strlen(file) + 2;
+ char *full_path = malloc(len * sizeof(char));
+ if (!full_path)
+ return NULL;
- sprintf (full_path, "%s/%s", root, file);
- return full_path;
+ sprintf(full_path, "%s/%s", root, file);
+ return full_path;
}
static void
-free_action_keywords ()
+free_action_keywords()
{
- pt_free (action_keywords);
- action_keywords = NULL;
+ pt_free(action_keywords);
+ action_keywords = NULL;
}
static int
-init_action_keywords ()
+init_action_keywords()
{
- action_keywords = pt_new ();
- if (!action_keywords)
- return TIB_EALLOC;
+ action_keywords = pt_new();
+ if (!action_keywords)
+ return TIB_EALLOC;
- for (int i = TIB_CHAR_AND; i <= TIB_CHAR_YSCL; ++i)
- {
- const char *trans = tib_special_char_text (i);
- if (!trans)
- continue;
+ for (int i = TIB_CHAR_AND; i <= TIB_CHAR_YSCL; ++i)
+ {
+ const char *trans = tib_special_char_text(i);
+ if (!trans)
+ continue;
- if (' ' == *trans)
- ++trans; /* trim any leading space */
+ if (' ' == *trans)
+ ++trans; // trim any leading space
- char trim[11]; /* long enough to hold all translated strings and NUL */
- strcpy (trim, trans);
+ char trim[11]; /* long enough to hold all translated strings
+ * and NUL
+ */
+ strcpy(trim, trans);
- char *p = strrchr (trim, ' ');
- if (p)
- *p = '\0'; /* trim any trailing space */
+ char *p = strrchr(trim, ' ');
+ if (p)
+ *p = '\0'; // trim any trailing space
- for (p = trim; *p != '\0'; ++p)
- *p = tolower (*p);
+ for (p = trim; *p != '\0'; ++p)
+ *p = tolower(*p);
- tib_errno = pt_add (action_keywords, trim, i);
- if (tib_errno)
- goto fail;
- }
+ tib_errno = pt_add(action_keywords, trim, i);
+ if (tib_errno)
+ goto fail;
+ }
- return 0;
+ return 0;
fail:
- free_action_keywords ();
- return TIB_EALLOC;
+ free_action_keywords();
+ return TIB_EALLOC;
}
static int
-action_type_from_string (const char *s)
+action_type_from_string(const char *s)
{
- if (!s)
- return -1;
-
- if (0 == strcmp (s, "mode"))
- return CHANGE_MODES;
- else if (0 == strcmp (s, "char"))
- return CHAR_INSERT;
- else if (0 == strcmp (s, "move"))
- return CURSOR_MOVE;
- else if (0 == strcmp (s, "shift"))
- return TOGGLE_2ND;
- else if (0 == strcmp (s, "alpha"))
- return TOGGLE_ALPHA;
- else if (0 == strcmp (s, "insert"))
- return TOGGLE_INSERT;
-
- return -1;
+ if (!s)
+ return -1;
+
+ if (0 == strcmp(s, "mode"))
+ return CHANGE_MODES;
+ else if (0 == strcmp(s, "char"))
+ return CHAR_INSERT;
+ else if (0 == strcmp(s, "move"))
+ return CURSOR_MOVE;
+ else if (0 == strcmp(s, "shift"))
+ return TOGGLE_2ND;
+ else if (0 == strcmp(s, "alpha"))
+ return TOGGLE_ALPHA;
+ else if (0 == strcmp(s, "insert"))
+ return TOGGLE_INSERT;
+
+ return -1;
}
static bool
-isdisplayable (char c)
+isdisplayable(char c)
{
- return (c > 31 && c < 96) || (c > 96 && c < 127);
+ return (c > 31 && c < 96) || (c > 96 && c < 127);
}
static int
-char_insert_from_string (const char *s)
+char_insert_from_string(const char *s)
{
- const PrefixTree *t = pt_search (action_keywords, s);
- if (t)
- return pt_data (t);
+ const PrefixTree *t = pt_search(action_keywords, s);
+ if (t)
+ return pt_data(t);
- if (strlen (s) != 1 || !isdisplayable (s[0]))
- return -1;
+ if (strlen(s) != 1 || !isdisplayable(s[0]))
+ return -1;
- return s[0];
+ return s[0];
}
static int
-cursor_move_from_string (const char *s)
+cursor_move_from_string(const char *s)
{
- if (!s)
- return -1;
-
- if (0 == strcmp (s, "up"))
- return UP;
- else if (0 == strcmp (s, "down"))
- return DOWN;
- else if (0 == strcmp (s, "left"))
- return LEFT;
- else if (0 == strcmp (s, "right"))
- return RIGHT;
-
- return -1;
+ if (!s)
+ return -1;
+
+ if (0 == strcmp(s, "up"))
+ return UP;
+ else if (0 == strcmp(s, "down"))
+ return DOWN;
+ else if (0 == strcmp(s, "left"))
+ return LEFT;
+ else if (0 == strcmp(s, "right"))
+ return RIGHT;
+
+ return -1;
}
static int
-get_action_set (const config_setting_t *mode, const char *name,
- struct button_action_set *action)
+get_action_set(const config_setting_t *mode, const char *name,
+ struct button_action_set *action)
{
- const config_setting_t *root = config_setting_get_member (mode, name);
- if (!root)
- return TIB_EBADFILE;
-
- const config_setting_t *setting = config_setting_get_member (root, "type");
- if (!setting || CONFIG_TYPE_STRING != config_setting_type (setting))
- return TIB_EBADFILE;
-
- int i = action_type_from_string (config_setting_get_string (setting));
- if (-1 == i)
- return TIB_EBADFILE;
-
- action->type = i;
- setting = config_setting_get_member (root, "which");
- const char *value = NULL;
- if (setting)
- value = config_setting_get_string (setting);
- switch (i)
- {
- case CHANGE_MODES:
- if (!setting)
- return TIB_EBADFILE;
-
- i = mode_from_string (value);
- if (-1 == i)
- return TIB_EBADFILE;
-
- action->which.mode_open = i;
- break;
-
- case CHAR_INSERT:
- if (!setting)
- return TIB_EBADFILE;
-
- action->which.char_insert = char_insert_from_string (value);
- if (-1 == action->which.char_insert)
- return TIB_EBADFILE;
- break;
-
- case CURSOR_MOVE:
- if (!setting)
- return TIB_EBADFILE;
-
- i = cursor_move_from_string (value);
- if (-1 == i)
- return TIB_EBADFILE;
-
- action->which.cursor_move = i;
- break;
-
- default:
- break;
- }
-
- return 0;
+ const config_setting_t *root = config_setting_get_member(mode, name);
+ if (!root)
+ return TIB_EBADFILE;
+
+ const config_setting_t *setting =
+ config_setting_get_member(root, "type");
+ if (!setting || CONFIG_TYPE_STRING != config_setting_type(setting))
+ return TIB_EBADFILE;
+
+ int i = action_type_from_string(config_setting_get_string(setting));
+ if (-1 == i)
+ return TIB_EBADFILE;
+
+ action->type = i;
+ setting = config_setting_get_member(root, "which");
+ const char *value = NULL;
+ if (setting)
+ value = config_setting_get_string(setting);
+ switch (i)
+ {
+ case CHANGE_MODES:
+ if (!setting)
+ return TIB_EBADFILE;
+
+ i = mode_from_string(value);
+ if (-1 == i)
+ return TIB_EBADFILE;
+
+ action->which.mode_open = i;
+ break;
+
+ case CHAR_INSERT:
+ if (!setting)
+ return TIB_EBADFILE;
+
+ action->which.char_insert = char_insert_from_string(value);
+ if (-1 == action->which.char_insert)
+ return TIB_EBADFILE;
+ break;
+
+ case CURSOR_MOVE:
+ if (!setting)
+ return TIB_EBADFILE;
+
+ i = cursor_move_from_string(value);
+ if (-1 == i)
+ return TIB_EBADFILE;
+
+ action->which.cursor_move = i;
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
}
static int
-get_all_actions (const config_setting_t *mode,
- struct button_action_set actions[])
+get_all_actions(const config_setting_t *mode,
+ struct button_action_set actions[])
{
- if (!mode)
- return TIB_EBADFILE;
+ if (!mode)
+ return TIB_EBADFILE;
- tib_errno = init_action_keywords ();
+ tib_errno = init_action_keywords();
#define GET_ACTION_SET(A,S) tib_errno = get_action_set (mode, S, &A); \
- if (tib_errno) goto fail;
+ if (tib_errno) goto fail;
- GET_ACTION_SET (actions[STATE_NORMAL], "normal");
- GET_ACTION_SET (actions[STATE_2ND], "shift");
- GET_ACTION_SET (actions[STATE_ALPHA], "alpha");
+ GET_ACTION_SET(actions[STATE_NORMAL], "normal");
+ GET_ACTION_SET(actions[STATE_2ND], "shift");
+ GET_ACTION_SET(actions[STATE_ALPHA], "alpha");
fail:
- free_action_keywords ();
- return tib_errno;
+ free_action_keywords();
+ return tib_errno;
}
Skin *
-open_skin (const char *path, struct state *state, struct point2d size)
+open_skin(const char *path, struct state *state, struct point2d size)
{
- if (!state)
- {
- tib_errno = TIB_ENULLPTR;
- return NULL;
- }
-
- Skin *new = malloc (sizeof (Skin));
- if (!new)
- {
- tib_errno = TIB_EALLOC;
- return NULL;
- }
-
- memset (new, 0, sizeof (Skin));
- new->state = state;
-
- config_t conf;
- config_init (&conf);
-
- if (path)
- {
- char *spec_path = skin_file_path (path, "spec.conf");
- if (!spec_path)
- {
- tib_errno = TIB_EALLOC;
- goto fail;
- }
-
- tib_errno = config_read_file (&conf, spec_path);
- free (spec_path);
- }
- else
- {
- tib_errno = config_read_string (&conf, DEFAULT_SKIN);
- }
-
- if (CONFIG_FALSE == tib_errno)
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- tib_errno = 0;
-
- config_setting_t *setting = config_lookup (&conf, "background");
- if (setting)
- {
- if (CONFIG_TYPE_STRING != config_setting_type (setting))
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- char *bgpath = skin_file_path (path,
- config_setting_get_string (setting));
- if (!bgpath)
- {
- tib_errno = TIB_EALLOC;
- goto fail;
- }
-
- new->background = IMG_Load (bgpath);
- free (bgpath);
- if (!new->background)
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- new->size.x = new->background->w;
- new->size.y = new->background->h;
- }
- else
- {
- new->size = size;
- }
-
- setting = config_lookup (&conf, "screens");
- if (setting)
- {
- if (!config_setting_is_list (setting))
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- config_setting_t * const screens = setting;
- unsigned int i = 0;
- while ((setting = config_setting_get_elem (screens, i++)))
- {
- if (!config_setting_is_group (setting))
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- config_setting_t * const screen = setting;
-
- setting = config_setting_get_member (screen, "mode");
- if (!setting || config_setting_type (setting) != CONFIG_TYPE_STRING)
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- int mode = mode_from_string (config_setting_get_string (setting));
- if (-1 == mode)
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- setting = config_setting_get_member (screen, "x");
- if (!setting || !config_setting_is_number (setting))
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- struct point2d pos;
- pos.x = config_setting_get_int (setting);
-
- setting = config_setting_get_member (screen, "y");
- if (!setting || !config_setting_is_number (setting))
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- pos.y = config_setting_get_int (setting);
-
- double scale = 1.0;
- setting = config_setting_get_member (screen, "scale");
- if (setting)
- {
- if (!config_setting_is_number (setting))
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- scale = config_setting_get_float (setting);
- }
-
- tib_errno = add_screen (new, state, pos, mode, scale);
- if (tib_errno)
- goto fail;
- }
- }
-
- setting = config_lookup (&conf, "buttons");
- if (setting)
- {
- if (!config_setting_is_list (setting))
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- new->buttons = malloc (sizeof (struct skin_button_list));
- if (!new->buttons)
- {
- tib_errno = TIB_EALLOC;
- goto fail;
- }
-
- const config_setting_t *buttons = setting;
- struct skin_button_list *next = new->buttons;
- unsigned int i = 0;
- while ((setting = config_setting_get_elem (buttons, i++)))
- {
- if (!config_setting_is_group (setting))
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- if (i > 1)
- {
- next->next = malloc (sizeof (struct skin_button_list));
- if (!next->next)
- {
- tib_errno = TIB_EALLOC;
- goto fail;
- }
-
- next = next->next;
- }
-
- next->button = malloc (sizeof (struct button));
- if (!next->button)
- {
- tib_errno = TIB_EALLOC;
- goto fail;
- }
-
- const config_setting_t *button = setting;
-
- setting = config_setting_get_member (button, "actions");
- if (!setting)
- {
- tib_errno = TIB_EBADFILE;
- goto fail;
- }
-
- const config_setting_t *modes = setting;
-
- setting = config_setting_get_member (modes, "default");
- bool have_default = setting != NULL;
- struct button_action_set default_actions[NUM_ACTION_STATES];
- if (have_default)
- {
- tib_errno = get_all_actions (setting, default_actions);
- if (tib_errno)
- goto fail;
- }
-
- size_t j;
- struct button_action_set actions[NUM_ACTION_STATES];
-#define ADD_ACTION(A,I) setting = config_setting_get_member (modes, (A)); \
- if (setting) \
- { \
- tib_errno = get_all_actions (setting, actions); \
- if (tib_errno) \
- goto fail; \
- } \
- else \
- { \
- for (j = 0; j < NUM_ACTION_STATES; ++j) \
- actions[j] = default_actions[j]; \
- } \
- for (j = 0; j < NUM_ACTION_STATES; ++j) \
- next->button->actions[(I)][j] = actions[j];
-
- ADD_ACTION ("default", DEFAULT_SCREEN_MODE);
-
-#define ADD_DIM(D,V) setting = config_setting_get_member (button, (D)); \
- if (!setting || !config_setting_is_number (setting)) \
- { \
- tib_errno = TIB_EBADFILE; \
- goto fail; \
- } \
- (V) = config_setting_get_int (setting);
-
- ADD_DIM ("x", next->button->pos.x);
- ADD_DIM ("y", next->button->pos.y);
- ADD_DIM ("w", next->button->size.x);
- ADD_DIM ("h", next->button->size.y);
- }
- }
-
- config_destroy (&conf);
- return new;
+ if (!state)
+ {
+ tib_errno = TIB_ENULLPTR;
+ return NULL;
+ }
+
+ Skin *new = malloc(sizeof(Skin));
+ if (!new)
+ {
+ tib_errno = TIB_EALLOC;
+ return NULL;
+ }
+
+ memset(new, 0, sizeof(Skin));
+ new->state = state;
+
+ config_t conf;
+ config_init(&conf);
+
+ if (path)
+ {
+ char *spec_path = skin_file_path(path, "spec.conf");
+ if (!spec_path)
+ {
+ tib_errno = TIB_EALLOC;
+ goto fail;
+ }
+
+ tib_errno = config_read_file(&conf, spec_path);
+ free(spec_path);
+ }
+ else
+ {
+ tib_errno = config_read_string(&conf, DEFAULT_SKIN);
+ }
+
+ if (CONFIG_FALSE == tib_errno)
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ tib_errno = 0;
+
+ config_setting_t *setting = config_lookup(&conf, "background");
+ if (setting)
+ {
+ if (CONFIG_TYPE_STRING != config_setting_type(setting))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ char *bgpath = skin_file_path(path,
+ config_setting_get_string(setting));
+ if (!bgpath)
+ {
+ tib_errno = TIB_EALLOC;
+ goto fail;
+ }
+
+ new->background = IMG_Load(bgpath);
+ free(bgpath);
+ if (!new->background)
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ new->size.x = new->background->w;
+ new->size.y = new->background->h;
+ }
+ else
+ {
+ new->size = size;
+ }
+
+ setting = config_lookup(&conf, "screens");
+ if (setting)
+ {
+ if (!config_setting_is_list(setting))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ config_setting_t * const screens = setting;
+ unsigned int i = 0;
+ while ((setting = config_setting_get_elem(screens, i++)))
+ {
+ if (!config_setting_is_group(setting))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ config_setting_t * const screen = setting;
+
+ setting = config_setting_get_member(screen, "mode");
+ if (!setting
+ || (config_setting_type(setting) !=
+ CONFIG_TYPE_STRING))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ const char *mode_str =
+ config_setting_get_string(setting);
+ int mode = mode_from_string(mode_str);
+ if (-1 == mode)
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ setting = config_setting_get_member(screen, "x");
+ if (!setting || !config_setting_is_number(setting))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ struct point2d pos;
+ pos.x = config_setting_get_int(setting);
+
+ setting = config_setting_get_member(screen, "y");
+ if (!setting || !config_setting_is_number(setting))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ pos.y = config_setting_get_int(setting);
+
+ double scale = 1.0;
+ setting = config_setting_get_member(screen, "scale");
+ if (setting)
+ {
+ if (!config_setting_is_number(setting))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ scale = config_setting_get_float(setting);
+ }
+
+ tib_errno = add_screen(new, state, pos, mode, scale);
+ if (tib_errno)
+ goto fail;
+ }
+ }
+
+ setting = config_lookup(&conf, "buttons");
+ if (setting)
+ {
+ if (!config_setting_is_list(setting))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ new->buttons = malloc(sizeof(struct skin_button_list));
+ if (!new->buttons)
+ {
+ tib_errno = TIB_EALLOC;
+ goto fail;
+ }
+
+ const config_setting_t *buttons = setting;
+ struct skin_button_list *next = new->buttons;
+ unsigned int i = 0;
+ while ((setting = config_setting_get_elem(buttons, i++)))
+ {
+ if (!config_setting_is_group(setting))
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ if (i > 1)
+ {
+ next->next =
+ malloc(sizeof(struct skin_button_list));
+ if (!next->next)
+ {
+ tib_errno = TIB_EALLOC;
+ goto fail;
+ }
+
+ next = next->next;
+ }
+
+ next->button = malloc(sizeof(struct button));
+ if (!next->button)
+ {
+ tib_errno = TIB_EALLOC;
+ goto fail;
+ }
+
+ const config_setting_t *button = setting;
+
+ setting = config_setting_get_member(button, "actions");
+ if (!setting)
+ {
+ tib_errno = TIB_EBADFILE;
+ goto fail;
+ }
+
+ const config_setting_t *modes = setting;
+
+ setting = config_setting_get_member(modes, "default");
+ bool have_default = setting != NULL;
+ struct button_action_set default_actions[NUM_ACTION_STATES];
+ if (have_default)
+ {
+ tib_errno = get_all_actions(setting,
+ default_actions);
+ if (tib_errno)
+ goto fail;
+ }
+
+ size_t j;
+ struct button_action_set actions[NUM_ACTION_STATES];
+#define ADD_ACTION(A,I) setting = config_setting_get_member(modes, (A)); \
+ if (setting) \
+ { \
+ tib_errno = get_all_actions(setting, actions); \
+ if (tib_errno) \
+ goto fail; \
+ } \
+ else \
+ { \
+ for (j = 0; j < NUM_ACTION_STATES; ++j) \
+ actions[j] = default_actions[j]; \
+ } \
+ for (j = 0; j < NUM_ACTION_STATES; ++j) \
+ next->button->actions[(I)][j] = actions[j];
+
+ ADD_ACTION("default", DEFAULT_SCREEN_MODE);
+
+#define ADD_DIM(D,V) setting = config_setting_get_member(button, (D)); \
+ if (!setting || !config_setting_is_number(setting)) \
+ { \
+ tib_errno = TIB_EBADFILE; \
+ goto fail; \
+ } \
+ (V) = config_setting_get_int(setting);
+
+ ADD_DIM("x", next->button->pos.x);
+ ADD_DIM("y", next->button->pos.y);
+ ADD_DIM("w", next->button->size.x);
+ ADD_DIM("h", next->button->size.y);
+ }
+ }
+
+ config_destroy(&conf);
+ return new;
fail:
- config_destroy (&conf);
-
- if (new->background)
- SDL_FreeSurface (new->background);
-
- if (new->screens)
- {
- struct skin_screen_list *s = new->screens;
- while (s)
- {
- s = s->next;
- free (new->screens);
- new->screens = s;
- }
- }
-
- if (new->buttons)
- {
- struct skin_button_list *s = new->buttons;
- while (s)
- {
- if (s->button)
- free (s->button);
- s = s->next;
- free (new->buttons);
- new->buttons = s;
- }
- }
-
- free (new);
- return NULL;
+ config_destroy(&conf);
+
+ if (new->background)
+ SDL_FreeSurface(new->background);
+
+ if (new->screens)
+ {
+ struct skin_screen_list *s = new->screens;
+ while (s)
+ {
+ s = s->next;
+ free(new->screens);
+ new->screens = s;
+ }
+ }
+
+ if (new->buttons)
+ {
+ struct skin_button_list *s = new->buttons;
+ while (s)
+ {
+ if (s->button)
+ free(s->button);
+ s = s->next;
+ free(new->buttons);
+ new->buttons = s;
+ }
+ }
+
+ free(new);
+ return NULL;
}
void
-free_skin (Skin *self)
+free_skin(Skin *self)
{
- if (self->background)
- SDL_FreeSurface (self->background);
-
- struct skin_screen_list *s = self->screens;
- while (s)
- {
- s = s->next;
- free (self->screens);
- self->screens = s;
- }
-
- struct skin_button_list *b = self->buttons;
- while (b)
- {
- free (b->button);
- b = b->next;
- free (self->buttons);
- self->buttons = b;
- }
-
- free (self);
+ if (self->background)
+ SDL_FreeSurface(self->background);
+
+ struct skin_screen_list *s = self->screens;
+ while (s)
+ {
+ s = s->next;
+ free(self->screens);
+ self->screens = s;
+ }
+
+ struct skin_button_list *b = self->buttons;
+ while (b)
+ {
+ free(b->button);
+ b = b->next;
+ free(self->buttons);
+ self->buttons = b;
+ }
+
+ free(self);
}
static bool
-in_bounds (struct point2d start, struct point2d size, struct point2d pos)
+in_bounds(struct point2d start, struct point2d size, struct point2d pos)
{
- return pos.x >= start.x && pos.x <= (start.x + size.x)
- && pos.y >= start.y && pos.y <= (start.y + size.y);
+ return pos.x >= start.x && pos.x <= (start.x + size.x)
+ && pos.y >= start.y && pos.y <= (start.y + size.y);
}
static bool
-on_skin (const Skin *self, struct point2d pos)
+on_skin(const Skin *self, struct point2d pos)
{
- struct point2d size = { .x = self->background->w, .y = self->background->h };
- return in_bounds ((struct point2d) { 0, 0 }, size, pos);
+ struct point2d size = {
+ .x = self->background->w,
+ .y = self->background->h
+ };
+
+ return in_bounds((struct point2d) { 0, 0 }, size, pos);
}
static bool
-on_screen (const struct screen *screen, struct point2d pos)
+on_screen(const struct screen *screen, struct point2d pos)
{
- return in_bounds (screen->pos, screen->size, pos);
+ return in_bounds(screen->pos, screen->size, pos);
}
static bool
-on_button (const struct button *button, struct point2d pos)
+on_button(const struct button *button, struct point2d pos)
{
- return in_bounds (button->pos, button->size, pos);
+ return in_bounds(button->pos, button->size, pos);
}
static int
-do_button_action (Skin *self, struct button *button)
+do_button_action(Skin *self, struct button *button)
{
- struct screen *screen = self->active_screen;
- struct state *state = self->state;
- enum screen_mode mode = screen->mode;
+ struct screen *screen = self->active_screen;
+ struct state *state = self->state;
+ enum screen_mode mode = screen->mode;
- struct button_action_set *action;
- action = &button->actions[mode][state->action_state];
- union button_action which = action->which;
+ struct button_action_set *action;
+ action = &button->actions[mode][state->action_state];
+ union button_action which = action->which;
- switch (action->type)
- {
- case CHANGE_MODES:
- screen->mode = which.mode_open;
- break;
+ switch (action->type)
+ {
+ case CHANGE_MODES:
+ screen->mode = which.mode_open;
+ break;
- case CHAR_INSERT:
- return entry_write (state, which.char_insert);
+ case CHAR_INSERT:
+ return entry_write(state, which.char_insert);
- case CURSOR_MOVE:
- entry_move_cursor (state, which.cursor_move);
- break;
+ case CURSOR_MOVE:
+ entry_move_cursor(state, which.cursor_move);
+ break;
- case TOGGLE_2ND:
- change_action_state (state, STATE_2ND);
- break;
+ case TOGGLE_2ND:
+ change_action_state(state, STATE_2ND);
+ break;
- case TOGGLE_ALPHA:
- change_action_state (state, STATE_ALPHA);
- break;
+ case TOGGLE_ALPHA:
+ change_action_state(state, STATE_ALPHA);
+ break;
- case TOGGLE_INSERT:
- state->insert_mode = !state->insert_mode;
- break;
- }
+ case TOGGLE_INSERT:
+ state->insert_mode = !state->insert_mode;
+ break;
+ }
- return 0;
+ return 0;
}
int
-Skin_click (Skin *self, struct point2d pos)
+Skin_click(Skin * self, struct point2d pos)
{
- if (!on_skin (self, pos))
- return TIB_EDIM;
-
- for (struct skin_button_list *elem = self->buttons;
- elem != NULL;
- elem = elem->next)
- {
- struct button *button = elem->button;
-
- if (on_button (button, pos))
- return do_button_action (self, button);
- }
-
- for (struct skin_screen_list *elem = self->screens;
- elem != NULL;
- elem = elem->next)
- {
- struct screen *screen = &elem->screen;
-
- if (on_screen (screen, pos))
- {
- if (screen != self->active_screen)
- {
- self->active_screen = screen;
- self->state->action_state = STATE_NORMAL;
- }
- }
- }
-
- return 0;
+ if (!on_skin(self, pos))
+ return TIB_EDIM;
+
+ for (struct skin_button_list *elem = self->buttons; elem != NULL;
+ elem = elem->next)
+ {
+ struct button *button = elem->button;
+
+ if (on_button(button, pos))
+ return do_button_action(self, button);
+ }
+
+ for (struct skin_screen_list *elem = self->screens; elem != NULL;
+ elem = elem->next)
+ {
+ struct screen *screen = &elem->screen;
+
+ if (on_screen(screen, pos))
+ {
+ if (screen != self->active_screen)
+ {
+ self->active_screen = screen;
+ self->state->action_state = STATE_NORMAL;
+ }
+ }
+ }
+
+ return 0;
}
int
-Skin_input (Skin *self, SDL_KeyboardEvent *event)
+Skin_input(Skin *self, SDL_KeyboardEvent *event)
{
- return screen_input (self->active_screen, event);
+ return screen_input(self->active_screen, event);
}
static SDL_Rect
-get_rect (struct point2d pos, struct point2d size)
+get_rect(struct point2d pos, struct point2d size)
{
- SDL_Rect r =
- {
- .x = pos.x,
- .y = pos.y,
- .w = size.x,
- .h = size.y
- };
-
- return r;
+ SDL_Rect r = {
+ .x = pos.x,
+ .y = pos.y,
+ .w = size.x,
+ .h = size.y
+ };
+
+ return r;
}
SDL_Surface *
-Skin_get_frame (Skin *self)
+Skin_get_frame(Skin *self)
{
- int rc;
- SDL_Surface *final;
-
- final = SDL_CreateRGBSurface (0, self->size.x, self->size.y, 32, 0, 0, 0, 0);
- if (!final)
- {
- error ("Failed to initialize skin frame: %s", SDL_GetError ());
- return NULL;
- }
-
- if (self->background)
- {
- rc = SDL_BlitSurface (self->background, NULL, final, NULL);
- if (rc < 0)
- error ("Failed to blit background: %s", SDL_GetError ());
- }
-
- struct skin_screen_list *elem = self->screens;
- unsigned int i = 0;
- for (; elem != NULL; elem = elem->next, ++i)
- {
- struct screen *screen = &elem->screen;
- SDL_Surface *render = screen_draw (screen);
- if (render)
- {
- SDL_Rect r = get_rect (screen->pos, screen->size);
- rc = SDL_BlitScaled (render, NULL, final, &r);
- SDL_FreeSurface (render);
- if (rc < 0)
- error ("Failed to blit screen %u: %s", i, SDL_GetError ());
- }
- }
-
- return final;
+ int rc;
+ SDL_Surface *final;
+
+ final = SDL_CreateRGBSurface(0, self->size.x, self->size.y, 32, 0, 0,
+ 0, 0);
+ if (!final)
+ {
+ error("Failed to initialize skin frame: %s", SDL_GetError());
+ return NULL;
+ }
+
+ if (self->background)
+ {
+ rc = SDL_BlitSurface(self->background, NULL, final, NULL);
+ if (rc < 0)
+ error("Failed to blit background: %s", SDL_GetError());
+ }
+
+ struct skin_screen_list *elem = self->screens;
+ unsigned int i = 0;
+ for (; elem != NULL; elem = elem->next, ++i)
+ {
+ struct screen *screen = &elem->screen;
+ SDL_Surface *render = screen_draw(screen);
+ if (render)
+ {
+ SDL_Rect r = get_rect(screen->pos, screen->size);
+ rc = SDL_BlitScaled(render, NULL, final, &r);
+ SDL_FreeSurface(render);
+ if (rc < 0)
+ error("Failed to blit screen %u: %s", i,
+ SDL_GetError());
+ }
+ }
+
+ return final;
}
diff --git a/src/skin.h b/src/skin.h
index 92afe68..0996fb9 100644
--- a/src/skin.h
+++ b/src/skin.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -27,40 +27,40 @@
struct skin_button_list
{
- struct button *button;
- struct skin_button_list *next;
+ struct button *button;
+ struct skin_button_list *next;
};
struct skin_screen_list
{
- struct screen screen;
- struct skin_screen_list *next;
+ struct screen screen;
+ struct skin_screen_list *next;
};
typedef struct
{
- SDL_Surface *background;
- struct screen *active_screen;
- struct skin_screen_list *screens;
- struct skin_button_list *buttons;
- struct state *state;
+ SDL_Surface *background;
+ struct screen *active_screen;
+ struct skin_screen_list *screens;
+ struct skin_button_list *buttons;
+ struct state *state;
- struct point2d size;
+ struct point2d size;
} Skin;
Skin *
-open_skin (const char *path, struct state *state, struct point2d size);
+open_skin(const char *path, struct state *state, struct point2d size);
void
-free_skin (Skin *self);
+free_skin(Skin *self);
int
-Skin_click (Skin *self, struct point2d pos);
+Skin_click(Skin *self, struct point2d pos);
int
-Skin_input (Skin *self, SDL_KeyboardEvent *event);
+Skin_input(Skin *self, SDL_KeyboardEvent *event);
SDL_Surface *
-Skin_get_frame (Skin *self);
+Skin_get_frame(Skin *self);
#endif
diff --git a/src/state.c b/src/state.c
index f280e0f..dcb8884 100644
--- a/src/state.c
+++ b/src/state.c
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -26,302 +26,301 @@
#include "util.h"
static void
-add_history (struct state *state, struct tib_expr *in, struct tib_expr *ans_s,
- TIB *ans)
+add_history(struct state *state, struct tib_expr *in, struct tib_expr *ans_s,
+ TIB *ans)
{
- if (MAX_HISTORY == state->history_len)
- {
- tib_expr_destroy (&state->history[0].entry);
- tib_expr_destroy (&state->history[0].answer_string);
- tib_decref (state->history[0].answer);
-
- for (unsigned int i = 0; i < MAX_HISTORY - 1; ++i)
- state->history[i] = state->history[i + 1];
- }
- else
- {
- ++state->history_len;
- }
-
- unsigned int i = state->history_len - 1;
- state->history[i].entry = *in;
- state->history[i].answer_string = *ans_s;
- state->history[i].answer = ans;
+ if (MAX_HISTORY == state->history_len)
+ {
+ tib_expr_destroy(&state->history[0].entry);
+ tib_expr_destroy(&state->history[0].answer_string);
+ tib_decref(state->history[0].answer);
+
+ for (unsigned int i = 0; i < MAX_HISTORY - 1; ++i)
+ state->history[i] = state->history[i + 1];
+ }
+ else
+ {
+ ++state->history_len;
+ }
+
+ unsigned int i = state->history_len - 1;
+ state->history[i].entry = *in;
+ state->history[i].answer_string = *ans_s;
+ state->history[i].answer = ans;
}
int
-load_state (struct state *dest, const char *path)
+load_state(struct state *dest, const char *path)
{
- int rc = 0;
-
- if (!dest)
- return TIB_ENULLPTR;
-
- dest->action_state = STATE_NORMAL;
- dest->entry_cursor = 0;
- dest->history_len = 0;
- dest->blink_state = true;
- dest->insert_mode = false;
-
- rc = tib_expr_init (&dest->entry);
- if (rc)
- return rc;
-
- if (!path)
- return 0;
-
- config_t conf;
- config_init (&conf);
-
- rc = config_read_file (&conf, path);
- if (CONFIG_FALSE == rc)
- {
- config_destroy (&conf);
- return TIB_EBADFILE;
- }
-
- config_setting_t *setting = config_lookup (&conf, "history");
- if (setting)
- {
- if (config_setting_type (setting) != CONFIG_TYPE_LIST)
- {
- rc = TIB_EBADFILE;
- goto fail;
- }
-
- unsigned int i = 0;
- config_setting_t *line;
-
- while ((line = config_setting_get_elem (setting, i++)))
- {
- if (config_setting_type (line) != CONFIG_TYPE_GROUP)
- {
- rc = TIB_EBADFILE;
- goto fail;
- }
-
- config_setting_t *e = config_setting_get_member (line, "input");
- if (!e || config_setting_type (e) != CONFIG_TYPE_STRING)
- {
- rc = TIB_EBADFILE;
- goto fail;
- }
-
- const char *s = config_setting_get_string (e);
- rc = tib_encode_str (&dest->entry, s);
- if (rc)
- goto fail;
-
- rc = state_calc_entry (dest);
- if (rc)
- goto fail;
- }
- }
-
- config_destroy (&conf);
- return 0;
+ int rc = 0;
+
+ if (!dest)
+ return TIB_ENULLPTR;
+
+ dest->action_state = STATE_NORMAL;
+ dest->entry_cursor = 0;
+ dest->history_len = 0;
+ dest->blink_state = true;
+ dest->insert_mode = false;
+
+ rc = tib_expr_init(&dest->entry);
+ if (rc)
+ return rc;
+
+ if (!path)
+ return 0;
+
+ config_t conf;
+ config_init(&conf);
+
+ rc = config_read_file(&conf, path);
+ if (CONFIG_FALSE == rc)
+ {
+ config_destroy(&conf);
+ return TIB_EBADFILE;
+ }
+
+ config_setting_t *setting = config_lookup(&conf, "history");
+ if (setting)
+ {
+ if (config_setting_type(setting) != CONFIG_TYPE_LIST)
+ {
+ rc = TIB_EBADFILE;
+ goto fail;
+ }
+
+ unsigned int i = 0;
+ config_setting_t *line;
+
+ while ((line = config_setting_get_elem(setting, i++)))
+ {
+ if (config_setting_type(line) != CONFIG_TYPE_GROUP)
+ {
+ rc = TIB_EBADFILE;
+ goto fail;
+ }
+
+ config_setting_t *e =
+ config_setting_get_member(line, "input");
+ if (!e || config_setting_type(e) != CONFIG_TYPE_STRING)
+ {
+ rc = TIB_EBADFILE;
+ goto fail;
+ }
+
+ const char *s = config_setting_get_string(e);
+ rc = tib_encode_str(&dest->entry, s);
+ if (rc)
+ goto fail;
+
+ rc = state_calc_entry(dest);
+ if (rc)
+ goto fail;
+ }
+ }
+
+ config_destroy(&conf);
+ return 0;
fail:
- state_destroy (dest);
- config_destroy (&conf);
- return rc;
+ state_destroy(dest);
+ config_destroy(&conf);
+ return rc;
}
int
-save_state (const struct state *state, const char *path)
+save_state(const struct state *state, const char *path)
{
- int rc = 0;
+ int rc = 0;
- if (!state || !path)
- return TIB_ENULLPTR;
+ if (!state || !path)
+ return TIB_ENULLPTR;
- config_t conf;
- config_init (&conf);
+ config_t conf;
+ config_init(&conf);
- config_setting_t * const root = config_root_setting (&conf);
+ config_setting_t * const root = config_root_setting(&conf);
#define CHECK_NULL(P) if (!(P)) { rc = TIB_EALLOC; goto end; }
- {
- config_setting_t *history = config_setting_add (root, "history",
- CONFIG_TYPE_LIST);
- CHECK_NULL (history);
-
- for (unsigned int i = 0; i < state->history_len; ++i)
- {
- config_setting_t * const line = config_setting_add (history, NULL,
- CONFIG_TYPE_GROUP);
- CHECK_NULL (line);
-
- config_setting_t *info = config_setting_add (line, "input",
- CONFIG_TYPE_STRING);
- CHECK_NULL (info);
-
- char *s = tib_expr_tostr (&state->history[i].entry);
- if (!s)
- {
- rc = tib_errno;
- goto end;
- }
-
- rc = config_setting_set_string (info, s);
- free (s);
- if (CONFIG_FALSE == rc)
- {
- rc = TIB_EALLOC;
- goto end;
- }
- }
- }
+ config_setting_t *history = config_setting_add(root, "history",
+ CONFIG_TYPE_LIST);
+ CHECK_NULL(history);
+
+ for (unsigned int i = 0; i < state->history_len; ++i)
+ {
+ config_setting_t * const line =
+ config_setting_add(history, NULL, CONFIG_TYPE_GROUP);
+ CHECK_NULL(line);
+
+ config_setting_t *info = config_setting_add(line, "input",
+ CONFIG_TYPE_STRING);
+ CHECK_NULL(info);
+
+ char *s = tib_expr_tostr(&state->history[i].entry);
+ if (!s)
+ {
+ rc = tib_errno;
+ goto end;
+ }
+
+ rc = config_setting_set_string(info, s);
+ free(s);
+ if (CONFIG_FALSE == rc)
+ {
+ rc = TIB_EALLOC;
+ goto end;
+ }
+ }
#undef CHECK_NULL
- rc = 0;
- config_write_file (&conf, path);
+ rc = 0;
+ config_write_file(&conf, path);
end:
- config_destroy (&conf);
- return rc;
+ config_destroy(&conf);
+ return rc;
}
void
-state_destroy (struct state *state)
+state_destroy(struct state *state)
{
- tib_expr_destroy (&state->entry);
- state_clear_history (state);
+ tib_expr_destroy(&state->entry);
+ state_clear_history(state);
}
void
-entry_move_cursor (struct state *state, int distance)
+entry_move_cursor(struct state *state, int distance)
{
- state->entry_cursor += distance;
+ state->entry_cursor += distance;
- if (state->entry_cursor > state->entry.len)
- state->entry_cursor = state->entry.len;
- else if (state->entry_cursor < 0)
- state->entry_cursor = 0;
+ if (state->entry_cursor > state->entry.len)
+ state->entry_cursor = state->entry.len;
+ else if (state->entry_cursor < 0)
+ state->entry_cursor = 0;
- state->action_state = STATE_NORMAL;
+ state->action_state = STATE_NORMAL;
}
static int
-entry_insert (struct state *state, int c)
+entry_insert(struct state *state, int c)
{
- int rc = tib_expr_insert (&state->entry, state->entry_cursor, c);
- if (!rc)
- {
- ++state->entry_cursor;
- state->action_state = STATE_NORMAL;
- state->insert_mode = false;
- }
-
- return rc;
+ int rc = tib_expr_insert(&state->entry, state->entry_cursor, c);
+ if (!rc)
+ {
+ ++state->entry_cursor;
+ state->action_state = STATE_NORMAL;
+ state->insert_mode = false;
+ }
+
+ return rc;
}
int
-entry_write (struct state *state, int c)
+entry_write(struct state *state, int c)
{
- if (state->insert_mode || state->entry_cursor == state->entry.len)
- return entry_insert (state, c);
+ if (state->insert_mode || state->entry_cursor == state->entry.len)
+ return entry_insert(state, c);
- state->entry.data[state->entry_cursor++] = c;
- state->action_state = STATE_NORMAL;
- return 0;
+ state->entry.data[state->entry_cursor++] = c;
+ state->action_state = STATE_NORMAL;
+ return 0;
}
int
-entry_recall (struct state *state)
+entry_recall(struct state *state)
{
- if (state->history_len)
- {
- int rc = tib_exprcpy (&state->entry,
- &state->history[state->history_len - 1].entry);
- if (rc)
- return rc;
-
- state->entry_cursor = state->entry.len;
- }
- else
- {
- state->entry.len = 0;
- }
-
- return 0;
+ if (state->history_len)
+ {
+ int rc = tib_exprcpy(&state->entry,
+ &state->history[state->history_len - 1].entry);
+ if (rc)
+ return rc;
+
+ state->entry_cursor = state->entry.len;
+ }
+ else
+ {
+ state->entry.len = 0;
+ }
+
+ return 0;
}
void
-change_action_state (struct state *state, enum action_state action_state)
+change_action_state(struct state *state, enum action_state action_state)
{
- if (state->action_state != action_state)
- state->action_state = action_state;
- else
- state->action_state = STATE_NORMAL;
+ if (state->action_state != action_state)
+ state->action_state = action_state;
+ else
+ state->action_state = STATE_NORMAL;
}
int
-state_calc_entry (struct state *state)
+state_calc_entry(struct state *state)
{
- TIB *ans = tib_eval (&state->entry);
- if (!ans)
- return tib_errno;
-
- int rc = state_add_history (state, &state->entry, ans);
- if (rc)
- {
- tib_decref (ans);
- return rc;
- }
-
- state->entry_cursor = 0;
- state->entry.len = 0;
-
- rc = tib_var_set (TIB_CHAR_ANS, ans);
- tib_decref (ans);
- return rc;
+ TIB *ans = tib_eval(&state->entry);
+ if (!ans)
+ return tib_errno;
+
+ int rc = state_add_history(state, &state->entry, ans);
+ if (rc)
+ {
+ tib_decref(ans);
+ return rc;
+ }
+
+ state->entry_cursor = 0;
+ state->entry.len = 0;
+
+ rc = tib_var_set(TIB_CHAR_ANS, ans);
+ tib_decref(ans);
+ return rc;
}
int
-state_add_history (struct state *state, const struct tib_expr *in,
- const TIB *answer)
+state_add_history(struct state *state, const struct tib_expr *in,
+ const TIB *answer)
{
- struct tib_expr in_copy = { .bufsize = 0 };
- int rc = tib_exprcpy (&in_copy, in);
- if (rc)
- return rc;
-
- TIB *ans_copy = tib_copy (answer);
- if (!ans_copy)
- {
- tib_expr_destroy (&in_copy);
- return tib_errno;
- }
-
- struct tib_expr ans_s;
- rc = tib_toexpr (&ans_s, ans_copy);
- if (rc)
- {
- rc = load_expr (&ans_s, "Error");
- if (rc)
- {
- tib_expr_destroy (&in_copy);
- tib_decref (ans_copy);
- return rc;
- }
- }
-
- add_history (state, &in_copy, &ans_s, ans_copy);
- return 0;
+ struct tib_expr in_copy = { .bufsize = 0 };
+ int rc = tib_exprcpy(&in_copy, in);
+ if (rc)
+ return rc;
+
+ TIB *ans_copy = tib_copy(answer);
+ if (!ans_copy)
+ {
+ tib_expr_destroy(&in_copy);
+ return tib_errno;
+ }
+
+ struct tib_expr ans_s;
+ rc = tib_toexpr(&ans_s, ans_copy);
+ if (rc)
+ {
+ rc = load_expr(&ans_s, "Error");
+ if (rc)
+ {
+ tib_expr_destroy(&in_copy);
+ tib_decref(ans_copy);
+ return rc;
+ }
+ }
+
+ add_history(state, &in_copy, &ans_s, ans_copy);
+ return 0;
}
void
-state_clear_history (struct state *state)
+state_clear_history(struct state *state)
{
- for (unsigned int i = 0; i < state->history_len; ++i)
- {
- tib_expr_destroy (&state->history[i].entry);
- tib_expr_destroy (&state->history[i].answer_string);
- tib_decref (state->history[i].answer);
- }
-
- state->history_len = 0;
+ for (unsigned int i = 0; i < state->history_len; ++i)
+ {
+ tib_expr_destroy(&state->history[i].entry);
+ tib_expr_destroy(&state->history[i].answer_string);
+ tib_decref(state->history[i].answer);
+ }
+
+ state->history_len = 0;
}
diff --git a/src/state.h b/src/state.h
index 7522673..316ad60 100644
--- a/src/state.h
+++ b/src/state.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -24,63 +24,63 @@
#define MAX_HISTORY 35
enum action_state
- {
- STATE_NORMAL,
- STATE_2ND,
- STATE_ALPHA,
- NUM_ACTION_STATES
- };
+{
+ STATE_NORMAL,
+ STATE_2ND,
+ STATE_ALPHA,
+ NUM_ACTION_STATES
+};
struct history
{
- struct tib_expr entry;
- struct tib_expr answer_string;
+ struct tib_expr entry;
+ struct tib_expr answer_string;
- TIB *answer;
+ TIB *answer;
};
struct state
{
- struct history history[MAX_HISTORY];
- struct tib_expr entry;
+ struct history history[MAX_HISTORY];
+ struct tib_expr entry;
- enum action_state action_state;
- int entry_cursor;
- unsigned int history_len;
+ enum action_state action_state;
+ int entry_cursor;
+ unsigned int history_len;
- bool blink_state;
- bool insert_mode;
+ bool blink_state;
+ bool insert_mode;
};
int
-load_state (struct state *dest, const char *path);
+load_state(struct state *dest, const char *path);
int
-save_state (const struct state *state, const char *path);
+save_state(const struct state *state, const char *path);
void
-state_destroy (struct state *state);
+state_destroy(struct state *state);
void
-entry_move_cursor (struct state *state, int distance);
+entry_move_cursor(struct state *state, int distance);
int
-entry_write (struct state *state, int c);
+entry_write(struct state *state, int c);
int
-entry_recall (struct state *state);
+entry_recall(struct state *state);
void
-change_action_state (struct state *state, enum action_state action_state);
+change_action_state(struct state *state, enum action_state action_state);
int
-state_calc_entry (struct state *state);
+state_calc_entry(struct state *state);
int
-state_add_history (struct state *state, const struct tib_expr *in,
- const TIB *answer);
+state_add_history(struct state *state, const struct tib_expr *in,
+ const TIB *answer);
void
-state_clear_history (struct state *state);
+state_clear_history(struct state *state);
#endif
diff --git a/src/tibchar.c b/src/tibchar.c
index 876cc77..8b59fbc 100644
--- a/src/tibchar.c
+++ b/src/tibchar.c
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -26,412 +26,412 @@
static PrefixTree *keywords = NULL;
const char *
-tib_special_char_text (int c)
+tib_special_char_text(int c)
{
- switch (c)
- {
- case TIB_CHAR_AND:
- return " And ";
+ switch (c)
+ {
+ case TIB_CHAR_AND:
+ return " And ";
- case TIB_CHAR_ANS:
- return "Ans";
+ case TIB_CHAR_ANS:
+ return "Ans";
- case TIB_CHAR_AXESOFF:
- return "AxesOff";
+ case TIB_CHAR_AXESOFF:
+ return "AxesOff";
- case TIB_CHAR_CLEARDRAW:
- return "ClrDraw";
+ case TIB_CHAR_CLEARDRAW:
+ return "ClrDraw";
- case TIB_CHAR_CLEARHOME:
- return "ClrHome";
+ case TIB_CHAR_CLEARHOME:
+ return "ClrHome";
- case TIB_CHAR_CLRLIST:
- return "ClrList";
+ case TIB_CHAR_CLRLIST:
+ return "ClrList";
- case TIB_CHAR_COS:
- return "cos(";
+ case TIB_CHAR_COS:
+ return "cos(";
- case TIB_CHAR_DEGREE:
- return "*(pi/180)";
+ case TIB_CHAR_DEGREE:
+ return "*(pi/180)";
- case TIB_CHAR_DELVAR:
- return "DelVar";
+ case TIB_CHAR_DELVAR:
+ return "DelVar";
- case TIB_CHAR_DIFFERENT:
- return "~";
+ case TIB_CHAR_DIFFERENT:
+ return "~";
- case TIB_CHAR_DIM:
- return "Dim(";
+ case TIB_CHAR_DIM:
+ return "Dim(";
- case TIB_CHAR_DISP:
- return "Disp(";
+ case TIB_CHAR_DISP:
+ return "Disp(";
- case TIB_CHAR_ELSE:
- return "Else";
+ case TIB_CHAR_ELSE:
+ return "Else";
- case TIB_CHAR_END:
- return "End";
+ case TIB_CHAR_END:
+ return "End";
- case TIB_CHAR_EPOW10:
- return "*10^";
+ case TIB_CHAR_EPOW10:
+ return "*10^";
- case TIB_CHAR_FILL:
- return "Fill(";
+ case TIB_CHAR_FILL:
+ return "Fill(";
- case TIB_CHAR_FOR:
- return "For(";
+ case TIB_CHAR_FOR:
+ return "For(";
- case TIB_CHAR_GETKEY:
- return "GetKey";
+ case TIB_CHAR_GETKEY:
+ return "GetKey";
- case TIB_CHAR_GOTO:
- return "Goto ";
+ case TIB_CHAR_GOTO:
+ return "Goto ";
- case TIB_CHAR_IF:
- return "If ";
+ case TIB_CHAR_IF:
+ return "If ";
- case TIB_CHAR_INPUT:
- return "Input ";
+ case TIB_CHAR_INPUT:
+ return "Input ";
- case TIB_CHAR_INT:
- return "int(";
+ case TIB_CHAR_INT:
+ return "int(";
- case TIB_CHAR_L1:
- return "L\\1";
+ case TIB_CHAR_L1:
+ return "L\\1";
- case TIB_CHAR_L2:
- return "L\\2";
+ case TIB_CHAR_L2:
+ return "L\\2";
- case TIB_CHAR_L3:
- return "L\\3";
+ case TIB_CHAR_L3:
+ return "L\\3";
- case TIB_CHAR_L4:
- return "L\\4";
+ case TIB_CHAR_L4:
+ return "L\\4";
- case TIB_CHAR_L5:
- return "L\\5";
+ case TIB_CHAR_L5:
+ return "L\\5";
- case TIB_CHAR_L6:
- return "L\\6";
+ case TIB_CHAR_L6:
+ return "L\\6";
- case TIB_CHAR_L7:
- return "L\\7";
+ case TIB_CHAR_L7:
+ return "L\\7";
- case TIB_CHAR_L8:
- return "L\\8";
+ case TIB_CHAR_L8:
+ return "L\\8";
- case TIB_CHAR_L9:
- return "L\\9";
+ case TIB_CHAR_L9:
+ return "L\\9";
- case TIB_CHAR_LABEL:
- return "Lbl ";
+ case TIB_CHAR_LABEL:
+ return "Lbl ";
- case TIB_CHAR_LINE:
- return "Line(";
+ case TIB_CHAR_LINE:
+ return "Line(";
- case TIB_CHAR_MATA:
- return "[[A]]";
+ case TIB_CHAR_MATA:
+ return "[[A]]";
- case TIB_CHAR_MATB:
- return "[[B]]";
+ case TIB_CHAR_MATB:
+ return "[[B]]";
- case TIB_CHAR_MATC:
- return "[[C]]";
+ case TIB_CHAR_MATC:
+ return "[[C]]";
- case TIB_CHAR_MATD:
- return "[[D]]";
+ case TIB_CHAR_MATD:
+ return "[[D]]";
- case TIB_CHAR_MATE:
- return "[[E]]";
+ case TIB_CHAR_MATE:
+ return "[[E]]";
- case TIB_CHAR_MATF:
- return "[[F]]";
+ case TIB_CHAR_MATF:
+ return "[[F]]";
- case TIB_CHAR_MATG:
- return "[[G]]";
+ case TIB_CHAR_MATG:
+ return "[[G]]";
- case TIB_CHAR_MATH:
- return "[[H]]";
+ case TIB_CHAR_MATH:
+ return "[[H]]";
- case TIB_CHAR_MATI:
- return "[[I]]";
+ case TIB_CHAR_MATI:
+ return "[[I]]";
- case TIB_CHAR_MENU:
- return "Menu(";
+ case TIB_CHAR_MENU:
+ return "Menu(";
- case TIB_CHAR_NOT:
- return "Not(";
+ case TIB_CHAR_NOT:
+ return "Not(";
- case TIB_CHAR_OR:
- return " Or ";
+ case TIB_CHAR_OR:
+ return " Or ";
- case TIB_CHAR_OUTPUT:
- return "Output(";
+ case TIB_CHAR_OUTPUT:
+ return "Output(";
- case TIB_CHAR_PAUSE:
- return "Pause ";
+ case TIB_CHAR_PAUSE:
+ return "Pause ";
- case TIB_CHAR_PI:
- return "pi";
+ case TIB_CHAR_PI:
+ return "pi";
- case TIB_CHAR_PIC1:
- return "Pic1";
+ case TIB_CHAR_PIC1:
+ return "Pic1";
- case TIB_CHAR_PIXEL_TEST:
- return "pxl-Test(";
+ case TIB_CHAR_PIXEL_TEST:
+ return "pxl-Test(";
- case TIB_CHAR_RAND:
- return "RAND";
+ case TIB_CHAR_RAND:
+ return "RAND";
- case TIB_CHAR_RANDINT:
- return "RandInt(";
+ case TIB_CHAR_RANDINT:
+ return "RandInt(";
- case TIB_CHAR_RECALLPIC:
- return "RecallPic ";
+ case TIB_CHAR_RECALLPIC:
+ return "RecallPic ";
- case TIB_CHAR_REPEAT:
- return "Repeat ";
+ case TIB_CHAR_REPEAT:
+ return "Repeat ";
- case TIB_CHAR_RETURN:
- return "Return ";
+ case TIB_CHAR_RETURN:
+ return "Return ";
- case TIB_CHAR_ROUND:
- return "Round(";
+ case TIB_CHAR_ROUND:
+ return "Round(";
- case TIB_CHAR_SIN:
- return "sin(";
+ case TIB_CHAR_SIN:
+ return "sin(";
- case TIB_CHAR_STO:
- return "$";
+ case TIB_CHAR_STO:
+ return "$";
- case TIB_CHAR_STOP:
- return "Stop ";
+ case TIB_CHAR_STOP:
+ return "Stop ";
- case TIB_CHAR_STOREPIC:
- return "StorePic ";
+ case TIB_CHAR_STOREPIC:
+ return "StorePic ";
- case TIB_CHAR_TAN:
- return "tan(";
+ case TIB_CHAR_TAN:
+ return "tan(";
- case TIB_CHAR_TEXT:
- return "Text(";
+ case TIB_CHAR_TEXT:
+ return "Text(";
- case TIB_CHAR_THEN:
- return "Then";
+ case TIB_CHAR_THEN:
+ return "Then";
- case TIB_CHAR_THETA:
- return "Theta";
+ case TIB_CHAR_THETA:
+ return "Theta";
- case TIB_CHAR_WHILE:
- return "While ";
+ case TIB_CHAR_WHILE:
+ return "While ";
- case TIB_CHAR_XMIN:
- return "Xmin";
+ case TIB_CHAR_XMIN:
+ return "Xmin";
- case TIB_CHAR_XMAX:
- return "Xmax";
+ case TIB_CHAR_XMAX:
+ return "Xmax";
- case TIB_CHAR_XSCL:
- return "Xscl";
+ case TIB_CHAR_XSCL:
+ return "Xscl";
- case TIB_CHAR_YMIN:
- return "Ymin";
+ case TIB_CHAR_YMIN:
+ return "Ymin";
- case TIB_CHAR_YMAX:
- return "Ymax";
+ case TIB_CHAR_YMAX:
+ return "Ymax";
- case TIB_CHAR_YSCL:
- return "Yscl";
+ case TIB_CHAR_YSCL:
+ return "Yscl";
- default:
- return NULL;
- }
+ default:
+ return NULL;
+ }
}
static int
-load_range (int beg, int end)
+load_range(int beg, int end)
{
- int rc = 0, i;
- for (i = beg; i <= end; ++i)
- {
- const char *trans = tib_special_char_text (i);
- if (NULL == trans)
- continue;
-
- rc = pt_add (keywords, trans, i);
- if (rc)
- return rc;
- }
-
- return rc;
+ int rc = 0, i;
+ for (i = beg; i <= end; ++i)
+ {
+ const char *trans = tib_special_char_text(i);
+ if (NULL == trans)
+ continue;
+
+ rc = pt_add(keywords, trans, i);
+ if (rc)
+ return rc;
+ }
+
+ return rc;
}
static int
-tokenize (struct tib_expr *expr, char *beg)
+tokenize(struct tib_expr *expr, char *beg)
{
- int rc;
- char *orig = beg;
- size_t len = strlen (beg);
-
- rc = tib_expr_init (expr);
- if (rc)
- return rc;
-
- while (beg < orig + len)
- {
- char temp;
- char *end = strchr (beg, '(');
-
- if (end)
- {
- temp = *(++end);
- *end = '\0';
-
- const PrefixTree *t = pt_search (keywords, beg);
- *end = temp;
-
- if (t)
- {
- rc = tib_expr_push (expr, pt_data (t));
- if (rc)
- goto fail;
-
- beg = end;
- continue;
- }
- }
-
- bool found = false;
- for (end = beg + 1; end <= orig + len; ++end)
- {
- temp = *end;
- *end = '\0';
-
- const PrefixTree *t = pt_search (keywords, beg);
- if (t)
- {
- rc = tib_expr_push (expr, pt_data (t));
- if (rc)
- goto fail;
-
- beg = end;
- found = true;
- }
-
- *end = temp;
- if (found)
- break;
- }
-
- if (!found)
- {
- rc = tib_expr_push (expr, *beg);
- if (rc)
- goto fail;
-
- ++beg;
- }
- }
-
- return rc;
+ int rc;
+ char *orig = beg;
+ size_t len = strlen(beg);
+
+ rc = tib_expr_init(expr);
+ if (rc)
+ return rc;
+
+ while (beg < orig + len)
+ {
+ char temp;
+ char *end = strchr(beg, '(');
+
+ if (end)
+ {
+ temp = *(++end);
+ *end = '\0';
+
+ const PrefixTree *t = pt_search(keywords, beg);
+ *end = temp;
+
+ if (t)
+ {
+ rc = tib_expr_push(expr, pt_data(t));
+ if (rc)
+ goto fail;
+
+ beg = end;
+ continue;
+ }
+ }
+
+ bool found = false;
+ for (end = beg + 1; end <= orig + len; ++end)
+ {
+ temp = *end;
+ *end = '\0';
+
+ const PrefixTree *t = pt_search(keywords, beg);
+ if (t)
+ {
+ rc = tib_expr_push(expr, pt_data(t));
+ if (rc)
+ goto fail;
+
+ beg = end;
+ found = true;
+ }
+
+ *end = temp;
+ if (found)
+ break;
+ }
+
+ if (!found)
+ {
+ rc = tib_expr_push(expr, *beg);
+ if (rc)
+ goto fail;
+
+ ++beg;
+ }
+ }
+
+ return rc;
fail:
- tib_expr_destroy (expr);
- return rc;
+ tib_expr_destroy(expr);
+ return rc;
}
int
-tib_encode_str (struct tib_expr *expr, const char *s)
+tib_encode_str(struct tib_expr *expr, const char *s)
{
- int rc = 0;
- char *buf, *beg;
- size_t line_len = strlen (s);
-
- buf = malloc ((line_len + 1) * sizeof (char));
- if (!buf)
- return TIB_EALLOC;
-
- strcpy (buf, s);
- beg = buf;
- expr->len = 0;
-
- while (beg < buf + line_len)
- {
- char *end = strchr (beg, '"');
- if (end)
- *end = '\0';
-
- struct tib_expr part;
- rc = tokenize (&part, beg);
- if (rc)
- break;
-
- rc = tib_exprcat (expr, &part);
- tib_expr_destroy (&part);
- if (rc)
- break;
-
- if (!end)
- break;
-
- beg = end + 1;
- end = strchr (beg, '"');
-
- if (!end)
- end = buf + line_len;
-
- rc = tib_expr_push (expr, '"');
- if (rc)
- break;
-
- for (; beg < end; ++beg)
- {
- rc = tib_expr_push (expr, *beg);
- if (rc)
- goto end;
- }
-
- if (*end)
- {
- rc = tib_expr_push (expr, *end);
- if (rc)
- break;
- }
-
- beg = end + 1;
- }
+ int rc = 0;
+ char *buf, *beg;
+ size_t line_len = strlen(s);
+
+ buf = malloc((line_len + 1) * sizeof(char));
+ if (!buf)
+ return TIB_EALLOC;
+
+ strcpy(buf, s);
+ beg = buf;
+ expr->len = 0;
+
+ while (beg < buf + line_len)
+ {
+ char *end = strchr(beg, '"');
+ if (end)
+ *end = '\0';
+
+ struct tib_expr part;
+ rc = tokenize(&part, beg);
+ if (rc)
+ break;
+
+ rc = tib_exprcat(expr, &part);
+ tib_expr_destroy(&part);
+ if (rc)
+ break;
+
+ if (!end)
+ break;
+
+ beg = end + 1;
+ end = strchr(beg, '"');
+
+ if (!end)
+ end = buf + line_len;
+
+ rc = tib_expr_push(expr, '"');
+ if (rc)
+ break;
+
+ for (; beg < end; ++beg)
+ {
+ rc = tib_expr_push(expr, *beg);
+ if (rc)
+ goto end;
+ }
+
+ if (*end)
+ {
+ rc = tib_expr_push(expr, *end);
+ if (rc)
+ break;
+ }
+
+ beg = end + 1;
+ }
end:
- if (rc)
- tib_expr_destroy (expr);
+ if (rc)
+ tib_expr_destroy(expr);
- free (buf);
- return rc;
+ free(buf);
+ return rc;
}
int
-tib_keyword_init ()
+tib_keyword_init()
{
- if (keywords)
- return 0;
+ if (keywords)
+ return 0;
- keywords = pt_new ();
- if (NULL == keywords)
- return TIB_EALLOC;
+ keywords = pt_new();
+ if (NULL == keywords)
+ return TIB_EALLOC;
- int rc = load_range (TIB_FIRST_CHAR, TIB_LAST_CHAR);
- if (rc)
- tib_keyword_free ();
+ int rc = load_range(TIB_FIRST_CHAR, TIB_LAST_CHAR);
+ if (rc)
+ tib_keyword_free();
- return rc;
+ return rc;
}
void
-tib_keyword_free ()
+tib_keyword_free()
{
- if (keywords)
- {
- pt_free (keywords);
- keywords = NULL;
- }
+ if (keywords)
+ {
+ pt_free(keywords);
+ keywords = NULL;
+ }
}
diff --git a/src/tibchar.h b/src/tibchar.h
index 1b35b71..84c3521 100644
--- a/src/tibchar.h
+++ b/src/tibchar.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,112 +21,112 @@
#include "tibexpr.h"
enum tib_special_char
- {
- /* printing characters */
- TIB_CHAR_DEGREE = 128,
- TIB_CHAR_EPOW10,
- TIB_CHAR_LESSEQUAL,
- TIB_CHAR_GREATEREQUAL,
- TIB_CHAR_L1,
- TIB_CHAR_L2,
- TIB_CHAR_L3,
- TIB_CHAR_L4,
- TIB_CHAR_L5,
- TIB_CHAR_L6,
- TIB_CHAR_L7,
- TIB_CHAR_L8,
- TIB_CHAR_L9,
- TIB_CHAR_PI,
- TIB_CHAR_SMALL1,
- TIB_CHAR_SMALL2,
- TIB_CHAR_SMALL3,
- TIB_CHAR_SMALL4,
- TIB_CHAR_SMALL5,
- TIB_CHAR_SMALL6,
- TIB_CHAR_SMALL7,
- TIB_CHAR_SMALL8,
- TIB_CHAR_SMALL9,
- TIB_CHAR_SMALL_MINUS,
- TIB_CHAR_STO,
- TIB_CHAR_THETA,
+{
+ /* printing characters */
+ TIB_CHAR_DEGREE = 128,
+ TIB_CHAR_EPOW10,
+ TIB_CHAR_LESSEQUAL,
+ TIB_CHAR_GREATEREQUAL,
+ TIB_CHAR_L1,
+ TIB_CHAR_L2,
+ TIB_CHAR_L3,
+ TIB_CHAR_L4,
+ TIB_CHAR_L5,
+ TIB_CHAR_L6,
+ TIB_CHAR_L7,
+ TIB_CHAR_L8,
+ TIB_CHAR_L9,
+ TIB_CHAR_PI,
+ TIB_CHAR_SMALL1,
+ TIB_CHAR_SMALL2,
+ TIB_CHAR_SMALL3,
+ TIB_CHAR_SMALL4,
+ TIB_CHAR_SMALL5,
+ TIB_CHAR_SMALL6,
+ TIB_CHAR_SMALL7,
+ TIB_CHAR_SMALL8,
+ TIB_CHAR_SMALL9,
+ TIB_CHAR_SMALL_MINUS,
+ TIB_CHAR_STO,
+ TIB_CHAR_THETA,
- /* "characters" expanded to strings */
- TIB_CHAR_AND,
- TIB_CHAR_ANS,
- TIB_CHAR_AXESOFF,
- TIB_CHAR_AXESON,
- TIB_CHAR_CLEARDRAW,
- TIB_CHAR_CLEARHOME,
- TIB_CHAR_CLRLIST,
- TIB_CHAR_COS,
- TIB_CHAR_DELVAR,
- TIB_CHAR_DIFFERENT,
- TIB_CHAR_DIM,
- TIB_CHAR_DISP,
- TIB_CHAR_ELSE,
- TIB_CHAR_END,
- TIB_CHAR_FILL,
- TIB_CHAR_FOR,
- TIB_CHAR_GETKEY,
- TIB_CHAR_GOTO,
- TIB_CHAR_IF,
- TIB_CHAR_INPUT,
- TIB_CHAR_INT,
- TIB_CHAR_LABEL,
- TIB_CHAR_LINE,
- TIB_CHAR_LUSER,
- TIB_CHAR_MATA,
- TIB_CHAR_MATB,
- TIB_CHAR_MATC,
- TIB_CHAR_MATD,
- TIB_CHAR_MATE,
- TIB_CHAR_MATF,
- TIB_CHAR_MATG,
- TIB_CHAR_MATH,
- TIB_CHAR_MATI,
- TIB_CHAR_MENU,
- TIB_CHAR_NOT,
- TIB_CHAR_OR,
- TIB_CHAR_OUTPUT,
- TIB_CHAR_PAUSE,
- TIB_CHAR_PIC1,
- TIB_CHAR_PIXEL_TEST,
- TIB_CHAR_RAND,
- TIB_CHAR_RANDINT,
- TIB_CHAR_RECALLPIC,
- TIB_CHAR_REPEAT,
- TIB_CHAR_RETURN,
- TIB_CHAR_ROUND,
- TIB_CHAR_SIN,
- TIB_CHAR_STOP,
- TIB_CHAR_STOREPIC,
- TIB_CHAR_TAN,
- TIB_CHAR_TEXT,
- TIB_CHAR_THEN,
- TIB_CHAR_TRANSPOSE,
- TIB_CHAR_WHILE,
- TIB_CHAR_XMAX,
- TIB_CHAR_XMIN,
- TIB_CHAR_XSCL,
- TIB_CHAR_YMAX,
- TIB_CHAR_YMIN,
- TIB_CHAR_YSCL,
+ /* "characters" expanded to strings */
+ TIB_CHAR_AND,
+ TIB_CHAR_ANS,
+ TIB_CHAR_AXESOFF,
+ TIB_CHAR_AXESON,
+ TIB_CHAR_CLEARDRAW,
+ TIB_CHAR_CLEARHOME,
+ TIB_CHAR_CLRLIST,
+ TIB_CHAR_COS,
+ TIB_CHAR_DELVAR,
+ TIB_CHAR_DIFFERENT,
+ TIB_CHAR_DIM,
+ TIB_CHAR_DISP,
+ TIB_CHAR_ELSE,
+ TIB_CHAR_END,
+ TIB_CHAR_FILL,
+ TIB_CHAR_FOR,
+ TIB_CHAR_GETKEY,
+ TIB_CHAR_GOTO,
+ TIB_CHAR_IF,
+ TIB_CHAR_INPUT,
+ TIB_CHAR_INT,
+ TIB_CHAR_LABEL,
+ TIB_CHAR_LINE,
+ TIB_CHAR_LUSER,
+ TIB_CHAR_MATA,
+ TIB_CHAR_MATB,
+ TIB_CHAR_MATC,
+ TIB_CHAR_MATD,
+ TIB_CHAR_MATE,
+ TIB_CHAR_MATF,
+ TIB_CHAR_MATG,
+ TIB_CHAR_MATH,
+ TIB_CHAR_MATI,
+ TIB_CHAR_MENU,
+ TIB_CHAR_NOT,
+ TIB_CHAR_OR,
+ TIB_CHAR_OUTPUT,
+ TIB_CHAR_PAUSE,
+ TIB_CHAR_PIC1,
+ TIB_CHAR_PIXEL_TEST,
+ TIB_CHAR_RAND,
+ TIB_CHAR_RANDINT,
+ TIB_CHAR_RECALLPIC,
+ TIB_CHAR_REPEAT,
+ TIB_CHAR_RETURN,
+ TIB_CHAR_ROUND,
+ TIB_CHAR_SIN,
+ TIB_CHAR_STOP,
+ TIB_CHAR_STOREPIC,
+ TIB_CHAR_TAN,
+ TIB_CHAR_TEXT,
+ TIB_CHAR_THEN,
+ TIB_CHAR_TRANSPOSE,
+ TIB_CHAR_WHILE,
+ TIB_CHAR_XMAX,
+ TIB_CHAR_XMIN,
+ TIB_CHAR_XSCL,
+ TIB_CHAR_YMAX,
+ TIB_CHAR_YMIN,
+ TIB_CHAR_YSCL,
- /* meta */
- TIB_FIRST_CHAR = 128,
- TIB_LAST_CHAR = TIB_CHAR_YSCL
- };
+ /* meta */
+ TIB_FIRST_CHAR = 128,
+ TIB_LAST_CHAR = TIB_CHAR_YSCL
+};
const char *
-tib_special_char_text (int c);
+tib_special_char_text(int c);
int
-tib_encode_str (struct tib_expr *dest, const char *src);
+tib_encode_str(struct tib_expr *dest, const char *src);
int
-tib_keyword_init (void);
+tib_keyword_init(void);
void
-tib_keyword_free (void);
+tib_keyword_free(void);
#endif
diff --git a/src/tibdecode.c b/src/tibdecode.c
index d4f0092..3ec916e 100644
--- a/src/tibdecode.c
+++ b/src/tibdecode.c
@@ -1,6 +1,6 @@
/*
* tibdecode - Decompile a TI BASIC program
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <getopt.h>
#include "tiberr.h"
#include "tibtranscode.h"
@@ -28,95 +27,87 @@
#define USAGE_INFO "USAGE: tibdecode [options]\n\n\
tibdecode reads a TI-82 or TI-83 program from stdin and prints to stdout.\n\n\
OPTIONS:\n\
-\t-d, --debug\tShows the decimal value of unknown characters in {}\n\
-\t-h, --help\tPrints this help message and exits\n\
-\t-v, --version\tPrints version info and exits\n"
+\t-d\tShows the decimal value of unknown characters in {}\n\
+\t-h\tPrints this help message and exits\n\
+\t-v\tPrints version info and exits\n"
-#define VERSION_INFO "tibdecode (Delwink LiberTI) 1.0.0\n\
-Copyright (C) 2015-2016 Delwink, LLC\n\
+#define VERSION_INFO "tibdecode (Delwink LiberTI) 0.0.0\n\
+Copyright (C) 2015-2017 Delwink, LLC\n\
License AGPLv3: GNU AGPL version 3 only <http://gnu.org/licenses/agpl.html>.\n\
This is libre software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n\n\
Written by David McMackins II."
#if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE
-# include <ctype.h>
+#include <ctype.h>
#else
static int
-isascii (int c)
+isascii(int c)
{
- return c & 0x7F;
+ return c & 0x7F;
}
#endif
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- bool debug = false;
+ bool debug = false;
- struct option longopts[] =
- {
- {"debug", no_argument, 0, 'd'},
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'v'},
- {0, 0, 0, 0}
- };
+ if (argc > 1)
+ {
+ int c;
+ while ((c = getopt(argc, argv, "dhv")) != -1)
+ {
+ switch (c)
+ {
+ case 'd':
+ debug = true;
+ break;
- if (argc > 1)
- {
- int c;
- int longindex;
- while ((c = getopt_long (argc, argv, "dhv", longopts, &longindex)) != -1)
- {
- switch (c)
- {
- case 'd':
- debug = true;
- break;
+ case 'h':
+ puts(USAGE_INFO);
+ return 0;
- case 'h':
- puts (USAGE_INFO);
- return 0;
+ case 'v':
+ puts(VERSION_INFO);
+ return 0;
- case 'v':
- puts (VERSION_INFO);
- return 0;
+ case '?':
+ return 1;
+ }
+ }
+ }
- case '?':
- return 1;
- }
- }
- }
+ struct tib_expr translated;
+ unsigned long parsed;
+ tib_errno = tib_fread(&translated, stdin, &parsed);
+ if (tib_errno)
+ {
+ fprintf(stderr,
+ "tibdecode: Error %d occurred while processing. Parsed %lu characters.\n",
+ tib_errno, parsed);
+ return 1;
+ }
- struct tib_expr translated;
- unsigned long parsed;
- tib_errno = tib_fread (&translated, stdin, &parsed);
- if (tib_errno)
- {
- fprintf (stderr, "tibdecode: Error %d occurred while processing. "
- "Parsed %lu characters.\n",
- tib_errno, parsed);
- return 1;
- }
+ char *s = tib_expr_tostr(&translated);
+ tib_expr_destroy(&translated);
+ if (NULL == s)
+ {
+ fprintf(stderr,
+ "tibdecode: Error %d occurred while processing\n",
+ tib_errno);
+ return 1;
+ }
- char *s = tib_expr_tostr (&translated);
- tib_expr_destroy (&translated);
- if (NULL == s)
- {
- fprintf (stderr, "tibdecode: Error %d occurred while processing\n",
- tib_errno);
- return 1;
- }
+ size_t len = strlen(s);
+ for (size_t i = 0; i < len; ++i)
+ {
+ if (debug && !isascii(s[i]))
+ printf("`%d`", s[i]);
+ else
+ putchar(s[i]);
+ }
- size_t len = strlen (s);
- for (size_t i = 0; i < len; ++i)
- {
- if (debug && !isascii (s[i]))
- printf ("`%d`", s[i]);
- else
- putchar (s[i]);
- }
-
- free (s);
- return 0;
+ free(s);
+ return 0;
}
diff --git a/src/tibencode.c b/src/tibencode.c
index a08fc69..022004f 100644
--- a/src/tibencode.c
+++ b/src/tibencode.c
@@ -1,6 +1,6 @@
/*
* tibencode - Compile a TI BASIC program
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -19,7 +19,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <getopt.h>
#include "tibchar.h"
#include "tibtranscode.h"
@@ -28,146 +27,141 @@
#define USAGE_INFO "USAGE: tibencode [options]\n\n\
tibencode reads a TI-BASIC program from stdin and prints to stdout.\n\n\
OPTIONS:\n\
-\t-h, --help\tPrints this help message and exits\n\
-\t-v, --version\tPrints version info and exits\n"
+\t-h\tPrints this help message and exits\n\
+\t-v\tPrints version info and exits\n"
-#define VERSION_INFO "tibencode (Delwink LiberTI) 1.0.0\n\
-Copyright (C) 2015-2016 Delwink, LLC\n\
+#define VERSION_INFO "tibencode (Delwink LiberTI) 0.0.0\n\
+Copyright (C) 2015-2017 Delwink, LLC\n\
License AGPLv3: GNU AGPL version 3 only <http://gnu.org/licenses/agpl.html>.\n\
This is libre software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n\n\
Written by David McMackins II."
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- unsigned long written;
-
- struct option longopts[] =
- {
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'v'},
- {0, 0, 0, 0}
- };
-
- if (argc > 1)
- {
- int c;
- int longindex;
- while ((c = getopt_long (argc, argv, "hv", longopts, &longindex)) != -1)
- {
- switch (c)
- {
- case 'h':
- puts (USAGE_INFO);
- return 0;
-
- case 'v':
- puts (VERSION_INFO);
- return 0;
-
- case '?':
- return 1;
- }
- }
- }
-
- tib_errno = tib_keyword_init ();
- if (tib_errno)
- {
- fputs ("tibencode: Error allocating space for keyword tree.\n", stderr);
- return 1;
- }
-
- struct tib_expr translated;
- tib_errno = tib_expr_init (&translated);
- if (tib_errno)
- {
- fputs ("tibencode: Error creating expression buffer.\n", stderr);
- return 1;
- }
-
- unsigned int max_line_len = 128;
- char *buf = malloc (max_line_len * sizeof (char));
- if (NULL == buf)
- {
- tib_expr_destroy (&translated);
- fputs ("tibencode: Error allocating line buffer.\n", stderr);
- return 1;
- }
-
- int c = '\0';
- unsigned int line_len = 0;
- while (c != EOF)
- {
- for (; line_len < max_line_len - 1; ++line_len)
- {
- c = getchar ();
- if ('\n' == c || EOF == c)
- break;
-
- buf[line_len] = c;
- }
-
- if (max_line_len - 1 == line_len)
- {
- char *old = buf;
-
- max_line_len *= 2;
- buf = realloc (buf, max_line_len * sizeof (char));
- if (!buf)
- {
- free (old);
- tib_errno = TIB_EALLOC;
- goto end;
- }
-
- continue;
- }
-
- buf[line_len] = '\0';
-
- struct tib_expr line;
- tib_errno = tib_encode_str (&line, buf);
- if (tib_errno)
- goto end;
-
- tib_errno = tib_exprcat (&translated, &line);
- tib_expr_destroy (&line);
- if (tib_errno)
- goto end;
-
- if (c != EOF)
- {
- tib_errno = tib_expr_push (&translated, '\n');
- if (tib_errno)
- goto end;
- }
-
- line_len = 0;
- }
+ unsigned long written;
+
+ if (argc > 1)
+ {
+ int c;
+ while ((c = getopt(argc, argv, "hv")) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ puts(USAGE_INFO);
+ return 0;
+
+ case 'v':
+ puts(VERSION_INFO);
+ return 0;
+
+ case '?':
+ return 1;
+ }
+ }
+ }
+
+ tib_errno = tib_keyword_init();
+ if (tib_errno)
+ {
+ fputs("tibencode: Error allocating space for keyword tree.\n",
+ stderr);
+ return 1;
+ }
+
+ struct tib_expr translated;
+ tib_errno = tib_expr_init(&translated);
+ if (tib_errno)
+ {
+ fputs("tibencode: Error creating expression buffer.\n",
+ stderr);
+ return 1;
+ }
+
+ unsigned int max_line_len = 128;
+ char *buf = malloc(max_line_len * sizeof(char));
+ if (NULL == buf)
+ {
+ tib_expr_destroy(&translated);
+ fputs("tibencode: Error allocating line buffer.\n", stderr);
+ return 1;
+ }
+
+ int c = '\0';
+ unsigned int line_len = 0;
+ while (c != EOF)
+ {
+ for (; line_len < max_line_len - 1; ++line_len)
+ {
+ c = getchar();
+ if ('\n' == c || EOF == c)
+ break;
+
+ buf[line_len] = c;
+ }
+
+ if (max_line_len - 1 == line_len)
+ {
+ char *old = buf;
+
+ max_line_len *= 2;
+ buf = realloc(buf, max_line_len * sizeof(char));
+ if (!buf)
+ {
+ free(old);
+ tib_errno = TIB_EALLOC;
+ goto end;
+ }
+
+ continue;
+ }
+
+ buf[line_len] = '\0';
+
+ struct tib_expr line;
+ tib_errno = tib_encode_str(&line, buf);
+ if (tib_errno)
+ goto end;
+
+ tib_errno = tib_exprcat(&translated, &line);
+ tib_expr_destroy(&line);
+ if (tib_errno)
+ goto end;
+
+ if (c != EOF)
+ {
+ tib_errno = tib_expr_push(&translated, '\n');
+ if (tib_errno)
+ goto end;
+ }
+
+ line_len = 0;
+ }
end:
- free (buf);
- tib_keyword_free ();
-
- if (tib_errno)
- {
- tib_expr_destroy (&translated);
- fprintf (stderr, "tibencode: Error %d occurred while assembling.\n",
- tib_errno);
- return 1;
- }
-
- tib_errno = tib_fwrite (stdout, &translated, &written);
- tib_expr_destroy (&translated);
- if (tib_errno)
- {
- fprintf (stderr, "tibencode: Error %d occurred while processing. "
- "Wrote %lu characters.\n",
- tib_errno, written);
- return 1;
- }
-
- return 0;
+ free(buf);
+ tib_keyword_free();
+
+ if (tib_errno)
+ {
+ tib_expr_destroy(&translated);
+ fprintf(stderr,
+ "tibencode: Error %d occurred while assembling.\n",
+ tib_errno);
+ return 1;
+ }
+
+ tib_errno = tib_fwrite(stdout, &translated, &written);
+ tib_expr_destroy(&translated);
+ if (tib_errno)
+ {
+ fprintf(stderr,
+ "tibencode: Error %d occurred while processing. Wrote %lu characters.\n",
+ tib_errno, written);
+ return 1;
+ }
+
+ return 0;
}
diff --git a/src/tiberr.h b/src/tiberr.h
index b236510..696a249 100644
--- a/src/tiberr.h
+++ b/src/tiberr.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -19,22 +19,22 @@
#define DELWINK_TIB_ERR_H
enum tib_err
- {
- TIB_EALLOC = -1,
- TIB_EINDEX = -2,
- TIB_ESYNTAX = -3,
- TIB_ETYPE = -4,
- TIB_EDIM = -5,
- TIB_ENULLPTR = -6,
- TIB_EDOMAIN = -7,
- TIB_EBADCHAR = -8,
- TIB_EWRITE = -9,
- TIB_EBADFILE = -10,
- TIB_EBADFUNC = -11,
- TIB_EARGNUM = -12,
- TIB_DBYZERO = -13,
- TIB_EOVER = -14
- };
+{
+ TIB_EALLOC = -1,
+ TIB_EINDEX = -2,
+ TIB_ESYNTAX = -3,
+ TIB_ETYPE = -4,
+ TIB_EDIM = -5,
+ TIB_ENULLPTR = -6,
+ TIB_EDOMAIN = -7,
+ TIB_EBADCHAR = -8,
+ TIB_EWRITE = -9,
+ TIB_EBADFILE = -10,
+ TIB_EBADFUNC = -11,
+ TIB_EARGNUM = -12,
+ TIB_DBYZERO = -13,
+ TIB_EOVER = -14
+};
extern int tib_errno;
diff --git a/src/tibeval.c b/src/tibeval.c
index 3f1f182..364d569 100644
--- a/src/tibeval.c
+++ b/src/tibeval.c
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -26,787 +26,798 @@
#include "tibvar.h"
enum math_operator_function_type
- {
- T,
- TT
- };
+{
+ T,
+ TT
+};
struct math_operator
{
- union
- {
- TIB *(*t) (const TIB *);
- TIB *(*tt) (const TIB *, const TIB *);
- } func;
+ union
+ {
+ TIB *(*t)(const TIB *);
+ TIB *(*tt)(const TIB *, const TIB *);
+ } func;
- enum math_operator_function_type function_type;
+ enum math_operator_function_type function_type;
- int c;
- int priority;
+ int c;
+ int priority;
};
-static const struct math_operator OPERATORS[] =
- {
- { { .t = tib_factorial }, T, '!', 0 },
- { { .t = tib_toradians }, T, TIB_CHAR_DEGREE, 0 },
- { { .tt = tib_pow }, TT, '^', 1 },
- { { .tt = tib_mul }, TT, '*', 2 },
- { { .tt = tib_div }, TT, '/', 2 },
- { { .tt = tib_add }, TT, '+', 3 },
- { { .tt = tib_sub }, TT, '-', 3 }
- };
+static const struct math_operator OPERATORS[] = {
+ { {.t = tib_factorial }, T, '!', 0},
+ { {.t = tib_toradians }, T, TIB_CHAR_DEGREE, 0},
+ { {.tt = tib_pow }, TT, '^', 1},
+ { {.tt = tib_mul }, TT, '*', 2},
+ { {.tt = tib_div }, TT, '/', 2},
+ { {.tt = tib_add }, TT, '+', 3},
+ { {.tt = tib_sub }, TT, '-', 3}
+};
#define NUM_MATH_OPERATORS (sizeof OPERATORS / sizeof (struct math_operator))
#define LAST_PRIORITY 3
static bool
-is_var_char (int c)
+is_var_char(int c)
{
- return isupper (c) || TIB_CHAR_THETA == c;
+ return isupper(c) || TIB_CHAR_THETA == c;
}
static bool
-needs_mult_common (int c)
+needs_mult_common(int c)
{
- return (isdigit (c) || is_var_char (c) || tib_is_var (c));
+ return (isdigit(c) || is_var_char(c) || tib_is_var(c));
}
static bool
-needs_mult_right (int c)
+needs_mult_right(int c)
{
- return (needs_mult_common (c) || tib_is_func (c));
+ return (needs_mult_common(c) || tib_is_func(c));
}
static bool
-needs_mult_left (int c)
+needs_mult_left(int c)
{
- return (needs_mult_common (c) || ')' == c);
+ return (needs_mult_common(c) || ')' == c);
}
bool
-is_sign_operator (int c)
+is_sign_operator(int c)
{
- return ('+' == c || '-' == c);
+ return ('+' == c || '-' == c);
}
static const struct math_operator *
-get_math_operator (int c)
+get_math_operator(int c)
{
- for (unsigned int i = 0; i < NUM_MATH_OPERATORS; ++i)
- if (OPERATORS[i].c == c)
- return &OPERATORS[i];
+ for (unsigned int i = 0; i < NUM_MATH_OPERATORS; ++i)
+ if (OPERATORS[i].c == c)
+ return &OPERATORS[i];
- return NULL;
+ return NULL;
}
bool
-is_math_operator (int c)
+is_math_operator(int c)
{
- return get_math_operator (c) != NULL;
+ return get_math_operator(c) != NULL;
}
unsigned int
-sign_count (const struct tib_expr *expr)
+sign_count(const struct tib_expr *expr)
{
- int i;
- unsigned int out = 0;
+ int i;
+ unsigned int out = 0;
- tib_expr_foreach (expr, i)
- if (is_sign_operator (expr->data[i]))
- ++out;
+ tib_expr_foreach(expr, i)
+ if (is_sign_operator(expr->data[i]))
+ ++out;
- return out;
+ return out;
}
bool
-contains_i (const struct tib_expr *expr)
+contains_i(const struct tib_expr *expr)
{
- int i;
+ int i;
- tib_expr_foreach (expr, i)
- if ('i' == expr->data[i])
- return true;
+ tib_expr_foreach(expr, i)
+ if ('i' == expr->data[i])
+ return true;
- return false;
+ return false;
}
static int
-replace_epow10 (struct tib_expr *expr)
+replace_epow10(struct tib_expr *expr)
{
- int i;
-
- tib_expr_foreach (expr, i)
- {
- if (TIB_CHAR_EPOW10 == expr->data[i])
- {
- expr->data[i++] = '*';
-
- const char *s = "10^";
- for (; *s != '\0'; ++s, ++i)
- {
- int rc = tib_expr_insert (expr, i, *s);
- if (rc)
- return rc;
- }
- }
- }
-
- return 0;
+ int i;
+
+ tib_expr_foreach(expr, i)
+ {
+ if (TIB_CHAR_EPOW10 == expr->data[i])
+ {
+ expr->data[i++] = '*';
+
+ const char *s = "10^";
+ for (; *s != '\0'; ++s, ++i)
+ {
+ int rc = tib_expr_insert(expr, i, *s);
+ if (rc)
+ return rc;
+ }
+ }
+ }
+
+ return 0;
}
static TIB *
-single_eval (const struct tib_expr *expr)
+single_eval(const struct tib_expr *expr)
{
- int len = expr->len;
-
- if (0 == len)
- return tib_empty ();
-
- if (1 == len && (is_var_char (expr->data[0]) || tib_is_var (expr->data[0])))
- return tib_var_get (expr->data[0]);
-
- int func = tib_eval_surrounded (expr);
- if (func)
- {
- struct tib_expr temp;
- tib_subexpr (&temp, expr, 1, len - 1);
- return tib_call (func, &temp);
- }
-
- if (tib_eval_isnum (expr))
- {
- gsl_complex z;
- tib_errno = tib_expr_parse_complex (expr, &z);
- return tib_errno ? NULL : tib_new_complex (GSL_REAL (z), GSL_IMAG (z));
- }
-
- if (tib_eval_isstr (expr))
- {
- char *s = tib_expr_tostr (expr);
- if (NULL == s)
- return NULL;
-
- TIB *temp = tib_new_str (s);
- free (s);
-
- return temp;
- }
-
- tib_errno = TIB_ESYNTAX;
- return NULL;
+ int len = expr->len;
+
+ if (0 == len)
+ return tib_empty();
+
+ if (1 == len
+ && (is_var_char(expr->data[0]) || tib_is_var(expr->data[0])))
+ return tib_var_get(expr->data[0]);
+
+ int func = tib_eval_surrounded(expr);
+ if (func)
+ {
+ struct tib_expr temp;
+ tib_subexpr(&temp, expr, 1, len - 1);
+ return tib_call(func, &temp);
+ }
+
+ if (tib_eval_isnum(expr))
+ {
+ gsl_complex z;
+ tib_errno = tib_expr_parse_complex(expr, &z);
+ return tib_errno ? NULL : tib_new_complex(GSL_REAL(z),
+ GSL_IMAG(z));
+ }
+
+ if (tib_eval_isstr(expr))
+ {
+ char *s = tib_expr_tostr(expr);
+ if (NULL == s)
+ return NULL;
+
+ TIB *temp = tib_new_str(s);
+ free(s);
+
+ return temp;
+ }
+
+ tib_errno = TIB_ESYNTAX;
+ return NULL;
}
TIB *
-tib_eval (const struct tib_expr *in)
+tib_eval(const struct tib_expr *in)
{
- int i;
-
- if (0 == in->len)
- return tib_empty ();
-
- /* check for store operator */
- i = tib_expr_indexof (in, TIB_CHAR_STO);
- if (i >= 0)
- {
- if (i != in->len - 2 || 0 == i)
- {
- tib_errno = TIB_ESYNTAX;
- return NULL;
- }
-
- int c = in->data[i + 1];
- if (!is_var_char (c))
- {
- tib_errno = TIB_ESYNTAX;
- return NULL;
- }
-
- struct tib_expr e;
- tib_subexpr (&e, in, 0, i);
-
- TIB *stoval = tib_eval (&e);
- if (NULL == stoval)
- return NULL;
-
- tib_errno = tib_var_set (c, stoval);
- if (tib_errno)
- {
- tib_decref (stoval);
- return NULL;
- }
-
- return stoval;
- }
-
- struct tib_expr expr = { .bufsize = 0 };
- tib_errno = tib_exprcpy (&expr, in);
- if (tib_errno)
- return NULL;
-
- /* check for sign operator at the beginning of number */
- if (expr.len > 0 && ('-' == expr.data[0] || '+' == expr.data[0]))
- {
- tib_errno = tib_expr_insert (&expr, 0, '0');
- if (tib_errno)
- {
- tib_expr_destroy (&expr);
- return NULL;
- }
- }
-
- /* check for implicit closing parentheses and close them */
- tib_errno = tib_eval_close_parens (&expr);
- if (tib_errno)
- {
- tib_expr_destroy (&expr);
- return NULL;
- }
-
- /* replace power of 10 E character with "*10^" */
- tib_errno = replace_epow10 (&expr);
- if (tib_errno)
- {
- tib_expr_destroy (&expr);
- return NULL;
- }
-
- /* add multiplication operators between implicit multiplications */
- bool add = true;
- tib_expr_foreach (&expr, i)
- {
- int c = expr.data[i];
-
- if ('"' == c)
- {
- add = !add; /* don't change anything inside a string */
- }
- else if (add)
- {
- if (is_var_char (c) || tib_is_var (c))
- {
- if (i > 0 && needs_mult_left (expr.data[i - 1]))
- tib_errno = tib_expr_insert (&expr, i++, '*');
-
- if (!tib_errno && i < expr.len - 1
- && needs_mult_right (expr.data[i + 1]))
- tib_errno = tib_expr_insert (&expr, ++i, '*');
- }
- else if (i > 0 && i < expr.len - 1)
- {
- if (tib_is_func (c) && needs_mult_left (expr.data[i - 1]))
- tib_errno = tib_expr_insert (&expr, i++, '*');
- else if (')' == c && needs_mult_right (expr.data[i + 1]))
- tib_errno = tib_expr_insert (&expr, ++i, '*');
- }
-
- if (tib_errno)
- {
- tib_expr_destroy (&expr);
- return NULL;
- }
- }
- }
-
- /* this is temp storage for internally-resolved portions */
- struct tib_lst *resolved = tib_new_lst ();
- if (!resolved)
- {
- tib_expr_destroy (&expr);
- tib_errno = TIB_EALLOC;
- return NULL;
- }
-
- /* this is to remember the operations to be executed */
- struct tib_expr calc;
- tib_errno = tib_expr_init (&calc);
- if (tib_errno)
- {
- tib_expr_destroy (&expr);
- tib_free_lst (resolved);
- return NULL;
- }
-
- /* resolve operand expressions, and store the values for later */
- int beg = 0, numpar = 0;
- add = true;
- tib_expr_foreach (&expr, i)
- {
- int c = expr.data[i];
-
- if ('"' == c)
- {
- add = !add;
- continue;
- }
-
- if (!add)
- continue;
-
- if (tib_is_func (c))
- {
- ++numpar;
- }
- else if (')' == c)
- {
- if (0 == numpar)
- {
- tib_errno = TIB_ESYNTAX;
- break;
- }
-
- --numpar;
- }
-
- const struct math_operator *oper;
- if (0 == numpar && (oper = get_math_operator (c)) != NULL)
- {
- struct tib_expr sub;
- tib_subexpr (&sub, &expr, beg, i);
-
- TIB *part = single_eval (&sub);
- if (!part)
- break;
-
- if (T == oper->function_type)
- {
- do
- {
- TIB *temp = oper->func.t (part);
- tib_decref (part);
- if (!temp)
- break;
-
- part = temp;
- }
- while (++i < expr.len
- && (oper = get_math_operator (expr.data[i])) != NULL
- && T == oper->function_type);
-
- if (tib_errno)
- break;
-
- tib_errno = tib_lst_push (resolved, part);
- tib_decref (part);
- if (tib_errno)
- break;
-
- if (i < expr.len)
- {
- c = expr.data[i];
-
- if (is_math_operator (c))
- {
- tib_errno = tib_expr_push (&calc, c);
- if (tib_errno)
- break;
-
- ++i;
- }
- else
- {
- tib_errno = tib_expr_push (&calc, '*');
- if (tib_errno)
- break;
- }
-
- beg = i;
- }
- }
- else
- {
- tib_errno = tib_lst_push (resolved, part);
- tib_decref (part);
- if (tib_errno)
- break;
-
- tib_errno = tib_expr_push (&calc, c);
- if (tib_errno)
- break;
-
- beg = i + 1;
- }
- }
- }
-
- if (!tib_errno)
- {
- const struct math_operator *oper;
-
- if (tib_lst_len (resolved) == 0)
- {
- TIB *temp = single_eval (&expr);
- if (!temp)
- goto end;
-
- tib_errno = tib_lst_push (resolved, temp);
- tib_decref (temp);
- if (tib_errno)
- goto end;
- }
- else if (NULL == (oper = get_math_operator (expr.data[expr.len - 1]))
- || oper->function_type != T)
- {
- struct tib_expr sub;
- tib_subexpr (&sub, &expr, beg, i);
-
- TIB *temp = single_eval (&sub);
- if (!temp)
- goto end;
-
- tib_errno = tib_lst_push (resolved, temp);
- tib_decref (temp);
- if (tib_errno)
- goto end;
- }
-
- if (tib_lst_len (resolved) != calc.len + 1)
- tib_errno = TIB_ESYNTAX;
- }
-
- tib_expr_destroy (&expr);
-
- if (tib_errno)
- goto end;
-
- for (int priority = 1; priority <= LAST_PRIORITY; ++priority)
- {
- for (i = 0; i < calc.len; ++i)
- {
- const struct math_operator *oper = get_math_operator (calc.data[i]);
- if (oper->priority != priority)
- continue;
-
- TIB *t;
- unsigned int num_operands;
- switch (oper->function_type)
- {
- case TT:
- t = oper->func.tt (tib_lst_ref (resolved, i),
- tib_lst_ref (resolved, i + 1));
- if (!t)
- goto end;
-
- num_operands = 2;
- break;
-
- default:
- tib_errno = TIB_ESYNTAX;
- goto end;
- }
-
- for (unsigned int _ = 0; _ < num_operands; ++_)
- tib_lst_remove (resolved, i);
-
- tib_errno = tib_lst_insert (resolved, t, i);
- tib_decref (t);
-
- if (tib_errno)
- goto end;
-
- tib_expr_delete (&calc, i--);
- }
- }
+ int i;
+
+ if (0 == in->len)
+ return tib_empty();
+
+ /* check for store operator */
+ i = tib_expr_indexof(in, TIB_CHAR_STO);
+ if (i >= 0)
+ {
+ if (i != in->len - 2 || 0 == i)
+ {
+ tib_errno = TIB_ESYNTAX;
+ return NULL;
+ }
+
+ int c = in->data[i + 1];
+ if (!is_var_char(c))
+ {
+ tib_errno = TIB_ESYNTAX;
+ return NULL;
+ }
+
+ struct tib_expr e;
+ tib_subexpr(&e, in, 0, i);
+
+ TIB *stoval = tib_eval(&e);
+ if (NULL == stoval)
+ return NULL;
+
+ tib_errno = tib_var_set(c, stoval);
+ if (tib_errno)
+ {
+ tib_decref(stoval);
+ return NULL;
+ }
+
+ return stoval;
+ }
+
+ struct tib_expr expr = {.bufsize = 0 };
+ tib_errno = tib_exprcpy(&expr, in);
+ if (tib_errno)
+ return NULL;
+
+ // check for sign operator at the beginning of number
+ if (expr.len > 0 && ('-' == expr.data[0] || '+' == expr.data[0]))
+ {
+ tib_errno = tib_expr_insert(&expr, 0, '0');
+ if (tib_errno)
+ {
+ tib_expr_destroy(&expr);
+ return NULL;
+ }
+ }
+
+ // check for implicit closing parentheses and close them
+ tib_errno = tib_eval_close_parens(&expr);
+ if (tib_errno)
+ {
+ tib_expr_destroy(&expr);
+ return NULL;
+ }
+
+ // replace power of 10 E character with "*10^"
+ tib_errno = replace_epow10(&expr);
+ if (tib_errno)
+ {
+ tib_expr_destroy(&expr);
+ return NULL;
+ }
+
+ // add multiplication operators between implicit multiplications
+ bool add = true;
+ tib_expr_foreach(&expr, i)
+ {
+ int c = expr.data[i];
+
+ if ('"' == c)
+ {
+ add = !add; // don't change anything inside a string
+ }
+ else if (add)
+ {
+ if (is_var_char(c) || tib_is_var(c))
+ {
+ if (i > 0 && needs_mult_left(expr.data[i - 1]))
+ tib_errno = tib_expr_insert(&expr,
+ i++, '*');
+
+ if (!tib_errno && i < expr.len - 1
+ && needs_mult_right(expr.data[i + 1]))
+ tib_errno = tib_expr_insert(&expr,
+ ++i, '*');
+ }
+ else if (i > 0 && i < expr.len - 1)
+ {
+ if (tib_is_func(c)
+ && needs_mult_left(expr.data[i - 1]))
+ tib_errno = tib_expr_insert(&expr,
+ i++, '*');
+ else if (')' == c
+ && needs_mult_right(expr.data[i + 1]))
+ tib_errno = tib_expr_insert(&expr,
+ ++i, '*');
+ }
+
+ if (tib_errno)
+ {
+ tib_expr_destroy(&expr);
+ return NULL;
+ }
+ }
+ }
+
+ // this is temp storage for internally-resolved portions
+ struct tib_lst *resolved = tib_new_lst();
+ if (!resolved)
+ {
+ tib_expr_destroy(&expr);
+ tib_errno = TIB_EALLOC;
+ return NULL;
+ }
+
+ // this is to remember the operations to be executed
+ struct tib_expr calc;
+ tib_errno = tib_expr_init(&calc);
+ if (tib_errno)
+ {
+ tib_expr_destroy(&expr);
+ tib_free_lst(resolved);
+ return NULL;
+ }
+
+ // resolve operand expressions, and store the values for later
+ int beg = 0, numpar = 0;
+ add = true;
+ tib_expr_foreach(&expr, i)
+ {
+ int c = expr.data[i];
+
+ if ('"' == c)
+ {
+ add = !add;
+ continue;
+ }
+
+ if (!add)
+ continue;
+
+ if (tib_is_func(c))
+ {
+ ++numpar;
+ }
+ else if (')' == c)
+ {
+ if (0 == numpar)
+ {
+ tib_errno = TIB_ESYNTAX;
+ break;
+ }
+
+ --numpar;
+ }
+
+ const struct math_operator *oper;
+ if (0 == numpar && (oper = get_math_operator(c)) != NULL)
+ {
+ struct tib_expr sub;
+ tib_subexpr(&sub, &expr, beg, i);
+
+ TIB *part = single_eval(&sub);
+ if (!part)
+ break;
+
+ if (T == oper->function_type)
+ {
+ do
+ {
+ TIB *temp = oper->func.t(part);
+ tib_decref(part);
+ if (!temp)
+ break;
+
+ part = temp;
+ } while (++i < expr.len
+ && (oper = get_math_operator(expr.data[i])) != NULL
+ && T == oper->function_type);
+
+ if (tib_errno)
+ break;
+
+ tib_errno = tib_lst_push(resolved, part);
+ tib_decref(part);
+ if (tib_errno)
+ break;
+
+ if (i < expr.len)
+ {
+ c = expr.data[i];
+
+ if (is_math_operator(c))
+ {
+ tib_errno = tib_expr_push(&calc,
+ c);
+ if (tib_errno)
+ break;
+
+ ++i;
+ }
+ else
+ {
+ tib_errno = tib_expr_push(&calc,
+ '*');
+ if (tib_errno)
+ break;
+ }
+
+ beg = i;
+ }
+ }
+ else
+ {
+ tib_errno = tib_lst_push(resolved, part);
+ tib_decref(part);
+ if (tib_errno)
+ break;
+
+ tib_errno = tib_expr_push(&calc, c);
+ if (tib_errno)
+ break;
+
+ beg = i + 1;
+ }
+ }
+ }
+
+ if (!tib_errno)
+ {
+ const struct math_operator *oper;
+
+ if (tib_lst_len(resolved) == 0)
+ {
+ TIB *temp = single_eval(&expr);
+ if (!temp)
+ goto end;
+
+ tib_errno = tib_lst_push(resolved, temp);
+ tib_decref(temp);
+ if (tib_errno)
+ goto end;
+ }
+ else if (NULL ==
+ (oper = get_math_operator(expr.data[expr.len - 1]))
+ || oper->function_type != T)
+ {
+ struct tib_expr sub;
+ tib_subexpr(&sub, &expr, beg, i);
+
+ TIB *temp = single_eval(&sub);
+ if (!temp)
+ goto end;
+
+ tib_errno = tib_lst_push(resolved, temp);
+ tib_decref(temp);
+ if (tib_errno)
+ goto end;
+ }
+
+ if (tib_lst_len(resolved) != calc.len + 1)
+ tib_errno = TIB_ESYNTAX;
+ }
+
+ tib_expr_destroy(&expr);
+
+ if (tib_errno)
+ goto end;
+
+ for (int priority = 1; priority <= LAST_PRIORITY; ++priority)
+ {
+ for (i = 0; i < calc.len; ++i)
+ {
+ const struct math_operator *oper =
+ get_math_operator(calc.data[i]);
+ if (oper->priority != priority)
+ continue;
+
+ TIB *t;
+ unsigned int num_operands;
+ switch (oper->function_type)
+ {
+ case TT:
+ t = oper->func.tt(tib_lst_ref(resolved, i),
+ tib_lst_ref(resolved, i + 1));
+ if (!t)
+ goto end;
+
+ num_operands = 2;
+ break;
+
+ default:
+ tib_errno = TIB_ESYNTAX;
+ goto end;
+ }
+
+ for (unsigned int _ = 0; _ < num_operands; ++_)
+ tib_lst_remove(resolved, i);
+
+ tib_errno = tib_lst_insert(resolved, t, i);
+ tib_decref(t);
+
+ if (tib_errno)
+ goto end;
+
+ tib_expr_delete(&calc, i--);
+ }
+ }
end:
- tib_expr_destroy (&calc);
-
- TIB *out = NULL;
- if (!tib_errno)
- {
- if (tib_lst_len (resolved) != 1)
- {
- tib_errno = TIB_ESYNTAX;
- }
- else
- {
- out = tib_lst_ref (resolved, 0);
- tib_incref (out);
- }
- }
-
- tib_free_lst (resolved);
-
- return out;
+ tib_expr_destroy(&calc);
+
+ TIB *out = NULL;
+ if (!tib_errno)
+ {
+ if (tib_lst_len(resolved) != 1)
+ {
+ tib_errno = TIB_ESYNTAX;
+ }
+ else
+ {
+ out = tib_lst_ref(resolved, 0);
+ tib_incref(out);
+ }
+ }
+
+ tib_free_lst(resolved);
+
+ return out;
}
int
-tib_eval_surrounded (const struct tib_expr *expr)
+tib_eval_surrounded(const struct tib_expr *expr)
{
- int count = 0, opening = expr->data[0], len = expr->len;
+ int count = 0, opening = expr->data[0], len = expr->len;
- if (len > 2 && tib_is_func (opening) && ')' == expr->data[len - 1])
- {
- count = 1;
+ if (len > 2 && tib_is_func(opening) && ')' == expr->data[len - 1])
+ {
+ count = 1;
- for (int i = 1; i < len-1; ++i)
- {
- int c = expr->data[i];
+ for (int i = 1; i < len - 1; ++i)
+ {
+ int c = expr->data[i];
- if (tib_is_func (c))
- ++count;
- else if (')' == c && --count == 0)
- return 0;
- }
+ if (tib_is_func(c))
+ ++count;
+ else if (')' == c && --count == 0)
+ return 0;
+ }
- return opening;
- }
+ return opening;
+ }
- return 0;
+ return 0;
}
static int
-char_count (const struct tib_expr *expr, int c)
+char_count(const struct tib_expr *expr, int c)
{
- int i, count = 0;
+ int i, count = 0;
- tib_expr_foreach (expr, i)
- if (c == expr->data[i])
- ++count;
+ tib_expr_foreach(expr, i)
+ if (c == expr->data[i])
+ ++count;
- return count;
+ return count;
}
int
-i_count (const struct tib_expr *expr)
+i_count(const struct tib_expr *expr)
{
- return char_count (expr, 'i');
+ return char_count(expr, 'i');
}
static int
-dot_count (const struct tib_expr *expr)
+dot_count(const struct tib_expr *expr)
{
- return char_count (expr, '.');
+ return char_count(expr, '.');
}
static bool
-is_number_char (int c)
+is_number_char(int c)
{
- return (isdigit (c) || '.' == c || 'i' == c || is_sign_operator (c));
+ return (isdigit(c) || '.' == c || 'i' == c || is_sign_operator(c));
}
int
-get_char_pos (const struct tib_expr *expr, int c, int which)
+get_char_pos(const struct tib_expr *expr, int c, int which)
{
- int i, found = 0;
+ int i, found = 0;
- tib_expr_foreach (expr, i)
- {
- if (c == expr->data[i] && ++found == which)
- break;
- }
+ tib_expr_foreach(expr, i)
+ {
+ if (c == expr->data[i] && ++found == which)
+ break;
+ }
- return i;
+ return i;
}
static int
-get_sign_pos (const struct tib_expr *expr, int which)
+get_sign_pos(const struct tib_expr *expr, int which)
{
- int i, found = 0;
+ int i, found = 0;
- tib_expr_foreach (expr, i)
- {
- if (is_sign_operator (expr->data[i]) && ++found == which)
- break;
- }
+ tib_expr_foreach(expr, i)
+ {
+ if (is_sign_operator(expr->data[i]) && ++found == which)
+ break;
+ }
- return i;
+ return i;
}
static bool
-good_sign_pos (const struct tib_expr *expr, int numsign, int numi)
+good_sign_pos(const struct tib_expr *expr, int numsign, int numi)
{
- switch (numsign)
- {
- case 0:
- return true;
-
- case 1:
- if (!numi && get_sign_pos (expr, 1) != 0)
- return false;
- break;
-
- case 2:
- if (!numi || get_sign_pos (expr, 1) != 0
- || get_sign_pos (expr, 2) > get_char_pos (expr, 'i', 1))
- return false;
- break;
-
- default:
- return false;
- }
-
- return true;
+ switch (numsign)
+ {
+ case 0:
+ return true;
+
+ case 1:
+ if (!numi && get_sign_pos(expr, 1) != 0)
+ return false;
+ break;
+
+ case 2:
+ if (!numi || get_sign_pos(expr, 1) != 0
+ || get_sign_pos(expr, 2) > get_char_pos(expr, 'i', 1))
+ return false;
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
}
bool
-tib_eval_isnum (const struct tib_expr *expr)
+tib_eval_isnum(const struct tib_expr *expr)
{
- int signs = sign_count (expr);
- int dots = dot_count (expr);
- int is = i_count (expr);
+ int signs = sign_count(expr);
+ int dots = dot_count(expr);
+ int is = i_count(expr);
- if (signs > 2 || dots > 2 || is > 1)
- return false;
+ if (signs > 2 || dots > 2 || is > 1)
+ return false;
- if (!good_sign_pos (expr, signs, is))
- return false;
+ if (!good_sign_pos(expr, signs, is))
+ return false;
- if (is && get_char_pos (expr, 'i', 1) < expr->len - 1)
- return false;
+ if (is && get_char_pos(expr, 'i', 1) < expr->len - 1)
+ return false;
- int i;
- tib_expr_foreach (expr, i)
- if (!is_number_char (expr->data[i]))
- return false;
+ int i;
+ tib_expr_foreach(expr, i)
+ if (!is_number_char(expr->data[i]))
+ return false;
- return true;
+ return true;
}
bool
-tib_eval_isstr (const struct tib_expr *expr)
+tib_eval_isstr(const struct tib_expr *expr)
{
- int len = expr->len;
+ int len = expr->len;
- if (len > 1 && '"' == expr->data[0])
- {
- for (int i = 1; i < len-1; ++i)
- {
- int c = expr->data[i];
+ if (len > 1 && '"' == expr->data[0])
+ {
+ for (int i = 1; i < len - 1; ++i)
+ {
+ int c = expr->data[i];
- if (c > 127 || '"' == c)
- return false;
- }
+ if (c > 127 || '"' == c)
+ return false;
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
bool
-tib_eval_islist (const struct tib_expr *expr)
+tib_eval_islist(const struct tib_expr *expr)
{
- int len = expr->len;
+ int len = expr->len;
- if (len > 2 && '{' == expr->data[0] && '}' == expr->data[len - 1])
- {
- for (int i = 1; i < len-1; ++i)
- {
- int c = expr->data[i];
+ if (len > 2 && '{' == expr->data[0] && '}' == expr->data[len - 1])
+ {
+ for (int i = 1; i < len - 1; ++i)
+ {
+ int c = expr->data[i];
- if ('{' == c || '}' == c)
- return false;
- }
+ if ('{' == c || '}' == c)
+ return false;
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
static bool
-sub_isnum (const struct tib_expr *expr, int beg, int end)
+sub_isnum(const struct tib_expr *expr, int beg, int end)
{
- if (end <= beg)
- return false;
+ if (end <= beg)
+ return false;
- struct tib_expr temp;
- int rc = tib_subexpr (&temp, expr, beg, end);
- if (rc)
- return false;
+ struct tib_expr temp;
+ int rc = tib_subexpr(&temp, expr, beg, end);
+ if (rc)
+ return false;
- return tib_eval_isnum (&temp);
+ return tib_eval_isnum(&temp);
}
bool
-tib_eval_ismatrix (const struct tib_expr *expr)
+tib_eval_ismatrix(const struct tib_expr *expr)
{
- int len = expr->len;
-
- if (len > 4 && '[' == expr->data[0] && '[' == expr->data[1]
- && ']' == expr->data[len - 1])
- {
- int i = 2;
- int open_brackets = i, fdim = 1, dim = 1, beg = i, end = i;
- bool first = true;
-
- for (; i < len; ++i)
- {
- int c = expr->data[i];
-
- switch (c)
- {
- case '[':
- ++open_brackets;
- beg = i + 1;
- break;
-
- case ']':
- --open_brackets;
-
- if (!first && dim != fdim)
- return false;
-
- first = false;
- dim = 1;
- end = i - 1;
-
- if (!sub_isnum (expr, beg, end))
- return false;
- break;
-
- case ',':
- if (first)
- ++fdim;
- else
- ++dim;
-
- end = i - 1;
- if (!sub_isnum (expr, beg, end))
- return false;
- beg = i + 1;
- break;
- }
-
- if ((0 == open_brackets && i != len-1) || open_brackets > 2)
- return false;
- }
-
- return true;
- }
-
- return false;
+ int len = expr->len;
+
+ if (len > 4 && '[' == expr->data[0] && '[' == expr->data[1]
+ && ']' == expr->data[len - 1])
+ {
+ int i = 2;
+ int open_brackets = i, fdim = 1, dim = 1, beg = i, end = i;
+ bool first = true;
+
+ for (; i < len; ++i)
+ {
+ int c = expr->data[i];
+
+ switch (c)
+ {
+ case '[':
+ ++open_brackets;
+ beg = i + 1;
+ break;
+
+ case ']':
+ --open_brackets;
+
+ if (!first && dim != fdim)
+ return false;
+
+ first = false;
+ dim = 1;
+ end = i - 1;
+
+ if (!sub_isnum(expr, beg, end))
+ return false;
+ break;
+
+ case ',':
+ if (first)
+ ++fdim;
+ else
+ ++dim;
+
+ end = i - 1;
+ if (!sub_isnum(expr, beg, end))
+ return false;
+ beg = i + 1;
+ break;
+ }
+
+ if ((0 == open_brackets && i != len - 1)
+ || open_brackets > 2)
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
}
int
-tib_eval_close_parens (struct tib_expr *expr)
+tib_eval_close_parens(struct tib_expr *expr)
{
- int count = 0, len = expr->len;
- bool str = false;
-
- for (int i = 0; i < len; ++i)
- {
- int c = expr->data[i];
-
- if ('"' == c)
- str = !str;
-
- if (!str)
- {
- if (tib_is_func (c))
- ++count;
-
- if (')' == c)
- --count;
- }
- }
-
- while (count--)
- {
- int rc = tib_expr_push (expr, ')');
- if (rc)
- return rc;
- }
-
- return 0;
+ int count = 0, len = expr->len;
+ bool str = false;
+
+ for (int i = 0; i < len; ++i)
+ {
+ int c = expr->data[i];
+
+ if ('"' == c)
+ str = !str;
+
+ if (!str)
+ {
+ if (tib_is_func(c))
+ ++count;
+
+ if (')' == c)
+ --count;
+ }
+ }
+
+ while (count--)
+ {
+ int rc = tib_expr_push(expr, ')');
+ if (rc)
+ return rc;
+ }
+
+ return 0;
}
diff --git a/src/tibeval.h b/src/tibeval.h
index 0257aae..c1b1f83 100644
--- a/src/tibeval.h
+++ b/src/tibeval.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -24,36 +24,36 @@
#include "tibtype.h"
bool
-is_sign_operator (int c);
+is_sign_operator(int c);
bool
-is_math_operator (int c);
+is_math_operator(int c);
unsigned int
-sign_count (const struct tib_expr *expr);
+sign_count(const struct tib_expr *expr);
bool
-contains_i (const struct tib_expr *expr);
+contains_i(const struct tib_expr *expr);
TIB *
-tib_eval (const struct tib_expr *expr);
+tib_eval(const struct tib_expr *expr);
int
-tib_eval_surrounded (const struct tib_expr *expr);
+tib_eval_surrounded(const struct tib_expr *expr);
bool
-tib_eval_isnum (const struct tib_expr *expr);
+tib_eval_isnum(const struct tib_expr *expr);
bool
-tib_eval_isstr (const struct tib_expr *expr);
+tib_eval_isstr(const struct tib_expr *expr);
bool
-tib_eval_islist (const struct tib_expr *expr);
+tib_eval_islist(const struct tib_expr *expr);
bool
-tib_eval_ismatrix (const struct tib_expr *expr);
+tib_eval_ismatrix(const struct tib_expr *expr);
int
-tib_eval_close_parens (struct tib_expr *expr);
+tib_eval_close_parens(struct tib_expr *expr);
#endif
diff --git a/src/tibexpr.c b/src/tibexpr.c
index 7ab48b8..2f122d2 100644
--- a/src/tibexpr.c
+++ b/src/tibexpr.c
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -26,267 +26,267 @@
#define BUFFER_BLOCK_SIZE 16
int
-tib_expr_init (struct tib_expr *self)
+tib_expr_init(struct tib_expr *self)
{
- self->data = malloc (BUFFER_BLOCK_SIZE * sizeof (int));
- if (!self->data)
- return TIB_EALLOC;
+ self->data = malloc(BUFFER_BLOCK_SIZE * sizeof(int));
+ if (!self->data)
+ return TIB_EALLOC;
- self->bufsize = BUFFER_BLOCK_SIZE;
- self->len = 0;
+ self->bufsize = BUFFER_BLOCK_SIZE;
+ self->len = 0;
- return 0;
+ return 0;
}
void
-tib_expr_destroy (struct tib_expr *self)
+tib_expr_destroy(struct tib_expr *self)
{
- if (self->bufsize)
- {
- free (self->data);
-
- self->data = NULL;
- self->bufsize = 0;
- self->len = 0;
- }
+ if (self->bufsize)
+ {
+ free(self->data);
+
+ self->data = NULL;
+ self->bufsize = 0;
+ self->len = 0;
+ }
}
int
-tib_exprcpy (struct tib_expr *dest, const struct tib_expr *src)
+tib_exprcpy(struct tib_expr *dest, const struct tib_expr *src)
{
- dest->len = 0;
- return tib_exprcat (dest, src);
+ dest->len = 0;
+ return tib_exprcat(dest, src);
}
int
-tib_exprcat (struct tib_expr *dest, const struct tib_expr *src)
+tib_exprcat(struct tib_expr *dest, const struct tib_expr *src)
{
- int rc;
-
- if (!dest->bufsize)
- {
- rc = tib_expr_init (dest);
- if (rc)
- return rc;
- }
-
- int i;
- tib_expr_foreach (src, i)
- {
- rc = tib_expr_push (dest, src->data[i]);
- if (rc)
- {
- tib_expr_destroy (dest);
- return rc;
- }
- }
-
- return 0;
+ int rc;
+
+ if (!dest->bufsize)
+ {
+ rc = tib_expr_init(dest);
+ if (rc)
+ return rc;
+ }
+
+ int i;
+ tib_expr_foreach(src, i)
+ {
+ rc = tib_expr_push(dest, src->data[i]);
+ if (rc)
+ {
+ tib_expr_destroy(dest);
+ return rc;
+ }
+ }
+
+ return 0;
}
char *
-tib_expr_tostr_f (const struct tib_expr *self,
- const char *(*get_special) (int))
+tib_expr_tostr_f(const struct tib_expr *self, const char *(*get_special)(int))
{
- if (!self->data)
- {
- tib_errno = TIB_ENULLPTR;
- return NULL;
- }
-
- int i, len = 1;
- tib_expr_foreach (self, i)
- {
- const char *special = get_special (self->data[i]);
- if (special)
- len += strlen (special);
- else
- ++len;
- }
-
- char *out = malloc (len * sizeof (char));
- if (!out)
- {
- tib_errno = TIB_EALLOC;
- return NULL;
- }
-
- int bump = 0;
- tib_expr_foreach (self, i)
- {
- const char *special = get_special (self->data[i]);
- if (special)
- {
- out[i + bump] = '\0';
- strcat (out, special);
- bump += strlen (special) - 1;
- }
- else
- {
- out[i + bump] = self->data[i];
- }
- }
-
- out[i + bump] = '\0';
- return out;
+ if (!self->data)
+ {
+ tib_errno = TIB_ENULLPTR;
+ return NULL;
+ }
+
+ int i, len = 1;
+ tib_expr_foreach(self, i)
+ {
+ const char *special = get_special(self->data[i]);
+ if (special)
+ len += strlen(special);
+ else
+ ++len;
+ }
+
+ char *out = malloc(len * sizeof(char));
+ if (!out)
+ {
+ tib_errno = TIB_EALLOC;
+ return NULL;
+ }
+
+ int bump = 0;
+ tib_expr_foreach(self, i)
+ {
+ const char *special = get_special(self->data[i]);
+ if (special)
+ {
+ out[i + bump] = '\0';
+ strcat(out, special);
+ bump += strlen(special) - 1;
+ }
+ else
+ {
+ out[i + bump] = self->data[i];
+ }
+ }
+
+ out[i + bump] = '\0';
+ return out;
}
char *
-tib_expr_tostr (const struct tib_expr *self)
+tib_expr_tostr(const struct tib_expr *self)
{
- return tib_expr_tostr_f (self, tib_special_char_text);
+ return tib_expr_tostr_f(self, tib_special_char_text);
}
int
-tib_expr_parse_complex (const struct tib_expr *self, gsl_complex *out)
+tib_expr_parse_complex(const struct tib_expr *self, gsl_complex *out)
{
- if (!tib_eval_isnum (self))
- return TIB_ESYNTAX;
-
- const int len = self->len;
- char s[len + 1];
-
- for (int i = 0; i < len; ++i)
- s[i] = self->data[i];
-
- s[len] = '\0';
-
- char *i_start = NULL;
- if (contains_i (self))
- {
- int num_operators = sign_count (self);
- for (int i = 0; i < len; ++i)
- {
- int c = self->data[i];
-
- if ('i' == c)
- {
- i_start = s;
- break;
- }
- else if (is_sign_operator (c) && --num_operators == 0)
- {
- i_start = &s[i];
- break;
- }
- }
- }
-
- GSL_SET_REAL (out, s == i_start ? 0 : strtod (s, NULL));
-
- if (i_start)
- {
- if (is_sign_operator (i_start[0]) && 'i' == i_start[1])
- i_start[1] = '1';
- else if ('i' == i_start[0])
- i_start[0] = '1';
- }
-
- GSL_SET_IMAG (out, i_start ? strtod (i_start, NULL) : 0);
-
- return 0;
+ if (!tib_eval_isnum(self))
+ return TIB_ESYNTAX;
+
+ const int len = self->len;
+ char s[len + 1];
+
+ for (int i = 0; i < len; ++i)
+ s[i] = self->data[i];
+
+ s[len] = '\0';
+
+ char *i_start = NULL;
+ if (contains_i(self))
+ {
+ int num_operators = sign_count(self);
+ for (int i = 0; i < len; ++i)
+ {
+ int c = self->data[i];
+
+ if ('i' == c)
+ {
+ i_start = s;
+ break;
+ }
+ else if (is_sign_operator(c) && --num_operators == 0)
+ {
+ i_start = &s[i];
+ break;
+ }
+ }
+ }
+
+ GSL_SET_REAL(out, s == i_start ? 0 : strtod(s, NULL));
+
+ if (i_start)
+ {
+ if (is_sign_operator(i_start[0]) && 'i' == i_start[1])
+ i_start[1] = '1';
+ else if ('i' == i_start[0])
+ i_start[0] = '1';
+ }
+
+ GSL_SET_IMAG(out, i_start ? strtod(i_start, NULL) : 0);
+
+ return 0;
}
int
-tib_expr_delete (struct tib_expr *self, int i)
+tib_expr_delete(struct tib_expr *self, int i)
{
- if (i > self->len)
- return TIB_EINDEX;
+ if (i > self->len)
+ return TIB_EINDEX;
- --self->len;
+ --self->len;
- for (; i < self->len; ++i)
- self->data[i] = self->data[i + 1];
+ for (; i < self->len; ++i)
+ self->data[i] = self->data[i + 1];
- return 0;
+ return 0;
}
int
-tib_expr_insert (struct tib_expr *self, int i, int c)
+tib_expr_insert(struct tib_expr *self, int i, int c)
{
- if (i > ++self->len)
- {
- --self->len;
- return TIB_EINDEX;
- }
-
- if (!self->bufsize)
- {
- struct tib_expr temp = { .bufsize = 0 };
- --self->len;
-
- int rc = tib_exprcpy (&temp, self);
- if (rc)
- return rc;
-
- *self = temp;
- ++self->len;
- }
- else if (self->len > self->bufsize)
- {
- if (16384 == self->bufsize)
- {
- return TIB_EALLOC;
- }
- else
- {
- int *old = self->data;
- self->bufsize *= 2;
-
- self->data = realloc (self->data, self->bufsize * sizeof (int));
- if (!self->data)
- {
- self->bufsize /= 2;
- --self->len;
- self->data = old;
- return TIB_EALLOC;
- }
- }
- }
-
- for (int j = self->len - 1; j > i; --j)
- self->data[j] = self->data[j - 1];
-
- self->data[i] = c;
- return 0;
+ if (i > ++self->len)
+ {
+ --self->len;
+ return TIB_EINDEX;
+ }
+
+ if (!self->bufsize)
+ {
+ struct tib_expr temp = { .bufsize = 0 };
+ --self->len;
+
+ int rc = tib_exprcpy(&temp, self);
+ if (rc)
+ return rc;
+
+ *self = temp;
+ ++self->len;
+ }
+ else if (self->len > self->bufsize)
+ {
+ if (16384 == self->bufsize)
+ {
+ return TIB_EALLOC;
+ }
+ else
+ {
+ int *old = self->data;
+ self->bufsize *= 2;
+
+ self->data = realloc(self->data,
+ self->bufsize * sizeof(int));
+ if (!self->data)
+ {
+ self->bufsize /= 2;
+ --self->len;
+ self->data = old;
+ return TIB_EALLOC;
+ }
+ }
+ }
+
+ for (int j = self->len - 1; j > i; --j)
+ self->data[j] = self->data[j - 1];
+
+ self->data[i] = c;
+ return 0;
}
int
-tib_expr_push (struct tib_expr *self, int c)
+tib_expr_push(struct tib_expr *self, int c)
{
- return tib_expr_insert (self, self->len, c);
+ return tib_expr_insert(self, self->len, c);
}
int
-tib_expr_indexof (const struct tib_expr *self, int c)
+tib_expr_indexof(const struct tib_expr *self, int c)
{
- for (int i = 0; i < self->len; ++i)
- if (c == self->data[i])
- return i;
+ for (int i = 0; i < self->len; ++i)
+ if (c == self->data[i])
+ return i;
- return -1;
+ return -1;
}
int
-tib_expr_indexof_r (const struct tib_expr *self, int c)
+tib_expr_indexof_r(const struct tib_expr *self, int c)
{
- for (int i = self->len - 1; i >= 0; --i)
- if (c == self->data[i])
- return i;
+ for (int i = self->len - 1; i >= 0; --i)
+ if (c == self->data[i])
+ return i;
- return -1;
+ return -1;
}
int
-tib_subexpr (struct tib_expr *dest, const struct tib_expr *src, int beg,
- int end)
+tib_subexpr(struct tib_expr *dest, const struct tib_expr *src, int beg,
+ int end)
{
- if (end > src->len || end < beg)
- return TIB_EINDEX;
+ if (end > src->len || end < beg)
+ return TIB_EINDEX;
- dest->len = end - beg;
- dest->bufsize = 0;
- dest->data = &src->data[beg];
+ dest->len = end - beg;
+ dest->bufsize = 0;
+ dest->data = &src->data[beg];
- return 0;
+ return 0;
}
diff --git a/src/tibexpr.h b/src/tibexpr.h
index 41195a9..9905a67 100644
--- a/src/tibexpr.h
+++ b/src/tibexpr.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -24,50 +24,49 @@
struct tib_expr
{
- int *data;
- int len;
- int bufsize;
+ int *data;
+ int len;
+ int bufsize;
};
int
-tib_expr_init (struct tib_expr *self);
+tib_expr_init(struct tib_expr *self);
void
-tib_expr_destroy (struct tib_expr *self);
+tib_expr_destroy(struct tib_expr *self);
int
-tib_exprcpy (struct tib_expr *dest, const struct tib_expr *src);
+tib_exprcpy(struct tib_expr *dest, const struct tib_expr *src);
int
-tib_exprcat (struct tib_expr *dest, const struct tib_expr *src);
+tib_exprcat(struct tib_expr *dest, const struct tib_expr *src);
char *
-tib_expr_tostr_f (const struct tib_expr *self,
- const char *(*get_special) (int));
+tib_expr_tostr_f(const struct tib_expr *self, const char *(*get_special)(int));
char *
-tib_expr_tostr (const struct tib_expr *self);
+tib_expr_tostr(const struct tib_expr *self);
int
-tib_expr_parse_complex (const struct tib_expr *self, gsl_complex *out);
+tib_expr_parse_complex(const struct tib_expr *self, gsl_complex *out);
int
-tib_expr_delete (struct tib_expr *self, int i);
+tib_expr_delete(struct tib_expr *self, int i);
int
-tib_expr_insert (struct tib_expr *self, int i, int c);
+tib_expr_insert(struct tib_expr *self, int i, int c);
int
-tib_expr_push (struct tib_expr *self, int c);
+tib_expr_push(struct tib_expr *self, int c);
int
-tib_expr_indexof (const struct tib_expr *self, int c);
+tib_expr_indexof(const struct tib_expr *self, int c);
int
-tib_expr_indexof_r (const struct tib_expr *self, int c);
+tib_expr_indexof_r(const struct tib_expr *self, int c);
int
-tib_subexpr (struct tib_expr *dest, const struct tib_expr *src, int beg,
- int end);
+tib_subexpr(struct tib_expr *dest, const struct tib_expr *src, int beg,
+ int end);
#endif
diff --git a/src/tibfunction.c b/src/tibfunction.c
index d2085f5..b1d59fc 100644
--- a/src/tibfunction.c
+++ b/src/tibfunction.c
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -30,267 +30,266 @@
struct registry_node
{
- int key;
- tib_Function f;
+ int key;
+ tib_Function f;
};
struct registry
{
- size_t len;
- struct registry_node *nodes;
+ size_t len;
+ struct registry_node *nodes;
};
static gsl_rng *rng = NULL;
-static struct registry registry =
- {
- .len = 0,
- .nodes = NULL
- };
+static struct registry registry = {
+ .len = 0,
+ .nodes = NULL
+};
static TIB *
-func_paren (const struct tib_expr *expr)
+func_paren(const struct tib_expr *expr)
{
- return tib_eval (expr);
+ return tib_eval(expr);
}
static int
-split_number_args (const struct tib_expr *expr, int num_params, ...)
+split_number_args(const struct tib_expr *expr, int num_params, ...)
{
- const int *beg, *end;
- int rc = 0, numpar = 0;
- va_list ap;
-
- va_start (ap, num_params);
- for (beg = expr->data, end = beg; end < expr->data + expr->len; ++end)
- {
- if (tib_is_func (*end))
- {
- ++numpar;
- }
- else if (')' == *end)
- {
- if (--numpar < 0)
- {
- rc = TIB_ESYNTAX;
- break;
- }
- }
- else if (0 == numpar &&
- (',' == *end || end + 1 == expr->data + expr->len))
- {
- if (num_params-- == 0)
- {
- rc = TIB_EARGNUM;
- break;
- }
-
- int start = beg - expr->data, stop = end - expr->data;
- if (end + 1 == expr->data + expr->len)
- ++stop;
-
- struct tib_expr arg;
- tib_subexpr (&arg, expr, start, stop);
-
- TIB *t = tib_eval (&arg);
- if (!t)
- {
- rc = tib_errno;
- break;
- }
-
- if (tib_type (t) != TIB_TYPE_COMPLEX)
- {
- tib_decref (t);
- tib_errno = TIB_ETYPE;
- break;
- }
-
- gsl_complex *out = va_arg (ap, gsl_complex *);
- *out = tib_complex_value (t);
- tib_decref (t);
-
- beg = end + 1;
- }
- }
- va_end (ap);
-
- return rc;
+ const int *beg, *end;
+ int rc = 0, numpar = 0;
+ va_list ap;
+
+ va_start(ap, num_params);
+ for (beg = expr->data, end = beg; end < expr->data + expr->len; ++end)
+ {
+ if (tib_is_func(*end))
+ {
+ ++numpar;
+ }
+ else if (')' == *end)
+ {
+ if (--numpar < 0)
+ {
+ rc = TIB_ESYNTAX;
+ break;
+ }
+ }
+ else if (0 == numpar &&
+ (',' == *end || end + 1 == expr->data + expr->len))
+ {
+ if (num_params-- == 0)
+ {
+ rc = TIB_EARGNUM;
+ break;
+ }
+
+ int start = beg - expr->data, stop = end - expr->data;
+ if (end + 1 == expr->data + expr->len)
+ ++stop;
+
+ struct tib_expr arg;
+ tib_subexpr(&arg, expr, start, stop);
+
+ TIB *t = tib_eval(&arg);
+ if (!t)
+ {
+ rc = tib_errno;
+ break;
+ }
+
+ if (tib_type(t) != TIB_TYPE_COMPLEX)
+ {
+ tib_decref(t);
+ tib_errno = TIB_ETYPE;
+ break;
+ }
+
+ gsl_complex *out = va_arg(ap, gsl_complex *);
+ *out = tib_complex_value(t);
+ tib_decref(t);
+
+ beg = end + 1;
+ }
+ }
+ va_end(ap);
+
+ return rc;
}
static TIB *
-single_parameter_function (const struct tib_expr *expr,
- gsl_complex (*f) (gsl_complex))
+single_parameter_function(const struct tib_expr *expr,
+ gsl_complex(*f)(gsl_complex))
{
- gsl_complex z;
+ gsl_complex z;
- tib_errno = split_number_args (expr, 1, &z);
- if (tib_errno)
- return NULL;
+ tib_errno = split_number_args(expr, 1, &z);
+ if (tib_errno)
+ return NULL;
- z = f (z);
- return tib_new_complex (GSL_REAL (z), GSL_IMAG (z));
+ z = f(z);
+ return tib_new_complex(GSL_REAL(z), GSL_IMAG(z));
}
static TIB *
-func_sin (const struct tib_expr *expr)
+func_sin(const struct tib_expr *expr)
{
- return single_parameter_function (expr, gsl_complex_sin);
+ return single_parameter_function(expr, gsl_complex_sin);
}
static TIB *
-func_cos (const struct tib_expr *expr)
+func_cos(const struct tib_expr *expr)
{
- return single_parameter_function (expr, gsl_complex_cos);
+ return single_parameter_function(expr, gsl_complex_cos);
}
static TIB *
-func_tan (const struct tib_expr *expr)
+func_tan(const struct tib_expr *expr)
{
- return single_parameter_function (expr, gsl_complex_tan);
+ return single_parameter_function(expr, gsl_complex_tan);
}
static int
-is_int (gsl_complex z)
+is_int(gsl_complex z)
{
- return GSL_IMAG (z) == 0 && fmod (GSL_REAL (z), 1.0) == 0;
+ return GSL_IMAG(z) == 0 && fmod(GSL_REAL(z), 1.0) == 0;
}
static TIB *
-func_randint (const struct tib_expr *expr)
+func_randint(const struct tib_expr *expr)
{
- int len = expr->len, num_commas = 0;
-
- for (int i = 0; i < len; ++i)
- {
- if (',' == expr->data[i])
- {
- if (++num_commas > 2)
- break;
- }
- }
-
- if (num_commas != 2)
- {
- tib_errno = TIB_EARGNUM;
- return NULL;
- }
-
- gsl_complex min, max, count;
- tib_errno = split_number_args (expr, 3, &min, &max, &count);
- if (tib_errno)
- return NULL;
-
- if (!(is_int (min) && is_int (max) && is_int (count))
- || GSL_REAL (count) < 0)
- return NULL;
-
- double diff = GSL_REAL (max) - GSL_REAL (min);
-
- len = (unsigned int) GSL_REAL (count);
- gsl_complex vals[len];
-
- for (int i = 0; i < len; ++i)
- {
- GSL_SET_COMPLEX (&vals[i], (double) gsl_rng_get (rng), 0);
-
- while (GSL_REAL (vals[i]) < GSL_REAL (min))
- GSL_SET_REAL (&vals[i], GSL_REAL (vals[i]) + diff);
- while (GSL_REAL (vals[i]) > GSL_REAL (max))
- GSL_SET_REAL (&vals[i], GSL_REAL (vals[i]) - diff);
- }
-
- return tib_new_list (vals, len);
+ int len = expr->len, num_commas = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ if (',' == expr->data[i])
+ {
+ if (++num_commas > 2)
+ break;
+ }
+ }
+
+ if (num_commas != 2)
+ {
+ tib_errno = TIB_EARGNUM;
+ return NULL;
+ }
+
+ gsl_complex min, max, count;
+ tib_errno = split_number_args(expr, 3, &min, &max, &count);
+ if (tib_errno)
+ return NULL;
+
+ if (!(is_int(min) && is_int(max) && is_int(count))
+ || GSL_REAL(count) < 0)
+ return NULL;
+
+ double diff = GSL_REAL(max) - GSL_REAL(min);
+
+ len = (unsigned int) GSL_REAL(count);
+ gsl_complex vals[len];
+
+ for (int i = 0; i < len; ++i)
+ {
+ GSL_SET_COMPLEX(&vals[i], (double) gsl_rng_get(rng), 0);
+
+ while (GSL_REAL(vals[i]) < GSL_REAL(min))
+ GSL_SET_REAL(&vals[i], GSL_REAL(vals[i]) + diff);
+
+ while (GSL_REAL(vals[i]) > GSL_REAL(max))
+ GSL_SET_REAL(&vals[i], GSL_REAL(vals[i]) - diff);
+ }
+
+ return tib_new_list(vals, len);
}
int
-tib_registry_init ()
+tib_registry_init()
{
- int rc;
+ int rc;
- if (registry.nodes != NULL || rng != NULL)
- tib_registry_free ();
+ if (registry.nodes != NULL || rng != NULL)
+ tib_registry_free();
- rng = gsl_rng_alloc (gsl_rng_taus2);
- if (NULL == rng)
- return TIB_EALLOC;
+ rng = gsl_rng_alloc(gsl_rng_taus2);
+ if (NULL == rng)
+ return TIB_EALLOC;
- gsl_rng_set (rng, (unsigned long) time (NULL));
+ gsl_rng_set(rng, (unsigned long) time(NULL));
-#define ADD(K,F) rc = tib_registry_add (K, F); if (rc) goto fail;
+#define ADD(K,F) rc = tib_registry_add(K, F); if (rc) goto fail;
- ADD ('(', func_paren);
- ADD (TIB_CHAR_SIN, func_sin);
- ADD (TIB_CHAR_COS, func_cos);
- ADD (TIB_CHAR_TAN, func_tan);
- ADD (TIB_CHAR_RANDINT, func_randint);
+ ADD('(', func_paren);
+ ADD(TIB_CHAR_SIN, func_sin);
+ ADD(TIB_CHAR_COS, func_cos);
+ ADD(TIB_CHAR_TAN, func_tan);
+ ADD(TIB_CHAR_RANDINT, func_randint);
#undef ADD
fail:
- if (rc)
- tib_registry_free ();
+ if (rc)
+ tib_registry_free();
- return rc;
+ return rc;
}
void
-tib_registry_free ()
+tib_registry_free()
{
- if (registry.nodes)
- free (registry.nodes);
- if (rng)
- gsl_rng_free (rng);
-
- registry.len = 0;
- registry.nodes = NULL;
- rng = NULL;
+ if (registry.nodes)
+ free(registry.nodes);
+ if (rng)
+ gsl_rng_free(rng);
+
+ registry.len = 0;
+ registry.nodes = NULL;
+ rng = NULL;
}
int
-tib_registry_add (int key, tib_Function f)
+tib_registry_add(int key, tib_Function f)
{
- struct registry_node *old = registry.nodes;
-
- ++registry.len;
- registry.nodes = realloc (registry.nodes,
- registry.len * sizeof (struct registry_node));
- if (NULL == registry.nodes)
- {
- registry.nodes = old;
- --registry.len;
- return TIB_EALLOC;
- }
-
- struct registry_node new =
- {
- .key = key,
- .f = f
- };
-
- registry.nodes[registry.len - 1] = new;
- return 0;
+ struct registry_node *old = registry.nodes;
+
+ ++registry.len;
+ registry.nodes = realloc(registry.nodes,
+ registry.len * sizeof(struct registry_node));
+ if (NULL == registry.nodes)
+ {
+ registry.nodes = old;
+ --registry.len;
+ return TIB_EALLOC;
+ }
+
+ struct registry_node new = {
+ .key = key,
+ .f = f
+ };
+
+ registry.nodes[registry.len - 1] = new;
+ return 0;
}
bool
-tib_is_func (int key)
+tib_is_func(int key)
{
- size_t i;
- for (i = 0; i < registry.len; ++i)
- if (key == registry.nodes[i].key)
- return true;
+ size_t i;
+ for (i = 0; i < registry.len; ++i)
+ if (key == registry.nodes[i].key)
+ return true;
- return false;
+ return false;
}
TIB *
-tib_call (int key, const struct tib_expr *expr)
+tib_call(int key, const struct tib_expr *expr)
{
- size_t i;
- for (i = 0; i < registry.len; ++i)
- if (key == registry.nodes[i].key)
- return registry.nodes[i].f (expr);
+ size_t i;
+ for (i = 0; i < registry.len; ++i)
+ if (key == registry.nodes[i].key)
+ return registry.nodes[i].f(expr);
- tib_errno = TIB_EBADFUNC;
- return NULL;
+ tib_errno = TIB_EBADFUNC;
+ return NULL;
}
diff --git a/src/tibfunction.h b/src/tibfunction.h
index e3383dc..29d80b7 100644
--- a/src/tibfunction.h
+++ b/src/tibfunction.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -23,21 +23,21 @@
#include "tibexpr.h"
#include "tibtype.h"
-typedef TIB *(*tib_Function) (const struct tib_expr *);
+typedef TIB *(*tib_Function)(const struct tib_expr *);
int
-tib_registry_init (void);
+tib_registry_init(void);
void
-tib_registry_free (void);
+tib_registry_free(void);
int
-tib_registry_add (int key, tib_Function f);
+tib_registry_add(int key, tib_Function f);
bool
-tib_is_func (int key);
+tib_is_func(int key);
TIB *
-tib_call (int key, const struct tib_expr *expr);
+tib_call(int key, const struct tib_expr *expr);
#endif
diff --git a/src/tiblst.c b/src/tiblst.c
index c908c92..c11ab01 100644
--- a/src/tiblst.c
+++ b/src/tiblst.c
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,125 +21,125 @@
#include "tiblst.h"
struct tib_lst *
-tib_new_lst ()
+tib_new_lst()
{
- struct tib_lst *out = malloc (sizeof (struct tib_lst));
- out->beg = NULL;
- out->end = NULL;
+ struct tib_lst *out = malloc(sizeof(struct tib_lst));
+ out->beg = NULL;
+ out->end = NULL;
- return out;
+ return out;
}
static struct tib_el *
-el_ref (const struct tib_lst *lst, int index)
+el_ref(const struct tib_lst *lst, int index)
{
- for (struct tib_el *el = lst->beg; el != NULL; el = el->next, --index)
- if (0 == index)
- return el;
+ for (struct tib_el *el = lst->beg; el != NULL; el = el->next, --index)
+ if (0 == index)
+ return el;
- return NULL;
+ return NULL;
}
void
-tib_free_lst (struct tib_lst *lst)
+tib_free_lst(struct tib_lst *lst)
{
- while (tib_lst_len (lst))
- tib_lst_remove (lst, 0);
+ while (tib_lst_len(lst))
+ tib_lst_remove(lst, 0);
- free (lst);
+ free(lst);
}
int
-tib_lst_insert (struct tib_lst *lst, TIB *t, int index)
+tib_lst_insert(struct tib_lst *lst, TIB *t, int index)
{
- int len = tib_lst_len (lst);
+ int len = tib_lst_len(lst);
- if (index > len)
- return TIB_EINDEX;
+ if (index > len)
+ return TIB_EINDEX;
- struct tib_el *new = malloc (sizeof (struct tib_el));
- if (NULL == new)
- return TIB_EALLOC;
+ struct tib_el *new = malloc(sizeof(struct tib_el));
+ if (NULL == new)
+ return TIB_EALLOC;
- tib_incref (t);
- new->val = t;
+ tib_incref(t);
+ new->val = t;
- if (0 == index)
- new->prev = NULL;
- else
- new->prev = el_ref (lst, index - 1);
+ if (0 == index)
+ new->prev = NULL;
+ else
+ new->prev = el_ref(lst, index - 1);
- if (index == len)
- new->next = NULL;
- else
- new->next = el_ref (lst, index);
+ if (index == len)
+ new->next = NULL;
+ else
+ new->next = el_ref(lst, index);
- if (new->next)
- new->next->prev = new;
- else
- lst->end = new;
+ if (new->next)
+ new->next->prev = new;
+ else
+ lst->end = new;
- if (new->prev)
- new->prev->next = new;
- else
- lst->beg = new;
+ if (new->prev)
+ new->prev->next = new;
+ else
+ lst->beg = new;
- return 0;
+ return 0;
}
int
-tib_lst_push (struct tib_lst *lst, TIB *t)
+tib_lst_push(struct tib_lst *lst, TIB *t)
{
- return tib_lst_insert (lst, t, tib_lst_len (lst));
+ return tib_lst_insert(lst, t, tib_lst_len(lst));
}
void
-tib_lst_remove (struct tib_lst *lst, int index)
+tib_lst_remove(struct tib_lst *lst, int index)
{
- struct tib_el *e = el_ref (lst, index);
- if (!e)
- return;
-
- if (e->next)
- e->next->prev = e->prev;
- else
- lst->end = e->prev;
-
- if (e->prev)
- e->prev->next = e->next;
- else
- lst->beg = e->next;
-
- tib_decref (e->val);
- free (e);
+ struct tib_el *e = el_ref(lst, index);
+ if (!e)
+ return;
+
+ if (e->next)
+ e->next->prev = e->prev;
+ else
+ lst->end = e->prev;
+
+ if (e->prev)
+ e->prev->next = e->next;
+ else
+ lst->beg = e->next;
+
+ tib_decref(e->val);
+ free(e);
}
int
-tib_lst_len (const struct tib_lst *lst)
+tib_lst_len(const struct tib_lst *lst)
{
- int i = 0;
- struct tib_el *e = lst->beg;
+ int i = 0;
+ struct tib_el *e = lst->beg;
- while (e != NULL)
- {
- ++i;
- e = e->next;
- }
+ while (e != NULL)
+ {
+ ++i;
+ e = e->next;
+ }
- return i;
+ return i;
}
TIB *
-tib_lst_ref (const struct tib_lst *lst, int index)
+tib_lst_ref(const struct tib_lst *lst, int index)
{
- struct tib_el *i;
- int looped = 0;
+ struct tib_el *i;
+ int looped = 0;
- for (i = lst->beg; i != NULL; i = i->next)
- {
- if (looped++ == index)
- return i->val;
- }
+ for (i = lst->beg; i != NULL; i = i->next)
+ {
+ if (looped++ == index)
+ return i->val;
+ }
- return NULL;
+ return NULL;
}
diff --git a/src/tiblst.h b/src/tiblst.h
index ea1f82c..593a645 100644
--- a/src/tiblst.h
+++ b/src/tiblst.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -20,40 +20,40 @@
#include "tibtype.h"
-#define tib_foreachlst(L,I) for (I = 0; i < tib_lst_len (L); ++I)
+#define tib_foreachlst(L,I) for ((I) = 0; (I) < tib_lst_len (L); ++(I))
struct tib_el
{
- TIB *val;
- struct tib_el *next;
- struct tib_el *prev;
+ TIB *val;
+ struct tib_el *next;
+ struct tib_el *prev;
};
struct tib_lst
{
- struct tib_el *beg;
- struct tib_el *end;
+ struct tib_el *beg;
+ struct tib_el *end;
};
struct tib_lst *
-tib_new_lst (void);
+tib_new_lst(void);
void
-tib_free_lst (struct tib_lst *lst);
+tib_free_lst(struct tib_lst *lst);
int
-tib_lst_insert (struct tib_lst *lst, TIB *t, int index);
+tib_lst_insert(struct tib_lst *lst, TIB *t, int index);
int
-tib_lst_push (struct tib_lst *lst, TIB *t);
+tib_lst_push(struct tib_lst *lst, TIB *t);
void
-tib_lst_remove (struct tib_lst *lst, int index);
+tib_lst_remove(struct tib_lst *lst, int index);
int
-tib_lst_len (const struct tib_lst *lst);
+tib_lst_len(const struct tib_lst *lst);
TIB *
-tib_lst_ref (const struct tib_lst *lst, int index);
+tib_lst_ref(const struct tib_lst *lst, int index);
#endif
diff --git a/src/tibtranscode.c b/src/tibtranscode.c
index 103f14b..b0b814c 100644
--- a/src/tibtranscode.c
+++ b/src/tibtranscode.c
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -23,877 +23,879 @@
#include "tiberr.h"
static int
-need_next (int c, int *err, FILE *program, unsigned long *parsed)
+need_next(int c, int *err, FILE *program, unsigned long *parsed)
{
- int next;
+ int next;
- if ((next = fgetc (program)) == EOF)
- {
- *err = TIB_EBADCHAR;
- return EOF;
- }
+ if ((next = fgetc(program)) == EOF)
+ {
+ *err = TIB_EBADCHAR;
+ return EOF;
+ }
- ++(*parsed);
+ ++(*parsed);
- switch (c)
- {
- case -69:
- if (10 == next)
- return TIB_CHAR_RANDINT;
+ switch (c)
+ {
+ case -69:
+ if (10 == next)
+ return TIB_CHAR_RANDINT;
- *err = TIB_EBADCHAR;
- return EOF;
+ *err = TIB_EBADCHAR;
+ return EOF;
- case 92:
- if (next >= 0 && next <= 8)
- return next + TIB_CHAR_MATA;
+ case 92:
+ if (next >= 0 && next <= 8)
+ return next + TIB_CHAR_MATA;
- *err = TIB_EBADCHAR;
- return EOF;
+ *err = TIB_EBADCHAR;
+ return EOF;
- case 93:
- if (next >= 0 && next <= 8)
- return next + TIB_CHAR_L1;
+ case 93:
+ if (next >= 0 && next <= 8)
+ return next + TIB_CHAR_L1;
- *err = TIB_EBADCHAR;
- return EOF;
+ *err = TIB_EBADCHAR;
+ return EOF;
- case 96:
- if (0 == next)
- return TIB_CHAR_PIC1;
+ case 96:
+ if (0 == next)
+ return TIB_CHAR_PIC1;
- *err = TIB_EBADCHAR;
- return EOF;
+ *err = TIB_EBADCHAR;
+ return EOF;
- case 99:
- switch (next)
- {
- case 10:
- return TIB_CHAR_XMIN;
+ case 99:
+ switch (next)
+ {
+ case 10:
+ return TIB_CHAR_XMIN;
- case 11:
- return TIB_CHAR_XMAX;
+ case 11:
+ return TIB_CHAR_XMAX;
- case 12:
- return TIB_CHAR_YMIN;
+ case 12:
+ return TIB_CHAR_YMIN;
- case 13:
- return TIB_CHAR_YMAX;
+ case 13:
+ return TIB_CHAR_YMAX;
- default:
- *err = TIB_EBADCHAR;
- return EOF;
- }
+ default:
+ *err = TIB_EBADCHAR;
+ return EOF;
+ }
- case 126:
- if (9 == c)
- return TIB_CHAR_AXESOFF;
+ case 126:
+ if (9 == c)
+ return TIB_CHAR_AXESOFF;
- *err = TIB_EBADCHAR;
- return EOF;
+ *err = TIB_EBADCHAR;
+ return EOF;
- default:
- *err = TIB_EBADCHAR;
- return EOF;
- }
+ default:
+ *err = TIB_EBADCHAR;
+ return EOF;
+ }
}
static int
-trans_from (int c, int *err, FILE *program, unsigned long *parsed)
+trans_from(int c, int *err, FILE *program, unsigned long *parsed)
{
- if (c > SCHAR_MAX)
- c -= 256;
+ if (c > SCHAR_MAX)
+ c -= 256;
- /* The original author of LibreCalc's TI emulator had several comments in
- this conversion case analysis where he was unsure of the legitimacy of
- some character conversions. Be wary of the following: 91, 109 or 14, 114,
- 98, 24, 127 or -40, 95 */
- switch (c)
- {
- case -126:
- return '*';
+ /* The original author of LibreCalc's TI emulator had several comments
+ * in this conversion case analysis where he was unsure of the
+ * legitimacy of some character converstion. Be wary of the following:
+ * 91, 109 or 14, 114, 98, 24, 127 or -40, 95
+ */
+ switch (c)
+ {
+ case -126:
+ return '*';
- case -125:
- return '/';
+ case -125:
+ return '/';
- case -123:
- return TIB_CHAR_CLEARDRAW;
+ case -123:
+ return TIB_CHAR_CLEARDRAW;
- case -109:
- return TIB_CHAR_TEXT;
+ case -109:
+ return TIB_CHAR_TEXT;
- case -104:
- return TIB_CHAR_STOREPIC;
+ case -104:
+ return TIB_CHAR_STOREPIC;
- case -103:
- return TIB_CHAR_RECALLPIC;
+ case -103:
+ return TIB_CHAR_RECALLPIC;
- case -100:
- return TIB_CHAR_LINE;
+ case -100:
+ return TIB_CHAR_LINE;
- case -85:
- return TIB_CHAR_RAND;
+ case -85:
+ return TIB_CHAR_RAND;
- case -84:
- return TIB_CHAR_PI;
+ case -84:
+ return TIB_CHAR_PI;
- case -83:
- return TIB_CHAR_GETKEY;
+ case -83:
+ return TIB_CHAR_GETKEY;
- case -81:
- return '?';
+ case -81:
+ return '?';
- case -80:
- return TIB_CHAR_SMALL_MINUS;
+ case -80:
+ return TIB_CHAR_SMALL_MINUS;
- case -79:
- return TIB_CHAR_INT;
+ case -79:
+ return TIB_CHAR_INT;
- case -75:
- return TIB_CHAR_DIM;
+ case -75:
+ return TIB_CHAR_DIM;
- case -72:
- return TIB_CHAR_NOT;
+ case -72:
+ return TIB_CHAR_NOT;
- case -69:
- return need_next (c, err, program, parsed);
+ case -69:
+ return need_next(c, err, program, parsed);
- case -50:
- return TIB_CHAR_IF;
+ case -50:
+ return TIB_CHAR_IF;
- case -49:
- return TIB_CHAR_THEN;
+ case -49:
+ return TIB_CHAR_THEN;
- case -48:
- return TIB_CHAR_ELSE;
+ case -48:
+ return TIB_CHAR_ELSE;
- case -47:
- return TIB_CHAR_WHILE;
+ case -47:
+ return TIB_CHAR_WHILE;
- case -46:
- return TIB_CHAR_REPEAT;
+ case -46:
+ return TIB_CHAR_REPEAT;
- case -45:
- return TIB_CHAR_FOR;
+ case -45:
+ return TIB_CHAR_FOR;
- case -44:
- return TIB_CHAR_END;
+ case -44:
+ return TIB_CHAR_END;
- case -43:
- return TIB_CHAR_RETURN;
+ case -43:
+ return TIB_CHAR_RETURN;
- case -42:
- return TIB_CHAR_LABEL;
+ case -42:
+ return TIB_CHAR_LABEL;
- case -41:
- return TIB_CHAR_GOTO;
+ case -41:
+ return TIB_CHAR_GOTO;
- case -40:
- return TIB_CHAR_PAUSE;
+ case -40:
+ return TIB_CHAR_PAUSE;
- case -39:
- return TIB_CHAR_STOP;
+ case -39:
+ return TIB_CHAR_STOP;
- case -36:
- return TIB_CHAR_INPUT;
+ case -36:
+ return TIB_CHAR_INPUT;
- case -34:
- return TIB_CHAR_DISP;
+ case -34:
+ return TIB_CHAR_DISP;
- case -32:
- return TIB_CHAR_OUTPUT;
+ case -32:
+ return TIB_CHAR_OUTPUT;
- case -31:
- return TIB_CHAR_CLEARHOME;
+ case -31:
+ return TIB_CHAR_CLEARHOME;
- case -30:
- return TIB_CHAR_FILL;
+ case -30:
+ return TIB_CHAR_FILL;
- case -26:
- return TIB_CHAR_MENU;
+ case -26:
+ return TIB_CHAR_MENU;
- case -21:
- return TIB_CHAR_LUSER;
+ case -21:
+ return TIB_CHAR_LUSER;
- case -16:
- return '^';
+ case -16:
+ return '^';
- case -6:
- return TIB_CHAR_CLRLIST;
+ case -6:
+ return TIB_CHAR_CLRLIST;
- case 4:
- return TIB_CHAR_STO;
+ case 4:
+ return TIB_CHAR_STO;
- case 6:
- return '[';
+ case 6:
+ return '[';
- case 7:
- return ']';
+ case 7:
+ return ']';
- case 8:
- return '{';
+ case 8:
+ return '{';
- case 9:
- return '}';
+ case 9:
+ return '}';
- case 11:
- return TIB_CHAR_DEGREE;
+ case 11:
+ return TIB_CHAR_DEGREE;
- case 14:
- return 'T';
+ case 14:
+ return 'T';
- case 16:
- return '(';
+ case 16:
+ return '(';
- case 17:
- return ')';
+ case 17:
+ return ')';
- case 18:
- return TIB_CHAR_ROUND;
+ case 18:
+ return TIB_CHAR_ROUND;
- case 19:
- return TIB_CHAR_PIXEL_TEST;
+ case 19:
+ return TIB_CHAR_PIXEL_TEST;
- case 22:
- return '|';
+ case 22:
+ return '|';
- /* 24 was simply skipped in the original emulator; could cause problems */
- case 24:
- return 0;
+ // 24 was simply skipped in the original emulator; could cause problems
+ case 24:
+ return 0;
- case 41:
- return ' ';
+ case 41:
+ return ' ';
- case 42:
- return '"';
+ case 42:
+ return '"';
- case 43:
- return ',';
+ case 43:
+ return ',';
- case 45:
- return '!';
+ case 45:
+ return '!';
- case 58:
- return '.';
+ case 58:
+ return '.';
- case 59:
- return TIB_CHAR_EPOW10;
+ case 59:
+ return TIB_CHAR_EPOW10;
- case 60:
- return TIB_CHAR_OR;
+ case 60:
+ return TIB_CHAR_OR;
- case 62:
- case 63:
- return '\n';
+ case 62:
+ case 63:
+ return '\n';
- case 64:
- return TIB_CHAR_AND;
+ case 64:
+ return TIB_CHAR_AND;
- case 91:
- return TIB_CHAR_THETA;
+ case 91:
+ return TIB_CHAR_THETA;
- case 92:
- case 93:
- return need_next (c, err, program, parsed);
+ case 92:
+ case 93:
+ return need_next(c, err, program, parsed);
- /* 95 was not evaluated, but it printed "Pause " to stdout */
+ // 95 was not evaluated, but it printed "Pause " to stdout
- case 96:
- return need_next (c, err, program, parsed);
+ case 96:
+ return need_next(c, err, program, parsed);
- case 98:
- return 'c';
+ case 98:
+ return 'c';
- case 99:
- return need_next (c, err, program, parsed);
+ case 99:
+ return need_next(c, err, program, parsed);
- case 106:
- return '=';
+ case 106:
+ return '=';
- case 107:
- return '<';
+ case 107:
+ return '<';
- case 108:
- return '>';
+ case 108:
+ return '>';
- case 109:
- return TIB_CHAR_LESSEQUAL;
+ case 109:
+ return TIB_CHAR_LESSEQUAL;
- case 110:
- return TIB_CHAR_GREATEREQUAL;
+ case 110:
+ return TIB_CHAR_GREATEREQUAL;
- case 111:
- return TIB_CHAR_DIFFERENT;
+ case 111:
+ return TIB_CHAR_DIFFERENT;
- case 112:
- return '+';
+ case 112:
+ return '+';
- case 113:
- return '-';
+ case 113:
+ return '-';
- case 114:
- return TIB_CHAR_ANS;
+ case 114:
+ return TIB_CHAR_ANS;
- case 126:
- return need_next (c, err, program, parsed);
+ case 126:
+ return need_next(c, err, program, parsed);
- case 127:
- return '[';
+ case 127:
+ return '[';
- default:
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'))
- {
- return c;
- }
- else if (fgetc (program) != EOF || fgetc (program) != EOF)
- {
- *err = 0;
- *parsed += 2;
- return EOF;
- }
+ default:
+ if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'))
+ {
+ return c;
+ }
+ else if (fgetc(program) != EOF || fgetc(program) != EOF)
+ {
+ *err = 0;
+ *parsed += 2;
+ return EOF;
+ }
- *err = TIB_EBADCHAR;
- return EOF;
- }
+ *err = TIB_EBADCHAR;
+ return EOF;
+ }
}
int
-tib_fread (struct tib_expr *out, FILE *program, unsigned long *parsed)
+tib_fread(struct tib_expr *out, FILE *program, unsigned long *parsed)
{
- int rc, c;
-
- rc = tib_expr_init (out);
- if (rc)
- return rc;
-
- *parsed = 0;
- while ((c = fgetc (program)) != EOF && *parsed < 71)
- ++(*parsed);
-
- if (*parsed != 71)
- {
- rc = TIB_EBADFILE;
- goto end;
- }
-
- while ((c = fgetc (program)) != EOF)
- {
- ++(*parsed);
-
- int trans = trans_from ((char) c, &rc, program, parsed);
- if (EOF == trans)
- break;
-
- if (trans)
- {
- rc = tib_expr_push (out, trans);
- if (rc)
- break;
- }
- }
+ int rc, c;
+
+ rc = tib_expr_init(out);
+ if (rc)
+ return rc;
+
+ *parsed = 0;
+ while ((c = fgetc(program)) != EOF && *parsed < 71)
+ ++(*parsed);
+
+ if (*parsed != 71)
+ {
+ rc = TIB_EBADFILE;
+ goto end;
+ }
+
+ while ((c = fgetc(program)) != EOF)
+ {
+ ++(*parsed);
+
+ int trans = trans_from((char) c, &rc, program, parsed);
+ if (EOF == trans)
+ break;
+
+ if (trans)
+ {
+ rc = tib_expr_push(out, trans);
+ if (rc)
+ break;
+ }
+ }
end:
- if (rc)
- tib_expr_destroy (out);
+ if (rc)
+ tib_expr_destroy(out);
- return rc;
+ return rc;
}
int
-tib_fwrite (FILE *out, const struct tib_expr *program, unsigned long *written)
+tib_fwrite(FILE *out, const struct tib_expr *program, unsigned long *written)
{
- int rc, i;
-
- for (*written = 0; *written <= 71; ++(*written))
- {
- rc = fputc (0, out);
- if (rc)
- return TIB_EWRITE;
- }
-
- tib_expr_foreach (program, i)
- {
- int c = program->data[i];
- /* The original conversion table had a "TODO transpose" comment. May be
- an incomplete table. */
- switch (c)
- {
- case '\n':
- rc = fputc (62, out);
- break;
-
- case ' ':
- rc = fputc (41, out);
- break;
-
- case '!':
- rc = fputc (45, out);
- break;
-
- case '"':
- rc = fputc (42, out);
- break;
-
- case '(':
- rc = fputc (16, out);
- break;
-
- case ')':
- rc = fputc (17, out);
- break;
-
- case '*':
- rc = fputc (-126, out);
- break;
-
- case '+':
- rc = fputc (112, out);
- break;
-
- case ',':
- rc = fputc (43, out);
- break;
-
- case '-':
- rc = fputc (113, out);
- break;
-
- case '.':
- rc = fputc (58, out);
- break;
-
- case '/':
- rc = fputc (-125, out);
- break;
-
- case '<':
- rc = fputc (107, out);
- break;
-
- case '=':
- rc = fputc (106, out);
- break;
-
- case '>':
- rc = fputc (108, out);
- break;
-
- case '?':
- rc = fputc (-81, out);
- break;
-
- case '[':
- rc = fputc (6, out);
- break;
-
- case ']':
- rc = fputc (7, out);
- break;
-
- case '^':
- rc = fputc (-16, out);
- break;
-
- case '{':
- rc = fputc (8, out);
- break;
-
- case '|':
- rc = fputc (22, out);
- break;
-
- case '}':
- rc = fputc (9, out);
- break;
-
- case TIB_CHAR_AND:
- rc = fputc (64, out);
- break;
-
- case TIB_CHAR_ANS:
- rc = fputc (114, out);
- break;
-
- case TIB_CHAR_AXESOFF:
- rc = fputc (126, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (9, out);
- break;
-
- case TIB_CHAR_CLEARHOME:
- rc = fputc (-31, out);
- break;
-
- case TIB_CHAR_CLEARDRAW:
- rc = fputc (-123, out);
- break;
-
- case TIB_CHAR_CLRLIST:
- rc = fputc (-6, out);
- break;
-
- case TIB_CHAR_DEGREE:
- rc = fputc (11, out);
- break;
-
- case TIB_CHAR_DIFFERENT:
- rc = fputc (111, out);
- break;
-
- case TIB_CHAR_DIM:
- rc = fputc (-75, out);
- break;
-
- case TIB_CHAR_DISP:
- rc = fputc (-34, out);
- break;
-
- case TIB_CHAR_ELSE:
- rc = fputc (-48, out);
- break;
-
- case TIB_CHAR_END:
- rc = fputc (-44, out);
- break;
-
- case TIB_CHAR_EPOW10:
- rc = fputc (59, out);
- break;
-
- case TIB_CHAR_FILL:
- rc = fputc (-30, out);
- break;
-
- case TIB_CHAR_FOR:
- rc = fputc (-45, out);
- break;
-
- case TIB_CHAR_GETKEY:
- rc = fputc (-83, out);
- break;
-
- case TIB_CHAR_GOTO:
- rc = fputc (-41, out);
- break;
-
- case TIB_CHAR_GREATEREQUAL:
- rc = fputc (110, out);
- break;
-
- case TIB_CHAR_IF:
- rc = fputc (-50, out);
- break;
-
- case TIB_CHAR_INPUT:
- rc = fputc (-36, out);
- break;
-
- case TIB_CHAR_INT:
- rc = fputc (-79, out);
- break;
-
- case TIB_CHAR_L1:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (0, out);
- break;
-
- case TIB_CHAR_L2:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (1, out);
- break;
-
- case TIB_CHAR_L3:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (2, out);
- break;
-
- case TIB_CHAR_L4:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (3, out);
- break;
-
- case TIB_CHAR_L5:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (4, out);
- break;
-
- case TIB_CHAR_L6:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (5, out);
- break;
-
- case TIB_CHAR_L7:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (6, out);
- break;
-
- case TIB_CHAR_L8:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (7, out);
- break;
-
- case TIB_CHAR_L9:
- rc = fputc (93, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (8, out);
- break;
-
- case TIB_CHAR_LABEL:
- rc = fputc (-42, out);
- break;
-
- case TIB_CHAR_LESSEQUAL:
- rc = fputc (109, out);
- break;
-
- case TIB_CHAR_LINE:
- rc = fputc (-100, out);
- break;
-
- case TIB_CHAR_LUSER:
- rc = fputc (-21, out);
- break;
-
- case TIB_CHAR_MATA:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (0, out);
- break;
-
- case TIB_CHAR_MATB:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (1, out);
- break;
-
- case TIB_CHAR_MATC:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (2, out);
- break;
-
- case TIB_CHAR_MATD:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (3, out);
- break;
-
- case TIB_CHAR_MATE:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (4, out);
- break;
-
- case TIB_CHAR_MATF:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (5, out);
- break;
-
- case TIB_CHAR_MATG:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (6, out);
- break;
-
- case TIB_CHAR_MATH:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (7, out);
- break;
-
- case TIB_CHAR_MATI:
- rc = fputc (92, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (8, out);
- break;
-
- case TIB_CHAR_MENU:
- rc = fputc (-26, out);
- break;
-
- case TIB_CHAR_NOT:
- rc = fputc (-72, out);
- break;
-
- case TIB_CHAR_OUTPUT:
- rc = fputc (-32, out);
- break;
-
- case TIB_CHAR_OR:
- rc = fputc (60, out);
- break;
-
- case TIB_CHAR_PAUSE:
- rc = fputc (-40, out);
- break;
-
- case TIB_CHAR_PI:
- rc = fputc (-84, out);
- break;
-
- case TIB_CHAR_PIC1:
- rc = fputc (96, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (0, out);
- break;
-
- case TIB_CHAR_PIXEL_TEST:
- rc = fputc (19, out);
- break;
-
- case TIB_CHAR_RAND:
- rc = fputc (-85, out);
- break;
-
- case TIB_CHAR_RANDINT:
- rc = fputc (-69, out);
- if (EOF == rc)
- break;
- rc = fputc (10, out);
- break;
-
- case TIB_CHAR_RECALLPIC:
- rc = fputc (-103, out);
- break;
-
- case TIB_CHAR_REPEAT:
- rc = fputc (-46, out);
- break;
-
- case TIB_CHAR_RETURN:
- rc = fputc (-43, out);
- break;
-
- case TIB_CHAR_ROUND:
- rc = fputc (18, out);
- break;
-
- case TIB_CHAR_SMALL_MINUS:
- rc = fputc (-80, out);
- break;
-
- case TIB_CHAR_STO:
- rc = fputc (4, out);
- break;
-
- case TIB_CHAR_STOP:
- rc = fputc (-39, out);
- break;
-
- case TIB_CHAR_STOREPIC:
- rc = fputc (-104, out);
- break;
-
- case TIB_CHAR_TEXT:
- rc = fputc (-109, out);
- break;
-
- case TIB_CHAR_THEN:
- rc = fputc (-49, out);
- break;
-
- case TIB_CHAR_THETA:
- rc = fputc (91, out);
- break;
-
- case TIB_CHAR_WHILE:
- rc = fputc (-47, out);
- break;
-
- case TIB_CHAR_XMAX:
- rc = fputc (99, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (11, out);
- break;
-
- case TIB_CHAR_XMIN:
- rc = fputc (99, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (10, out);
- break;
-
- case TIB_CHAR_YMAX:
- rc = fputc (99, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (13, out);
- break;
-
- case TIB_CHAR_YMIN:
- rc = fputc (99, out);
- if (EOF == rc)
- break;
- ++(*written);
- rc = fputc (12, out);
- break;
-
- default:
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'))
- rc = fputc (c, out);
- else
- rc = EOF;
- break;
- }
-
- if (EOF == rc)
- return TIB_EWRITE;
-
- ++(*written);
- }
-
- return 0;
+ int rc, i;
+
+ for (*written = 0; *written <= 71; ++(*written))
+ {
+ rc = fputc(0, out);
+ if (rc)
+ return TIB_EWRITE;
+ }
+
+ tib_expr_foreach(program, i)
+ {
+ int c = program->data[i];
+ /* The original conversion table had a "TODO transpose"
+ * comment. May be an incomplete table.
+ */
+ switch (c)
+ {
+ case '\n':
+ rc = fputc(62, out);
+ break;
+
+ case ' ':
+ rc = fputc(41, out);
+ break;
+
+ case '!':
+ rc = fputc(45, out);
+ break;
+
+ case '"':
+ rc = fputc(42, out);
+ break;
+
+ case '(':
+ rc = fputc(16, out);
+ break;
+
+ case ')':
+ rc = fputc(17, out);
+ break;
+
+ case '*':
+ rc = fputc(-126, out);
+ break;
+
+ case '+':
+ rc = fputc(112, out);
+ break;
+
+ case ',':
+ rc = fputc(43, out);
+ break;
+
+ case '-':
+ rc = fputc(113, out);
+ break;
+
+ case '.':
+ rc = fputc(58, out);
+ break;
+
+ case '/':
+ rc = fputc(-125, out);
+ break;
+
+ case '<':
+ rc = fputc(107, out);
+ break;
+
+ case '=':
+ rc = fputc(106, out);
+ break;
+
+ case '>':
+ rc = fputc(108, out);
+ break;
+
+ case '?':
+ rc = fputc(-81, out);
+ break;
+
+ case '[':
+ rc = fputc(6, out);
+ break;
+
+ case ']':
+ rc = fputc(7, out);
+ break;
+
+ case '^':
+ rc = fputc(-16, out);
+ break;
+
+ case '{':
+ rc = fputc(8, out);
+ break;
+
+ case '|':
+ rc = fputc(22, out);
+ break;
+
+ case '}':
+ rc = fputc(9, out);
+ break;
+
+ case TIB_CHAR_AND:
+ rc = fputc(64, out);
+ break;
+
+ case TIB_CHAR_ANS:
+ rc = fputc(114, out);
+ break;
+
+ case TIB_CHAR_AXESOFF:
+ rc = fputc(126, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(9, out);
+ break;
+
+ case TIB_CHAR_CLEARHOME:
+ rc = fputc(-31, out);
+ break;
+
+ case TIB_CHAR_CLEARDRAW:
+ rc = fputc(-123, out);
+ break;
+
+ case TIB_CHAR_CLRLIST:
+ rc = fputc(-6, out);
+ break;
+
+ case TIB_CHAR_DEGREE:
+ rc = fputc(11, out);
+ break;
+
+ case TIB_CHAR_DIFFERENT:
+ rc = fputc(111, out);
+ break;
+
+ case TIB_CHAR_DIM:
+ rc = fputc(-75, out);
+ break;
+
+ case TIB_CHAR_DISP:
+ rc = fputc(-34, out);
+ break;
+
+ case TIB_CHAR_ELSE:
+ rc = fputc(-48, out);
+ break;
+
+ case TIB_CHAR_END:
+ rc = fputc(-44, out);
+ break;
+
+ case TIB_CHAR_EPOW10:
+ rc = fputc(59, out);
+ break;
+
+ case TIB_CHAR_FILL:
+ rc = fputc(-30, out);
+ break;
+
+ case TIB_CHAR_FOR:
+ rc = fputc(-45, out);
+ break;
+
+ case TIB_CHAR_GETKEY:
+ rc = fputc(-83, out);
+ break;
+
+ case TIB_CHAR_GOTO:
+ rc = fputc(-41, out);
+ break;
+
+ case TIB_CHAR_GREATEREQUAL:
+ rc = fputc(110, out);
+ break;
+
+ case TIB_CHAR_IF:
+ rc = fputc(-50, out);
+ break;
+
+ case TIB_CHAR_INPUT:
+ rc = fputc(-36, out);
+ break;
+
+ case TIB_CHAR_INT:
+ rc = fputc(-79, out);
+ break;
+
+ case TIB_CHAR_L1:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(0, out);
+ break;
+
+ case TIB_CHAR_L2:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(1, out);
+ break;
+
+ case TIB_CHAR_L3:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(2, out);
+ break;
+
+ case TIB_CHAR_L4:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(3, out);
+ break;
+
+ case TIB_CHAR_L5:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(4, out);
+ break;
+
+ case TIB_CHAR_L6:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(5, out);
+ break;
+
+ case TIB_CHAR_L7:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(6, out);
+ break;
+
+ case TIB_CHAR_L8:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(7, out);
+ break;
+
+ case TIB_CHAR_L9:
+ rc = fputc(93, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(8, out);
+ break;
+
+ case TIB_CHAR_LABEL:
+ rc = fputc(-42, out);
+ break;
+
+ case TIB_CHAR_LESSEQUAL:
+ rc = fputc(109, out);
+ break;
+
+ case TIB_CHAR_LINE:
+ rc = fputc(-100, out);
+ break;
+
+ case TIB_CHAR_LUSER:
+ rc = fputc(-21, out);
+ break;
+
+ case TIB_CHAR_MATA:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(0, out);
+ break;
+
+ case TIB_CHAR_MATB:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(1, out);
+ break;
+
+ case TIB_CHAR_MATC:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(2, out);
+ break;
+
+ case TIB_CHAR_MATD:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(3, out);
+ break;
+
+ case TIB_CHAR_MATE:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(4, out);
+ break;
+
+ case TIB_CHAR_MATF:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(5, out);
+ break;
+
+ case TIB_CHAR_MATG:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(6, out);
+ break;
+
+ case TIB_CHAR_MATH:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(7, out);
+ break;
+
+ case TIB_CHAR_MATI:
+ rc = fputc(92, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(8, out);
+ break;
+
+ case TIB_CHAR_MENU:
+ rc = fputc(-26, out);
+ break;
+
+ case TIB_CHAR_NOT:
+ rc = fputc(-72, out);
+ break;
+
+ case TIB_CHAR_OUTPUT:
+ rc = fputc(-32, out);
+ break;
+
+ case TIB_CHAR_OR:
+ rc = fputc(60, out);
+ break;
+
+ case TIB_CHAR_PAUSE:
+ rc = fputc(-40, out);
+ break;
+
+ case TIB_CHAR_PI:
+ rc = fputc(-84, out);
+ break;
+
+ case TIB_CHAR_PIC1:
+ rc = fputc(96, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(0, out);
+ break;
+
+ case TIB_CHAR_PIXEL_TEST:
+ rc = fputc(19, out);
+ break;
+
+ case TIB_CHAR_RAND:
+ rc = fputc(-85, out);
+ break;
+
+ case TIB_CHAR_RANDINT:
+ rc = fputc(-69, out);
+ if (EOF == rc)
+ break;
+ rc = fputc(10, out);
+ break;
+
+ case TIB_CHAR_RECALLPIC:
+ rc = fputc(-103, out);
+ break;
+
+ case TIB_CHAR_REPEAT:
+ rc = fputc(-46, out);
+ break;
+
+ case TIB_CHAR_RETURN:
+ rc = fputc(-43, out);
+ break;
+
+ case TIB_CHAR_ROUND:
+ rc = fputc(18, out);
+ break;
+
+ case TIB_CHAR_SMALL_MINUS:
+ rc = fputc(-80, out);
+ break;
+
+ case TIB_CHAR_STO:
+ rc = fputc(4, out);
+ break;
+
+ case TIB_CHAR_STOP:
+ rc = fputc(-39, out);
+ break;
+
+ case TIB_CHAR_STOREPIC:
+ rc = fputc(-104, out);
+ break;
+
+ case TIB_CHAR_TEXT:
+ rc = fputc(-109, out);
+ break;
+
+ case TIB_CHAR_THEN:
+ rc = fputc(-49, out);
+ break;
+
+ case TIB_CHAR_THETA:
+ rc = fputc(91, out);
+ break;
+
+ case TIB_CHAR_WHILE:
+ rc = fputc(-47, out);
+ break;
+
+ case TIB_CHAR_XMAX:
+ rc = fputc(99, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(11, out);
+ break;
+
+ case TIB_CHAR_XMIN:
+ rc = fputc(99, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(10, out);
+ break;
+
+ case TIB_CHAR_YMAX:
+ rc = fputc(99, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(13, out);
+ break;
+
+ case TIB_CHAR_YMIN:
+ rc = fputc(99, out);
+ if (EOF == rc)
+ break;
+ ++(*written);
+ rc = fputc(12, out);
+ break;
+
+ default:
+ if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'))
+ rc = fputc(c, out);
+ else
+ rc = EOF;
+ break;
+ }
+
+ if (EOF == rc)
+ return TIB_EWRITE;
+
+ ++(*written);
+ }
+
+ return 0;
}
diff --git a/src/tibtranscode.h b/src/tibtranscode.h
index bf9356c..e0530cd 100644
--- a/src/tibtranscode.h
+++ b/src/tibtranscode.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,9 +21,9 @@
#include "tibexpr.h"
int
-tib_fread (struct tib_expr *out, FILE *program, unsigned long *parsed);
+tib_fread(struct tib_expr *out, FILE *program, unsigned long *parsed);
int
-tib_fwrite (FILE *out, const struct tib_expr *program, unsigned long *written);
+tib_fwrite(FILE *out, const struct tib_expr *program, unsigned long *written);
#endif
diff --git a/src/tibtype.c b/src/tibtype.c
index 1351dec..8dc8773 100644
--- a/src/tibtype.c
+++ b/src/tibtype.c
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -30,1086 +30,1119 @@
#include "util.h"
TIB *
-tib_empty ()
+tib_empty()
{
- TIB *out = malloc (sizeof (TIB));
- if (NULL == out)
- {
- tib_errno = TIB_EALLOC;
- return NULL;
- }
+ TIB *out = malloc(sizeof(TIB));
+ if (NULL == out)
+ {
+ tib_errno = TIB_EALLOC;
+ return NULL;
+ }
- out->type = TIB_TYPE_NONE;
- out->refs = 1;
+ out->type = TIB_TYPE_NONE;
+ out->refs = 1;
- return out;
+ return out;
}
TIB *
-tib_copy (const TIB *t)
+tib_copy(const TIB *t)
{
- TIB *temp;
-
- if (NULL == t)
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
-
- switch (t->type)
- {
- case TIB_TYPE_NONE:
- return tib_empty ();
-
- case TIB_TYPE_COMPLEX:
- return tib_new_complex (GSL_REAL (t->value.number),
- GSL_IMAG (t->value.number));
-
- case TIB_TYPE_STRING:
- return tib_new_str (t->value.string);
-
- case TIB_TYPE_LIST:
- temp = tib_new_list (NULL, t->value.list->size);
- if (NULL == temp)
- return NULL;
-
- tib_errno = gsl_vector_complex_memcpy (temp->value.list, t->value.list);
- if (tib_errno)
- {
- tib_decref (temp);
- return NULL;
- }
-
- return temp;
-
- case TIB_TYPE_MATRIX:
- temp = tib_new_matrix (NULL, t->value.matrix->size1,
- t->value.matrix->size2);
- if (NULL == temp)
- return NULL;
-
- tib_errno = gsl_matrix_complex_memcpy (temp->value.matrix,
- t->value.matrix);
- if (tib_errno)
- {
- tib_decref (temp);
- return NULL;
- }
-
- return temp;
-
- default:
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ TIB *temp;
+
+ if (NULL == t)
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+
+ switch (t->type)
+ {
+ case TIB_TYPE_NONE:
+ return tib_empty();
+
+ case TIB_TYPE_COMPLEX:
+ return tib_new_complex(GSL_REAL(t->value.number),
+ GSL_IMAG(t->value.number));
+
+ case TIB_TYPE_STRING:
+ return tib_new_str(t->value.string);
+
+ case TIB_TYPE_LIST:
+ temp = tib_new_list(NULL, t->value.list->size);
+ if (NULL == temp)
+ return NULL;
+
+ tib_errno = gsl_vector_complex_memcpy(temp->value.list,
+ t->value.list);
+ if (tib_errno)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ return temp;
+
+ case TIB_TYPE_MATRIX:
+ temp = tib_new_matrix(NULL, t->value.matrix->size1,
+ t->value.matrix->size2);
+ if (NULL == temp)
+ return NULL;
+
+ tib_errno = gsl_matrix_complex_memcpy(temp->value.matrix,
+ t->value.matrix);
+ if (tib_errno)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ return temp;
+
+ default:
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
}
void
-tib_incref (TIB *t)
+tib_incref(TIB *t)
{
- ++t->refs;
+ ++t->refs;
}
void
-tib_decref (TIB *t)
+tib_decref(TIB *t)
{
- if (0 == t->refs)
- return;
-
- if (--t->refs == 0)
- {
- switch (t->type)
- {
- case TIB_TYPE_LIST:
- gsl_vector_complex_free (t->value.list);
- break;
-
- case TIB_TYPE_MATRIX:
- gsl_matrix_complex_free (t->value.matrix);
- break;
-
- case TIB_TYPE_STRING:
- free (t->value.string);
- break;
-
- default:
- break;
- }
-
- free (t);
- }
+ if (0 == t->refs)
+ return;
+
+ if (--t->refs == 0)
+ {
+ switch (t->type)
+ {
+ case TIB_TYPE_LIST:
+ gsl_vector_complex_free(t->value.list);
+ break;
+
+ case TIB_TYPE_MATRIX:
+ gsl_matrix_complex_free(t->value.matrix);
+ break;
+
+ case TIB_TYPE_STRING:
+ free(t->value.string);
+ break;
+
+ default:
+ break;
+ }
+
+ free(t);
+ }
}
TIB *
-tib_new_complex (double real, double imaginary)
+tib_new_complex(double real, double imaginary)
{
- TIB *out = malloc (sizeof (TIB));
- if (NULL == out)
- {
- tib_errno = TIB_EALLOC;
- return NULL;
- }
-
- out->type = TIB_TYPE_COMPLEX;
- out->refs = 1;
- GSL_SET_COMPLEX (&out->value.number, real, imaginary);
-
- return out;
+ TIB *out = malloc(sizeof(TIB));
+ if (NULL == out)
+ {
+ tib_errno = TIB_EALLOC;
+ return NULL;
+ }
+
+ out->type = TIB_TYPE_COMPLEX;
+ out->refs = 1;
+ GSL_SET_COMPLEX(&out->value.number, real, imaginary);
+
+ return out;
}
TIB *
-tib_new_str (const char *value)
+tib_new_str(const char *value)
{
- if (NULL == value)
- return NULL;
-
- TIB *out = malloc (sizeof (TIB));
- if (NULL == out)
- {
- tib_errno = TIB_EALLOC;
- return NULL;
- }
-
- out->type = TIB_TYPE_STRING;
- out->refs = 1;
- out->value.string = malloc ((strlen (value) + 1) * sizeof (char));
- if (NULL == out->value.string)
- {
- tib_errno = TIB_EALLOC;
- free (out);
- return NULL;
- }
-
- strcpy (out->value.string, value);
- return out;
+ if (NULL == value)
+ return NULL;
+
+ TIB *out = malloc(sizeof(TIB));
+ if (NULL == out)
+ {
+ tib_errno = TIB_EALLOC;
+ return NULL;
+ }
+
+ out->type = TIB_TYPE_STRING;
+ out->refs = 1;
+ out->value.string = malloc((strlen(value) + 1) * sizeof(char));
+ if (NULL == out->value.string)
+ {
+ tib_errno = TIB_EALLOC;
+ free(out);
+ return NULL;
+ }
+
+ strcpy(out->value.string, value);
+ return out;
}
TIB *
-tib_new_list (const gsl_complex *value, size_t len)
+tib_new_list(const gsl_complex *value, size_t len)
{
- TIB *out = malloc (sizeof (TIB));
- if (NULL == out)
- {
- tib_errno = TIB_EALLOC;
- return NULL;
- }
-
- out->type = TIB_TYPE_LIST;
- out->refs = 1;
- out->value.list = gsl_vector_complex_alloc (len);
- if (!out->value.list)
- {
- tib_errno = TIB_EALLOC;
- free (out);
- return NULL;
- }
-
- size_t i;
- if (value != NULL)
- for (i = 0; i < len; ++i)
- gsl_vector_complex_set (out->value.list, i, value[i]);
-
- return out;
+ TIB *out = malloc(sizeof(TIB));
+ if (NULL == out)
+ {
+ tib_errno = TIB_EALLOC;
+ return NULL;
+ }
+
+ out->type = TIB_TYPE_LIST;
+ out->refs = 1;
+ out->value.list = gsl_vector_complex_alloc(len);
+ if (!out->value.list)
+ {
+ tib_errno = TIB_EALLOC;
+ free(out);
+ return NULL;
+ }
+
+ size_t i;
+ if (value != NULL)
+ for (i = 0; i < len; ++i)
+ gsl_vector_complex_set(out->value.list, i, value[i]);
+
+ return out;
}
TIB *
-tib_new_matrix (const gsl_complex **value, size_t w, size_t h)
+tib_new_matrix(const gsl_complex **value, size_t w, size_t h)
{
- TIB *out = malloc (sizeof (TIB));
- if (NULL == out)
- {
- tib_errno = TIB_EALLOC;
- return NULL;
- }
-
- out->type = TIB_TYPE_MATRIX;
- out->refs = 1;
- out->value.matrix = gsl_matrix_complex_alloc (h, w);
- if (!out->value.matrix)
- {
- tib_errno = TIB_EALLOC;
- free (out);
- return NULL;
- }
-
- size_t i, j;
- if (value != NULL)
- for (i = 0; i < h; ++i)
- for (j = 0; j < w; ++j)
- gsl_matrix_complex_set (out->value.matrix, i, j, value[i][j]);
-
- return out;
+ TIB *out = malloc(sizeof(TIB));
+ if (NULL == out)
+ {
+ tib_errno = TIB_EALLOC;
+ return NULL;
+ }
+
+ out->type = TIB_TYPE_MATRIX;
+ out->refs = 1;
+ out->value.matrix = gsl_matrix_complex_alloc(h, w);
+ if (!out->value.matrix)
+ {
+ tib_errno = TIB_EALLOC;
+ free(out);
+ return NULL;
+ }
+
+ size_t i, j;
+ if (value != NULL)
+ for (i = 0; i < h; ++i)
+ for (j = 0; j < w; ++j)
+ gsl_matrix_complex_set(out->value.matrix, i, j,
+ value[i][j]);
+
+ return out;
}
enum tib_type
-tib_type (const TIB *t)
+tib_type(const TIB *t)
{
- return t->type;
+ return t->type;
}
gsl_complex
-tib_complex_value (const TIB *t)
+tib_complex_value(const TIB *t)
{
- if (t->type == TIB_TYPE_COMPLEX)
- return t->value.number;
+ if (t->type == TIB_TYPE_COMPLEX)
+ return t->value.number;
- tib_errno = TIB_ETYPE;
- return (gsl_complex) {.dat = {0, 0}};
+ tib_errno = TIB_ETYPE;
+ return (gsl_complex) { .dat = { 0, 0 } };
}
const char *
-tib_str_value (const TIB *t)
+tib_str_value(const TIB *t)
{
- if (t->type == TIB_TYPE_STRING)
- return t->value.string;
+ if (t->type == TIB_TYPE_STRING)
+ return t->value.string;
- tib_errno = TIB_ETYPE;
- return NULL;
+ tib_errno = TIB_ETYPE;
+ return NULL;
}
const gsl_vector_complex *
-tib_list_value (const TIB *t)
+tib_list_value(const TIB *t)
{
- if (t->type == TIB_TYPE_LIST)
- return t->value.list;
+ if (t->type == TIB_TYPE_LIST)
+ return t->value.list;
- tib_errno = TIB_ETYPE;
- return NULL;
+ tib_errno = TIB_ETYPE;
+ return NULL;
}
const gsl_matrix_complex *
-tib_matrix_value (const TIB *t)
+tib_matrix_value(const TIB *t)
{
- if (t->type == TIB_TYPE_MATRIX)
- return t->value.matrix;
+ if (t->type == TIB_TYPE_MATRIX)
+ return t->value.matrix;
- tib_errno = TIB_ETYPE;
- return NULL;
+ tib_errno = TIB_ETYPE;
+ return NULL;
}
static void
-format_double_str (char *buf, double value)
+format_double_str(char *buf, double value)
{
- snprintf (buf, 17, "%.*g", 10, value);
+ snprintf(buf, 17, "%.*g", 10, value);
}
static bool
-abs_too_big (double value)
+abs_too_big(double value)
{
- return fabs (value) > 10e100;
+ return fabs(value) > 10e100;
}
static int
-complex_toexpr (struct tib_expr *dest, gsl_complex value)
+complex_toexpr(struct tib_expr *dest, gsl_complex value)
{
- int rc;
- char buf[17];
-
- if (abs_too_big (GSL_REAL (value)) || abs_too_big (GSL_IMAG (value)))
- return TIB_EOVER;
-
- dest->len = 0;
-
- if (GSL_REAL (value))
- {
- format_double_str (buf, GSL_REAL (value));
-
- rc = load_expr_num (dest, buf);
- if (rc)
- return rc;
- }
-
- if (GSL_IMAG (value))
- {
- if (GSL_IMAG (value) > 0 && GSL_REAL (value))
- {
- rc = tib_expr_push (dest, '+');
- if (rc)
- return rc;
- }
-
- if (GSL_IMAG (value) != 1.0)
- {
- format_double_str (buf, GSL_IMAG (value));
- rc = load_expr_num (dest, buf);
- if (rc)
- return rc;
- }
-
- rc = tib_expr_push (dest, 'i');
- if (rc)
- return rc;
- }
- else if (!GSL_REAL (value))
- {
- rc = tib_expr_push (dest, '0');
- if (rc)
- return rc;
- }
-
- return 0;
+ int rc;
+ char buf[17];
+
+ if (abs_too_big(GSL_REAL(value)) || abs_too_big(GSL_IMAG(value)))
+ return TIB_EOVER;
+
+ dest->len = 0;
+
+ if (GSL_REAL(value))
+ {
+ format_double_str(buf, GSL_REAL(value));
+
+ rc = load_expr_num(dest, buf);
+ if (rc)
+ return rc;
+ }
+
+ if (GSL_IMAG(value))
+ {
+ if (GSL_IMAG(value) > 0 && GSL_REAL(value))
+ {
+ rc = tib_expr_push(dest, '+');
+ if (rc)
+ return rc;
+ }
+
+ if (GSL_IMAG(value) != 1.0)
+ {
+ format_double_str(buf, GSL_IMAG(value));
+ rc = load_expr_num(dest, buf);
+ if (rc)
+ return rc;
+ }
+
+ rc = tib_expr_push(dest, 'i');
+ if (rc)
+ return rc;
+ }
+ else if (!GSL_REAL(value))
+ {
+ rc = tib_expr_push(dest, '0');
+ if (rc)
+ return rc;
+ }
+
+ return 0;
}
int
-tib_toexpr (struct tib_expr *dest, const TIB *src)
+tib_toexpr(struct tib_expr *dest, const TIB *src)
{
- int rc = tib_expr_init (dest);
- if (rc)
- return rc;
-
- size_t i;
- switch (src->type)
- {
- case TIB_TYPE_NONE:
- rc = load_expr (dest, "Error");
- break;
-
- case TIB_TYPE_COMPLEX:
- rc = complex_toexpr (dest, tib_complex_value (src));
- break;
-
- case TIB_TYPE_STRING:
- rc = load_expr (dest, tib_str_value (src));
- break;
-
- case TIB_TYPE_LIST:
- rc = tib_expr_push (dest, '{');
- if (rc)
- break;
-
- for (i = 0; i < src->value.list->size; ++i)
- {
- gsl_complex z = gsl_vector_complex_get (src->value.list, i);
- rc = complex_toexpr (dest, z);
- if (rc)
- goto end;
-
- rc = tib_expr_push (dest, ',');
- if (rc)
- goto end;
- }
-
- if (i)
- dest->data[dest->len - 1] = '}';
- else
- rc = tib_expr_push (dest, '}');
- break;
-
- case TIB_TYPE_MATRIX:
- rc = tib_expr_push (dest, '[');
- if (rc)
- break;
-
- for (i = 0; i < src->value.matrix->size1; ++i)
- {
- size_t j;
-
- rc = tib_expr_push (dest, '[');
- if (rc)
- goto end;
-
- for (j = 0; j < src->value.matrix->size2; ++j)
- {
- gsl_complex z = gsl_matrix_complex_get (src->value.matrix, i, j);
- rc = complex_toexpr (dest, z);
- if (rc)
- goto end;
-
- rc = tib_expr_push (dest, ',');
- if (rc)
- goto end;
- }
-
- if (j)
- {
- dest->data[dest->len - 1] = ']';
- }
- else
- {
- rc = tib_expr_push (dest, ']');
- if (rc)
- goto end;
- }
-
- rc = tib_expr_push (dest, ',');
- if (rc)
- goto end;
- }
-
- if (i)
- dest->data[dest->len - 1] = ']';
- else
- rc = tib_expr_push (dest, ']');
- break;
- }
+ int rc = tib_expr_init(dest);
+ if (rc)
+ return rc;
+
+ size_t i;
+ switch (src->type)
+ {
+ case TIB_TYPE_NONE:
+ rc = load_expr(dest, "Error");
+ break;
+
+ case TIB_TYPE_COMPLEX:
+ rc = complex_toexpr(dest, tib_complex_value(src));
+ break;
+
+ case TIB_TYPE_STRING:
+ rc = load_expr(dest, tib_str_value(src));
+ break;
+
+ case TIB_TYPE_LIST:
+ rc = tib_expr_push(dest, '{');
+ if (rc)
+ break;
+
+ for (i = 0; i < src->value.list->size; ++i)
+ {
+ gsl_complex z = gsl_vector_complex_get(src->value.list,
+ i);
+ rc = complex_toexpr(dest, z);
+ if (rc)
+ goto end;
+
+ rc = tib_expr_push(dest, ',');
+ if (rc)
+ goto end;
+ }
+
+ if (i)
+ dest->data[dest->len - 1] = '}';
+ else
+ rc = tib_expr_push(dest, '}');
+ break;
+
+ case TIB_TYPE_MATRIX:
+ rc = tib_expr_push(dest, '[');
+ if (rc)
+ break;
+
+ for (i = 0; i < src->value.matrix->size1; ++i)
+ {
+ size_t j;
+
+ rc = tib_expr_push(dest, '[');
+ if (rc)
+ goto end;
+
+ for (j = 0; j < src->value.matrix->size2; ++j)
+ {
+ gsl_complex z;
+ z = gsl_matrix_complex_get(src->value.matrix,
+ i, j);
+ rc = complex_toexpr(dest, z);
+ if (rc)
+ goto end;
+
+ rc = tib_expr_push(dest, ',');
+ if (rc)
+ goto end;
+ }
+
+ if (j)
+ {
+ dest->data[dest->len - 1] = ']';
+ }
+ else
+ {
+ rc = tib_expr_push(dest, ']');
+ if (rc)
+ goto end;
+ }
+
+ rc = tib_expr_push(dest, ',');
+ if (rc)
+ goto end;
+ }
+
+ if (i)
+ dest->data[dest->len - 1] = ']';
+ else
+ rc = tib_expr_push(dest, ']');
+ break;
+ }
end:
- if (rc)
- tib_expr_destroy (dest);
+ if (rc)
+ tib_expr_destroy(dest);
- return rc;
+ return rc;
}
TIB *
-tib_add (const TIB *t1, const TIB *t2)
+tib_add(const TIB *t1, const TIB *t2)
{
- if (t1->type != t2->type
- && !(TIB_TYPE_COMPLEX == t1->type && TIB_TYPE_LIST == t2->type)
- && !(TIB_TYPE_LIST == t1->type && TIB_TYPE_COMPLEX == t2->type))
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
-
- char *s;
- TIB *temp;
- size_t i;
- switch (t1->type)
- {
- case TIB_TYPE_COMPLEX:
- if (TIB_TYPE_COMPLEX == t2->type)
- {
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- temp->value.number = gsl_complex_add (t1->value.number,
- t2->value.number);
-
- return temp;
- }
- else
- {
- temp = tib_copy (t2);
- if (NULL == temp)
- return NULL;
-
- for (i = 0; i < temp->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t2->value.list, i);
- gsl_complex sum = gsl_complex_add (a, t1->value.number);
- gsl_vector_complex_set (temp->value.list, i, sum);
- }
-
- return temp;
- }
-
- case TIB_TYPE_STRING:
- s = malloc ((strlen (t1->value.string) + strlen (t2->value.string) + 1)
- * sizeof (char));
- sprintf (s, "%s%s", t1->value.string, t2->value.string);
- temp = tib_new_str (s);
- free (s);
- return temp;
-
- case TIB_TYPE_LIST:
- if (TIB_TYPE_LIST == t2->type)
- {
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- tib_errno = gsl_vector_complex_add (temp->value.list,
- t2->value.list);
- if (tib_errno)
- {
- tib_decref (temp);
- return NULL;
- }
-
- return temp;
- }
- else
- {
- return tib_add (t2, t1);
- }
-
- case TIB_TYPE_MATRIX:
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- tib_errno = gsl_matrix_complex_add (temp->value.matrix,
- t2->value.matrix);
- if (tib_errno)
- {
- tib_decref (temp);
- return NULL;
- }
-
- return temp;
-
- default:
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ if (t1->type != t2->type
+ && !(TIB_TYPE_COMPLEX == t1->type && TIB_TYPE_LIST == t2->type)
+ && !(TIB_TYPE_LIST == t1->type && TIB_TYPE_COMPLEX == t2->type))
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+
+ char *s;
+ TIB *temp;
+ size_t i;
+ switch (t1->type)
+ {
+ case TIB_TYPE_COMPLEX:
+ if (TIB_TYPE_COMPLEX == t2->type)
+ {
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ temp->value.number = gsl_complex_add(t1->value.number,
+ t2->value.number);
+
+ return temp;
+ }
+ else
+ {
+ temp = tib_copy(t2);
+ if (NULL == temp)
+ return NULL;
+
+ for (i = 0; i < temp->value.list->size; ++i)
+ {
+ gsl_complex a, sum;
+ a = gsl_vector_complex_get(t2->value.list, i);
+ sum = gsl_complex_add(a, t1->value.number);
+ gsl_vector_complex_set(temp->value.list, i,
+ sum);
+ }
+
+ return temp;
+ }
+
+ case TIB_TYPE_STRING:
+ s = malloc((strlen(t1->value.string) +
+ strlen(t2->value.string) + 1) * sizeof(char));
+ sprintf(s, "%s%s", t1->value.string, t2->value.string);
+ temp = tib_new_str(s);
+ free(s);
+ return temp;
+
+ case TIB_TYPE_LIST:
+ if (TIB_TYPE_LIST == t2->type)
+ {
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ tib_errno = gsl_vector_complex_add(temp->value.list,
+ t2->value.list);
+ if (tib_errno)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ return temp;
+ }
+ else
+ {
+ return tib_add(t2, t1);
+ }
+
+ case TIB_TYPE_MATRIX:
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ tib_errno = gsl_matrix_complex_add(temp->value.matrix,
+ t2->value.matrix);
+ if (tib_errno)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ return temp;
+
+ default:
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
}
TIB *
-tib_sub (const TIB *t1, const TIB *t2)
+tib_sub(const TIB *t1, const TIB *t2)
{
- if (t1->type != t2->type
- && !(TIB_TYPE_COMPLEX == t1->type && TIB_TYPE_LIST == t2->type)
- && !(TIB_TYPE_LIST == t1->type && TIB_TYPE_COMPLEX == t2->type))
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
-
- TIB *temp;
- size_t i;
- switch (t1->type)
- {
- case TIB_TYPE_COMPLEX:
- if (TIB_TYPE_COMPLEX == t2->type)
- {
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- temp->value.number = gsl_complex_sub (t1->value.number,
- t2->value.number);
-
- return temp;
- }
- else
- {
- temp = tib_copy (t2);
- if (NULL == temp)
- return NULL;
-
- for (i = 0; i < temp->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t2->value.list, i);
- gsl_complex diff = gsl_complex_sub (a, t1->value.number);
- gsl_vector_complex_set (temp->value.list, i, diff);
- }
-
- return temp;
- }
-
- case TIB_TYPE_LIST:
- if (TIB_TYPE_LIST == t2->type)
- {
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- tib_errno = gsl_vector_complex_sub (temp->value.list,
- t2->value.list);
- if (tib_errno)
- {
- tib_decref (temp);
- return NULL;
- }
-
- return temp;
- }
- else
- {
- temp = tib_copy (t2);
- if (NULL == temp)
- return NULL;
-
- for (i = 0; i < temp->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t2->value.list, i);
- gsl_complex diff = gsl_complex_sub (t1->value.number, a);
- gsl_vector_complex_set (temp->value.list, i, diff);
- }
-
- return temp;
- }
-
- case TIB_TYPE_MATRIX:
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- tib_errno = gsl_matrix_complex_sub (temp->value.matrix,
- t2->value.matrix);
- if (tib_errno)
- {
- tib_decref (temp);
- return NULL;
- }
-
- return temp;
-
- default:
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ if (t1->type != t2->type
+ && !(TIB_TYPE_COMPLEX == t1->type && TIB_TYPE_LIST == t2->type)
+ && !(TIB_TYPE_LIST == t1->type && TIB_TYPE_COMPLEX == t2->type))
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+
+ TIB *temp;
+ size_t i;
+ switch (t1->type)
+ {
+ case TIB_TYPE_COMPLEX:
+ if (TIB_TYPE_COMPLEX == t2->type)
+ {
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ temp->value.number = gsl_complex_sub(t1->value.number,
+ t2->value.number);
+
+ return temp;
+ }
+ else
+ {
+ temp = tib_copy(t2);
+ if (NULL == temp)
+ return NULL;
+
+ for (i = 0; i < temp->value.list->size; ++i)
+ {
+ gsl_complex a, diff;
+ a = gsl_vector_complex_get(t2->value.list, i);
+ diff = gsl_complex_sub(a, t1->value.number);
+ gsl_vector_complex_set(temp->value.list, i,
+ diff);
+ }
+
+ return temp;
+ }
+
+ case TIB_TYPE_LIST:
+ if (TIB_TYPE_LIST == t2->type)
+ {
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ tib_errno = gsl_vector_complex_sub(temp->value.list,
+ t2->value.list);
+ if (tib_errno)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ return temp;
+ }
+ else
+ {
+ temp = tib_copy(t2);
+ if (NULL == temp)
+ return NULL;
+
+ for (i = 0; i < temp->value.list->size; ++i)
+ {
+ gsl_complex a, diff;
+ a = gsl_vector_complex_get(t2->value.list, i);
+ diff = gsl_complex_sub(t1->value.number, a);
+ gsl_vector_complex_set(temp->value.list, i,
+ diff);
+ }
+
+ return temp;
+ }
+
+ case TIB_TYPE_MATRIX:
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ tib_errno = gsl_matrix_complex_sub(temp->value.matrix,
+ t2->value.matrix);
+ if (tib_errno)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ return temp;
+
+ default:
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
}
static int
-matrix_mul (gsl_matrix_complex *out, const gsl_matrix_complex *m1,
- const gsl_matrix_complex *m2)
+matrix_mul(gsl_matrix_complex *out, const gsl_matrix_complex *m1,
+ const gsl_matrix_complex *m2)
{
- gsl_complex a = { .dat={1, 1} }, b = { .dat={0, 0} };
- return gsl_blas_zgemm (CblasNoTrans, CblasNoTrans, a, m1, m2, b, out);
+ gsl_complex a = { .dat = {1, 1} }, b = { .dat = { 0, 0 } };
+ return gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, a, m1, m2, b, out);
}
TIB *
-tib_mul (const TIB *t1, const TIB *t2)
+tib_mul(const TIB *t1, const TIB *t2)
{
- if (t1->type != t2->type)
- {
- switch (t1->type)
- {
- case TIB_TYPE_COMPLEX:
- if (TIB_TYPE_NONE == t2->type || TIB_TYPE_STRING == t2->type)
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
- break;
-
- case TIB_TYPE_LIST:
- case TIB_TYPE_MATRIX:
- if (TIB_TYPE_COMPLEX != t2->type)
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
- break;
-
- default:
- tib_errno = TIB_ETYPE;
- return NULL;
- }
- }
-
- TIB *temp;
- size_t i, j;
- switch (t1->type)
- {
- case TIB_TYPE_COMPLEX:
- if (TIB_TYPE_COMPLEX == t2->type)
- {
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- temp->value.number = gsl_complex_mul (t1->value.number,
- t2->value.number);
-
- return temp;
- }
- else
- {
- temp = tib_copy (t2);
- if (NULL == temp)
- return NULL;
-
- gsl_complex a, product;
- if (TIB_TYPE_LIST == t2->type)
- {
- for (i = 0; i < t2->value.list->size; ++i)
- {
- a = gsl_vector_complex_get (t2->value.list, i);
- product = gsl_complex_mul (t1->value.number, a);
- gsl_vector_complex_set (temp->value.list, i, product);
- }
- }
- else /* must be matrix */
- {
- for (i = 0; i < t2->value.matrix->size1; ++i)
- for (j = 0; j < t2->value.matrix->size2; ++j)
- {
- a = gsl_matrix_complex_get (t2->value.matrix, i, j);
- product = gsl_complex_mul (t1->value.number, a);
- gsl_matrix_complex_set (temp->value.matrix, i, j, product);
- }
- }
-
- return temp;
- }
-
- case TIB_TYPE_LIST:
- if (TIB_TYPE_LIST == t2->type)
- {
- if (t1->value.list->size != t2->value.list->size)
- {
- tib_errno = TIB_EDIM;
- return NULL;
- }
-
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- for (i = 0; i < temp->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t1->value.list, i);
- gsl_complex b = gsl_vector_complex_get (t2->value.list, i);
- gsl_complex product = gsl_complex_mul (a, b);
- gsl_vector_complex_set (temp->value.list, i, product);
- }
-
- return temp;
- }
- else /* must be complex */
- {
- return tib_mul (t2, t1);
- }
-
- case TIB_TYPE_MATRIX:
- if (TIB_TYPE_MATRIX == t2->type)
- {
- if (t1->value.matrix->size2 != t2->value.matrix->size1)
- {
- tib_errno = TIB_EDIM;
- return NULL;
- }
-
- temp = tib_new_matrix (NULL, t1->value.matrix->size1,
- t2->value.matrix->size2);
- if (NULL == temp)
- return NULL;
-
- tib_errno = matrix_mul (temp->value.matrix, t1->value.matrix,
- t2->value.matrix);
- if (tib_errno)
- {
- tib_decref (temp);
- return NULL;
- }
-
- return temp;
- }
- else /* must be complex */
- {
- return tib_mul (t2, t1);
- }
-
- default:
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ if (t1->type != t2->type)
+ {
+ switch (t1->type)
+ {
+ case TIB_TYPE_COMPLEX:
+ if (TIB_TYPE_NONE == t2->type
+ || TIB_TYPE_STRING == t2->type)
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+ break;
+
+ case TIB_TYPE_LIST:
+ case TIB_TYPE_MATRIX:
+ if (TIB_TYPE_COMPLEX != t2->type)
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+ break;
+
+ default:
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+ }
+
+ TIB *temp;
+ size_t i, j;
+ switch (t1->type)
+ {
+ case TIB_TYPE_COMPLEX:
+ if (TIB_TYPE_COMPLEX == t2->type)
+ {
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ temp->value.number = gsl_complex_mul(t1->value.number,
+ t2->value.number);
+
+ return temp;
+ }
+ else
+ {
+ temp = tib_copy(t2);
+ if (NULL == temp)
+ return NULL;
+
+ gsl_complex a, product;
+ if (TIB_TYPE_LIST == t2->type)
+ {
+ for (i = 0; i < t2->value.list->size; ++i)
+ {
+ a = gsl_vector_complex_get(t2->value.
+ list, i);
+ product =
+ gsl_complex_mul(t1->value.number,
+ a);
+ gsl_vector_complex_set(temp->value.list,
+ i, product);
+ }
+ }
+ else // must be matrix
+ {
+ for (i = 0; i < t2->value.matrix->size1; ++i)
+ for (j = 0; j < t2->value.matrix->size2;
+ ++j)
+ {
+ a = gsl_matrix_complex_get(t2->value.matrix,
+ i, j);
+ product = gsl_complex_mul(t1->value.number,
+ a);
+ gsl_matrix_complex_set(temp->value.matrix,
+ i, j,
+ product);
+ }
+ }
+
+ return temp;
+ }
+
+ case TIB_TYPE_LIST:
+ if (TIB_TYPE_LIST == t2->type)
+ {
+ if (t1->value.list->size != t2->value.list->size)
+ {
+ tib_errno = TIB_EDIM;
+ return NULL;
+ }
+
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ for (i = 0; i < temp->value.list->size; ++i)
+ {
+ gsl_complex a, b, product;
+ a = gsl_vector_complex_get(t1->value.list, i);
+ b = gsl_vector_complex_get(t2->value.list, i);
+ product = gsl_complex_mul(a, b);
+ gsl_vector_complex_set(temp->value.list, i,
+ product);
+ }
+
+ return temp;
+ }
+ else // must be complex
+ {
+ return tib_mul(t2, t1);
+ }
+
+ case TIB_TYPE_MATRIX:
+ if (TIB_TYPE_MATRIX == t2->type)
+ {
+ if (t1->value.matrix->size2 != t2->value.matrix->size1)
+ {
+ tib_errno = TIB_EDIM;
+ return NULL;
+ }
+
+ temp = tib_new_matrix(NULL, t1->value.matrix->size1,
+ t2->value.matrix->size2);
+ if (NULL == temp)
+ return NULL;
+
+ tib_errno = matrix_mul(temp->value.matrix,
+ t1->value.matrix, t2->value.matrix);
+ if (tib_errno)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ return temp;
+ }
+ else // must be complex
+ {
+ return tib_mul(t2, t1);
+ }
+
+ default:
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
}
static bool
-less_than_0 (gsl_complex x)
+less_than_0(gsl_complex x)
{
- return gsl_complex_abs (x) < 0;
+ return gsl_complex_abs(x) < 0;
}
#define COMPLEX_ONE ((gsl_complex) { .dat = { 1, 0 } })
static TIB *
-inverse (const TIB *t)
+inverse(const TIB *t)
{
- TIB *temp = tib_copy (t);
- if (NULL == temp)
- return NULL;
-
- size_t i;
- switch (t->type)
- {
- case TIB_TYPE_COMPLEX:
- temp->value.number = gsl_complex_div (COMPLEX_ONE, t->value.number);
- return temp;
-
- case TIB_TYPE_LIST:
- for (i = 0; i < t->value.list->size; ++i)
- {
- gsl_complex z = gsl_vector_complex_get (t->value.list, i);
- gsl_vector_complex_set (temp->value.list, i,
- gsl_complex_div (COMPLEX_ONE, z));
- }
-
- return temp;
-
- case TIB_TYPE_MATRIX:
- // SPILLS OVER!
-
- default:
- tib_decref (temp);
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ TIB *temp = tib_copy(t);
+ if (NULL == temp)
+ return NULL;
+
+ size_t i;
+ switch (t->type)
+ {
+ case TIB_TYPE_COMPLEX:
+ temp->value.number = gsl_complex_div(COMPLEX_ONE,
+ t->value.number);
+ return temp;
+
+ case TIB_TYPE_LIST:
+ for (i = 0; i < t->value.list->size; ++i)
+ {
+ gsl_complex z = gsl_vector_complex_get(t->value.list,
+ i);
+ gsl_vector_complex_set(temp->value.list, i,
+ gsl_complex_div(COMPLEX_ONE, z));
+ }
+
+ return temp;
+
+ case TIB_TYPE_MATRIX:
+ // SPILLS OVER!
+
+ default:
+ tib_decref(temp);
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
}
static bool
-is_zero (gsl_complex z)
+is_zero(gsl_complex z)
{
- return 0 == GSL_REAL (z) && 0 == GSL_IMAG (z);
+ return 0 == GSL_REAL(z) && 0 == GSL_IMAG(z);
}
TIB *
-tib_div (const TIB *t1, const TIB *t2)
+tib_div(const TIB *t1, const TIB *t2)
{
- if (!(TIB_TYPE_COMPLEX == t1->type || TIB_TYPE_LIST == t1->type)
- || !(TIB_TYPE_COMPLEX == t2->type || TIB_TYPE_LIST == t2->type))
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
-
- TIB *temp;
- size_t i;
- switch (t1->type)
- {
- case TIB_TYPE_COMPLEX:
- if (TIB_TYPE_COMPLEX == t2->type)
- {
- if (is_zero (t2->value.number))
- {
- tib_errno = TIB_DBYZERO;
- return NULL;
- }
-
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- temp->value.number = gsl_complex_div (t1->value.number,
- t2->value.number);
- }
- else /* must be list */
- {
- temp = tib_copy (t2);
- if (NULL == temp)
- return NULL;
-
- for (i = 0; i < temp->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t2->value.list, i);
- if (is_zero (a))
- {
- tib_decref (temp);
- tib_errno = TIB_DBYZERO;
- return NULL;
- }
-
- gsl_complex quotient = gsl_complex_div (t1->value.number, a);
- gsl_vector_complex_set (temp->value.list, i, quotient);
- }
- }
-
- return temp;
-
- case TIB_TYPE_LIST:
- temp = tib_copy (t1);
- if (NULL == temp)
- return NULL;
-
- if (TIB_TYPE_LIST == t2->type)
- {
- for (i = 0; i < temp->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t1->value.list, i);
- gsl_complex b = gsl_vector_complex_get (t2->value.list, i);
- if (is_zero (b))
- {
- tib_decref (temp);
- tib_errno = TIB_DBYZERO;
- return NULL;
- }
-
- gsl_complex quotient = gsl_complex_div (a, b);
- gsl_vector_complex_set (temp->value.list, i, quotient);
- }
- }
- else /* must be complex */
- {
- if (is_zero (t2->value.number))
- {
- tib_decref (temp);
- tib_errno = TIB_DBYZERO;
- return NULL;
- }
-
- for (i = 0; i < temp->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t1->value.list, i);
- gsl_complex quotient = gsl_complex_div (a, t2->value.number);
- gsl_vector_complex_set (temp->value.list, i, quotient);
- }
- }
-
- return temp;
-
- default:
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ if (!(TIB_TYPE_COMPLEX == t1->type || TIB_TYPE_LIST == t1->type)
+ || !(TIB_TYPE_COMPLEX == t2->type || TIB_TYPE_LIST == t2->type))
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+
+ TIB *temp;
+ size_t i;
+ switch (t1->type)
+ {
+ case TIB_TYPE_COMPLEX:
+ if (TIB_TYPE_COMPLEX == t2->type)
+ {
+ if (is_zero(t2->value.number))
+ {
+ tib_errno = TIB_DBYZERO;
+ return NULL;
+ }
+
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ temp->value.number = gsl_complex_div(t1->value.number,
+ t2->value.number);
+ }
+ else // must be list
+ {
+ temp = tib_copy(t2);
+ if (NULL == temp)
+ return NULL;
+
+ for (i = 0; i < temp->value.list->size; ++i)
+ {
+ gsl_complex a, q;
+ a = gsl_vector_complex_get(t2->value.list, i);
+ if (is_zero(a))
+ {
+ tib_decref(temp);
+ tib_errno = TIB_DBYZERO;
+ return NULL;
+ }
+
+ q = gsl_complex_div(t1->value.number, a);
+ gsl_vector_complex_set(temp->value.list, i, q);
+ }
+ }
+
+ return temp;
+
+ case TIB_TYPE_LIST:
+ temp = tib_copy(t1);
+ if (NULL == temp)
+ return NULL;
+
+ if (TIB_TYPE_LIST == t2->type)
+ {
+ for (i = 0; i < temp->value.list->size; ++i)
+ {
+ gsl_complex a, b, q;
+ a = gsl_vector_complex_get(t1->value.list, i);
+ b = gsl_vector_complex_get(t2->value.list, i);
+ if (is_zero(b))
+ {
+ tib_decref(temp);
+ tib_errno = TIB_DBYZERO;
+ return NULL;
+ }
+
+ q = gsl_complex_div(a, b);
+ gsl_vector_complex_set(temp->value.list, i, q);
+ }
+ }
+ else // must be complex
+ {
+ if (is_zero(t2->value.number))
+ {
+ tib_decref(temp);
+ tib_errno = TIB_DBYZERO;
+ return NULL;
+ }
+
+ for (i = 0; i < temp->value.list->size; ++i)
+ {
+ gsl_complex a, q;
+ a = gsl_vector_complex_get(t1->value.list, i);
+ q = gsl_complex_div(a, t2->value.number);
+ gsl_vector_complex_set(temp->value.list, i, q);
+ }
+ }
+
+ return temp;
+
+ default:
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
}
static gsl_complex
-complex_root (gsl_complex z, gsl_complex root)
+complex_root(gsl_complex z, gsl_complex root)
{
- return gsl_complex_pow (z, gsl_complex_div (COMPLEX_ONE, root));
+ return gsl_complex_pow(z, gsl_complex_div(COMPLEX_ONE, root));
}
TIB *
-tib_root (const TIB *t, gsl_complex root)
+tib_root(const TIB *t, gsl_complex root)
{
- TIB *temp;
- size_t i;
-
- if (TIB_TYPE_COMPLEX != t->type && TIB_TYPE_LIST != t->type)
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
-
- temp = tib_copy (t);
- if (NULL == temp)
- return NULL;
-
- switch (t->type)
- {
- case TIB_TYPE_COMPLEX:
- temp->value.number = complex_root (t->value.number, root);
- return temp;
-
- case TIB_TYPE_LIST:
- for (i = 0; i < t->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t->value.list, i);
- gsl_vector_complex_set (temp->value.list, i, complex_root (a, root));
- }
- return temp;
-
- default:
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ TIB *temp;
+ size_t i;
+
+ if (TIB_TYPE_COMPLEX != t->type && TIB_TYPE_LIST != t->type)
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+
+ temp = tib_copy(t);
+ if (NULL == temp)
+ return NULL;
+
+ switch (t->type)
+ {
+ case TIB_TYPE_COMPLEX:
+ temp->value.number = complex_root(t->value.number, root);
+ return temp;
+
+ case TIB_TYPE_LIST:
+ for (i = 0; i < t->value.list->size; ++i)
+ {
+ gsl_complex a = gsl_vector_complex_get(t->value.list,
+ i);
+ gsl_vector_complex_set(temp->value.list, i,
+ complex_root(a, root));
+ }
+ return temp;
+
+ default:
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
}
static bool
-is_int (gsl_complex z)
+is_int(gsl_complex z)
{
- return fmod (GSL_REAL (z), 1.0) == 0 && fmod (GSL_IMAG (z), 1.0) == 0;
+ return fmod(GSL_REAL(z), 1.0) == 0 && fmod(GSL_IMAG(z), 1.0) == 0;
}
TIB *
-tib_pow (const TIB *t, const TIB *power)
+tib_pow(const TIB *t, const TIB *power)
{
- TIB *temp;
-
- if (TIB_TYPE_COMPLEX != power->type)
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
-
- gsl_complex exp = tib_complex_value (power);
-
- if (less_than_0 (exp))
- {
- temp = inverse (t);
- exp = gsl_complex_negative (exp);
- }
- else
- {
- temp = tib_copy (t);
- }
-
- if (NULL == temp)
- {
- tib_decref (temp);
- return NULL;
- }
-
- size_t i;
- switch (t->type)
- {
- case TIB_TYPE_COMPLEX:
- temp->value.number = gsl_complex_pow (t->value.number, exp);
- return temp;
-
- case TIB_TYPE_LIST:
- for (i = 0; i < t->value.list->size; ++i)
- {
- gsl_complex a = gsl_vector_complex_get (t->value.list, i);
- gsl_vector_complex_set (temp->value.list, i,
- gsl_complex_pow (a, exp));
- }
- return temp;
-
- case TIB_TYPE_MATRIX:
- if (t->value.matrix->size1 != t->value.matrix->size2)
- {
- tib_errno = TIB_EDIM;
- tib_decref (temp);
- return NULL;
- }
-
- if (!is_int (exp))
- {
- tib_errno = TIB_EDOMAIN;
- tib_decref (temp);
- return NULL;
- }
-
- if (GSL_IMAG (exp))
- {
- tib_errno = TIB_ETYPE;
- tib_decref (temp);
- return NULL;
- }
-
- TIB *tempmat = tib_copy (temp);
- if (NULL == tempmat)
- {
- tib_decref (temp);
- return NULL;
- }
-
- for (i = 0; i < GSL_REAL (exp); ++i)
- {
- tib_errno = matrix_mul (temp->value.matrix, tempmat->value.matrix,
- t->value.matrix);
- if (tib_errno)
- break;
-
- tib_errno = gsl_matrix_complex_memcpy (tempmat->value.matrix,
- temp->value.matrix);
- if (tib_errno)
- break;
- }
-
- tib_decref (tempmat);
-
- if (tib_errno)
- {
- tib_decref (temp);
- return NULL;
- }
-
- return temp;
-
- default:
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ TIB *temp;
+
+ if (TIB_TYPE_COMPLEX != power->type)
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
+
+ gsl_complex exp = tib_complex_value(power);
+
+ if (less_than_0(exp))
+ {
+ temp = inverse(t);
+ exp = gsl_complex_negative(exp);
+ }
+ else
+ {
+ temp = tib_copy(t);
+ }
+
+ if (NULL == temp)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ size_t i;
+ switch (t->type)
+ {
+ case TIB_TYPE_COMPLEX:
+ temp->value.number = gsl_complex_pow(t->value.number, exp);
+ return temp;
+
+ case TIB_TYPE_LIST:
+ for (i = 0; i < t->value.list->size; ++i)
+ {
+ gsl_complex a = gsl_vector_complex_get(t->value.list,
+ i);
+ gsl_vector_complex_set(temp->value.list, i,
+ gsl_complex_pow(a, exp));
+ }
+ return temp;
+
+ case TIB_TYPE_MATRIX:
+ if (t->value.matrix->size1 != t->value.matrix->size2)
+ {
+ tib_errno = TIB_EDIM;
+ tib_decref(temp);
+ return NULL;
+ }
+
+ if (!is_int(exp))
+ {
+ tib_errno = TIB_EDOMAIN;
+ tib_decref(temp);
+ return NULL;
+ }
+
+ if (GSL_IMAG(exp))
+ {
+ tib_errno = TIB_ETYPE;
+ tib_decref(temp);
+ return NULL;
+ }
+
+ TIB *tempmat = tib_copy(temp);
+ if (NULL == tempmat)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ for (i = 0; i < GSL_REAL(exp); ++i)
+ {
+ tib_errno = matrix_mul(temp->value.matrix,
+ tempmat->value.matrix,
+ t->value.matrix);
+ if (tib_errno)
+ break;
+
+ tib_errno =
+ gsl_matrix_complex_memcpy(tempmat->value.matrix,
+ temp->value.matrix);
+ if (tib_errno)
+ break;
+ }
+
+ tib_decref(tempmat);
+
+ if (tib_errno)
+ {
+ tib_decref(temp);
+ return NULL;
+ }
+
+ return temp;
+
+ default:
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
}
TIB *
-tib_factorial (const TIB *t)
+tib_factorial(const TIB *t)
{
- if (t->type != TIB_TYPE_COMPLEX || GSL_IMAG (t->value.number))
- {
- tib_errno = TIB_ETYPE;
- return NULL;
- }
+ if (t->type != TIB_TYPE_COMPLEX || GSL_IMAG(t->value.number))
+ {
+ tib_errno = TIB_ETYPE;
+ return NULL;
+ }
- return tib_new_complex (gsl_sf_gamma (GSL_REAL (t->value.number) + 1), 0);
+ return tib_new_complex(gsl_sf_gamma(GSL_REAL(t->value.number) + 1), 0);
}
TIB *
-tib_toradians (const TIB *t)
+tib_toradians(const TIB *t)
{
- TIB *factor = tib_new_complex (3.141592653589793238462643383279502884 / 180,
- 0);
- if (!factor)
- return NULL;
+ TIB *factor = tib_new_complex(3.141592653589793238462643383279502884 / 180,
+ 0);
+ if (!factor)
+ return NULL;
- TIB *temp = tib_mul (t, factor);
- tib_decref (factor);
+ TIB *temp = tib_mul(t, factor);
+ tib_decref(factor);
- return temp;
+ return temp;
}
diff --git a/src/tibtype.h b/src/tibtype.h
index 68549b7..9361687 100644
--- a/src/tibtype.h
+++ b/src/tibtype.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015-2016 Delwink, LLC
+ * Copyright (C) 2015-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -27,96 +27,96 @@
#include "tibexpr.h"
enum tib_type
- {
- TIB_TYPE_NONE=0,
- TIB_TYPE_COMPLEX,
- TIB_TYPE_STRING,
- TIB_TYPE_LIST,
- TIB_TYPE_MATRIX
- };
+{
+ TIB_TYPE_NONE = 0,
+ TIB_TYPE_COMPLEX,
+ TIB_TYPE_STRING,
+ TIB_TYPE_LIST,
+ TIB_TYPE_MATRIX
+};
union variant
{
- gsl_complex number;
- char *string;
- gsl_vector_complex *list;
- gsl_matrix_complex *matrix;
+ gsl_complex number;
+ char *string;
+ gsl_vector_complex *list;
+ gsl_matrix_complex *matrix;
};
typedef struct
{
- enum tib_type type;
- union variant value;
- size_t refs;
+ enum tib_type type;
+ union variant value;
+ size_t refs;
} TIB;
TIB *
-tib_empty (void);
+tib_empty(void);
TIB *
-tib_copy (const TIB *t);
+tib_copy(const TIB *t);
void
-tib_incref (TIB *t);
+tib_incref(TIB *t);
void
-tib_decref (TIB *t);
+tib_decref(TIB *t);
TIB *
-tib_new_complex (double real, double imaginary);
+tib_new_complex(double real, double imaginary);
TIB *
-tib_new_str (const char *value);
+tib_new_str(const char *value);
TIB *
-tib_new_list (const gsl_complex *value, size_t len);
+tib_new_list(const gsl_complex *value, size_t len);
TIB *
-tib_new_matrix (const gsl_complex **value, size_t w, size_t h);
+tib_new_matrix(const gsl_complex **value, size_t w, size_t h);
enum tib_type
-tib_type (const TIB *t);
+tib_type(const TIB *t);
gsl_complex
-tib_complex_value (const TIB *t);
+tib_complex_value(const TIB *t);
const char *
-tib_str_value (const TIB *t);
+tib_str_value(const TIB *t);
const gsl_vector_complex *
-tib_list_value (const TIB *t);
+tib_list_value(const TIB *t);
const gsl_matrix_complex *
-tib_matrix_value (const TIB *t);
+tib_matrix_value(const TIB *t);
int
-tib_toexpr (struct tib_expr *dest, const TIB *src);
+tib_toexpr(struct tib_expr *dest, const TIB *src);
TIB *
-tib_add (const TIB *t1, const TIB *t2);
+tib_add(const TIB *t1, const TIB *t2);
TIB *
-tib_sub (const TIB *t1, const TIB *t2);
+tib_sub(const TIB *t1, const TIB *t2);
TIB *
-tib_mul (const TIB *t1, const TIB *t2);
+tib_mul(const TIB *t1, const TIB *t2);
TIB *
-tib_div (const TIB *t1, const TIB *t2);
+tib_div(const TIB *t1, const TIB *t2);
TIB *
-tib_pow (const TIB *t, const TIB *power);
+tib_pow(const TIB *t, const TIB *power);
TIB *
-tib_root (const TIB *t, gsl_complex root);
+tib_root(const TIB *t, gsl_complex root);
TIB *
-tib_factorial (const TIB *t);
+tib_factorial(const TIB *t);
TIB *
-tib_log (const TIB *t);
+tib_log(const TIB *t);
TIB *
-tib_toradians (const TIB *t);
+tib_toradians(const TIB *t);
#endif
diff --git a/src/tibvar.c b/src/tibvar.c
index f25061a..c3a3fae 100644
--- a/src/tibvar.c
+++ b/src/tibvar.c
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015 Delwink, LLC
+ * Copyright (C) 2015, 2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -24,127 +24,127 @@
struct varlist
{
- tib_Variable *vars;
- int len;
+ tib_Variable *vars;
+ int len;
};
-static struct varlist varlist =
- {
- .len = 0,
- .vars = NULL
- };
+static struct varlist varlist = {
+ .len = 0,
+ .vars = NULL
+};
int
-tib_var_init ()
+tib_var_init()
{
- int rc;
- TIB *t;
-
-#define ADD(K,V) \
- { \
- t = (V); \
- if (t) \
- { \
- rc = tib_var_set ((K), t); \
- tib_decref (t); \
- } \
- else \
- { \
- rc = tib_errno; \
- } \
- \
- if (rc) \
- goto end; \
- }
-
- ADD ('e', tib_new_complex (2.718281828459045235360287471352662498, 0));
- ADD (TIB_CHAR_PI,
- tib_new_complex (3.141592653589793238462643383279502884, 0));
+ int rc;
+ TIB *t;
+
+#define ADD(K,V) \
+ { \
+ t = (V); \
+ if (t) \
+ { \
+ rc = tib_var_set((K), t); \
+ tib_decref(t); \
+ } \
+ else \
+ { \
+ rc = tib_errno; \
+ } \
+ \
+ if (rc) \
+ goto end; \
+ }
+
+ ADD('e', tib_new_complex(2.718281828459045235360287471352662498, 0));
+ ADD(TIB_CHAR_PI,
+ tib_new_complex(3.141592653589793238462643383279502884, 0));
#undef ADD
end:
- return rc;
+ return rc;
}
void
-tib_var_free ()
+tib_var_free()
{
- for (int i = 0; i < varlist.len; ++i)
- tib_decref (varlist.vars[i].value);
+ for (int i = 0; i < varlist.len; ++i)
+ tib_decref(varlist.vars[i].value);
- free (varlist.vars);
+ free(varlist.vars);
- varlist.len = 0;
- varlist.vars = NULL;
+ varlist.len = 0;
+ varlist.vars = NULL;
}
static int
-add_var (int key, const TIB *value)
+add_var(int key, const TIB *value)
{
- tib_Variable *old = varlist.vars;
-
- ++varlist.len;
- varlist.vars = realloc (varlist.vars, varlist.len * sizeof (tib_Variable));
- if (NULL == varlist.vars)
- {
- varlist.vars = old;
- --varlist.len;
- return TIB_EALLOC;
- }
-
- tib_errno = 0;
- tib_Variable *new = varlist.vars + varlist.len - 1;
- new->key = key;
- new->value = tib_copy (value);
- if (tib_errno)
- --varlist.len;
-
- return tib_errno;
+ tib_Variable *old = varlist.vars;
+
+ ++varlist.len;
+ varlist.vars = realloc(varlist.vars,
+ varlist.len * sizeof(tib_Variable));
+ if (NULL == varlist.vars)
+ {
+ varlist.vars = old;
+ --varlist.len;
+ return TIB_EALLOC;
+ }
+
+ tib_errno = 0;
+ tib_Variable *new = varlist.vars + varlist.len - 1;
+ new->key = key;
+ new->value = tib_copy(value);
+ if (tib_errno)
+ --varlist.len;
+
+ return tib_errno;
}
int
-tib_var_set (int key, const TIB *value)
+tib_var_set(int key, const TIB *value)
{
- if (!tib_is_var (key))
- return add_var (key, value);
-
- for (int i = 0; i < varlist.len; ++i)
- {
- if (key == varlist.vars[i].key)
- {
- TIB *old = varlist.vars[i].value;
- varlist.vars[i].value = tib_copy (value);
- if (tib_errno)
- {
- varlist.vars[i].value = old;
- return tib_errno;
- }
-
- tib_decref (old);
- return 0;
- }
- }
-
- return TIB_EINDEX; /* should be unreachable */
+ if (!tib_is_var(key))
+ return add_var(key, value);
+
+ for (int i = 0; i < varlist.len; ++i)
+ {
+ if (key == varlist.vars[i].key)
+ {
+ TIB *old = varlist.vars[i].value;
+ varlist.vars[i].value = tib_copy(value);
+ if (tib_errno)
+ {
+ varlist.vars[i].value = old;
+ return tib_errno;
+ }
+
+ tib_decref(old);
+ return 0;
+ }
+ }
+
+ return TIB_EINDEX; // should be unreachable
}
TIB *
-tib_var_get (int key)
+tib_var_get(int key)
{
- for (int i = 0; i < varlist.len; ++i)
- if (key == varlist.vars[i].key)
- return tib_copy (varlist.vars[i].value);
+ for (int i = 0; i < varlist.len; ++i)
+ if (key == varlist.vars[i].key)
+ return tib_copy(varlist.vars[i].value);
- return tib_new_complex (0, 0);
+ return tib_new_complex(0, 0);
}
bool
-tib_is_var (int key)
+tib_is_var(int key)
{
- for (int i = 0; i < varlist.len; ++i)
- if (key == varlist.vars[i].key)
- return true;
+ for (int i = 0; i < varlist.len; ++i)
+ if (key == varlist.vars[i].key)
+ return true;
- return false;
+ return false;
}
diff --git a/src/tibvar.h b/src/tibvar.h
index 134ad1b..84bafa6 100644
--- a/src/tibvar.h
+++ b/src/tibvar.h
@@ -1,6 +1,6 @@
/*
* libtib - Read, write, and evaluate TI BASIC programs
- * Copyright (C) 2015 Delwink, LLC
+ * Copyright (C) 2015, 2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -24,23 +24,23 @@
typedef struct
{
- int key;
- TIB *value;
+ int key;
+ TIB *value;
} tib_Variable;
int
-tib_var_init (void);
+tib_var_init(void);
void
-tib_var_free (void);
+tib_var_free(void);
int
-tib_var_set (int key, const TIB *value);
+tib_var_set(int key, const TIB *value);
TIB *
-tib_var_get (int key);
+tib_var_get(int key);
bool
-tib_is_var (int key);
+tib_is_var(int key);
#endif
diff --git a/src/util.c b/src/util.c
index cfa7fc0..a54288d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -22,94 +22,93 @@
#include "util.h"
int
-load_expr (struct tib_expr *dest, const char *src)
+load_expr(struct tib_expr *dest, const char *src)
{
- unsigned int len = strlen (src);
- for (unsigned int i = 0; i < len; ++i)
- {
- int rc = tib_expr_push (dest, src[i]);
- if (rc)
- return rc;
- }
+ unsigned int len = strlen(src);
+ for (unsigned int i = 0; i < len; ++i)
+ {
+ int rc = tib_expr_push(dest, src[i]);
+ if (rc)
+ return rc;
+ }
- return 0;
+ return 0;
}
int
-load_expr_num (struct tib_expr *dest, const char *src)
+load_expr_num(struct tib_expr *dest, const char *src)
{
- int rc = load_expr (dest, src);
- if (rc)
- return rc;
+ int rc = load_expr(dest, src);
+ if (rc)
+ return rc;
- int e = tib_expr_indexof_r (dest, 'e');
- if (e >= 0)
- {
- tib_expr_delete (dest, e);
+ int e = tib_expr_indexof_r(dest, 'e');
+ if (e >= 0)
+ {
+ tib_expr_delete(dest, e);
- if ('+' == dest->data[e])
- dest->data[e] = TIB_CHAR_EPOW10;
- else
- rc = tib_expr_insert (dest, e, TIB_CHAR_EPOW10);
- }
+ if ('+' == dest->data[e])
+ dest->data[e] = TIB_CHAR_EPOW10;
+ else
+ rc = tib_expr_insert(dest, e, TIB_CHAR_EPOW10);
+ }
- return rc;
+ return rc;
}
const char *
-display_special_char (int c)
+display_special_char(int c)
{
- static const int SKIPS[] =
- {
- TIB_CHAR_DEGREE,
- TIB_CHAR_EPOW10,
- TIB_CHAR_GREATEREQUAL,
- TIB_CHAR_L1,
- TIB_CHAR_L2,
- TIB_CHAR_L3,
- TIB_CHAR_L4,
- TIB_CHAR_L5,
- TIB_CHAR_L6,
- TIB_CHAR_L7,
- TIB_CHAR_L8,
- TIB_CHAR_L9,
- TIB_CHAR_LESSEQUAL,
- TIB_CHAR_PI,
- TIB_CHAR_SMALL1,
- TIB_CHAR_SMALL2,
- TIB_CHAR_SMALL3,
- TIB_CHAR_SMALL4,
- TIB_CHAR_SMALL5,
- TIB_CHAR_SMALL6,
- TIB_CHAR_SMALL7,
- TIB_CHAR_SMALL8,
- TIB_CHAR_SMALL9,
- TIB_CHAR_SMALL_MINUS,
- TIB_CHAR_STO,
- TIB_CHAR_THETA
- };
+ static const int SKIPS[] = {
+ TIB_CHAR_DEGREE,
+ TIB_CHAR_EPOW10,
+ TIB_CHAR_GREATEREQUAL,
+ TIB_CHAR_L1,
+ TIB_CHAR_L2,
+ TIB_CHAR_L3,
+ TIB_CHAR_L4,
+ TIB_CHAR_L5,
+ TIB_CHAR_L6,
+ TIB_CHAR_L7,
+ TIB_CHAR_L8,
+ TIB_CHAR_L9,
+ TIB_CHAR_LESSEQUAL,
+ TIB_CHAR_PI,
+ TIB_CHAR_SMALL1,
+ TIB_CHAR_SMALL2,
+ TIB_CHAR_SMALL3,
+ TIB_CHAR_SMALL4,
+ TIB_CHAR_SMALL5,
+ TIB_CHAR_SMALL6,
+ TIB_CHAR_SMALL7,
+ TIB_CHAR_SMALL8,
+ TIB_CHAR_SMALL9,
+ TIB_CHAR_SMALL_MINUS,
+ TIB_CHAR_STO,
+ TIB_CHAR_THETA
+ };
- for (unsigned int i = 0; i < (sizeof SKIPS / sizeof (int)); ++i)
- if (SKIPS[i] == c)
- return NULL;
+ for (unsigned int i = 0; i < (sizeof SKIPS / sizeof(int)); ++i)
+ if (SKIPS[i] == c)
+ return NULL;
- return tib_special_char_text (c);
+ return tib_special_char_text(c);
}
char *
-get_expr_display_str (const struct tib_expr *expr)
+get_expr_display_str(const struct tib_expr *expr)
{
- return tib_expr_tostr_f (expr, display_special_char);
+ return tib_expr_tostr_f(expr, display_special_char);
}
int
-max (int x, int y)
+max(int x, int y)
{
- return (x > y) ? x : y;
+ return (x > y) ? x : y;
}
int
-min (int x, int y)
+min(int x, int y)
{
- return (x < y) ? x : y;
+ return (x < y) ? x : y;
}
diff --git a/src/util.h b/src/util.h
index b8898a7..d11b4e8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,6 +1,6 @@
/*
* LiberTI - TI-like calculator designed for LibreCalc
- * Copyright (C) 2016 Delwink, LLC
+ * Copyright (C) 2016-2017 Delwink, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,21 +21,21 @@
#include "tibexpr.h"
int
-load_expr (struct tib_expr *dest, const char *src);
+load_expr(struct tib_expr *dest, const char *src);
int
-load_expr_num (struct tib_expr *dest, const char *src);
+load_expr_num(struct tib_expr *dest, const char *src);
const char *
-display_special_char (int c);
+display_special_char(int c);
char *
-get_expr_display_str (const struct tib_expr *expr);
+get_expr_display_str(const struct tib_expr *expr);
int
-max (int x, int y);
+max(int x, int y);
int
-min (int x, int y);
+min(int x, int y);
#endif