source: projects/puncher/frontend.cli.c @ 9

Last change on this file since 9 was 9, checked in by sven, 11 years ago
  • Recreated Makefiles in visualisator/ and puncher/
  • All /visualisator/ sources now compile with -Wall compiler flag
  • The basic /puncher/ sources compile with -Wall, too.
  • Added Readme for schriften/

Current development is now focussed at /puncher/frontend.gtk.c.

-- Sven @ workstation

File size: 6.8 KB
RevLine 
[8]1/**
2 * The Paper Tape Project -- Punching subsystem
3 * CLI Frontend implementation
4 *
5 * This is a very simple cross-platform stand alone command
6 * line interface, with basic features (no [n]curses, etc.),
7 * like the old "userspace-driver" had them. This includes:
8 *
9 *  * Reading bytes from stdin and transfering to the backend
10 *  * Accepting some command line arguments for setting the file
11 *    size (how much bytes we can await at stdin) or switching
12 *    on DEBUG mode.
13 *  * Giving a very simple progress output: For every byte
14 *    one line.
15 *
16 * (c) 2008 Sven Köppel
17 *
18 **/
19
20#include <stdio.h>
21#include <stdlib.h>
[9]22#include <unistd.h> /* Problematisch auf Windows! (opterr, optarg, etc.) */
23#include <sys/time.h> /* gettimeofday -- unheimlich problematisch auf windows! */
[8]24#include <errno.h>
25#include <stdarg.h> /* var argument list */
26#include <math.h>
27
28#include "backend.h"
29
30#define DPRINTF(bla...) { if(debug_flag) fprintf(stderr,bla); }
31int debug_flag; /* global var. */
32
33void puncher_frontend_visualize_byte(unsigned char buf);
34void puncher_frontend_calculate_time(int already_punched_bytes, int estimated_punch_length, int mtime_since_beginning);
35
36// We need a portable function for this one!
37int puncher_frontend_mtime(long long since) {
38        /* gibt millisekunden zurueck seit since. since sind dabei die
39           Millisekunden seit der Unix-Epoche. Ein initiales since kann
40           per mtime(0) gefunden werden. */
41        struct timeval time;
42        gettimeofday(&time, NULL);
43              // Sec*10^6
44        return (time.tv_sec * 1000000 + time.tv_usec) - since;
45}
46
47int main(int argc, char **argv) {
48        long long time_since_beginning; // measuring time.
49        int already_punched = 0; // Anzahl bereits gepunchte bytes
50        int estimated_data_length = 0; // per Schalter -l angegebbare Datenlaenge
51        size_t ret; // multi purpose return value
52       
53        printf("The Paper Tape Project -- Punching subsystem\n");
54        printf("Cross Plattform Command line interface\n");
55        printf("time ms |123.45678|  hex=dec status: =) punch successful / :-( still busy\n");
56       
57        // Starting of parsing program arguments
58        debug_flag = 0;
59        opterr = 0;
60        int c;
61        while( (c = getopt(argc, argv, "dhl:s:")) != -1)
62            switch(c) {
63                case 'd':
64                    debug_flag = 1;
65                    break;
66                case 'h':
67                    fprintf(stderr, "Usage: %s [-d] [-h] [-lNUM]\n"
68                      "  optional parameters:\n"
69                      "   -d   debug mode, print out verbose informations about signals\n"
70                      "        if not set, only normal verbosity will be printed out on\n"
71                      "        stdout, painting an ASCII paper tape which visualizes the\n"
72                      "        bytes (see above for the caption)\n\n"
73                      "   -h   display this help message\n\n"
74                      "   -s   same as -l\n"
75                      "   -l   sets the NUMBER OF BYTES which are expected on stdin.\n"
76                      "        with this information we can complete the status information\n"
77                      "        with useful informations about the estimated remaining time\n"
78                      "        to punch (useful for longer data)\n"
79                      "        example: cat 2k-data-file | %s -l2000\n",
80                      argv[0], argv[0]);
81                    return 0;
82                case 'l':
83                case 's':
84                    c = atoi(optarg);
85                    if( c > 0 ) {
86                        estimated_data_length = c;
87                        break;
88                    }
89                    printf("%s: data length must be a positive integer, like '123', not %s\n", argv[0], optarg);
90                case '?': break;
91            }
92        // end of parsing program arguments
93
94        // initializing backend...
95        PuncherBackend* puncher;
96        if(! (puncher = puncher_backend_new(debug_flag)) ) {
97                perror("creating puncher backend");
98        }
99
100        /* The main loop (reading stdin and printing out) */
101        /* We will just read 1 byte at one time to handle
102         * it nicely... */
103        DPRINTF("Start reading from stdin...\n");
104        time_since_beginning = puncher_frontend_mtime(0);
105        for(;;) {
106                unsigned char buf; /* stdin 1 byte buffer */
107
108                ret = read(0, &buf, 1); /* 1 byte from stdin */
109                if(ret < 0) {
110                        perror("read stdin");
111                        puncher_backend_destroy(puncher);
112                        return 1;
113                }
114
115                if(ret == 0) {/* EOF, end of input, etc. */
116                        DPRINTF("stdin EOF\n");
117                        break;
118                }
119
120                /* Visualisation of the byte in a stdout line */
121                printf("%5ims ", (int)(puncher_frontend_mtime(time_since_beginning)/1000));
122                puncher_frontend_visualize_byte(buf);
123                printf(" 0x%02x=%03i ", buf, buf);
124                puncher_frontend_calculate_time(++already_punched, estimated_data_length, (int)(puncher_frontend_mtime(time_since_beginning)/1000));
125
126                /* call the backend */
127                ret = puncher_backend_write_byte(puncher, buf);
128                if(ret < 0) {
129                        perror("calling write backend");
130                        puncher_backend_destroy(puncher);
131                        return 1;
132                } else if(ret == 0) {
133                        printf("=)\n"); // everything okay
134                } else if(ret == 1) {
135                        printf(":-(\n"); // punch not okay, but go on.
136                }
137        } /* for stdin */
138
139        DPRINTF("Transmission finished\n");
140        if(puncher_backend_destroy(puncher)) {
141                perror("finishing backend");
142                return 1;
143        } else
144                return 0;
145}
146
147void puncher_frontend_visualize_byte(unsigned char buf) {
148        /* Draw a papertape byte (like the perl program) */
149        unsigned char against = 0x01;
150        unsigned char check;
151        int pos;
152       
153        printf("|");
154        for(pos=0; pos < 8; pos++) {
155                if(pos == 3) /* Streifenfuehrung */
156                        printf(".");
157                check = buf;
158                check >>= pos;
159               
160                if((check & against) == 0)
161                        printf(" "); /* bit nicht gesetzt */
162                else
163                        printf("*"); /* bit gesetzt */
164        } /*for */
165        printf("|");
166}
167
168
169void puncher_frontend_calculate_time(int already_punched_bytes, int estimated_punch_length, int mtime_since_beginning) {
170        /* In jeder Zeile berechnen, wie lange noch gepuncht wird,
171         * und ausgeben. Nur wenn Laenge per "-l" oder "-s" angegeben
172         * wird. In Bytes.
173         *
174         * Irgendwie ist der Berechnungsalgorithmus etwas schrottig und
175         * produziert in den ersten Sekunden nur Müll, aber ansonsten
176         * ist er ganz okay.
177         */
178        int percentage, remaining_sec = 0;
179         
180        if(!estimated_punch_length) return; // wenn es gar nicht abgegeben wurde
181       
182        //printf("%i %i ", already_punched_bytes, estimated_punch_length, mtime_since_beginning);
183       
184        percentage = (int)rint(((float)already_punched_bytes / (float)estimated_punch_length) * 100);
185        if(mtime_since_beginning != 0) // erst nach dem ersten Zyklus berechenbar
186            remaining_sec = (int)rint(((float)mtime_since_beginning / ((float)already_punched_bytes / (float)estimated_punch_length) - mtime_since_beginning)/1000);
187       
188        if(already_punched_bytes <= estimated_punch_length) {
189               printf("| %i%% (%i sec remaining)  ", percentage, remaining_sec);
190        }
191}
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License