#include <stdio.h>
#include <string.h>

#include "instructions.h"
#include "motsJS.h"
/*
    instructions.h contient les types, expressions, et mots clés API GoogleMaps V3:
        il contient les tableaux INSTR,TYPES,MOTS,APIEXT.

    motsJS.h est la base qui contient tous les mots/objets/prop/méthodes/titres/liens/infos.
    C'est une référence Javascript (sans API obsolètes, mais incomplète pour l'instant).
    Il contient le gros tableau FONCS.
    
    Ce tableau est trié, puis les doublons éliminés pour généner un fichier h qui sera
    chargé par le baliseur Javascript. (Le C génère du C!)

    Souci: plus le gros tableau FONCS est grand, plus la vitesse chute (900 o/s).
    Pour accélérer les traitements, FONCS est divisé en plusieurs tableaux.

    Ce préprocesseur génère donc, à partir de motsJS.h, 8 fichiers:

        1 fonctionsJS.html        sortie standard. pour publication

        Les tableaux sans descriptions ni doublons, optimisés pour comparaisons
        2 mots.h          FILE* fm            tableaux INSTR,TYPES,MOTS,APIEXT
            c'est instructions.h réécrit sans commentaires, et 8 items par ligne.
            utilisé pour l'affichage. pas besoin de les réécrire non?
        3 mots-Mb.h          FILE* fp0            Ponctuation, Majucule, a et b
        4 mots-ce.h                fp1            de c à e
        5 mots-fi.h                fp2            de f à i
        6 mots-jn.h                fp3            de j à n
        7 mots-or.h                fp4            de o à r
        8 mots-sz.h                fp5            de s à z

    Le baliseur Javascript inclut ces en-têtes qui ne contiennent que des tableaux initialisés,
    et regarde la 1re lettre du mot à comparer. Si c'est fprintf il compare au tableau mots-fi
    qui contient 200 mots, au lieu de comparer à FONCS qui en contient 1400.
    Et ça marche: la vitesse est remontée au taquet.

    Commentaires des tableaux C
        En C on ne peut pas initialiser un tableau multidimensionnel, il faut faire calloc().
        J'utilise donc certains éléments du tableau pour décrire et mettre en forme.
        Tout ce qui commence par slash est considéré comme commentaire et non obj/prop/methode/fonction.

            /1titre <h1>
            /2titre <h2>
            //Info:
            //Objets
            //Propriétés
            //Méthodes (parfois sans S, il ne regarde que la 1re lettre)
            //Fonctions
            /uhttps://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux
            /objet
            /A API
            /I Interface
            sinon objet, prop ou méthode/fonction
*/

