root/htags/cflowindex.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. makecflowindex

   1 /*
   2  * Copyright (c) 2010
   3  *      Tama Communications Corporation
   4  *
   5  * This file is part of GNU GLOBAL.
   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 3 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  * You should have received a copy of the GNU General Public License
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19  */
  20 #ifdef HAVE_CONFIG_H
  21 #include "config.h"
  22 #endif
  23 #include <ctype.h>
  24 #include <stdio.h>
  25 #ifdef STDC_HEADERS
  26 #include <stdlib.h>
  27 #endif
  28 #include "global.h"
  29 #include "htags.h"
  30 #include "path2url.h"
  31 #include "common.h"
  32 
  33 /**
  34  * makecflowindex: make call-tree based on @NAME{cflow}'s output
  35  *
  36  *      @param[in]      output          output file name
  37  *      @param[in]      cflow_file      input file which is the output of @NAME{Cflow} with @OPTION{--format=posix}
  38  */
  39 int
  40 makecflowindex(const char *output, const char *cflow_file)
  41 {
  42         STRBUF *input = strbuf_open(0);
  43         FILE *ip, *op;
  44         char *cflow_posix, *p;
  45         const char *m0 = "Gave up making call-tree because of illegal POSIX cflow format.";
  46         const char *m1 = "";
  47         const char *title = locatestring(output, "callee", MATCH_AT_FIRST) ? title_callee_tree : title_call_tree;
  48         int line = 0;
  49         int status = 0;
  50 #define ERROR   do { warning("%s\n%s:%d %s.", m0, cflow_file, line, m1); status = -1; goto finish; } while(0)
  51 
  52         /*
  53          * If syntax error occured then stop the jobs and return error status.
  54          * Don't die() because htags has already done a lot of work.
  55          */
  56         if ((ip = fopen(cflow_file, "r")) == NULL) {
  57                 warning("cannot open cflow file '%s'.", cflow_file);
  58                 return -1;
  59         }
  60         if ((op = fopen(makepath(distpath, output, NULL), "w")) == NULL) {
  61                 warning("cannot create file '%s'.", output);
  62                 fclose(ip);
  63                 return -1;
  64         }
  65         fputs_nl(gen_page_begin(title, TOPDIR), op);
  66         fputs_nl(body_begin, op);
  67         fputs(header_begin, op);
  68         fputs(gen_href_begin_simple(output), op);
  69         /* fputs(gen_href_begin(NULL, "cflow", normal_suffix, NULL), op);*/
  70         fputs(title, op);
  71         fputs(gen_href_end(), op);
  72         fputs_nl(header_end, op);
  73         fputs_nl(verbatim_begin, op);
  74         /*
  75          * Cflow's output format (with the --format=posix)
  76          * +----------------------------------------------------------------
  77          * |   25     isregex: int (const char *s), <libutil/char.c 54>...
  78          * |   32     func: 10
  79          * +----------------------------------------------------------------
  80          * cflow_posix
  81          * v
  82          *     25     isregex: int ...           , <libutil/char.c 54>...
  83          *     ^      ^                             ^              ^
  84          * anchor     name                         path           lineno
  85          *
  86          * cflow_posix
  87          * v
  88          *     32     func: 10
  89          *     ^      ^     ^
  90          * anchor     name  lineno
  91          */
  92         while ((cflow_posix = strbuf_fgets(input, ip, STRBUF_NOCRLF)) != NULL) {
  93                 char *anchor, *name, *path, *lineno;
  94                 char *anchor_end, *name_end, *path_end, *lineno_end;
  95 
  96                 anchor = name = path = lineno = anchor_end = name_end = path_end = lineno_end = NULL;
  97                 line++;
  98 
  99                 for (p = cflow_posix; *p && isspace(*p); p++)
 100                         ;
 101                 m1 = "line number at the head not found";
 102                 if (!*p || !isdigit(*p))
 103                         ERROR;
 104                 anchor = p;                                     /* anchor */
 105                 for (; *p && isdigit(*p); p++)
 106                         ;
 107                 if (!*p || !isspace(*p))
 108                         ERROR;
 109                 anchor_end = p;
 110                 /* seek to the function name */
 111                 for (; *p; p++) {
 112                         /* skip special characters of HTML like '&#09500;'*/
 113                         if (*p == '&') {
 114                                 for (p++; *p && *p != ';'; p++)
 115                                         ;
 116                                 if (*p != ';')
 117                                         ERROR;
 118                         } else if (isalpha(*p) || *p == '_')
 119                                 break;
 120                 }
 121                 m1 = "function name not found";
 122                 if (!*p || !isalpha(*p))
 123                         ERROR;
 124                 name = p;                                       /* name */
 125                 for (; *p && *p != ':'; p++)
 126                         ;
 127                 if (*p != ':')
 128                         ERROR;
 129                 name_end = p++;
 130                 if (*p++ != ' ')
 131                         ERROR;
 132                 if (isdigit(*p)) {                              /* (1) name: 999 */
 133                         lineno = p;                             /* lineno */
 134                         for (; *p && isdigit(*p); p++)
 135                                 ;
 136                         lineno_end = p;
 137                 } else if (*p == '<' && *(p + 1) == '>') {      /* (2) name: <> */
 138                         ;
 139                 } else {                                        /* (3) name: ... <path lineno> */
 140                         m1 = "<path lineno> not found";
 141                         for (; *p && *p != '<'; p++)
 142                                 ;
 143                         if (!*p++)
 144                                 ERROR;
 145                         path = p;
 146                         m1 = "path not found";
 147                         for (; *p && !isspace(*p); p++)
 148                                 if (*p == '>')
 149                                         ERROR;
 150                         if (!*p || *p != ' ')
 151                                 ERROR;
 152                         path_end = p++;
 153                         m1 = "lineno not found";
 154                         if (!isdigit(*p))
 155                                 ERROR;
 156                         lineno = p;
 157                         for (; *p && isdigit(*p); p++)
 158                                 ;
 159                         if (*p != '>')
 160                                 ERROR;
 161                         lineno_end = p;
 162                 }
 163                 /*
 164                  * print anchor
 165                  */
 166                 fprintf(op, gen_name_number(atoi(anchor)));
 167                 /*
 168                  * print until name
 169                  */
 170                 fwrite(cflow_posix, name - cflow_posix, 1, op);
 171                 /*
 172                  * print name
 173                  */
 174                 if (path) {
 175                         const char *fid = NULL;
 176                         int path_save = *path_end;
 177                         int lineno_save = *lineno_end;
 178 
 179                         *path_end = *lineno_end = 0;
 180                         if (test("f", path) && (fid = path2fid_readonly(path)) != NULL)
 181                                 fprintf(op, gen_href_begin(SRCS, fid, HTML, lineno));
 182                         else
 183                                 path = lineno = NULL;           /* not to print </a> */
 184                         *path_end = path_save;
 185                         *lineno_end = lineno_save;
 186                 } else if (lineno) {
 187                         int lineno_save = *lineno_end;
 188 
 189                         *lineno_end = 0;
 190                         fprintf(op, gen_href_begin(NULL, NULL, NULL, lineno));
 191                         *lineno_end = lineno_save;
 192                 }
 193                 fwrite(name, name_end - name, 1, op);
 194                 if (path || lineno)
 195                         fputs(gen_href_end(), op);
 196                 /*
 197                  * print the rest
 198                  */
 199                 for (p = name_end; *p; p++) {
 200                         if (*p == '<')
 201                                 fputs(quote_little, op);
 202                         else if (*p == '>')
 203                                 fputs(quote_great, op);
 204                         else
 205                                 fputc(*p, op);
 206                 }
 207                 fputc('\n', op);
 208         }
 209 finish:
 210         fputs_nl(verbatim_end, op);
 211         fputs_nl(body_end, op);
 212         fputs_nl(gen_page_end(), op);
 213         strbuf_close(input);
 214         fclose(ip);
 215         fclose(op);
 216         return status;
 217 }

/* [previous][next][first][last][top][bottom][index][help] */