Back to index

salome-paravis  6.5.0
vtkWrapText.c
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkWrapText.c
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 
00016 #include "vtkWrapText.h"
00017 #include "vtkWrap.h"
00018 #include <string.h>
00019 #include <ctype.h>
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 
00023 /* -------------------------------------------------------------------- */
00024 /* Convert special characters in a string into their escape codes
00025  * so that the string can be quoted in a source file.  The specified
00026  * maxlen must be at least 32 chars, and should not be over 2047 since
00027  * that is the maximum length of a string literal on some systems */
00028 
00029 const char *vtkWrapText_QuoteString(
00030   const char *comment, size_t maxlen)
00031 {
00032   static char *result = 0;
00033   static size_t oldmaxlen = 0;
00034   size_t i, j, n;
00035 
00036   if (maxlen > oldmaxlen)
00037     {
00038     if (result)
00039       {
00040       free(result);
00041       }
00042     result = (char *)malloc((size_t)(maxlen+1));
00043     oldmaxlen = maxlen;
00044     }
00045 
00046   if (comment == NULL)
00047     {
00048     return "";
00049     }
00050 
00051   j = 0;
00052 
00053   n = strlen(comment);
00054   for (i = 0; i < n; i++)
00055     {
00056     if (comment[i] == '\"')
00057       {
00058       strcpy(&result[j],"\\\"");
00059       j += 2;
00060       }
00061     else if (comment[i] == '\\')
00062       {
00063       strcpy(&result[j],"\\\\");
00064       j += 2;
00065       }
00066     else if (comment[i] == '\n')
00067       {
00068       strcpy(&result[j],"\\n");
00069       j += 2;
00070       }
00071     else if ((comment[i] & 0x80) != 0 || isprint(comment[i]))
00072       {
00073       // all characters in extended-ASCII set are printable. Some compilers (VS
00074       // 2010, in debug mode) asserts when isprint() is passed a negative value.
00075       // Hence, we simply skip the check.
00076       result[j] = comment[i];
00077       j++;
00078       }
00079     else
00080       {
00081       sprintf(&result[j],"\\%3.3o",comment[i]);
00082       j += 4;
00083       }
00084     if (j >= maxlen - 21)
00085       {
00086       sprintf(&result[j]," ...\\n [Truncated]\\n");
00087       j += (int)strlen(" ...\\n [Truncated]\\n");
00088       break;
00089       }
00090     }
00091   result[j] = '\0';
00092 
00093   return result;
00094 }
00095 
00096 /* -------------------------------------------------------------------- */
00097 /* A simple string that grows as necessary. */
00098 
00099 struct vtkWPString
00100 {
00101   char *str;
00102   size_t len;
00103   size_t maxlen;
00104 };
00105 
00106 /* -- append ---------- */
00107 static void vtkWPString_Append(
00108   struct vtkWPString *str, const char *text)
00109 {
00110   size_t n = strlen(text);
00111 
00112   if (str->len + n + 1 > str->maxlen)
00113     {
00114     str->maxlen = (str->len + n + 1 + 2*str->maxlen);
00115     str->str = (char *)realloc(str->str, str->maxlen);
00116     }
00117 
00118   strncpy(&str->str[str->len], text, n);
00119   str->len += n;
00120   str->str[str->len] = '\0';
00121 }
00122 
00123 /* -- add a char ---------- */
00124 static void vtkWPString_PushChar(
00125   struct vtkWPString *str, char c)
00126 {
00127   if (str->len + 2 > str->maxlen)
00128     {
00129     str->maxlen = (str->len + 2 + 2*str->maxlen);
00130     str->str = (char *)realloc(str->str, str->maxlen);
00131     }
00132 
00133   str->str[str->len++] = c;
00134   str->str[str->len] = '\0';
00135 }
00136 
00137 /* -- strip any of the given chars from the end ---------- */
00138 static void vtkWPString_Strip(
00139   struct vtkWPString *str, const char *trailers)
00140 {
00141   size_t k = str->len;
00142   char *cp = str->str;
00143   size_t j = 0;
00144   size_t n;
00145 
00146   if (cp)
00147     {
00148     n = strlen(trailers);
00149 
00150     while (k > 0 && j < n)
00151       {
00152       for (j = 0; j < n; j++)
00153         {
00154         if (cp[k-1] == trailers[j])
00155           {
00156           k--;
00157           break;
00158           }
00159         }
00160       }
00161 
00162     str->len = k;
00163     str->str[k] = '\0';
00164     }
00165 }
00166 
00167 /* -- Return the last char ---------- */
00168 static char vtkWPString_LastChar(
00169   struct vtkWPString *str)
00170 {
00171   if (str->str && str->len > 0)
00172     {
00173     return str->str[str->len-1];
00174     }
00175   return '\0';
00176 }
00177 
00178 /* -- do a linebreak on a method declaration ---------- */
00179 static void vtkWPString_BreakSignatureLine(
00180   struct vtkWPString *str, size_t *linestart, size_t indentation)
00181 {
00182   size_t i = 0;
00183   size_t m = 0;
00184   size_t j = *linestart;
00185   size_t l = str->len;
00186   size_t k = str->len;
00187   char *text = str->str;
00188   char delim;
00189 
00190   if (!text)
00191     {
00192     return;
00193     }
00194 
00195   while (l > j && text[l-1] != '\n' && text[l-1] != ',' &&
00196     text[l-1] != '(' && text[l-1] != ')')
00197     {
00198     /* treat each string as a unit */
00199     if (l > 4 && (text[l-1] == '\'' || text[l-1] == '\"'))
00200       {
00201       delim = text[l-1];
00202       l -= 2;
00203       while (l > 3 && (text[l-1] != delim || text[l-3] == '\\'))
00204         {
00205         l--;
00206         if (text[l-1] == '\\')
00207           {
00208           l--;
00209           }
00210         }
00211       l -= 2;
00212       }
00213     else
00214       {
00215       l--;
00216       }
00217     }
00218 
00219   /* if none of these chars was found, split is impossible */
00220   if (text[l-1] != ',' && text[l-1] != '(' &&
00221       text[l-1] != ')' && text[l-1] != '\n')
00222     {
00223     j++;
00224     }
00225 
00226   else
00227     {
00228     /* Append some chars to guarantee size */
00229     vtkWPString_PushChar(str, '\n');
00230     vtkWPString_PushChar(str, '\n');
00231     for (i = 0; i < indentation; i++)
00232       {
00233       vtkWPString_PushChar(str, ' ');
00234       }
00235     /* re-get the char pointer, it may have been reallocated */
00236     text = str->str;
00237 
00238     if (k > l)
00239       {
00240       m = 0;
00241       while (m < indentation+2 && text[l+m] == ' ')
00242         {
00243         m++;
00244         }
00245       memmove(&text[l+indentation+2-m], &text[l], k-l);
00246       k += indentation+2-m;
00247       }
00248     else
00249       {
00250       k += indentation+2;
00251       }
00252     text[l++] = '\\'; text[l++] = 'n';
00253     j = l;
00254     for (i = 0; i < indentation; i++)
00255       {
00256       text[l++] = ' ';
00257       }
00258     }
00259 
00260   str->len = k;
00261 
00262   /* return the new line start position */
00263   *linestart = j;
00264 }
00265 
00266 /* -- do a linebreak on regular text ---------- */
00267 static void vtkWPString_BreakCommentLine(
00268   struct vtkWPString *str, size_t *linestart, size_t indent)
00269 {
00270   size_t i = 0;
00271   size_t j = *linestart;
00272   size_t l = str->len;
00273   char *text = str->str;
00274 
00275   if (!text)
00276     {
00277     return;
00278     }
00279 
00280   /* try to break the line at a word */
00281   while (l > 0 && text[l-1] != ' ' && text[l-1] != '\n')
00282     {
00283     l--;
00284     }
00285   if (l > 0 && text[l-1] != '\n' && l-j > indent)
00286     {
00287     /* replace space with newline */
00288     text[l-1] = '\n';
00289     j = l;
00290 
00291     /* Append some chars to guarantee size */
00292     vtkWPString_PushChar(str, '\n');
00293     vtkWPString_PushChar(str, '\n');
00294     for (i = 0; i < indent; i++)
00295       {
00296       vtkWPString_PushChar(str, ' ');
00297       }
00298     /* re-get the char pointer, it may have been reallocated */
00299     text = str->str;
00300     str->len -= indent+2;
00301 
00302     if (str->len > l && indent > 0)
00303       {
00304       memmove(&text[l+indent], &text[l], str->len-l);
00305       memset(&text[l], ' ', indent);
00306       str->len += indent;
00307       }
00308     }
00309   else
00310     {
00311     /* long word, just split the word */
00312     vtkWPString_PushChar(str, '\n');
00313     j = str->len;
00314     for (i = 0; i < indent; i++)
00315       {
00316       vtkWPString_PushChar(str, ' ');
00317       }
00318     }
00319 
00320   /* return the new line start position */
00321   *linestart = j;
00322 }
00323 
00324 /* -------------------------------------------------------------------- */
00325 /* Format a signature to a 70 char linewidth and char limit */
00326 const char *vtkWrapText_FormatSignature(
00327   const char *signature, size_t width, size_t maxlen)
00328 {
00329   static struct vtkWPString staticString = { NULL, 0, 0 };
00330   struct vtkWPString *text;
00331   size_t i, j, n;
00332   const char *cp = signature;
00333   char delim;
00334   size_t lastSigStart = 0;
00335   size_t sigCount = 0;
00336 
00337   text = &staticString;
00338   text->len = 0;
00339 
00340   if (signature == 0)
00341     {
00342     return "";
00343     }
00344 
00345   i = 0;
00346   j = 0;
00347 
00348   while (cp[i] != '\0')
00349     {
00350     while (text->len - j < width && cp[i] != '\n' && cp[i] != '\0')
00351       {
00352       /* escape quotes */
00353       if (cp[i] == '\"' || cp[i] == '\'')
00354         {
00355         delim = cp[i];
00356         vtkWPString_PushChar(text, '\\');
00357         vtkWPString_PushChar(text, cp[i++]);
00358         while (cp[i] != delim && cp[i] != '\0')
00359           {
00360           if (cp[i] == '\\')
00361             {
00362             vtkWPString_PushChar(text, '\\');
00363             }
00364           vtkWPString_PushChar(text, cp[i++]);
00365           }
00366         if (cp[i] == delim)
00367           {
00368           vtkWPString_PushChar(text, '\\');
00369           vtkWPString_PushChar(text, cp[i++]);
00370           }
00371         }
00372       /* remove items that trail the closing parenthesis */
00373       else if (cp[i] == ')')
00374         {
00375         vtkWPString_PushChar(text, cp[i++]);
00376         if (strncmp(&cp[i], " const", 6) == 0)
00377           {
00378           i += 6;
00379           }
00380         if (strncmp(&cp[i], " = 0", 4) == 0)
00381           {
00382           i += 4;
00383           }
00384         if (cp[i] == ';')
00385           {
00386           i++;
00387           }
00388         }
00389       /* anything else */
00390       else
00391         {
00392         vtkWPString_PushChar(text, cp[i++]);
00393         }
00394       }
00395 
00396     /* break the line (try to break after a comma) */
00397     if (cp[i] != '\n' && cp[i] != '\0')
00398       {
00399       vtkWPString_BreakSignatureLine(text, &j, 4);
00400       }
00401     /* reached end of line: do next signature */
00402     else
00403       {
00404       vtkWPString_Strip(text, " \r\t");
00405       if (cp[i] != '\0')
00406         {
00407         sigCount++;
00408         /* if sig count is even, check length against maxlen */
00409         if ((sigCount & 1) == 0)
00410           {
00411           n = strlen(text->str);
00412           if (n >= maxlen)
00413             {
00414             break;
00415             }
00416           lastSigStart = n;
00417           }
00418 
00419         i++;
00420         vtkWPString_PushChar(text, '\\');
00421         vtkWPString_PushChar(text, 'n');
00422         }
00423       /* mark the position of the start of the line */
00424       j = text->len;
00425       }
00426     }
00427 
00428   vtkWPString_Strip(text, " \r\t");
00429 
00430   if (strlen(text->str) >= maxlen)
00431     {
00432     /* terminate before the current signature */
00433     text->str[lastSigStart] = '\0';
00434     }
00435 
00436   return text->str;
00437 }
00438 
00439 /* -------------------------------------------------------------------- */
00440 /* Format a comment to a 70 char linewidth, in several steps:
00441  * 1) remove html tags, convert <p> and <br> into breaks
00442  * 2) remove doxygen tags like \em
00443  * 3) remove extra whitespace (except paragraph breaks)
00444  * 4) re-break the lines
00445  */
00446 
00447 const char *vtkWrapText_FormatComment(
00448   const char *comment, size_t width)
00449 {
00450   static struct vtkWPString staticString = { NULL, 0, 0 };
00451   struct vtkWPString *text;
00452   const char *cp;
00453   size_t i, j, l;
00454   size_t indent = 0;
00455   int nojoin = 0;
00456   int start;
00457 
00458   text = &staticString;
00459   text->len = 0;
00460 
00461   if (comment == 0)
00462     {
00463     return "";
00464     }
00465 
00466   i = 0; j = 0; l = 0;
00467   start = 1;
00468   cp = comment;
00469 
00470   /* skip any leading whitespace */
00471   while (cp[i] == '\n' || cp[i] == '\r' ||
00472          cp[i] == '\t' || cp[i] == ' ')
00473     {
00474     i++;
00475     }
00476 
00477   while (cp[i] != '\0')
00478     {
00479     /* Add characters until the output line is complete */
00480     while (cp[i] != '\0' && text->len-j < width)
00481       {
00482       /* if the end of the line was found, see how next line begins */
00483       if (start)
00484         {
00485         /* eat the leading space */
00486         if (cp[i] == ' ')
00487           {
00488           i++;
00489           }
00490 
00491         /* skip ahead to find any interesting first characters */
00492         l = i;
00493         while (cp[l] == ' ' || cp[l] == '\t' || cp[l] == '\r')
00494           {
00495           l++;
00496           }
00497 
00498         /* check for new section */
00499         if (cp[l] == '.' && strncmp(&cp[l], ".SECTION", 8) == 0)
00500           {
00501           vtkWPString_Strip(text, "\n");
00502           if (text->len > 0)
00503             {
00504             vtkWPString_PushChar(text, '\n');
00505             vtkWPString_PushChar(text, '\n');
00506             }
00507           i = l+8;
00508           while (cp[i] == '\r' || cp[i] == '\t' || cp[i] == ' ')
00509             {
00510             i++;
00511             }
00512           while (cp[i] != '\n' && cp[i] != '\0')
00513             {
00514             vtkWPString_PushChar(text, cp[i++]);
00515             }
00516           vtkWPString_Strip(text, " \t\r");
00517 
00518           if (vtkWPString_LastChar(text) != ':')
00519             {
00520             vtkWPString_PushChar(text, ':');
00521             }
00522           vtkWPString_PushChar(text, '\n');
00523           vtkWPString_PushChar(text, '\n');
00524           j = text->len;
00525           indent = 0;
00526           if (cp[i] == '\n')
00527             {
00528             i++;
00529             }
00530           start = 1;
00531           continue;
00532           }
00533 
00534         /* handle doxygen tags that appear at start of line */
00535         if (cp[l] == '\\' || cp[l] == '@')
00536           {
00537           if (strncmp(&cp[l+1], "brief", 5) == 0 ||
00538               strncmp(&cp[l+1], "short", 5) == 0 ||
00539               strncmp(&cp[l+1], "pre", 3) == 0 ||
00540               strncmp(&cp[l+1], "post", 4) == 0 ||
00541               strncmp(&cp[l+1], "param", 5) == 0 ||
00542               strncmp(&cp[l+1], "tparam", 6) == 0 ||
00543               strncmp(&cp[l+1], "cmdparam", 8) == 0 ||
00544               strncmp(&cp[l+1], "exception", 9) == 0 ||
00545               strncmp(&cp[l+1], "return", 6) == 0 ||
00546               strncmp(&cp[l+1], "li", 2) == 0)
00547             {
00548             nojoin = 2;
00549             indent = 4;
00550             if (text->len > 0 && vtkWPString_LastChar(text) != '\n')
00551               {
00552               vtkWPString_PushChar(text, '\n');
00553               }
00554             j = text->len;
00555             i = l;
00556             }
00557           }
00558 
00559         /* handle bullets and numbering */
00560         else if (cp[l] == '-' || cp[l] == '*' || cp[l] == '#' ||
00561                  (cp[l] >= '0' && cp[l] <= '9' &&
00562                   (cp[l+1] == ')' || cp[l+1] == '.') && cp[l+2] == ' '))
00563           {
00564           indent = 0;
00565           while (indent < 3 && cp[l+indent] != ' ')
00566             {
00567             indent++;
00568             }
00569           indent++;
00570           if (text->len > 0 && vtkWPString_LastChar(text) != '\n')
00571             {
00572             vtkWPString_PushChar(text, '\n');
00573             }
00574           j = text->len;
00575           i = l;
00576           }
00577 
00578         /* keep paragraph breaks */
00579         else if (cp[l] == '\n')
00580           {
00581           i = l+1;
00582           vtkWPString_Strip(text, "\n");
00583           if (text->len > 0)
00584             {
00585             vtkWPString_PushChar(text, '\n');
00586             vtkWPString_PushChar(text, '\n');
00587             }
00588           nojoin = 0;
00589           indent = 0;
00590           j = text->len;
00591           start = 1;
00592           continue;
00593           }
00594 
00595         /* add newline if nojoin is not set */
00596         else if (nojoin ||
00597                 (cp[i] == ' ' && !indent))
00598           {
00599           if (nojoin == 2)
00600             {
00601             nojoin = 0;
00602             indent = 0;
00603             }
00604           vtkWPString_PushChar(text, '\n');
00605           j = text->len;
00606           }
00607 
00608         /* do line joining */
00609         else if (text->len > 0 && vtkWPString_LastChar(text) != '\n')
00610           {
00611           i = l;
00612           vtkWPString_PushChar(text, ' ');
00613           }
00614         }
00615 
00616       /* handle quotes */
00617       if (cp[i] == '\"')
00618         {
00619         size_t q = i;
00620         size_t r = text->len;
00621 
00622         /* try to keep the quote whole */
00623         vtkWPString_PushChar(text, cp[i++]);
00624         while (cp[i] != '\"' && cp[i] != '\r' &&
00625                cp[i] != '\n' && cp[i] != '\0')
00626           {
00627           vtkWPString_PushChar(text, cp[i++]);
00628           }
00629         /* if line ended before quote did, then reset */
00630         if (cp[i] != '\"')
00631           {
00632           i = q;
00633           text->len = r;
00634           }
00635         }
00636       else if (cp[i] == '\'')
00637         {
00638         size_t q = i;
00639         size_t r = text->len;
00640 
00641         /* try to keep the quote whole */
00642         vtkWPString_PushChar(text, cp[i++]);
00643         while (cp[i] != '\'' && cp[i] != '\r' &&
00644                cp[i] != '\n' && cp[i] != '\0')
00645           {
00646           vtkWPString_PushChar(text, cp[i++]);
00647           }
00648         /* if line ended before quote did, then reset */
00649         if (cp[i] != '\'')
00650           {
00651           i = q;
00652           text->len = r;
00653           }
00654         }
00655 
00656       /* handle simple html tags */
00657       else if (cp[i] == '<')
00658         {
00659         l = i+1;
00660         if (cp[l] == '/') { l++; }
00661         while ((cp[l] >= 'a' && cp[l] <= 'z') ||
00662                (cp[l] >= 'a' && cp[l] <= 'z')) { l++; }
00663         if (cp[l] == '>')
00664           {
00665           if (cp[i+1] == 'p' || cp[i+1] == 'P' ||
00666               (cp[i+1] == 'b' && cp[i+2] == 'r') ||
00667               (cp[i+1] == 'B' && cp[i+2] == 'R'))
00668             {
00669             vtkWPString_Strip(text, " \n");
00670             vtkWPString_PushChar(text, '\n');
00671             vtkWPString_PushChar(text, '\n');
00672             j = text->len;
00673             indent = 0;
00674             }
00675           i = l+1;
00676           while (cp[i] == '\r' || cp[i] == '\t' || cp[i] == ' ')
00677             {
00678             i++;
00679             }
00680           }
00681         }
00682       else if (cp[i] == '\\' || cp[i] == '@')
00683         {
00684         /* handle simple doxygen tags */
00685         if (strncmp(&cp[i+1], "em ", 3) == 0)
00686           {
00687           i += 4;
00688           }
00689         else if (strncmp(&cp[i+1], "a ", 2) == 0 ||
00690                  strncmp(&cp[i+1], "e ", 2) == 0 ||
00691                  strncmp(&cp[i+1], "c ", 2) == 0 ||
00692                  strncmp(&cp[i+1], "b ", 2) == 0 ||
00693                  strncmp(&cp[i+1], "p ", 2) == 0 ||
00694                  strncmp(&cp[i+1], "f$", 2) == 0 ||
00695                  strncmp(&cp[i+1], "f[", 2) == 0 ||
00696                  strncmp(&cp[i+1], "f]", 2) == 0)
00697           {
00698           if (i > 0 && cp[i-1] != ' ')
00699             {
00700             vtkWPString_PushChar(text, ' ');
00701             }
00702           if (cp[i+1] == 'f')
00703             {
00704             if (cp[i+2] == '$')
00705               {
00706               vtkWPString_PushChar(text, '$');
00707               }
00708             else
00709               {
00710               vtkWPString_PushChar(text, '\\');
00711               vtkWPString_PushChar(text, cp[i+2]);
00712               }
00713             }
00714           i += 3;
00715           }
00716         else if (cp[i+1] == '&' || cp[i+1] == '$' || cp[i+1] == '#' ||
00717                  cp[i+1] == '<' || cp[i+1] == '>' || cp[i+1] == '%' ||
00718                  cp[i+1] == '@' || cp[i+1] == '\\' || cp[i+1] == '\"')
00719           {
00720           i++;
00721           }
00722         else if (cp[i+1] == 'n')
00723           {
00724           vtkWPString_Strip(text, " \n");
00725           vtkWPString_PushChar(text, '\n');
00726           vtkWPString_PushChar(text, '\n');
00727           indent = 0;
00728           i += 2;
00729           j = text->len;
00730           }
00731         else if (strncmp(&cp[i+1], "code", 4) == 0)
00732           {
00733           nojoin = 1;
00734           i += 5;
00735           while (cp[i] == ' ' || cp[i] == '\r' ||
00736                  cp[i] == '\t' || cp[i] == '\n')
00737             {
00738             i++;
00739             }
00740           }
00741         else if (strncmp(&cp[i+1], "endcode", 7) == 0)
00742           {
00743           nojoin = 0;
00744           i += 8;
00745           l = i;
00746           while (cp[l] == ' ' || cp[l] == '\t' || cp[l] == '\r')
00747             {
00748             l++;
00749             }
00750           if (cp[l] == '\n')
00751             {
00752             i = l;
00753             vtkWPString_PushChar(text, '\n');
00754             j = text->len;
00755             }
00756           }
00757         else if (strncmp(&cp[i+1], "verbatim", 8) == 0)
00758           {
00759           i += 9;
00760           while (cp[i] != '\0' && ((cp[i] != '@' && cp[i] != '\\') ||
00761                  strncmp(&cp[i+1], "endverbatim", 11) != 0))
00762             {
00763             if (cp[i] != '\r')
00764               {
00765               vtkWPString_PushChar(text, cp[i]);
00766               }
00767             if (cp[i] == '\n')
00768               {
00769               j = text->len;
00770               }
00771             i++;
00772             }
00773           if (cp[i] != '\0')
00774             {
00775             i += 12;
00776             }
00777           }
00778         }
00779 
00780       /* search for newline */
00781       start = 0;
00782       l = i;
00783       while (cp[l] == ' ' || cp[l] == '\t' || cp[l] == '\r')
00784         {
00785         l++;
00786         }
00787       if (cp[l] == '\n')
00788         {
00789         i = l+1;
00790         start = 1;
00791         }
00792 
00793       /* append */
00794       else if (cp[i] != '\0')
00795         {
00796         vtkWPString_PushChar(text, cp[i++]);
00797         }
00798 
00799       } /* while (cp[i] != '\0' && text->len-j < width) */
00800 
00801     if (cp[i] == '\0')
00802       {
00803       break;
00804       }
00805 
00806     vtkWPString_BreakCommentLine(text, &j, indent);
00807     }
00808 
00809   /* remove any trailing blank lines */
00810   vtkWPString_Strip(text, "\n");
00811   vtkWPString_PushChar(text, '\n');
00812 
00813   return text->str;
00814 }
00815 
00816 /* -------------------------------------------------------------------- */
00817 /* Create a signature for the python version of a method. */
00818 
00819 static void vtkWrapText_PythonTypeSignature(
00820   struct vtkWPString *result, const char *delims[2], ValueInfo *arg);
00821 
00822 static void vtkWrapText_PythonArraySignature(
00823   struct vtkWPString *result, const char *classname,
00824   const char *delims[2], int ndim, const char **dims);
00825 
00826 const char *vtkWrapText_PythonSignature(
00827   FunctionInfo *currentFunction)
00828 {
00829   /* string is intentionally not freed until the program exits */
00830   static struct vtkWPString staticString = { NULL, 0, 0 };
00831   struct vtkWPString *result;
00832   ValueInfo *arg, *ret;
00833   const char *parens[2] = { "(", ")" };
00834   const char *braces[2] = { "[", "]" };
00835   const char **delims;
00836   int i, n;
00837 
00838   n = vtkWrap_CountWrappedArgs(currentFunction);
00839 
00840   result = &staticString;
00841   result->len = 0;
00842 
00843   /* print out the name of the method */
00844   vtkWPString_Append(result, "V.");
00845   vtkWPString_Append(result, currentFunction->Name);
00846 
00847   /* print the arg list */
00848   vtkWPString_Append(result, "(");
00849 
00850   for (i = 0; i < n; i++)
00851     {
00852     arg = currentFunction->Arguments[i];
00853 
00854     if (i != 0)
00855       {
00856       vtkWPString_Append(result, ", ");
00857       }
00858 
00859     delims = parens;
00860     if (!vtkWrap_IsConst(arg) &&
00861         !vtkWrap_IsSetVectorMethod(currentFunction))
00862       {
00863       delims = braces;
00864       }
00865 
00866     vtkWrapText_PythonTypeSignature(result, delims, arg);
00867     }
00868 
00869   vtkWPString_Append(result, ")");
00870 
00871   /* if this is a void method, we are finished */
00872   /* otherwise, print "->" and the return type */
00873   ret = currentFunction->ReturnValue;
00874   if (ret && (ret->Type & VTK_PARSE_UNQUALIFIED_TYPE) != VTK_PARSE_VOID)
00875     {
00876     vtkWPString_Append(result, " -> ");
00877 
00878     vtkWrapText_PythonTypeSignature(result, parens, ret);
00879     }
00880 
00881   if (currentFunction->Signature)
00882     {
00883     vtkWPString_Append(result, "\nC++: ");
00884     vtkWPString_Append(result, currentFunction->Signature);
00885     }
00886 
00887   return result->str;
00888 }
00889 
00890 static void vtkWrapText_PythonTypeSignature(
00891   struct vtkWPString *result, const char *braces[2], ValueInfo *arg)
00892 {
00893   char text[32];
00894   const char *dimension;
00895   const char *classname = "";
00896 
00897   if (vtkWrap_IsVoid(arg))
00898     {
00899     classname = "void";
00900     }
00901   else if (vtkWrap_IsObject(arg))
00902     {
00903     classname = arg->Class;
00904     }
00905   else if (vtkWrap_IsFunction(arg))
00906     {
00907     classname = "function";
00908     }
00909   else if (vtkWrap_IsString(arg) || vtkWrap_IsCharPointer(arg))
00910     {
00911     classname = "string";
00912     if ((arg->Type & VTK_PARSE_BASE_TYPE) == VTK_PARSE_UNICODE_STRING)
00913       {
00914       classname = "unicode";
00915       }
00916     }
00917   else if (vtkWrap_IsChar(arg))
00918     {
00919     classname = "char";
00920     }
00921   else if (vtkWrap_IsBool(arg))
00922     {
00923     classname = "bool";
00924     }
00925   else if (vtkWrap_IsRealNumber(arg))
00926     {
00927     classname = "float";
00928     }
00929   else if (vtkWrap_IsInteger(arg))
00930     {
00931     classname = "int";
00932     }
00933 
00934   if (vtkWrap_IsArray(arg))
00935     {
00936     if (arg->CountHint)
00937       {
00938       vtkWPString_Append(result, braces[0]);
00939       vtkWPString_Append(result, classname);
00940       vtkWPString_Append(result, ", ...");
00941       vtkWPString_Append(result, braces[1]);
00942       }
00943     else
00944       {
00945       sprintf(text, "%d", arg->Count);
00946       dimension = text;
00947       vtkWrapText_PythonArraySignature(result, classname, braces,
00948         1, &dimension);
00949       }
00950     }
00951   else if (vtkWrap_IsNArray(arg))
00952     {
00953     vtkWrapText_PythonArraySignature(result, classname, braces,
00954       arg->NumberOfDimensions, arg->Dimensions);
00955     }
00956   else
00957     {
00958     vtkWPString_Append(result, classname);
00959     }
00960 }
00961 
00962 static void vtkWrapText_PythonArraySignature(
00963   struct vtkWPString *result, const char *classname,
00964   const char *braces[2], int ndim, const char **dims)
00965 {
00966   int j, n;
00967 
00968   vtkWPString_Append(result, braces[0]);
00969   n = (int)strtoul(dims[0], 0, 0);
00970   if (ndim > 1)
00971     {
00972     for (j = 0; j < n; j++)
00973       {
00974       if (j != 0) { vtkWPString_Append(result, ", "); }
00975       vtkWrapText_PythonArraySignature(result, classname,
00976         braces, ndim-1, dims+1);
00977       }
00978     }
00979   else
00980     {
00981     for (j = 0; j < n; j++)
00982       {
00983       if (j != 0) { vtkWPString_Append(result, ", "); }
00984       vtkWPString_Append(result, classname);
00985       }
00986     }
00987   vtkWPString_Append(result, braces[1]);
00988 }