diff options
| author | Matthias Melcher <github@matthiasm.com> | 2025-07-03 00:39:53 +0200 |
|---|---|---|
| committer | Matthias Melcher <github@matthiasm.com> | 2025-07-03 00:39:53 +0200 |
| commit | 872e2b8fb6711ba277594ab610db38650d6708b6 (patch) | |
| tree | 0c2c30c738aaf097209049c1cc90608d8ad920d7 | |
| parent | 5919dbb6af174787cdc5f203d03ed396d8ca3031 (diff) | |
Fl_Help_View: Refactor more strings and dynamic lists.
| -rw-r--r-- | FL/Fl_Help_View.H | 16 | ||||
| -rw-r--r-- | src/Fl_Help_View.cxx | 254 |
2 files changed, 135 insertions, 135 deletions
diff --git a/FL/Fl_Help_View.H b/FL/Fl_Help_View.H index 9e486abec..2e47fc784 100644 --- a/FL/Fl_Help_View.H +++ b/FL/Fl_Help_View.H @@ -197,7 +197,7 @@ class FL_EXPORT Fl_Help_View : public Fl_Group enum { RIGHT = -1, CENTER, LEFT }; ///< Alignments - char title_[1024]; ///< Title string + std::string title_; ///< Title string Fl_Color defcolor_, ///< Default text color bgcolor_, ///< Background color textcolor_, ///< Text color @@ -206,9 +206,7 @@ class FL_EXPORT Fl_Help_View : public Fl_Group Fl_Fontsize textsize_; ///< Default font size const char *value_; ///< HTML text value Fl_Help_Font_Stack fstack_; ///< font stack management - int nblocks_, ///< Number of blocks/paragraphs - ablocks_; ///< Allocated blocks - Fl_Help_Block *blocks_; ///< Blocks + std::vector<Fl_Help_Block> blocks_; ///< Blocks Fl_Help_Func *link_; ///< Link transform function @@ -216,10 +214,9 @@ class FL_EXPORT Fl_Help_View : public Fl_Group std::map<std::string, int> target_line_map_; ///< Map of targets for fast access - // FIXME: do we really need this size? - char directory_[2 * FL_PATH_MAX + 15]; ///< Directory for current file + std::string directory_; ///< Directory for current file + std::string filename_; ///< Current filename - char filename_[FL_PATH_MAX]; ///< Current filename int topline_, ///< Top line in document leftline_, ///< Lefthand position size_, ///< Total document length @@ -287,7 +284,8 @@ public: const char *filename() const; const char *directory() const; - + const char *title() const; + int find(const char *s, int p = 0); void link(Fl_Help_Func *fn); int load(const char *f); @@ -306,8 +304,6 @@ public: void textsize(Fl_Fontsize s) { textsize_ = s; format(); } /** Gets the default text size. */ Fl_Fontsize textsize() const { return (textsize_); } - /** Returns the current document title, or NULL if there is no title. */ - const char *title() { return (title_); } void topline(const char *n); void topline(int); /** Returns the current top line in pixels. */ diff --git a/src/Fl_Help_View.cxx b/src/Fl_Help_View.cxx index cf22ba277..82e568c0f 100644 --- a/src/Fl_Help_View.cxx +++ b/src/Fl_Help_View.cxx @@ -388,17 +388,9 @@ Fl_Help_View::add_block(const char *s, // I - Pointer to start of block // printf("add_block(s = %p, xx = %d, yy = %d, ww = %d, hh = %d, border = %d)\n", // s, xx, yy, ww, hh, border); - if (nblocks_ >= ablocks_) - { - ablocks_ += 16; + blocks_.push_back(Fl_Help_Block()); // Add a new block to the vector + temp = &blocks_.back(); - if (ablocks_ == 16) - blocks_ = (Fl_Help_Block *)malloc(sizeof(Fl_Help_Block) * ablocks_); - else - blocks_ = (Fl_Help_Block *)realloc(blocks_, sizeof(Fl_Help_Block) * ablocks_); - } - - temp = blocks_ + nblocks_; memset(temp, 0, sizeof(Fl_Help_Block)); temp->start = s; temp->end = s; @@ -408,7 +400,6 @@ Fl_Help_View::add_block(const char *s, // I - Pointer to start of block temp->h = hh; temp->border = border; temp->bgcolor = bgcolor_; - nblocks_ ++; return (temp); } @@ -564,7 +555,7 @@ Fl_Help_View::draw() fl_color(textcolor_); // Draw all visible blocks... - for (i = 0, block = blocks_; i < nblocks_; i ++, block ++) + for (i = 0, block = &blocks_[0]; i < blocks_.size(); i ++, block ++) if ((block->y + block->h) >= topline_ && block->y < (topline_ + h())) { line = 0; @@ -1098,7 +1089,7 @@ Fl_Help_View::find(const char *s, // I - String to find if (p < 0 || p >= (int)strlen(value_)) p = 0; // Look for the string... - for (i = nblocks_, b = blocks_; i > 0; i--, b++) { + for (i = blocks_.size(), b = &blocks_[0]; i > 0; i--, b++) { if (b->end < (value_ + p)) continue; @@ -1228,7 +1219,7 @@ void Fl_Help_View::format() { { // Reset state variables... done = 1; - nblocks_ = 0; + blocks_.clear(); link_list_.clear(); target_line_map_.clear(); size_ = 0; @@ -1238,7 +1229,7 @@ void Fl_Help_View::format() { tc = rc = bgcolor_; - strcpy(title_, "Untitled"); + title_ = "Untitled"; if (!value_) return; @@ -1392,12 +1383,10 @@ void Fl_Help_View::format() { else if (buf.cmp("TITLE")) { // Copy the title in the document... - char *st; - for (st = title_; - *ptr != '<' && *ptr && st < (title_ + sizeof(title_) - 1); - *st++ = *ptr++) {/*empty*/} - - *st = '\0'; + title_.clear(); + for ( ; *ptr != '<' && *ptr; ptr++) { + title_.push_back(*ptr); + } buf.clear(); } else if (buf.cmp("A")) @@ -1652,18 +1641,18 @@ void Fl_Help_View::format() { { yy = blocks_[row].y + blocks_[row].h; - for (cell = blocks_ + row + 1; cell <= block; cell ++) + for (cell = &blocks_[row + 1]; cell <= block; cell ++) if ((cell->y + cell->h) > yy) yy = cell->y + cell->h; - block = blocks_ + row; + block = &blocks_[row]; block->h = yy - block->y + 2; for (i = 0; i < column; i ++) if (cells[i]) { - cell = blocks_ + cells[i]; + cell = &blocks_[cells[i]]; cell->h = block->h; } } @@ -1673,7 +1662,7 @@ void Fl_Help_View::format() { yy = block->y + block->h - 4; hh = 0; block = add_block(start, xx, yy, hsize_, 0); - row = (int) (block - blocks_); + row = (int) (block - &blocks_[0]); needspace = 0; column = 0; line = 0; @@ -1690,18 +1679,18 @@ void Fl_Help_View::format() { xx = blocks_[row].x; yy = blocks_[row].y + blocks_[row].h; - for (cell = blocks_ + row + 1; cell <= block; cell ++) + for (cell = &blocks_[row + 1]; cell <= block; cell ++) if ((cell->y + cell->h) > yy) yy = cell->y + cell->h; - block = blocks_ + row; + block = &blocks_[row]; block->h = yy - block->y + 2; for (i = 0; i < column; i ++) if (cells[i]) { - cell = blocks_ + cells[i]; + cell = &blocks_[cells[i]]; cell->h = block->h; } @@ -1742,9 +1731,9 @@ void Fl_Help_View::format() { for (i = 0, ww = -6; i < colspan; i ++) ww += columns[column + i] + 6; - if (block->end == block->start && nblocks_ > 1) + if (block->end == block->start && blocks_.size() > 1) { - nblocks_ --; + blocks_.pop_back(); block --; } @@ -1758,7 +1747,7 @@ void Fl_Help_View::format() { newalign = get_align(attrs, tolower(buf[1]) == 'h' ? CENTER : LEFT); talign = newalign; - cells[column] = (int) (block - blocks_); + cells[column] = (int) (block - &blocks_[0]); column += colspan; @@ -2506,13 +2495,7 @@ Fl_Help_View::free_data() { } // Free all of the arrays... - if (nblocks_) { - free(blocks_); - - ablocks_ = 0; - nblocks_ = 0; - blocks_ = 0; - } + blocks_ .clear(); link_list_.clear(); target_line_map_.clear(); @@ -2720,9 +2703,9 @@ Fl_Help_View::get_image(const char *name, int W, int H) { Fl_Shared_Image *ip; // Image pointer... // See if the image can be found... - if (strchr(directory_, ':') != NULL && strchr(name, ':') == NULL) { + if (strchr(directory_.c_str(), ':') != NULL && strchr(name, ':') == NULL) { if (name[0] == '/') { - strlcpy(temp, directory_, sizeof(temp)); + strlcpy(temp, directory_.c_str(), sizeof(temp)); // the following search (strchr) will always succeed, see condition above! tempptr = skip_bytes(strchr(temp, ':'), 3); if ((tempptr = strrchr(tempptr, '/')) != NULL) { @@ -2731,14 +2714,15 @@ Fl_Help_View::get_image(const char *name, int W, int H) { strlcat(temp, name, sizeof(temp)); } } else { - snprintf(temp, sizeof(temp), "%s/%s", directory_, name); + snprintf(temp, sizeof(temp), "%s/%s", directory_.c_str(), name); } if (link_) localname = (*link_)(this, temp); else localname = temp; } else if (name[0] != '/' && strchr(name, ':') == NULL) { - if (directory_[0]) snprintf(temp, sizeof(temp), "%s/%s", directory_, name); - else { + if (!directory_.empty()) { + snprintf(temp, sizeof(temp), "%s/%s", directory_.c_str(), name); + } else { fl_getcwd(dir, sizeof(dir)); snprintf(temp, sizeof(temp), "file:%s/%s", dir, name); } @@ -2800,26 +2784,25 @@ std::shared_ptr<Fl_Help_View::Link> Fl_Help_View::find_link(int xx, int yy) void Fl_Help_View::follow_link(std::shared_ptr<Link> linkp) { - char target[32]; // Current target + std::string target; // Current target clear_selection(); - strlcpy(target, linkp->target.c_str(), sizeof(target)); + target = linkp->target; set_changed(); - if (strcmp(linkp->filename_.c_str(), filename_) != 0 && !linkp->filename_.empty()) + if (strcmp(linkp->filename_.c_str(), filename_.c_str()) != 0 && !linkp->filename_.empty()) { - char dir[FL_PATH_MAX]; // Current directory char temp[3 * FL_PATH_MAX], // Temporary filename *tempptr; // Pointer into temporary filename - if (strchr(directory_, ':') != NULL && strchr(linkp->filename_.c_str(), ':') == NULL) + if (strchr(directory_.c_str(), ':') != NULL && strchr(linkp->filename_.c_str(), ':') == NULL) { if (linkp->filename_[0] == '/') { - strlcpy(temp, directory_, sizeof(temp)); + strlcpy(temp, directory_.c_str(), sizeof(temp)); // the following search (strchr) will always succeed, see condition above! tempptr = skip_bytes(strchr(temp, ':'), 3); if ((tempptr = strrchr(tempptr, '/')) != NULL) { @@ -2829,15 +2812,16 @@ void Fl_Help_View::follow_link(std::shared_ptr<Link> linkp) } } else - snprintf(temp, sizeof(temp), "%s/%s", directory_, linkp->filename_.c_str()); + snprintf(temp, sizeof(temp), "%s/%s", directory_.c_str(), linkp->filename_.c_str()); } else if (linkp->filename_[0] != '/' && strchr(linkp->filename_.c_str(), ':') == NULL) { - if (directory_[0]) - snprintf(temp, sizeof(temp), "%s/%s", directory_, linkp->filename_.c_str()); + if (!directory_.empty()) + snprintf(temp, sizeof(temp), "%s/%s", directory_.c_str(), linkp->filename_.c_str()); else { - fl_getcwd(dir, sizeof(dir)); + char dir[FL_PATH_MAX]; // Current directory + fl_getcwd(dir, sizeof(dir)); snprintf(temp, sizeof(temp), "file:%s/%s", dir, linkp->filename_.c_str()); } } @@ -2850,8 +2834,8 @@ void Fl_Help_View::follow_link(std::shared_ptr<Link> linkp) load(temp); } - else if (target[0]) - topline(target); + else if (!target.empty()) + topline(target.c_str()); else topline(0); @@ -3216,16 +3200,14 @@ Fl_Help_View::Fl_Help_View(int xx, // I - Left position textsize_ = 12; value_ = NULL; - ablocks_ = 0; - nblocks_ = 0; - blocks_ = (Fl_Help_Block *)0; + blocks_.clear(); link_ = (Fl_Help_Func *)0; link_list_.clear(); - directory_[0] = '\0'; - filename_[0] = '\0'; + directory_.clear(); + filename_.clear(); topline_ = 0; leftline_ = 0; @@ -3271,10 +3253,10 @@ Fl_Help_View::~Fl_Help_View() \return nullptr if the filename is empty */ const char *Fl_Help_View::filename() const { - if (filename_[0]) - return (filename_); + if (filename_.empty()) + return nullptr; else - return nullptr; + return filename_.c_str(); } @@ -3287,10 +3269,23 @@ const char *Fl_Help_View::filename() const { \return nullptr if the directory name is empty */ const char *Fl_Help_View::directory() const { - if (directory_[0]) - return (directory_); + if (directory_.empty()) + return nullptr; else - return nullptr; + return directory_.c_str(); +} + + +/** + \brief Return the title of the current document. + + Fl_Help_View remains the owner of the allocated memory. If the document + chages, the returned pointer will become stale. + + \return empty string if the directory name is empty + */ +const char *Fl_Help_View::title() const { + return title_.c_str(); } @@ -3324,6 +3319,7 @@ void Fl_Help_View::link(Fl_Help_Func *fn) { link_ = fn; } + /** Loads the specified file. This method loads the specified file or URL. The filename may end in a @@ -3347,11 +3343,10 @@ int Fl_Help_View::load(const char *f) { FILE *fp; // File to read from long len; // Length of file - char *target; // Target in file - char *slash; // Directory separator - const char *localname; // Local filename - char error[2 * FL_PATH_MAX]; // Error buffer - char newname[FL_PATH_MAX]; // New filename buffer + std::string target; // Target in file + std::string localname; // Local filename + std::string error; // Error buffer + std::string newname; // New filename buffer // printf("load(%s)\n",f); fflush(stdout); @@ -3366,37 +3361,41 @@ int Fl_Help_View::load(const char *f) if ( fl_open_uri(f, urimsg, sizeof(urimsg)) == 0 ) { clear_selection(); - strlcpy(newname, f, sizeof(newname)); - if ((target = strrchr(newname, '#')) != NULL) - *target++ = '\0'; - - if (link_) - localname = (*link_)(this, newname); - else - localname = filename_; + newname = f; + size_t hash_pos = newname.find_last_of('#'); + if (hash_pos != std::string::npos) { + target = newname.substr(hash_pos + 1); + newname.resize(hash_pos); + } - if (!localname) - return (0); + if (link_) { + const char *n = (*link_)(this, newname.c_str()); + if (n == nullptr) + return 0; + localname = n; + } else { + localname = newname; + } free_data(); - strlcpy(filename_, newname, sizeof(filename_)); - strlcpy(directory_, newname, sizeof(directory_)); + filename_ = newname; // Note: We do not support Windows backslashes, since they are illegal // in URLs... - if ((slash = strrchr(directory_, '/')) == NULL) - directory_[0] = '\0'; - else if (slash > directory_ && slash[-1] != '/') - *slash = '\0'; - - snprintf(error, sizeof(error), - "<HTML><HEAD><TITLE>Error</TITLE></HEAD>" - "<BODY><H1>Error</H1>" - "<P>Unable to follow the link \"%s\" - " - "%s.</P></BODY>", - f, urimsg); - value(error); + directory_ = newname; + size_t slash_pos = directory_.find_last_of('/'); + if (slash_pos == std::string::npos) { + directory_.clear(); + } else if ((slash_pos > 0) && (directory_[slash_pos-1] != '/')) { + directory_.resize(slash_pos); + } + + error = "<HTML><HEAD><TITLE>Error</TITLE></HEAD>" + "<BODY><H1>Error</H1>" + "<P>Unable to follow the link \"" + + std::string(f) + "\" - " + std::string(urimsg) + ".</P></BODY>"; + value(error.c_str()); return -1; } else { return 0; @@ -3405,35 +3404,42 @@ int Fl_Help_View::load(const char *f) clear_selection(); - strlcpy(newname, f, sizeof(newname)); - if ((target = strrchr(newname, '#')) != NULL) - *target++ = '\0'; - - if (link_) - localname = (*link_)(this, newname); - else - localname = filename_; + newname = f; + size_t hash_pos = newname.find_last_of('#'); + if (hash_pos != std::string::npos) { + target = newname.substr(hash_pos + 1); + newname.resize(hash_pos); + } - if (!localname) - return -1; + if (link_) { + const char *n = (*link_)(this, newname.c_str()); + if (n == nullptr) + return -1; + localname = n; + } else { + localname = newname; + } free_data(); - strlcpy(filename_, newname, sizeof(filename_)); - strlcpy(directory_, newname, sizeof(directory_)); + filename_ = newname; + directory_ = newname; // Note: We do not support Windows backslashes, since they are illegal // in URLs... - if ((slash = strrchr(directory_, '/')) == NULL) - directory_[0] = '\0'; - else if (slash > directory_ && slash[-1] != '/') - *slash = '\0'; + size_t slash_pos = directory_.find_last_of('/'); + if (slash_pos == std::string::npos) { + directory_.clear(); + } else if ((slash_pos > 0) && (directory_[slash_pos-1] != '/')) { + directory_.resize(slash_pos); + } - if (strncmp(localname, "file:", 5) == 0) - localname += 5; // Adjust for local filename... + if (localname.find("file:") == 0) { + localname.erase(0, 5); // Adjust for local filename... + } int ret = 0; - if ((fp = fl_fopen(localname, "rb")) != NULL) + if ((fp = fl_fopen(localname.c_str(), "rb")) != NULL) { fseek(fp, 0, SEEK_END); len = ftell(fp); @@ -3445,13 +3451,11 @@ int Fl_Help_View::load(const char *f) } else { - snprintf(error, sizeof(error), - "<HTML><HEAD><TITLE>Error</TITLE></HEAD>" - "<BODY><H1>Error</H1>" - "<P>Unable to follow the link \"%s\" - " - "%s.</P></BODY>", - localname, strerror(errno)); - value_ = fl_strdup(error); + error = "<HTML><HEAD><TITLE>Error</TITLE></HEAD>" + "<BODY><H1>Error</H1>" + "<P>Unable to follow the link \"" +localname + "\" - " + + strerror(errno) + ".</P></BODY>"; + value_ = fl_strdup(error.c_str()); ret = -1; } @@ -3459,8 +3463,8 @@ int Fl_Help_View::load(const char *f) format(); initial_load = 0; - if (target) - topline(target); + if (!target.empty()) + topline(target.c_str()); else topline(0); @@ -3492,8 +3496,7 @@ void Fl_Help_View::resize(int xx, int yy, int ww, int hh) \brief Scroll the text to the given anchor. \param[in] anchor scroll to this named anchor */ -void -Fl_Help_View::topline(const char *anchor) // I - Target name +void Fl_Help_View::topline(const char *anchor) { std::string target_name = to_lower(anchor); // Convert to lower case auto tl = target_line_map_.find(target_name); @@ -3506,6 +3509,7 @@ Fl_Help_View::topline(const char *anchor) // I - Target name } } + /** Scrolls the text to the indicated position, given a pixel line. If the given pixel value \p top is out of range, then the text is |
