Canola
0.8.D001
|
00001 // 00002 // canola - canon canola 1614p emulator 00003 // Copyright (C) 2011 Peter Miller 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License, version 3, as 00007 // published by the Free Software Foundation. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License along 00015 // with this program. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 #include <lib/ac/ctype.h> 00019 #include <lib/ac/stdio.h> 00020 #include <lib/ac/stdlib.h> 00021 #include <lib/ac/string.h> 00022 #include <lib/ac/unistd.h> 00023 #include <libexplain/fclose.h> 00024 #include <libexplain/fflush.h> 00025 #include <libexplain/fgets.h> 00026 #include <libexplain/fopen.h> 00027 #include <libexplain/output.h> 00028 #include <libexplain/program_name.h> 00029 #include <list> 00030 #include <string> 00031 00032 #include <lib/print_version.h> 00033 00034 00035 static void 00036 usage(void) 00037 { 00038 const char *prog = explain_program_name_get(); 00039 fprintf(stderr, "Usage: %s <filename>...\n", prog); 00040 fprintf(stderr, " %s -V\n", prog); 00041 exit(1); 00042 } 00043 00044 00045 static void 00046 grope(const char *filename) 00047 { 00048 FILE *fp = explain_fopen_or_die(filename, "r"); 00049 00050 { 00051 const char *cp = filename; 00052 while (cp[0] == 'b' && cp[1] == 'l') 00053 cp += 2; 00054 if (*cp == '/') 00055 filename = cp + 1; 00056 } 00057 00058 typedef std::list<std::string> lines_t; 00059 lines_t lines; 00060 00061 for (;;) 00062 { 00063 char line[2000]; 00064 if (!explain_fgets_or_die(line, sizeof(line), fp)) 00065 break; 00066 size_t len = strlen(line); 00067 while (len > 0 && isspace((unsigned char)line[len - 1])) 00068 --len; 00069 lines.push_back(std::string(line, len)); 00070 } 00071 explain_fclose_or_die(fp); 00072 00073 lines_t::const_iterator it = lines.begin(); 00074 int linum = 1; 00075 while (it != lines.end()) 00076 { 00077 const char *p = strstr(it->c_str(), "Ques" "tion:"); 00078 if (p) 00079 { 00080 p += 9; 00081 while (*p && isspace((unsigned char)*p)) 00082 ++p; 00083 if (*p) 00084 { 00085 printf("<li>\n"); 00086 printf("%s\n", p); 00087 printf("<br/>\n"); 00088 printf("<small>(file %s, line %d)</small>\n", filename, linum); 00089 } 00090 } 00091 else 00092 { 00093 p = strstr(it->c_str(), "<ques" "tion>"); 00094 if (p) 00095 { 00096 printf("<li>%s\n", p + 10); 00097 00098 lines_t::const_iterator ep = it; 00099 ++ep; 00100 for (;;) 00101 { 00102 if (ep == lines.end()) 00103 { 00104 explain_output_error_and_die 00105 ( 00106 "%s: %d: unterminated question", 00107 filename, 00108 linum 00109 ); 00110 } 00111 if (strstr(ep->c_str(), "</ques" "tion>")) 00112 break; 00113 const char *s = ep->c_str(); 00114 while (isspace((unsigned char)*s)) 00115 ++s; 00116 while (ispunct((unsigned char)*s)) 00117 ++s; 00118 while (isspace((unsigned char)*s)) 00119 ++s; 00120 if (*s) 00121 printf("%s\n", s); 00122 ++ep; 00123 } 00124 00125 printf("<br/>\n"); 00126 printf("<small>(file %s, line %d)</small>\n", filename, linum); 00127 } 00128 } 00129 ++it; 00130 ++linum; 00131 } 00132 } 00133 00134 00135 int 00136 main(int argc, char **argv) 00137 { 00138 for (;;) 00139 { 00140 int c = getopt(argc, argv, "V"); 00141 if (c == EOF) 00142 break; 00143 switch (c) 00144 { 00145 case 'V': 00146 print_version(); 00147 return 0; 00148 00149 default: 00150 usage(); 00151 } 00152 } 00153 if (optind == argc) 00154 usage(); 00155 00156 printf("<html>\n"); 00157 printf("<body>\n"); 00158 printf("<h1 align=\"center\">\n"); 00159 printf("<img src=\"canola.128.png\" align=\"left\" alt=\"\" />\n"); 00160 printf("<img src=\"canola.128.png\" align=\"right\" alt=\"\" />\n"); 00161 printf("<a href=\"index.html\" >Canola</a> Questions </h1>\n"); 00162 printf("Questions to be put to a real 1614P.\n"); 00163 printf("<p>\n"); 00164 printf("All these questions are with the decimal point dial\n"); 00165 printf("set to “F”, and the rounding switch set to\n"); 00166 printf("“5/4”.\n"); 00167 printf("<p>\n"); 00168 printf("The [SM3] notation means the [SM3~] key followed by the [3]\n"); 00169 printf("key, similarly for memories larger than 3, and similarly for\n"); 00170 printf("[+M<i>n</i>], [SM<i>n</i>], [CM<i>n</i>], and [RM<i>n</i>]\n"); 00171 printf("notations. Think of it as the opcode, rather than the key\n"); 00172 printf("sequence needed to produce the opcode.\n"); 00173 printf("<p>\n"); 00174 printf("<ol>\n"); 00175 for (;;) 00176 { 00177 grope(argv[optind++]); 00178 if (optind >= argc) 00179 break; 00180 } 00181 printf("</ol>\n"); 00182 printf("</body>\n"); 00183 printf("</html>\n"); 00184 00185 explain_fflush_or_die(stdout); 00186 00187 return 0; 00188 }