#include #include "assert.h" #include #include "proto.h" /* Imprime une liste de token et collecte les commentaire retourne nombre de commentaire enregistre */ static int prtpar ( TOKEN_LIST *tokl, int (*fctprt) (char *ctl,...), char *lstcom[]) { int nbcom=0; TOKEN *last=NULL; TOKEN *tok; tokrec_descend (tokl); while ((tok = tokrec_get(tokl)) != NULL){ if (token_needsep(tok,last)) (*fctprt) (" "); (*fctprt) (token_txt(tok)); if (tok->type == TOK_OPNPAR) nbcom += prtpar (tokl,fctprt,lstcom+nbcom); if (tok->comment != NULL) lstcom[nbcom++] = tok->comment->texte; last = tok; tokrec_next (tokl); } tokrec_monte (tokl); return (nbcom); } static int format; /* Set le format de sortie pour la generation des declaration 0 = declaration moderne ANSI 1 = declaration K&R */ void cproto_setformat (int mode) { assert (mode==0||mode==1); format = mode; } static void prtcom ( char *lstcom[], int nbcom, int (*fctprt) (char *ctl,...)) /* fonction d'impression */ { if (nbcom == 0){ (*fctprt) ("\n"); }else{ int i; for (i=0; i debpt){ char tmp = *pt; *pt = '\0'; (*fctprt) ("\t%s\n",debpt); *pt = tmp; } if (*pt == '\n') pt++; } while (*pt != '\0'); } } } /* Balaye la liste des arguments a la recherche du nom du parametre et imprime chacun separe par une virgule */ static void near prtlstprm (TOKEN_LIST *tokl,int (*fctprt) (char *ctl,...)) { TOKEN *lastid = NULL; TOKEN *id = NULL; TOK_TYPE last = TOK_BIDON; TOK_TYPE last1 = TOK_BIDON; int niveau = 0; int nbitem = 0; while (1){ int nonext = 0; TOKEN *tok=tokrec_get(tokl); if (tok == NULL){ if (niveau > 0){ tokrec_monte (tokl); niveau--; }else{ break; } }else{ TOK_TYPE type = tok->type; nbitem++; if (niveau == 0 && type == TOK_VIRGULE){ if (id == NULL) id = lastid; assert (id!=NULL); (*fctprt) ("%s,",token_txt(id)); id = NULL; lastid = NULL; last = last1 = TOK_BIDON; }else if (id == NULL){ if (last == TOK_OPNPAR && type != TOK_STAR){ id = lastid; }else if (type == TOK_ID){ if (last == TOK_STAR && last1 == TOK_OPNPAR){ id = tok; }else{ lastid = tok; } }else if (type == TOK_OPNBRAK){ id = lastid; }else if (type == TOK_OPNPAR){ tokrec_descend (tokl); niveau++; nonext=1; } } last1 = last; last = type; } if (!nonext) tokrec_next (tokl); } if (nbitem > 2){ if (id == NULL) id = lastid; assert (id!=NULL); (*fctprt) ("%s",token_txt(id)); } (*fctprt) (")"); } static TOKEN *last; /* Imprime les paramètres d'une fonction et ses commentaires Retourne le nombre de commentaire accumulés dans lstcom[] */ static int near cproto_formparm ( TOKEN_LIST *tokl, char *lstcom[], int nocom, int (*fctprt) (char *ctl,...)) /* fonction d'impression */ { TOKEN *tok; int premtok = 1; char *sepvar = ","; char *clspar = ")"; if (format == 1){ sepvar = ";"; clspar = ";"; } do{ TOKCOM *comment; TOKEN *nxtlast; tok = tokrec_get(tokl); nxtlast = tok; comment = tok->comment; if (comment != NULL){ lstcom[nocom++] = comment->texte; } if (premtok){ prtcom (lstcom,nocom,fctprt); (*fctprt) ("\t"); premtok = 0; nocom = 0; } if (tok->type == TOK_VIRGULE){ (*fctprt) (sepvar); premtok = 1; nxtlast = NULL; }else if (tok->type == TOK_OPNPAR){ (*fctprt) ("("); nocom += prtpar (tokl,fctprt,lstcom+nocom); }else if (tok->type == TOK_CLSPAR){ (*fctprt) (clspar); }else{ if (token_needsep (tok,last)) (*fctprt) (" "); (*fctprt) (token_txt(tok)); } last = nxtlast; if (tokrec_next (tokl)==-1) break; } while (tok->type != TOK_CLSPAR); return nocom; } /* Génère prototype avec documentation. tokl contient un prototype "moderne". La presentation de ce prototype doit etre reorganiser Met un paramètre par ligne suivit d'un commentaire si requis. */ void cproto_format ( TOKEN_LIST *tokl, /* prototype a traiter */ int (*fctprt) (char *ctl,...), /* fonction d'impression */ int ret_fct, int operator_fct, int extern_C) { TOKEN *tok; int nbskippar = ret_fct ? 1 : 0; if (operator_fct) nbskippar++; last = NULL; tokrec_inilec (tokl); tok = tokrec_get (tokl); if (tok->comment != NULL){ char *txt = tok->comment->texte; while (*txt != '\0' && *txt < ' ') txt++; (*fctprt) ("%s\n",txt); } if (extern_C) (*fctprt)("extern \"C\" "); while(1){ tok = tokrec_get (tokl); if (tok->type == TOK_OPNPAR){ last = tok; (*fctprt) ("("); if (nbskippar > 0){ if (tokrec_descend (tokl)==-1) tokrec_next(tokl); nbskippar--; }else{ break; } }else{ if (token_needsep (tok,last)) (*fctprt) (" "); (*fctprt) (token_txt(tok)); tokrec_next (tokl); } last = tok; } tokrec_descend (tokl); if (format == 1){ /* si format K&R, imprime liste des parametre suivit d'un parenthese */ TOKEN_LIST tmp; tmp = *tokl; prtlstprm (&tmp,fctprt); } { char *lstcom[100]; int nocom = 0; nocom = cproto_formparm (tokl,lstcom,nocom,fctprt); tokrec_monte (tokl); if (tokrec_next(tokl)!=-1){ /* Il y a le mot clé const utilisé en C++ Ou une fonction qui retourne un pointeur de fonction */ if (ret_fct){ nocom = cproto_formparm (tokl,lstcom,nocom,fctprt); tokrec_monte (tokl); if (tokrec_next(tokl)!=-1){ nocom = cproto_formparm (tokl,lstcom,nocom,fctprt); } }else{ TOKCOM *comment; tok = tokrec_get (tokl); comment = tok->comment; if (comment != NULL){ lstcom[nocom++] = comment->texte; } if (token_needsep (tok,last)) (*fctprt) (" "); (*fctprt) (" %s\n",token_txt(tok)); } } prtcom (lstcom,nocom,fctprt); } }