int main()
{
    int n = 0; 
    int total = 0; // nombre de tests effectués sur chaque char (nb de mots)

    printf( "<meta charset=\"utf-8\"/>"\
            "<title>Javascript: mots réservés, objets, propriétés, méthodes</title>\n"\
            "<style>\n"\
            ".code\n"\
            "{\n"\
            "    background: #fff;\n"\
            "    border: solid 1px #aaaaff;\n"\
            "    padding: 0.5em;\n"\
            "    -webkit-border-radius: 10px;\n"\
            "    -moz-border-radius: 10px;\n"\
            "    border-radius: 10px;\n"\
            "    box-shadow: 0px 0px 10px grey;\n"\
            "}\n"\
            ".js span.mot{color:#a52a2a; font-weight:bold}\n"\
            ".js span.type{color:#000080; font-weight:bold}\n"\
            ".js span.macro{color:#008b8b; font-weight:bold}\n"\
            ".js span.fonc {color:#a020f0; font-weight:bold}\n"\
            ".js span.api{color:orange; font-weight:bold}\n"\
            ".js span.c{color:#000;}\n"\
            "#info div span.fonc {color:#a020f0; font-weight:bold}\n"\
            "#info span.prop{color:#4A6789}\n"\
            "div.cols {\n"\
            "    -moz-column-count:7; /* Firefox */\n"\
            "    -webkit-column-count:7; /* Safari and Chrome */\n"\
            "    column-count:7;\n"\
            "    text-align: justify;\n"\
            "}\n"\
            "div.kcols {\n"\
            "    column-count:6;\n"\
            "}\n"\
            "h1 { color:black; }\n"\
            "h2 { color:black;font-size:14px; }\n"\
            "</style>\n"\
            "<script>\n"\
            "function v(id)\n"\
            "{\n"\
            "    var a = document.getElementById('obj'+id);\n"\
            "    document.getElementById('info').innerHTML = '<div class=\"kcols\">'+a.innerHTML+'</div>';\n"\
            "    return false;\n"\
            "}\n"\
            "</script>\n"\
            "\n<i>Cette page est générée par</i> <a href=\"web_fonctionsJS.c.html\">fonctionsJS.c</a>\n\n"\
            "<pre class=\"code js\"><div class=\"cols\">"\
            "<h3>%d instructions</h3><span class=\"mot\">\n", NBI);

    total += NBI;
    for (n=0;n<NBI;n++) {
        printf("%02d %s\n", n+1, MotsINSTR[n]);
    }

    printf( "</span></div></pre>\n\n"\
            "\n"\
            "<pre class=\"code js\"><div class=\"cols\">"
            "<h3>%d types</h3><span class=\"type\">\n", NBT);

    total += NBT;
    for (n=0;n<NBT;n++) {
        printf("%02d %s\n", n+1, MotsTYPES[n]);
    }

    printf( "</span></div></pre>\n\n"\
            "\n"\
            "<pre class=\"code js\"><div class=\"cols\">"
            "<h3>%d opérateurs et expressions</h3><span class=\"macro\">\n", NBM);

    total += NBM;
    for (n=0;n<NBM;n++) {
        printf("%02d %s\n", n+1, MotsMOTS[n]);
    }

    printf( "</span></div></pre>\n\n");

    // Tous les Objets, propriétés et méthodes
    // nombre complet avec noms d'objets inutiles
    NBF = sizeof(MotsFONCS)/sizeof(MotsFONCS[0]);

    printf( "<pre class=\"code js\">"\
            "<h3>Tous les Objets, propriétés et méthodes</h3>\n"\
            "<div class=\"cols\" style=\"column-count:7\"><span class=\"fonc\">\n"); 

    char flag=0; // soit on lit un nom d'objet 1, soit de Propriété 2, soit de Méthode/Fonc
    short id=0; // du div objet, display block/none

    for (n=0;n<NBF;n++) {
        if(MotsFONCS[n][0]=='/') {
            if (MotsFONCS[n][1]=='1') {
                if(flag > 0)  { printf("</div>\n"); flag=0; }
                printf("<h1>%s</h1>", MotsFONCS[n]+2);
            }
            else if(MotsFONCS[n][1]=='2') {
                if(flag > 0) { printf("</div>\n"); flag=0; }
                printf("<h2>%s</h2>", MotsFONCS[n]+2);
            }
            // nom d'objet ou API ou Interface
            else if(MotsFONCS[n][1]=='o'||MotsFONCS[n][1]=='A'||MotsFONCS[n][1]=='I') {
                if(flag > 0) { printf("</div>\n"); } flag=1;
                printf("<a href=\"#\" onclick=\"return v('%d');\">%s</a><div id=\"obj%d\" style=\"display:none\">",
                        id, MotsFONCS[n]+2, id);
                id++;
            }
            else if(MotsFONCS[n][2]=='I') { //Info:
                printf("\n<i>%s</i>\n", MotsFONCS[n]+3); //flag=2;
            }
            else if(MotsFONCS[n][2]=='O') { //Objets
                printf("\n<hr/><b style=\"color:black\">%s</b>\n", MotsFONCS[n]+2); flag=2;
            }
            else if(MotsFONCS[n][2]=='E') { //Evènements
                printf("\n<hr/><b style=\"color:black\">%s</b>\n", MotsFONCS[n]+2); flag=2;
            }
            else if(MotsFONCS[n][2]=='P') { //Propriétés
                printf("\n<hr/><b style=\"color:black\">%s</b>\n", MotsFONCS[n]+2); flag=2;
            }
            else if(MotsFONCS[n][2]=='M'||MotsFONCS[n][2]=='F') { // Méthode(s) ou Fonctions
                printf("\n<hr/><b style=\"color:black\">%s</b>\n", MotsFONCS[n]+2); flag=3;
            }
            else if(MotsFONCS[n][1]=='u') // /uhttps://www.
                printf(" <a href=\"%s\">Référence</a> ", MotsFONCS[n]+2);
        }
        else // ce n'est pas un commentaire. c'est un objet, prop ou méthode/fonction
        {
            if     (flag==1) printf("<h1>%s</h1>", MotsFONCS[n]); // objet
            else if(flag==2) printf("<span class=\"prop\">%s</span>\n", MotsFONCS[n]); // propriété
            else if(flag==3) printf("<span class=\"fonc\">%s()</span>\n", MotsFONCS[n]); // méthode/fonction
        }
    }
    if(flag > 0) printf("</div>");


    printf( "</span></div></pre>\n\n");
    // un div dessous
    printf("<pre class=\"code js\" id=\"info\"></pre>");




    // trie le tableau des fonctions
    char *tmp;
    int i, j;
    for(i=0; i<NBF; i++) {
        for(j=0; j<NBF; j++) {
            if(strcmp(MotsFONCS[i], MotsFONCS[j]) < 0) {
                tmp = MotsFONCS[i];
                MotsFONCS[i] = MotsFONCS[j];
                MotsFONCS[j] = tmp;
            }
        }
    }

    // affiche les objets/propriétés/méthodes sans doublons
    // génère les tableaux C optimisés sans descriptions ni doublons
    // Si ce n'est pas un commentaire spécial, ni un doublon,
    // regarde la 1re lettre. si majuscule écriture tableau1 etc

    short nbtabs = 7;
    static const char* tabs[] = {"Za","bc","dg","hn","oo","ps","tz"};
                   char   cpt[] = {0   ,0   ,0   ,0   ,0   ,0  , 0 };

    //short nbtabs = 11;
    //static const char* tabs[] = {"Za","bb","cc","df","gh","il","mn","oo","pr","ss","tz"};
    //               char   cpt[] = {0   ,0   ,0   ,0   ,0   ,0   ,0   ,0   ,0   ,0   , 0 };

    FILE* fp[nbtabs];

    printf( "\n<pre class=\"code\">Les %d tableaux (Code généré pour script de compilation et Javascript.c)\n\n", nbtabs);

    for (n=0; n<nbtabs; n++)
    {
        printf("DEL \"mots-%s.h\"\n", tabs[n]);
    }
    printf("\n");
    for (n=0; n<nbtabs; n++)
    {
        printf("#include \"mots-%s.h\"\n", tabs[n]);

        char f[10];
        sprintf(f,"mots-%c%c.h",tabs[n][0],tabs[n][1]);
        fp[n] = fopen(f,"w");

        char s[28];
        sprintf(s,"static const char *%c%c[]={\n\t",tabs[n][0],tabs[n][1]);
        fprintf (fp[n],"%s", s);
    }

    printf( "</pre>\n\n"\
            "<pre class=\"code js\">"\
            "<h3>Objets, propriétés méthodes et fonctions (triés, sans doublons)</h3>"\
            "<i>Mots utilisés pour les comparaisons. Répartis en %d tableaux pour des raisons de performances</i>\n"\
            "<div class=\"cols\"><span class=\"fonc\">\n", nbtabs);

    short nbfonc = 0;
    char numparligne = 8;
    for (n=0;n<NBF-1;n++) {
        if(MotsFONCS[n][0]!='/' && MotsFONCS[n]!=MotsFONCS[n+1])
        {
            printf("<span class=\"c\">%04d</span> %s\n", ++nbfonc, MotsFONCS[n]);

            // 11 tableaux de 100 mots environ
            //  7 tableaux de 200 mots environ
            // Fait le premier
            if(MotsFONCS[n][0] < 'b') {
                fprintf (fp[0], "\"%s\",",MotsFONCS[n]);
                if(++cpt[0]==numparligne) {fprintf(fp[0],"\n\t"); cpt[0]=0;}
            }
            else
            {
                for (i=1; i<nbtabs; i++)
                {
                    if (MotsFONCS[n][0] >= tabs[i][0] && MotsFONCS[n][0] <= tabs[i][1]) {
                        fprintf (fp[i], "\"%s\",",MotsFONCS[n]);
                        if(++cpt[i]==numparligne) {fprintf(fp[i],"\n\t"); cpt[i]=0;}
                    }
                }
            }
        }
    }

    total += nbfonc;

    for (i=0; i<nbtabs; i++)
    {
        fprintf (fp[i], "\n};\n");
        fclose(fp[i]);
    }


    printf( "</span></div></pre>\n"\
            "\n"\
            "<pre class=\"code js\"><div class=\"cols\">"
            "<h3>%d mots GoogleMaps API</h3><b><span class=\"api\">\n", NBA);
    total += NBA;
    for (n=0;n<NBA;n++) {
        printf("<span class=\"c\">%02d</span> %s\n", n+1, MotsAPIEXT[n]);
    }

    printf( "</span></div></pre>\n\n");
    printf( "<pre class=\"code js\">Le baliseur Javascript comparera donc chaque mot du fichier source à %d mots.\n"\
            "Mais il le fera de façon intelligente, et ne fera pas %d comparaisons!\n"\
            "\"Dive into Javascript\" et \"In Depth Javascript\" plongée en eaux obscures de Javascript</pre>", total,total);

    return 0;
}
fonctionsJS.c 305 lignes, 10732 octets. Balisé en 4.16 ms Vitesse : 2578 octets/ms