-
Notifications
You must be signed in to change notification settings - Fork 0
/
gyges.h
executable file
·1828 lines (1520 loc) · 86.2 KB
/
gyges.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*===============================[[ beg code ]]===============================*/
/*===[[ HEADER BEG ]]=========================================================*/
/* ´·········1·········2·········3·········4·········5·········6·········7*/
/*--------- 12345678901 ´123456789-123456789-123456789-123456789-123456789-123456789-123456789-*/
/*········· ··········· ´·····························´········································*/
#define P_NAME "gyges"
/*········· ··········· ´·····························´········································*/
#define P_FOCUS "TO (major tools)"
#define P_NICHE "ss (spreadsheet)"
#define P_SUBJECT "wicked technical spreadsheet"
#define P_PURPOSE "technical, fullsome, aesthetic, and keyboard-centric spreadsheet"
/*········· ··········· ´·····························´········································*/
#define P_NAMESAKE "gyges-hekatonkheires (hundred-handed)"
#define P_PRONOUNCE ""
#define P_HERITAGE "gyges, the furious, is one of the three hekatonkheires"
#define P_BRIEFLY "one-hundred handed monster"
#define P_IMAGERY "ugly, impossibly powerful, one-hundred handed, fifty headed giant"
#define P_REASON "gyges and spreadsheets are both impossibly scary and complex"
/*········· ··········· ´·····························´········································*/
#define P_ONELINE P_NAMESAKE " " P_SUBJECT
/*········· ··········· ´·····························´········································*/
#define P_HOMEDIR "/home/system/gyges.technical_spreadsheet"
#define P_BASENAME "gyges"
#define P_FULLPATH "/usr/local/bin/gyges"
#define P_SUFFIX "gyges"
#define P_CONTENT "spreadsheet data"
/*········· ··········· ´·····························´········································*/
#define P_SYSTEM "gnu/linux (powerful, ubiquitous, technical, and hackable)"
#define P_LANGUAGE "ansi-c (wicked, limitless, universal, and everlasting)"
#define P_COMPILER "gcc 11.3.0"
#define P_CODESIZE "large (appoximately 10,000 slocl)"
/*········· ··········· ´·····························´········································*/
#define P_DEPSTDC "stdio,stdlib,string,math,ctype,time,malloc"
#define P_DEPPOSIX "unistd,sys/time"
#define P_DEPCORE "yURG,yLOG,ySTR"
#define P_DEPVIKEYS "yMODE,yKEYS,yMACRO,ySRC,yFILE,yVIEW,yMAP,yCMD,yMARK"
#define P_DEPOTHER "yPARSE,yREGEX,yCALC,ySORT,yRPN,yEXEC"
#define P_DEPGRAPH "ncurses,yVICURSES"
#define P_DEPHEAD "yVIHUB_solo,yDLST_solo"
/*········· ··········· ´·····························´········································*/
#define P_AUTHOR "heatherlyrobert"
#define P_CREATED "2010-09"
/*········· ··········· ´·····························´········································*/
#define P_VERMAJOR "3.--, totally reworking to use yVIKEYS and yCALC"
#define P_VERMINOR "3.7-, moved to post-yVIHUB libraries"
#define P_VERNUM "3.7o"
#define P_VERTXT "found hidden, detailed cell creation issues and fixed/tested"
/*········· ··········· ´·····························´········································*/
#define P_PRIORITY "direct, simple, brief, vigorous, and lucid (h.w. fowler)"
#define P_PRINCIPAL "[grow a set] and build your wings on the way down (r. bradbury)"
#define P_REMINDER "there are many better options, but i *own* every byte of this one"
/*········· ··········· ´·····························´········································*/
/*--------- 12345678901 ´123456789-123456789-123456789-123456789-123456789-123456789-123456789-*/
/* ´·········1·········2·········3·········4·········5·········6·········7*/
/*===[[ HEADER END ]]=========================================================*/
/*
* spreadsheet
* presentation
* writing
* graphing/charting
* engineering/cad/vector
* drawing/paint/pixel
* note taking
* database
* project management
* todo/task management
* workflow
* data browser/hypercard
*
* signal processing
* computer vision
* simulation
* virtual reality/immersive
*
*
*/
#define P_DEFINE \
"as one of the major user-empowerment tools, spreadsheets allow ad-hoc,¦" \
"informal, low skill, quick, and evolving analysis and manipulation of any¦" \
"kind of data -- from massive tables to irregular and unclear collections.¦"
#define P_CURRENT \
"this is a fairly well-defined category of tool with a relatively stable¦" \
"interface and several major alternative products. while user experiences¦" \
"vary, major functions and features are broadly comparable across competitors.¦"
#define P_CONCERN \
"these tools have become overly complex, unwieldy, kitchen-sink tools that¦" \
"overlap with other major tools rather than complement them. spreadsheets in¦" \
"particular have become dangerous, error-prone replacements for real systems.¦"
#define P_ALTERNS "visicalc, lotus 123, excel, google, oocalc, gnumeric¦"
#define P_WHATFOR \
"i love spreadsheets. love them. but, in pursuit of market share, they have¦" \
"evolved into massive, complex, mouse-driven, productivity suckers that¦" \
"integrate poorly with other tools (anti-unix).¦"
#define P_DECISION \
"gonna make my own. crazy and unrealistic, but rewarding and sobering too.¦" \
"if you want to learn, pick blisteringly hard goals. my result will be¦" \
"keyboard-driven, scriptable, light, fast, and flexible.¦"
/*===[[ END_HEADER ]]=========================================================*/
/*===[[ END_HEADER ]]=========================================================*/
/*===[[ PURPOSE ]]============================================================*
* gyges is a light, clean, fast, and aesthetic consol-based spreadsheet
* that focuses on functionality, analysis, interfacing, scripting, and
* tailored usage rather than the modern trend of formatting, presentation,
* layout, and data storage. we are looking to "do one thing and do it well"
* in, hopefully, the best tradition of unix tools.
*
* in general, modern spreadsheet software has become the universal tool
* since it is all most people really learn and all business computers share.
* as a result, these applications have become positively huge, unwieldy
* monsters focused on being the one viable tool.
*
* gyges will specifically handle the following...
* - very rapid movement, editing, and manipulation in a vim-like manner
* - simple, editable, ascii-text file format (script creatable)
* - full set of core, basic functions such as in sc, oleo
* - dependency-graph calculation method to avoid issues (and learn)
* - compile calculations to byte-code for speed (and even more learning)
* - refactoring tools to prevent redundancy, mistakes, and inconsistencies
* - scriptable using the same commands as availabile interactively
* - accept data extracts into specific locations in the worksheet
* - write out a visual version for use as tables in other applications
* - ability to create files that oocalc and excel can pick up
* - transparent color console interface aesthetically matching our desktop
*
* gyges will NOT handle specialty needs like that are less common...
* - international support (who cares)
* - proportional fonts or any formatting other than color (no value)
* - graphing (that can be done in other specific tools)
* - import or export of special formats (like xls, etc.)
* - separate note entries (just confusing, put them right in a cell)
* - different cell heights, etc
* - no manual calculation option to turn off auto calcs (fast enough)
*
* gyges will additionally make some serious simplifying assumptions...
* - all numbers will be stored as doubles (flexible, but approximate)
* - spreadsheet cells will be allocated as needed, not upfront
*
*
*
* a key design decision is to recognize that data is not meant to be stored
* long-term in a spreadsheet. spreadsheets are for calculation and
* manipulation and therefore should focus on working with applicable extracts
* rather than the entire data set. we will be developing a database as well.
*
* a second key design decision is not to use a spreadsheet as a reporting and
* visualization mechanism. again, spreadsheets are for calculation and
* manipulation. there are better tools for final display that should really
* only receive a small, prepared set of data and go from there.
*
* finally, gyges is not meant to replace awk, it is meant to supplement it by
* being a much more interactive mechanism where theories can be tried out
* and analysis can be interactive. once the techniques for analysis and
* manipulation are finalized, awk or c programs should be used.
*
* the largest modern day caution must be that spreadsheets are dangerous,
* potentially misleading, almost entirely incapable of validation, and quite
* subject to data alteration and version control issues. everyone knows this
* but it doesn't stop spreadsheet prototypes from becoming the final
* solution. holy bloody cow.
*
* while it might seem peculiar, gyges will focus on being able to act as an
* interface and scriptable filter as well as a calculator replacement. it
* should be so easy that you would use it instead of any of the gui calculator
* tools. it should also be so useful and flexible that we will find new uses
* for it as a filter.
*
* AS ALWAYS, there are many stable, accepted, existing programs that have
* been built by better programmers and are likely superior in speed, size
* capability, and reliability; BUT, i would not have learned nearly as much
* using them, so i follow the adage
*
* TO TRULY LEARN> do not seek to follow in the footsteps of the men of old;
* seek what they sought ~ Matsuo Basho
*
* THE UNDERLYING IDEA is to use this build process to learn new programming
* capabilities and put additional pressure on me to improve my standards
* maintenance, and coding environment. just using programs and ideas does
* not lead to understanding -- so get in there and get messy ;
*
*/
/*===[[ HEADER GUARD ]]=======================================================*/
#ifndef YGYGES
#define YGYGES loaded
/*---(ansi-c standard)-------------------*/
#include <stdio.h> /* C_ANSI : strcpy, strlen, strchr, strcmp, ... */
#include <string.h> /* C_ANSI : printf, snprintf, fgets, fopen, ... */
#include <stdlib.h> /* C_ANSI : exit */
#include <math.h> /* C_ANSI : fabs, cos, sin, round, trunc, ... */
#include <ctype.h> /* C_ANSI : tolower, toupper, ... */
#include <time.h> /* C_ANSI : time, strftime, localtime */
#include <malloc.h> /* C_ANSI : malloc, free */
#include <signal.h>
/*---(posix standard)--------------------*/
#include <unistd.h> /* POSIX standard operating system API */
#include <sys/time.h> /* POSIX standard time access */
#include <make_curses.h> /* my standard curses headers */
/*---(defacto standard)------------------*/
#include <ncurses.h> /* CURSES : mvprintw, refresh, getch, ... */
/*---(custom core)-----------------------*/
#include <yURG.h> /* heatherly urgent processing */
#include <yLOG.h> /* heatherly program logging */
#include <ySTR.h> /* heatherly string processing */
/*---(custom vi-keys)--------------------*/
#include <yKEYS.h> /* heatherly vikeys key handling */
#include <yMODE.h> /* heatherly vikeys mode tracking */
#include <yMACRO.h> /* heatherly vikeys macro processing */
#include <ySRC.h> /* heatherly vikeys source editing */
#include <yCMD.h> /* heatherly vikeys command processing */
#include <yVIEW.h> /* heatherly vikeys view management */
#include <yMAP.h> /* heatherly vikeys location management */
#include <yFILE.h> /* heatherly vikeys content file handling */
#include <yMARK.h> /* heatherly vikeys search and marking */
#include <yVICURSES.h> /* heatherly vikeys curses handler */
#include <yX11.h> /* heatherly vikeys curses handler */
/*---(custom other)----------------------*/
/*> #include <yVAR.h> /+ CUSTOM : heatherly variable testing +/ <*/
#include <yREGEX.h> /* CUSTOM : heatherly regular expressions */
#include <yCALC.h> /* CUSTOM : heatherly interactive calculation */
#include <yPARSE.h> /* heatherly file reading and writing */
#include <ySORT.h> /* heatherly sorting library */
#include <yRPN.h> /* CUSTOM : heatherly infix to RPN conversion */
#include <yEXEC.h> /* heatherly job control */
/*---(custom constants only)-------------*/
#include <yDLST_solo.h> /* heatherly double-double-list */
#include <yVIHUB_solo.h>
#define PR static
#define PRIV static
/*===[[ TYPEDEFS : COMBINATIONS ]]============================================*/
/*---(basics)--------------------------*/
typedef signed char schar;
typedef unsigned char uchar;
typedef const char cchar;
typedef unsigned short ushort;
typedef const int cint;
typedef unsigned long long ullong;
/*---(library simplifications)---------*/
typedef struct tm tTIME;
/*---(data structures)-----------------*/
typedef struct cTAB tTAB;
typedef struct cNODE tNODE;
typedef struct cCELL tCELL;
typedef struct cDEP tDEP; /* inter-cell dependency */
typedef struct cCALC tCALC; /* cell calculation entry */
typedef struct cREG tREG; /* cut and paste registers */
typedef struct cHIST tHIST; /* undo-redo history */
typedef struct timespec tTSPEC;
/*===[[ CONSTANTS : LIMITS ]]=================================================*/
/*---(tabs)---------------------------*/
#define MAX_TABS 40
#define DEF_TABS 5
#define MIN_TABS 1
/*---(columns)------------------------*/
#define MAX_COLS 702
#define DEF_COLS 26
#define MIN_COLS 1
/*---(rows)---------------------------*/
#define MAX_ROWS 9999
#define DEF_ROWS 100
#define MIN_ROWS 1
/*---(cell width)---------------------*/
#define MAX_WIDTH 400
#define DEF_WIDTH 8
#define MIN_WIDTH 2
#define MAX_MERGE 10
/*---(cell height)--------------------*/
#define MAX_HEIGHT 4
#define DEF_HEIGHT 1
#define MIN_HEIGHT 1
/*---(registers)----------------------*/
#define DEF_FORMAT "??0--"
/*> extern char buf0 [LEN_RECD]; <*/
/*---(macros)-------------------------*/
/*---(run as)----------*/
#define RUN_USER 'i' /* running in user mode (ncurses) */
#define RUN_TEST '-' /* running as a test (no ncurses) */
/*---(mode)------------*/
/*> #define MACRO_OFF '-' /+ normal keyboard input +/ <*/
/*> #define MACRO_RUN 'M' /+ macro running with redisplay +/ <*/
/*> #define MACRO_DELAY 'D' /+ macro delay playback controls +/ <*/
/*> #define MACRO_PLAYBACK 'P' /+ macro under playback controls +/ <*/
/*> #define MACRO_RECORD 'r' /+ macro recording +/ <*/
/*---(conditions)------*/
/*> #define IF_MACRO_OFF if (my.macro_mode == MACRO_OFF ) <*/
/*> #define IF_MACRO_RUN if (my.macro_mode == MACRO_RUN ) <*/
/*> #define IF_MACRO_NOT_RUN if (my.macro_mode != MACRO_RUN ) <*/
/*> #define IF_MACRO_DELAY if (my.macro_mode == MACRO_DELAY ) <*/
/*> #define IF_MACRO_PLAYBACK if (my.macro_mode == MACRO_PLAYBACK ) <*/
/*> #define IF_MACRO_MOVING if (my.macro_mode == MACRO_RUN || my.macro_mode == MACRO_DELAY ) <*/
/*> #define IF_MACRO_NOT_PLAYING if (my.macro_mode == MACRO_OFF || my.macro_mode == MACRO_RECORD ) <*/
/*> #define IF_MACRO_PLAYING if (my.macro_mode != MACRO_OFF && my.macro_mode != MACRO_RECORD ) <*/
/*> #define IF_MACRO_RECORDING if (my.macro_mode == MACRO_RECORD ) <*/
/*> #define IF_MACRO_ON if (my.macro_mode != MACRO_OFF ) <*/
/*---(setting)---------*/
/*> #define SET_MACRO_OFF my.macro_mode = MACRO_OFF <*/
/*> #define SET_MACRO_RUN my.macro_mode = MACRO_RUN <*/
/*> #define SET_MACRO_PLAYBACK my.macro_mode = MACRO_PLAYBACK <*/
/*> #define SET_MACRO_DELAY my.macro_mode = MACRO_DELAY <*/
/*> #define SET_MACRO_RECORD my.macro_mode = MACRO_RECORD <*/
struct cACCESSOR {
/*---(files)----------------*/
char quiet; /* bool : 0=normal, 1=quiet */
int logger; /* log file so that we don't close it */
char btree; /* updates active (y/n) */
/*---(cell root)------------*/
tCELL *root;
/*---(keyboard macro)-------*/
char macro_mode; /* keyboard, macro, silent */
char macro_name; /* current macro name */
int macro_pos; /* step in current macro */
int macro_len; /* length of macro */
char macro_keys [LEN_RECD]; /* macro contents */
char macro_char; /* interpreted current char */
char macro_delay; /* time between steps */
/*---(layout)----------*/
char layout_formula; /* formula line display mode */
char layout_status; /* status line display mode */
char layout_command; /* command line display mode */
char message [LEN_RECD]; /* message line */
/*---(file hanndling)--*/
char f_loc [LEN_RECD]; /* specific file location */
char f_name [LEN_RECD]; /* full file name */
char f_title [LEN_RECD]; /* specific file base name */
int f_lines; /* file line number */
char f_recd [LEN_RECD]; /* current file record */
char f_type [LEN_RECD]; /* current record verb */
char f_vers; /* current record version */
/*---(reg/clip file)---*/
char f_clip [LEN_RECD]; /* register clip file */
/*---(current tab)-----*/
uchar start; /* tab start in reading file */
uchar ntab; /* number of worksheet tabs */
uchar ctab; /* current tab number */
tTAB *ptab; /* current tab pointer */
uchar tab1; /* tab of source */
uchar tab2; /* tab of destination */
/*---(current ool)-----*/
ushort ncol;
ushort ccol;
ushort bcol;
ushort ecol;
uchar froz_col;
ushort froz_bcol;
ushort froz_ecol;
/*---(current row)-----*/
ushort nrow;
ushort crow;
ushort brow;
ushort erow;
uchar froz_row;
ushort froz_brow;
ushort froz_erow;
/*---(horizontal size)----------------*/
int x_full; // total screen size in chars
int x_left; // number of chars for row labels to left
int x_right; // number of chars for text to right
int x_avail; // number of chars availible for cells
/*---(column working vars)------------*/
int col1; /* left side of range */
int col2; /* right side of range */
int col1_save; /* left side of range */
int col2_save; /* right side of range */
/*---(row vars)--------*/
int y_full; // total screen size in chars
int y_top; // number of chars for info/labels at top
int y_bottom; // number of chars for status/info at bottom
int y_avail; // number of chars availible for cells
/*---(row working vars)---------------*/
int row1; /* top side of range */
int row2; /* bottom side of range */
int row1_save; /* top side of range */
int row2_save; /* bottom side of range */
/*---(char vars)-------*/
int npos; /* number of characters in current cell */
int cpos; /* current position */
int bpos; /* beginning position in field */
int epos; /* ending position in field */
int apos; /* number of positions available for field */
/*---(marks)-----------*/
char mark_show; /* show temporary marks (y/n) */
/*---(registers)-------*/
char reg_curr;
/*---(count)-----------*/
/*> char repeat; /+ multiplier for normal keys +/ <*/
/*> char repeat_macro; /+ multiplier for macro execution +/ <*/
/*---(ncurses)---------*/
char info_win;
char menu;
char ball; /* agrios execution tracking */
char cagrios [LEN_LABEL]; /* current agrios position */
char reqs_list [LEN_RECD]; /* cell requires */
char deps_list [LEN_RECD]; /* cell depends */
char like_list [LEN_RECD]; /* cell likes */
char copy_list [LEN_RECD]; /* cell likes */
char rpn_list [LEN_RECD]; /* cell rpn contents */
char reg_list [LEN_RECD]; /* register contents */
char pros_plus [LEN_RECD];
char reqs_plus [LEN_RECD];
char keys [LEN_RECD]; /* current keystrokes */
/*---(done)------------*/
};
extern struct cACCESSOR my;
/*---(tabs)---------------------------*/
#define NTAB my.ntab
#define CTAB my.ctab
#define PTAB my.ptab
/*---(columns)------------------------*/
#define NCOL my.ncol
#define CCOL my.ccol
#define BCOL my.bcol
#define ECOL my.ecol
#define FR_COL my.froz_col
#define FR_BCOL my.froz_bcol
#define FR_ECOL my.froz_ecol
/*---(rows)---------------------------*/
#define NROW my.nrow
#define CROW my.crow
#define BROW my.brow
#define EROW my.erow
#define FR_ROW my.froz_row
#define FR_BROW my.froz_brow
#define FR_EROW my.froz_erow
#define G_INFO_NONE ' '
#define G_INFO_BUFS ','
#define G_INFO_MARK '\''
#define G_INFO_REGS '"'
#define G_INFO_TREG 't'
#define G_INFO_CELL 'c'
#define G_INFO_ERROR 'E'
#define G_INFO_LAYOUT 'L'
#define MAX_ERROR 10000
typedef struct cERROR tERROR;
struct cERROR {
tCELL *owner;
long when; /* timestamp of error reporting */
char phase; /* rpn, build, eval, display */
char step; /* step in phase */
char func [ 20]; /* function reporting issue */
char narg; /* particular arg ref */
char type; /* type of issue */
char desc [100]; /* fuller error message */
tERROR *next; /* next error for cell */
tERROR *prev; /* next error for cell */
tERROR *gnext; /* global error list next */
tERROR *gprev; /* global error list prev */
};
extern tERROR *herror; /* head */
extern tERROR *terror; /* tail */
extern int nerror; /* count */
#define PERR_RPN 'r'
#define PERR_BUILD 'b'
#define PERR_EVAL 'e'
#define PERR_DISP 'd'
#define TERR_OTHER '-'
#define TERR_ARGS 's'
#define TERR_ADDR 'a'
#define TERR_RANGE 'r'
#define TERR_FUNC 'f'
/*====================-----------------+------------------====================*/
/*===---- CELL DATA STRUCTURE ----===*/
/*====================-----------------+------------------====================*/
/*
*
* general discussion...
*
* first we lay in the most fundamental of the data structures, although it's
* not the most complex. a cell is simply a collection of characteristics,
* values, pointers to other data structures, and a fair amount of testing
* and debugging information which will aid you in verifying the code quality.
*
* there are a couple of simplifications used to keep the complexity down.
*
* first and foremost, the numeric value of the cell is stored as a double
* even if it is entered and displayed as another type. this allows the
* calculation code to be very streamlined. the only twist that adds is that
* all intermediates are also doubles and so rounding may be an issue at
* microscopic detail. not my concern for this project.
*
* second, as already stated, strings will only be allowed STR_MAX characters.
* this should not present an issue except if the spreadsheet is being used as
* a word processor, then you are on your own. it would be easy enough to
* make them of unlimited length if you so desire. they are stored as char
* pointers here anyway so the size won't change.
*
* a point of debate would be whether the cell data structure warrants a
* doublly linked list. don't care about the finer points as its not much
* harder, infintesimally slower to add cells, and gives me a very foregiving
* structure in case i make a mistake when altering the list.
*
* finally, some would feel that i don't need to keep a few things like the
* original length and printable version on the strucuture. also true, but i
* think they both simplify and speed the code with little loss of size.
* you can change it later if you like.
*
* on to the data structure. i have divided it into logical sections for
* documentation's sake. each section has comments that i hope are helpful.
* normally i would not do this as then i have to count on the compilier to
* to reorder the elements to optimize the storage space. i like doing all
* the work i can myself.
*
* i will not document the workings of the dependency, requirements,
* calculation, or cell linked lists here. i prefer that discussion to come
* with the code as it will be easier to see in context and digest. you'll
* have to trust me for now ;)
*
* and, just to get it out of the way, sometimes i use very short variable
* names where others whould make them much longer. personal choice. once
* you get the program working, feel free to tweak that as you so desire.
*
*
* actual data structure...
*
*/
struct cCELL {
/*---(location)-----------------------*/
char tab; /* which tab contains the cell */
short col; /* which column contains this cell */
short row; /* which row contains this cell */
uchar *label; /* label of the cell at its current location */
long key; /* label as a unique long (for sorting) */
/*---(source)-------------------------*/
uchar *source; /* unmodified input string just as user typed */
short len; /* length of input string */
/*---(result)-------------------------*/
uchar type; /* type of contents (program assigned) */
double v_num; /* cell contents translated to a numeric value */
uchar *v_str; /* cell contents translated to a string value */
/*---(formatting)---------------------*/
uchar align; /* alignment code */
uchar format; /* formatting/filler style */
uchar decs; /* number of decimals to be shown */
uchar unit; /* units for conversion */
uchar five; /* fifth characteristic (tbd) */
uchar *print; /* printable version of the cell */
uchar note; /* note for error, searching, etc */
/*---(calculation)--------------------*/
void *ycalc; /* connection to yCALC library */
/*---(master list)--------------------*/
uchar linked; /* 1=linked, 0=unlinked */
tCELL *m_prev; /* previous cell in doubly linked list */
tCELL *m_next; /* next cell in doubly linked list */
/*---(btree)--------------------------*/
tCELL *b_left; /* btree left branch */
tCELL *b_right; /* btree right branch */
/*---(ties to sheet)------------------*/
tNODE *C_parent; /* parent column */
tCELL *c_prev; /* prev in specific column */
tCELL *c_next; /* next in specific column */
tNODE *R_parent; /* parent row */
tCELL *r_prev; /* prev in specific row */
tCELL *r_next; /* next in specific row */
/*---(end)----------------------------*/
};
extern tCELL *hcell; /* head pointer for cell data structure */
extern tCELL *tcell; /* tail pointer for cell data structure */
extern tCELL *rcell; /* root pointer for tree operations */
extern int ncell; /* count of linked cells in data structure */
extern int acell; /* count of all cells */
#define LINKED 'y'
#define UNLINKED 'x'
#define UNHOOKED -1
#define G_TAB_FIXED 'f'
#define G_TAB_AUTO 'a'
#define G_TAB_MACRO 'm'
#define G_TAB_TABLE 't'
#define G_TAB_DATA 'd'
#define G_TAB_TYPES "fmtda"
#define G_TAB_LOCKED "FMTDA"
#define G_TAB_UNLOCK 'x'
#define G_TAB_LOCK 'X'
#define G_RESIZE_FIXED 'f'
#define G_RESIZE_MIN 'm'
#define G_RESIZE_AUTO 'a'
#define G_RESIZE_MAX '*'
#define G_RESIZE_NADA '-'
#define NCEL ncell
#define ACEL acell
/*====================-----------------+------------------====================*/
/*===---- ROW & COL DATA STRUCTURES ----===*/
/*====================-----------------+------------------====================*/
/*
*
* general discussion...
*
* second, in order to define the tab/sheet data structure, we must first
* define the information to be stored about the rows and columns.
*
* for columns, the simple one is column width. for easing the program and
* speeding refreshes, it is valuable to store the column label as converted
* from the index, i.e., column 0 is A, 3 is C, and 26 is AA. this only need
* be figured out once and the reused each time. additionally, we'll store
* the screen position as well to speed display.
*
* for rows, this initial version will not allow multi-line rows which are
* only really handy for entering gobs of text -- not our intent. also, the
* screen labels are the numbers themselves, so the only valuable piece of
* information we need at this point is the screen position for each row.
*
* to conserve a little room, i assumed that there would never be a cell wider
* that 255 characters (uchar).
*
*
* actual data structures...
*
*/
struct cNODE {
uchar type; /* 'c' column vs 'r' row */
uchar tab; /* number of tab */
ushort ref; /* sequential identifier */
uchar size; /* size */
tNODE *N_prev; /* prev col/row on tab */
tNODE *N_next; /* next col/row on tab */
ushort count; /* count of cells in col/row */
tCELL *n_head; /* first used/real cell in col/row */
tCELL *n_tail; /* last/bottom used/real cell in col/row */
};
/*====================-----------------+------------------====================*/
/*===---- TAB DATA STRUCTURE ----===*/
/*====================-----------------+------------------====================*/
/*
*
* general discussion...
*
* third we define the overarching tab/sheet data structure that provides
* the iconic spreadsheet feel to the program. a tab is simply a name
* associated with a retangle of potenial cells and a set of basic
* characteristics, such as width and height.
*
* the formost simplification is that a retangular matrix of cell pointers
* is created from the get go rather than using a clever data structure that
* conserves more memory. while it only allocates pointers, that's still a
* great deal of space that will never get used. but, on the performance
* side, a two-dimensional array provides direct access without any need to
* search a data structure, no matter how efficient. it also provides a very
* efficient means of conducting operations on visual ranges like columns,
* rows, and retangular selections. i think its well worth it -- you can
* adapt it in the long run if you wish.
*
* just like the cell data structure, i have divided it into sections and
* provided a little commentary for each.
*
*
* actual data structure...
*
*/
struct cTAB {
/*---(header)-------------------------*/
/* tabs are pre-allocated and can put into and taken out of use simply by */
/* starting to use them. */
uchar tab; /* number of tab */
uchar abbr; /* abbreviation of tab */
uchar *name; /* tab name for user reference */
uchar type; /* tab type */
/*---(columns)------------------------*/
tNODE *C_head;
tNODE *C_tail;
ushort C_count;
ushort ncol; /* current limit on cols */
ushort ccol; /* current column */
ushort bcol; /* beginning column */
ushort ecol; /* ending column */
uchar froz_col; /* are the cols frozen */
ushort froz_bcol; /* left of frozen cols */
ushort froz_ecol; /* right of frozen cols */
/*---(rows)---------------------------*/
tNODE *R_head;
tNODE *R_tail;
ushort R_count;
ushort nrow; /* current limit on rows */
ushort crow; /* current row */
ushort brow; /* beginning row */
ushort erow; /* ending row */
uchar froz_row; /* are the rows frozen */
ushort froz_brow; /* top of frozen rows */
ushort froz_erow; /* bottom of frozen rows */
/*---(overall)------------------------*/
uint count; /* count of entries in sheet */
/*---(end)----------------------------*/
};
extern tTAB *p_tab; /* current tab pointer */
/*
* calculation types
* f = function call
* n = constant number
* l = constant string literal
* s = string from another cell source field
* m = string from another cell modified field
* v = value from another cell value field
*/
/*> struct cCALC { <*
*> char t; /+ type of calculation element +/ <*
*> double v; /+ numeric literal +/ <*
*> char *s; /+ string literal +/ <*
*> tCELL *r; /+ pointer to a cell +/ <*
*> void (*f) (void); /+ function pointer +/ <*
*> tCELL *p; /+ pointer to parent +/ <*
*> tCALC *n; /+ pointer to next calc +/ <*
*> }; <*/
/*
* selection modes...
*
* selection mode SEL_FROM treats the starting point as fixed and the range
* revolves around it to the current point. this is the traditional
* spreadsheet selection method.
*
* selection mode SEL_CUM will grow the range in any direction you move by
* adjusting either the starting or ending of the selection as necessary.
* this method allows the selection to grow easily in any direction.
*
* selection mode SEL_3D is unimplemented, but would allow the selection to
* grow just like SEL_FROM, but also range across tabs to form a cube of data.
* this is not that complicated, but needs a real reason to be done.
*
* selection mode SEL_NONE essentially means that the selection is not live
* and is the default value.
*
*/
/*
* communication value to represent the end of processing a selection range
* used by range actions and formulas
*
*/
#define VISU_FROM 'f'
#define VISU_CUM 'c'
#define VISU_3D '3'
#define VISU_NONE '-'
/*
*
*
*/
extern tCELL denada;
#define DONE_DONE &denada
/*---(layout_formula)--------------------*/
#define G_FORMULA_TINY 't' /* top line shows only source */
#define G_FORMULA_SMALL 's' /* top line shows very little but source */
#define G_FORMULA_DEBUG 'n' /* top line has lots of stuff to debug */
/*---(layout_status)---------------------*/
#define G_STATUS_HIDE ' '
#define G_STATUS_FILE 'f'
#define G_STATUS_TAB 'T'
#define G_STATUS_RPN 'r'
#define G_STATUS_DEPS 'd'
#define G_STATUS_REGS '"'
#define G_STATUS_TREG 't'
#define G_STATUS_MARK 'm'
#define G_STATUS_CELL 'C'
#define G_STATUS_KEYLOG 'K'
#define G_STATUS_HISTORY 'H'
#define G_STATUS_MODELIST 'M'
#define G_STATUS_ERRORS 'E'
#define G_STATUS_BUFFER 'B'
#define G_STATUS_VISUAL 'V'
/*---(layout_command)--------------------*/
#define G_COMMAND_SHOW 's'
#define G_COMMAND_HIDE 'h'
#define G_COMMAND_FLOAT 'f'
#define MENU_NONE ' '
#define MENU_ROOT '-'
extern int save;
#define FILE_BUF "/var/run/buffer.gyges"
#define FILE_EXIM YSTR_CLIP
extern FILE *g_clip;
/*> extern char f_maker [LEN_RECD]; <*/
/*---(strchr validation strings)-----------*/
extern char *g_alpha;
extern char *g_rcnum;
extern char *g_rcops;
typedef struct cCURR tCURR;
struct cCURR {
uchar type;
uchar label [LEN_LABEL];
char tab;
short col;
short row;
short len;
uchar align;
uchar format;
uchar decs;
uchar unit;
};
extern tCURR g_curr;
extern char g_contents [LEN_RECD];
extern char message [LEN_RECD];
extern char sta_error;
extern char special;
extern char *g_tbd;
extern char ver_ctrl;
extern char ver_num [10];
extern char ver_txt [100];
extern int row_formula;
extern int row_main;
#define K_DONE -1
#define K_CTRL_B 2
#define K_CTRL_C 3
#define K_CTRL_E 5
#define K_CTRL_F 6
#define K_CTRL_L 12
#define K_CTRL_S 19
extern char unit_answer [LEN_FULL];
/*===[[ PROTOTYPES ]]=====================================*/
/*===[[ gyges_prog.c ]]=======================================================*/
/*··········>·······················>·········································*/
/*---(support)--------------*/
char PROG_usage (void);
char* PROG_version (void);
void PROG__signal (int a_signal, siginfo_t *a_info, char *a_name, char *a_desc);
/*---(preinit)--------------*/
char PROG_urgents (int a_argc, char *a_argv []);
/*---(startup)--------------*/
char PROG__init (int a_argc, char *a_argv []);
char PROG__args (int a_argc, char *a_argv []);
char PROG__begin (void);
char PROG_startup (int a_argc, char *a_argv []);
/*---(execution)------------*/
char PROG_dawn (void);
char PROG_dusk (void);
/*---(shutdown)-------------*/
char PROG__end (void);
char PROG_shutdown (void);
/*---(unittest)-------------*/
char PROG__unit_loud (void);
char PROG__unit_quiet (void);
char PROG__unit_end (void);
char PROG__unit_cleanse (void);
/*---(from s.c)----------------------------*/
char PROG_cleanse (void);
char PROG__end (void);
char PROG_bigdump (void *a_file);
/*> char PROG_main_input (char a_mode, char a_key); <*/
/*> char PROG_main_handle (char a_key); <*/
/*> char PROG_main_string (char *a_keys); <*/
/*> char PROG_layout_init (void); <*/
/*> char PROG_layout_set (char *a_who, char *a_cat, char *a_opt); <*
*> char PROG_layout_list (char *a_who); <*
*> char PROG_layout_entry (int a_num, char *a_line); <*
*> char PROG_layout_formula (char *a_opt); <*
*> char PROG_layout_status (char *a_opt); <*
*> char PROG_layout_command (char *a_opt); <*
*> char PROG_layout_layout (char *a_opt); <*/
char *PROG__unit (char *a_question, void *a_thing);
char PROG__testing (void);
/*===[ GYGES_VISU.C ]]========================================================*/
/*---(init)-----------------*/
char VISU_init (void);
char VISU_clear (void);
/*---(history)--------------*/
char VISU_save (void);
char VISU_restore (void);
/*---(setting)--------------*/
char VISU_start (int a_tab, int a_col, int a_row, char a_mode);
char VISU_increase (int a_tab, int a_col, int a_row);
char VISU_update (int a_tab, int a_col, int a_row);
char VISU_set (int a_tab, int a_bcol, int a_brow, int a_ecol, int a_erow);
char VISU_mark (void);
char VISU_reverse (void);