1|/*-----------------------------------------------------------------------------
     2| [src2html.c]
     3|        Implements a src --> html converter.
     4|
     5| Copyright (C) 2005 Ki
     6|
     7| This program is free software; you can redistribute it and/or modify
     8| it under the terms of the GNU General Public License as published by
     9| the Free Software Foundation; either version 2 of the License, or
    10| (at your option) any later version.
    11|
    12| This program is distributed in the hope that it will be useful,
    13| but WITHOUT ANY WARRANTY; without even the implied warranty of
    14| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15| GNU General Public License for more details.
    16|-----------------------------------------------------------------------------*/
    17|//#include <stdio.h>
    18|//#include <string.h>
    19|#include <ctype.h>
    20|
    21|#include "yacc_port.h"
    22|
    23|#include "printy.h"
    24|#include "malloc.h"
    25|#include "fopen.h"
    26|
    27|typedef  char           Sint8;
    28|typedef  unsigned char  Uint8;
    29|typedef  short          Sint16;
    30|typedef  unsigned short Uint16;
    31|typedef  long           Sint32;
    32|typedef  unsigned long  Uint32;
    33|
    34|typedef  int             BOOL;
    35|
    36|#define  TRUE           (1)
    37|#define  FALSE          (0)
    38|
    39|
    40|#define MAX_WORDLEN             256
    41|
    42|static char     _HtmlTitle[1024];
    43|
    44|static Uint32   _TabStop = 4;
    45|
    46|static Uint32   _PosX = 0;
    47|static Uint32   _LineNum = 1;
    48|
    49|static const char*      _pKeyWord[] = 
    50|{
    51| "#define",
    52| "#elif",
    53| "#else",
    54| "#endif",
    55| "#error",
    56| "#if",
    57| "#ifdef",
    58| "#ifndef",
    59| "#import",
    60| "#include",
    61| "#line",
    62| "#pragma",
    63| "#undef",
    64|
    65| "break",
    66| "case",
    67| "catch",
    68| "continue",
    69| "default",
    70| "delete",
    71| "do",
    72| "else",
    73| "for",
    74| "goto",
    75| "if",
    76| "new",
    77| "return",
    78| "switch",
    79| "try",
    80| "while",
    81|
    82| "typedef",
    83| NULL
    84|};
    85|
    86|
    87|static
    88|void
    89|tab_to_spaces(
    90| FILE*   pOut)
    91|{
    92| do
    93| {
    94|        fputc(' ', pOut);
    95|        ++_PosX;
    96| } while (_PosX % _TabStop != 0);
    97|}
    98|
    99|static
   100|void
   101|put_line_num(
   102| FILE*   pOut)
   103|{
   104| fprintf(pOut, "<b class=line>%6ld|</b>", _LineNum++);
   105|}
   106|
   107|
   108|
   109|/*
   110| 改行がきたら、ライン番号を+1したい。
   111| どのコードがきたら改行とみなすか?
   112|
   113| 改行コードは3通りある。
   114| 1. \r のみの場合
   115| 2. \r\n の場合
   116| 3. \n のみの場合
   117|
   118| \r\r ---- \r
   119| \r\n ---- \n
   120| \r?? ---- \r
   121| \n?? ---- \n
   122|
   123| \r がきたらとりあえず改行とみなす。
   124| 次に \n がきた場合、前のコードが \r でなければ改行とみなす。
   125|*/
   126|static
   127|void
   128|output_character(
   129| int            c,
   130| FILE*   pOut)
   131|{
   132| static int      cr = -1;
   133|
   134| switch (c)
   135| {
   136|        case '<':       fputs("&lt;", pOut);    ++_PosX; break;
   137|        case '>':       fputs("&gt;", pOut);    ++_PosX; break;
   138|        case '"':       fputs("&quot;", pOut);  ++_PosX; break;
   139|        case '&':       fputs("&amp;", pOut);   ++_PosX; break;
   140|        case ',':       fputs("&#44;", pOut);   ++_PosX; break;
   141|        case '\t':      tab_to_spaces(pOut);             break;
   142|        default: fputc(c, pOut);         ++_PosX;       break;
   143| }
   144|//TAK
   145|//Assume we are opening MSDOS FILE with binary read mode due to poor stdio I made.
   146| if (0)//TAK c == '\r')
   147| {
   148|        put_line_num(pOut);
   149|        _PosX = 0;
   150| }
   151| else if (c == '\n' && cr =='\r') //TAK != '\r')
   152| {
   153|        put_line_num(pOut);
   154|        _PosX = 0;
   155| }
   156|
   157| cr = c;
   158|}
   159|
   160|
   161|static
   162|void
   163|convert_single_line_comment(
   164| FILE*   pOut,
   165| FILE*   pIn)
   166|{
   167| int            c;
   168|
   169| fputs("<b class=comment>", pOut);
   170| output_character('/', pOut);
   171| output_character('/', pOut);
   172|
   173| while ((c = fgetc(pIn)) != EOF)
   174| {
   175|        if (c == '\r' || c == '\n')
   176|        {
   177|         fputs("</b>", pOut);
   178|         output_character(c, pOut);
   179|         break;
   180|        }
   181|        output_character(c, pOut);
   182| }
   183|}
   184|
   185|
   186|static
   187|void
   188|convert_multi_line_comment(
   189| FILE*   pOut,
   190| FILE*   pIn)
   191|{
   192| int            c;
   193|
   194| fputs("<b class=comment>", pOut);
   195| output_character('/', pOut);
   196| output_character('*', pOut);
   197|
   198| while ((c = fgetc(pIn)) != EOF)
   199| {
   200|        output_character(c, pOut);
   201|
   202|        // find end-of-comment
   203|        if (c == '*')
   204|        {
   205|         if ((c = fgetc(pIn)) == EOF)
   206|                break;
   207|
   208|         if (c == '/')
   209|         {
   210|                output_character(c, pOut);
   211|                break;
   212|         }
   213|         else
   214|         {
   215|                ungetc(c, pIn);
   216|         }
   217|        }
   218| }
   219|
   220| fputs("</b>", pOut);
   221|}
   222|
   223|
   224|static
   225|void
   226|convert_text_string(
   227| FILE*   pOut,
   228| FILE*   pIn)
   229|{
   230| int            c;
   231|
   232| fputs("<b class=string>", pOut);
   233| output_character('"', pOut);
   234|
   235| while ((c = fgetc(pIn)) != EOF)
   236| {
   237|        output_character(c, pOut);
   238|
   239|        // ignore escape sequences (\")
   240|        if (c == '\\')
   241|        {
   242|         if ((c = fgetc(pIn)) == EOF)
   243|                break;
   244|
   245|         output_character(c, pOut);
   246|         continue;
   247|        }
   248|
   249|        // find end-of-string
   250|        if (c == '"')
   251|         break;
   252| }
   253|
   254| fputs("</b>", pOut);
   255|}
   256|
   257|static
   258|void
   259|convert_char_const(
   260| FILE*   pOut,
   261| FILE*   pIn)
   262|{
   263| int            c;
   264|
   265| fputs("<b class=string>", pOut);
   266| output_character('\'', pOut);
   267|
   268| while ((c = fgetc(pIn)) != EOF)
   269| {
   270|        output_character(c, pOut);
   271|
   272|        // ignore escape sequences (\")
   273|        if (c == '\\')
   274|        {
   275|         if ((c = fgetc(pIn)) == EOF)
   276|                break;
   277|
   278|         output_character(c, pOut);
   279|         continue;
   280|        }
   281|
   282|        // find end-of-char-const
   283|        if (c == '\'')
   284|         break;
   285| }
   286|
   287| fputs("</b>", pOut);
   288|}
   289|
   290|
   291|static
   292|void
   293|convert_keyword(
   294| FILE*   pOut,
   295| FILE*   pIn)
   296|{
   297| int            c;
   298| char    buf[MAX_WORDLEN];
   299| int            i;
   300|
   301| i = 0;
   302|
   303| // get a word
   304| while ((c = fgetc(pIn)) != EOF)
   305| {
   306|        // break on any space characters
   307|        if (!isalnum(c) && c != '_' && c != '#')
   308|        {
   309|         ungetc(c, pIn);
   310|         break;
   311|        }
   312|
   313|        buf[i++] = c;
   314|        if (i == MAX_WORDLEN-1)
   315|         break;
   316| }
   317|
   318| buf[i] = '\0';
   319|
   320| // find a keyword
   321| i = 0;
   322| while (_pKeyWord[i] != NULL)
   323| {
   324|        if (strcmp(buf, _pKeyWord[i]) == 0)
   325|        {
   326|         int     j = 0;
   327|         // keyword found
   328|         fputs("<b class=keyword>", pOut);
   329|         while ((c = buf[j++]) != '\0')
   330|         {
   331|                output_character(c, pOut);
   332|         }
   333|         fputs("</b>", pOut);
   334|         return;
   335|        }
   336|        ++i;
   337| }
   338|
   339| // keyword not found; display as normal 
   340| i = 0;
   341| while ((c = buf[i++]) != '\0')
   342| {
   343|        output_character(c, pOut);
   344| }
   345|}
   346|
   347|
   348|static
   349|void
   350|convert(
   351| FILE*   pOut,
   352| FILE*   pIn)
   353|{
   354| int            c1;
   355| int            c2;
   356|
   357| while ((c1 = fgetc(pIn)) != EOF)
   358| {
   359|        // skip spaces (convert tabs to spaces if requested)
   360|        if (isspace(c1))
   361|        {
   362|         output_character(c1, pOut);
   363|        }
   364|        // find text string
   365|        else if (c1 == '"')
   366|        {
   367|         convert_text_string(pOut, pIn);
   368|        }
   369|        // find single-quoted char
   370|        else if (c1 == '\'')
   371|        {
   372|         convert_char_const(pOut, pIn);
   373|        }
   374|        // find comment
   375|        else if (c1 == '/')
   376|        {
   377|         if ((c2 = fgetc(pIn)) == EOF)
   378|         {
   379|                output_character(c1, pOut);
   380|                return;
   381|         }
   382|         
   383|         if (c2 == '/')
   384|                convert_single_line_comment(pOut, pIn);
   385|         else if (c2 == '*')
   386|                convert_multi_line_comment(pOut, pIn);
   387|         else
   388|         {
   389|                output_character(c1, pOut);
   390|                output_character(c2, pOut);
   391|         }
   392|        }
   393|        // find keyword
   394|        else if (isalpha(c1) || c1 == '_' || c1 == '#')
   395|        {
   396|         ungetc(c1, pIn);
   397|         convert_keyword(pOut, pIn);
   398|        }
   399|        else// if (isdigit(c1))
   400|        {
   401|         output_character(c1, pOut);
   402|        }
   403| }
   404| return;
   405|}
   406|
   407|
   408|static
   409|void
   410|output_html_header(
   411| FILE*          pFile,
   412| const char*    pTitle)
   413|{
   414| ASSERT(pFile);//TAK
   415| ASSERT(pTitle);//TAK
   416|//TAK   
   417|//      if (pFile == NULL)
   418|//       pFile = stdout;
   419|   
   420|   
   421| fputs("<html>\n", pFile);
   422| 
   423| fputs("<head>\n", pFile);
   424| fputs("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_Jis\">\n", pFile);
   425| fputs("<meta http-equiv=\"Content-Style-Type\" content=\"text/css\">\n", pFile);
   426|
   427| if (pTitle != NULL && strlen(pTitle) > 0)
   428|        fprintf(pFile, "<title>%s</title>\n", pTitle);
   429|
   430| fputs("<style type=\"text/css\">\n", pFile);
   431| fputs("<!--\n", pFile);
   432| fputs("b.keyword\n", pFile);
   433| fputs("{\n", pFile);
   434| fputs(" font-family:    \"FixedSys\", monospace;\n", pFile);
   435| fputs(" font-size:      1.0em;\n", pFile);
   436| fputs(" font-weight:    bold;\n", pFile);
   437| fputs(" background:     black;\n", pFile);
   438| fputs(" color:          white;\n", pFile);
   439| fputs(" line-height:    1.0;\n", pFile);
   440| fputs("}\n", pFile);
   441|
   442| fputs("\n", pFile);
   443| fputs("b.comment\n", pFile);
   444| fputs("{\n", pFile);
   445| fputs(" font-family:    \"FixedSys\", monospace;\n", pFile);
   446| fputs(" font-weight:    normal;\n", pFile);
   447| fputs(" background:     black;\n", pFile);
   448| fputs(" color:          lime;\n", pFile);
   449| fputs(" line-height:    1.0;\n", pFile);
   450| fputs("}\n", pFile);
   451|
   452| fputs("\n", pFile);
   453| fputs("b.string\n", pFile);
   454| fputs("{\n", pFile);
   455| fputs(" font-family:    \"FixedSys\", monospace;\n", pFile);
   456| fputs(" font-weight:    normal;\n", pFile);
   457| fputs(" background:     black;\n", pFile);
   458| fputs(" color:          cyan;\n", pFile);
   459| fputs(" line-height:    1.0;\n", pFile);
   460| fputs("}\n", pFile);
   461|
   462| fputs("\n", pFile);
   463| fputs("b.line\n", pFile);
   464| fputs("{\n", pFile);
   465| fputs(" font-family:    \"FixedSys\", monospace;\n", pFile);
   466| fputs(" font-weight:    normal;\n", pFile);
   467| fputs(" background:     black;\n", pFile);
   468| fputs(" color:          white;\n", pFile);
   469| fputs(" line-height:    1.0;\n", pFile);
   470| fputs("}\n", pFile);
   471|
   472| fputs("\n", pFile);
   473| fputs("pre\n", pFile);
   474| fputs("{\n", pFile);
   475| fputs(" font-family:    \"FixedSys\", monospace;\n", pFile);
   476| fputs(" font-size:      1.0em;\n", pFile);
   477| fputs(" background:     black;\n", pFile);
   478| fputs(" color:          #ccc;\n", pFile);
   479| fputs(" line-height:    1.0;\n", pFile);
   480| fputs(" border-width:   0.3em 0.3em;\n", pFile);
   481| fputs(" border-style:   solid solid;\n", pFile);
   482| fputs(" border-color:   black;\n", pFile);
   483| fputs(" margin-left:    2.0em;\n", pFile);
   484| fputs(" margin-right:   2.0em;\n", pFile);
   485| fputs("}\n", pFile);
   486| fputs("-->\n", pFile);
   487| fputs("</style>\n", pFile);
   488| fputs("</head>\n", pFile);
   489|}
   490|
   491|
   492|static
   493|void
   494|output_html_body(
   495| FILE*          pOut,
   496| FILE*          pIn)
   497|{
   498| fputs("<body>\n", pOut);
   499| fputs("<pre>\n", pOut);
   500|
   501| put_line_num(pOut);
   502| convert(pOut, pIn);
   503|
   504| fputs("</pre>\n", pOut);
   505| fputs("</body>\n", pOut);
   506|}
   507|
   508|
   509|static
   510|void
   511|output_html_footer(
   512| FILE*          pFile)
   513|{
   514| fputs("</html>\n", pFile);
   515|}
   516|
   517|
   518|
   519|BOOL
   520|SRC2HTML_Init(
   521| char*   filePathName)
   522|{
   523| return TRUE;
   524|}
   525|
   526|
   527|BOOL
   528|SRC2HTML_Deinit()
   529|{
   530| return TRUE;
   531|}
   532|
   533|
   534|void
   535|SRC2HTML_SetHtmlTitle(
   536| const char*    pTitle)
   537|{
   538| int    len;
   539|
   540| if (pTitle == NULL)
   541|        return;
   542|
   543| len = strlen(pTitle);
   544|
   545| if (len > sizeof(_HtmlTitle)-1)
   546|        len = sizeof(_HtmlTitle)-1;
   547|
   548| strncpy(_HtmlTitle, pTitle, len);
   549| _HtmlTitle[len] = '\0';
   550|}
   551|
   552|
   553|
   554|int
   555|main(
   556| int     argc,
   557| char**  argv)
   558|{
   559| char name[]="src2html.c";
   560| char name_binary[]="src2html.cb";
   561| char output_html[]="src2html.html";
   562| 
   563| FILE*   pIn;
   564| FILE*       pInBinary;
   565| FILE*       pOut;
   566| 
   567|
   568|
   569| 
   570| pIn=fopen(name,"rb");
   571| ASSERT(pIn);
   572| 
   573| 
   574|//Open write file       
   575| pOut=fopen(output_html,"wb");
   576| ASSERT(pOut);
   577| 
   578|
   579|
   580| SRC2HTML_SetHtmlTitle(name);//??
   581|        printf("output_html_header\n");
   582|
   583| output_html_header(pOut,name);
   584|         printf("output_html_body\n");
   585|
   586| output_html_body(pOut, pIn);
   587|                printf("output_html_footer\n");
   588|
   589| output_html_footer(pOut);
   590|
   591| fclose(pIn);
   592| fclose(pOut);
   593| print("$finish");
   594| return 0;
   595|}
   596|