Add split_filename.cpp impl with base functions and std::string

This commit is contained in:
David Capello 2014-09-21 13:42:46 -03:00
parent ed67ee0d59
commit 0a3901cf39
5 changed files with 181 additions and 101 deletions

View File

@ -123,6 +123,7 @@ add_library(app-lib
file/palette_file.cpp
file/pcx_format.cpp
file/png_format.cpp
file/split_filename.cpp
file/tga_format.cpp
file_selector.cpp
file_system.cpp

View File

@ -28,6 +28,7 @@
#include "app/file/file_format.h"
#include "app/file/file_formats_manager.h"
#include "app/file/format_options.h"
#include "app/file/split_filename.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/ui/status_bar.h"
@ -41,7 +42,6 @@
#include "raster/raster.h"
#include "ui/alert.h"
#include <allegro.h>
#include <cstring>
namespace app {
@ -50,22 +50,20 @@ using namespace base;
static FileOp* fop_new(FileOpType type, Context* context);
static void fop_prepare_for_sequence(FileOp* fop);
static int split_filename(const char* filename, char* left, char* right, int* width);
void get_readable_extensions(char* buf, int size)
{
FileFormatsList::iterator it = FileFormatsManager::instance()->begin();
FileFormatsList::iterator end = FileFormatsManager::instance()->end();
/* clear the string */
ustrncpy(buf, empty_string, size);
// Clear the string
strncpy(buf, "", size);
/* insert file format */
// Insert file format
for (; it != end; ++it) {
if ((*it)->support(FILE_SUPPORT_LOAD)) {
if (ustrcmp(buf, empty_string) != 0)
ustrncat(buf, ",", size);
ustrncat(buf, (*it)->extensions(), size);
if (*buf) strncat(buf, ",", size);
strncat(buf, (*it)->extensions(), size);
}
}
}
@ -75,15 +73,14 @@ void get_writable_extensions(char* buf, int size)
FileFormatsList::iterator it = FileFormatsManager::instance()->begin();
FileFormatsList::iterator end = FileFormatsManager::instance()->end();
/* clear the string */
ustrncpy(buf, empty_string, size);
// Clear the string
strncpy(buf, "", size);
/* insert file format */
// Insert file format
for (; it != end; ++it) {
if ((*it)->support(FILE_SUPPORT_SAVE)) {
if (ustrcmp(buf, empty_string) != 0)
ustrncat(buf, ",", size);
ustrncat(buf, (*it)->extensions(), size);
if (*buf) strncat(buf, ",", size);
strncat(buf, (*it)->extensions(), size);
}
}
}
@ -180,22 +177,23 @@ FileOp* fop_to_load_document(Context* context, const char* filename, int flags)
/* don't load the sequence (just the one file/one frame) */
if (!(flags & FILE_LOAD_SEQUENCE_NONE)) {
char buf[512], left[512], right[512];
std::string left, right;
int c, width, start_from;
char buf[512];
/* first of all, we must generate the list of files to load in the
sequence... */
/* check is this could be a sequence */
start_from = split_filename(filename, left, right, &width);
// Check is this could be a sequence
start_from = split_filename(filename, left, right, width);
if (start_from >= 0) {
/* try to get more file names */
// Try to get more file names
for (c=start_from+1; ; c++) {
/* get the next file name */
usprintf(buf, "%s%0*d%s", left, width, c, right);
// Get the next file name
sprintf(buf, "%s%0*d%s", left.c_str(), width, c, right.c_str());
/* if the file doesn't exist, we doesn't need more files to load */
if (!exists(buf))
// If the file doesn't exist, we doesn't need more files to load
if (!base::is_file(buf))
break;
/* add this file name to the list */
@ -208,14 +206,15 @@ FileOp* fop_to_load_document(Context* context, const char* filename, int flags)
/* really want load all files? */
if ((fop->seq.filename_list.size() > 1) &&
(ui::Alert::show("Notice"
"<<Possible animation with:"
"<<%s"
"<<Load the sequence of bitmaps?"
"||&Agree||&Skip",
get_filename(filename)) != 1)) {
"<<Possible animation with:"
"<<%s, %s..."
"<<Do you want to load the sequence of bitmaps?"
"||&Agree||&Skip",
base::get_file_name(fop->seq.filename_list[0]).c_str(),
base::get_file_name(fop->seq.filename_list[1]).c_str()) != 1)) {
/* if the user replies "Skip", we need just one file name (the
first one) */
// If the user replies "Skip", we need just one file name
// (the first one).
if (fop->seq.filename_list.size() > 1) {
fop->seq.filename_list.erase(fop->seq.filename_list.begin()+1,
fop->seq.filename_list.end());
@ -365,10 +364,10 @@ FileOp* fop_to_save_document(Context* context, Document* document)
}
// To save more frames
else {
char left[256], right[256];
std::string left, right;
int width, start_from;
start_from = split_filename(fop->document->filename().c_str(), left, right, &width);
start_from = split_filename(fop->document->filename().c_str(), left, right, width);
if (start_from < 0) {
start_from = 0;
width =
@ -380,7 +379,7 @@ FileOp* fop_to_save_document(Context* context, Document* document)
for (FrameNumber frame(0); frame<fop->document->sprite()->totalFrames(); ++frame) {
// Get the name for this frame
char buf[4096];
sprintf(buf, "%s%0*d%s", left, width, start_from+frame, right);
sprintf(buf, "%s%0*d%s", left.c_str(), width, start_from+frame, right.c_str());
fop->seq.filename_list.push_back(buf);
}
}
@ -755,9 +754,8 @@ void fop_error(FileOp *fop, const char *format, ...)
{
char buf_error[4096];
va_list ap;
va_start(ap, format);
uvszprintf(buf_error, sizeof(buf_error), format, ap);
vsnprintf(buf_error, sizeof(buf_error), format, ap);
va_end(ap);
// Concatenate the new error
@ -850,71 +848,4 @@ static void fop_prepare_for_sequence(FileOp* fop)
fop->seq.format_options.reset();
}
// Splits a file-name like "my_ani0000.pcx" to "my_ani" and ".pcx",
// returning the number of the center; returns "-1" if the function
// can't split anything
static int split_filename(const char* filename, char* left, char* right, int* width)
{
char *ptr, *ext;
char buf[16];
int chr, ret;
// Get the extension.
ext = get_extension(filename);
// With extension.
if ((ext) && (*ext)) {
// Left side (the filename without the extension and without the '.').
ext--;
*ext = 0;
ustrcpy(left, filename);
*ext = '.';
// Right side (the extension with the '.').
ustrcpy(right, ext);
}
// Without extension (without right side).
else {
ustrcpy(left, filename);
ustrcpy(right, empty_string);
}
// Remove all trailing numbers in the "left" side, and pass they to "buf".
ptr = buf+9;
ptr[1] = 0;
ret = -1;
if (width)
*width = 0;
for (;;) {
chr = ugetat(left, -1);
if ((chr >= '0') && (chr <= '9')) {
ret = 0;
if (ptr >= buf) {
*(ptr--) = chr;
if (width)
(*width)++;
}
uremove(left, -1);
}
else
break;
}
// Convert the "buf" to integer and return it.
if (ret == 0) {
while (ptr >= buf)
*(ptr--) = '0';
ret = ustrtol(buf, NULL, 10);
}
return ret;
}
} // namespace app

View File

@ -0,0 +1,73 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/file/split_filename.h"
#include "base/convert_to.h"
#include "base/path.h"
#include "base/string.h"
#include <cstring>
namespace app {
// Splits a file-name like "my_ani0000.pcx" to "my_ani" and ".pcx",
// returning the number of the center; returns "-1" if the function
// can't split anything
int split_filename(const char* filename, std::string& left, std::string& right, int& width)
{
left = base::join_path(
base::get_file_path(filename),
base::get_file_title(filename));
right = base::get_file_extension(filename);
if (!right.empty())
right.insert(right.begin(), '.');
// Remove all trailing numbers in the "left" side, and pass they to "buf".
std::string result_str;
width = 0;
for (;;) {
// Get the last utf-8 character
int chr = 0;
base::utf8_const_iterator begin(left.begin()), end(left.end());
base::utf8_const_iterator it(begin), prev(begin);
for (; it != end; prev=it, ++it)
chr = *it;
if ((chr >= '0') && (chr <= '9')) {
result_str.insert(result_str.begin(), chr);
width++;
left.erase(std::distance(begin, prev));
}
else
break;
}
// Convert the "buf" to integer and return it.
if (!result_str.empty()) {
return base::convert_to<int>(result_str);
}
else
return -1;
}
} // namespace app

View File

@ -0,0 +1,31 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_FILE_SPLIT_FILENAME_H_INCLUDED
#define APP_FILE_SPLIT_FILENAME_H_INCLUDED
#pragma once
#include <string>
namespace app {
int split_filename(const char* filename, std::string& left, std::string& right, int& width);
} // namespace app
#endif

View File

@ -0,0 +1,44 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tests/test.h"
#include "app/file/split_filename.h"
using namespace app;
TEST(SplitFilename, Common)
{
std::string left, right;
int width;
EXPECT_EQ(1, split_filename("C:\\test\\a1.png", left, right, width));
EXPECT_EQ("C:\\test\\a", left);
EXPECT_EQ(".png", right);
EXPECT_EQ(1, width);
EXPECT_EQ(0, split_filename("file00.png", left, right, width));
EXPECT_EQ("file", left);
EXPECT_EQ(".png", right);
EXPECT_EQ(2, width);
EXPECT_EQ(32, split_filename("sprite1-0032", left, right, width));
EXPECT_EQ("sprite1-", left);
EXPECT_EQ("", right);
EXPECT_EQ(4, width);
}