Canola  0.8.D001
test_questions/main.cc
Go to the documentation of this file.
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 &ldquo;F&rdquo;, and the rounding switch set to\n");
00166     printf("&ldquo;5/4&rdquo;.\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 }