mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-05 06:20:10 +00:00
Add split_filename.cpp impl with base functions and std::string
This commit is contained in:
parent
ed67ee0d59
commit
0a3901cf39
@ -123,6 +123,7 @@ add_library(app-lib
|
|||||||
file/palette_file.cpp
|
file/palette_file.cpp
|
||||||
file/pcx_format.cpp
|
file/pcx_format.cpp
|
||||||
file/png_format.cpp
|
file/png_format.cpp
|
||||||
|
file/split_filename.cpp
|
||||||
file/tga_format.cpp
|
file/tga_format.cpp
|
||||||
file_selector.cpp
|
file_selector.cpp
|
||||||
file_system.cpp
|
file_system.cpp
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "app/file/file_format.h"
|
#include "app/file/file_format.h"
|
||||||
#include "app/file/file_formats_manager.h"
|
#include "app/file/file_formats_manager.h"
|
||||||
#include "app/file/format_options.h"
|
#include "app/file/format_options.h"
|
||||||
|
#include "app/file/split_filename.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
#include "app/modules/palettes.h"
|
#include "app/modules/palettes.h"
|
||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
@ -41,7 +42,6 @@
|
|||||||
#include "raster/raster.h"
|
#include "raster/raster.h"
|
||||||
#include "ui/alert.h"
|
#include "ui/alert.h"
|
||||||
|
|
||||||
#include <allegro.h>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -50,22 +50,20 @@ using namespace base;
|
|||||||
|
|
||||||
static FileOp* fop_new(FileOpType type, Context* context);
|
static FileOp* fop_new(FileOpType type, Context* context);
|
||||||
static void fop_prepare_for_sequence(FileOp* fop);
|
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)
|
void get_readable_extensions(char* buf, int size)
|
||||||
{
|
{
|
||||||
FileFormatsList::iterator it = FileFormatsManager::instance()->begin();
|
FileFormatsList::iterator it = FileFormatsManager::instance()->begin();
|
||||||
FileFormatsList::iterator end = FileFormatsManager::instance()->end();
|
FileFormatsList::iterator end = FileFormatsManager::instance()->end();
|
||||||
|
|
||||||
/* clear the string */
|
// Clear the string
|
||||||
ustrncpy(buf, empty_string, size);
|
strncpy(buf, "", size);
|
||||||
|
|
||||||
/* insert file format */
|
// Insert file format
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
if ((*it)->support(FILE_SUPPORT_LOAD)) {
|
if ((*it)->support(FILE_SUPPORT_LOAD)) {
|
||||||
if (ustrcmp(buf, empty_string) != 0)
|
if (*buf) strncat(buf, ",", size);
|
||||||
ustrncat(buf, ",", size);
|
strncat(buf, (*it)->extensions(), size);
|
||||||
ustrncat(buf, (*it)->extensions(), size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,15 +73,14 @@ void get_writable_extensions(char* buf, int size)
|
|||||||
FileFormatsList::iterator it = FileFormatsManager::instance()->begin();
|
FileFormatsList::iterator it = FileFormatsManager::instance()->begin();
|
||||||
FileFormatsList::iterator end = FileFormatsManager::instance()->end();
|
FileFormatsList::iterator end = FileFormatsManager::instance()->end();
|
||||||
|
|
||||||
/* clear the string */
|
// Clear the string
|
||||||
ustrncpy(buf, empty_string, size);
|
strncpy(buf, "", size);
|
||||||
|
|
||||||
/* insert file format */
|
// Insert file format
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
if ((*it)->support(FILE_SUPPORT_SAVE)) {
|
if ((*it)->support(FILE_SUPPORT_SAVE)) {
|
||||||
if (ustrcmp(buf, empty_string) != 0)
|
if (*buf) strncat(buf, ",", size);
|
||||||
ustrncat(buf, ",", size);
|
strncat(buf, (*it)->extensions(), size);
|
||||||
ustrncat(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) */
|
/* don't load the sequence (just the one file/one frame) */
|
||||||
if (!(flags & FILE_LOAD_SEQUENCE_NONE)) {
|
if (!(flags & FILE_LOAD_SEQUENCE_NONE)) {
|
||||||
char buf[512], left[512], right[512];
|
std::string left, right;
|
||||||
int c, width, start_from;
|
int c, width, start_from;
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
/* first of all, we must generate the list of files to load in the
|
/* first of all, we must generate the list of files to load in the
|
||||||
sequence... */
|
sequence... */
|
||||||
|
|
||||||
/* check is this could be a sequence */
|
// Check is this could be a sequence
|
||||||
start_from = split_filename(filename, left, right, &width);
|
start_from = split_filename(filename, left, right, width);
|
||||||
if (start_from >= 0) {
|
if (start_from >= 0) {
|
||||||
/* try to get more file names */
|
// Try to get more file names
|
||||||
for (c=start_from+1; ; c++) {
|
for (c=start_from+1; ; c++) {
|
||||||
/* get the next file name */
|
// Get the next file name
|
||||||
usprintf(buf, "%s%0*d%s", left, width, c, right);
|
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 the file doesn't exist, we doesn't need more files to load
|
||||||
if (!exists(buf))
|
if (!base::is_file(buf))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* add this file name to the list */
|
/* 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? */
|
/* really want load all files? */
|
||||||
if ((fop->seq.filename_list.size() > 1) &&
|
if ((fop->seq.filename_list.size() > 1) &&
|
||||||
(ui::Alert::show("Notice"
|
(ui::Alert::show("Notice"
|
||||||
"<<Possible animation with:"
|
"<<Possible animation with:"
|
||||||
"<<%s"
|
"<<%s, %s..."
|
||||||
"<<Load the sequence of bitmaps?"
|
"<<Do you want to load the sequence of bitmaps?"
|
||||||
"||&Agree||&Skip",
|
"||&Agree||&Skip",
|
||||||
get_filename(filename)) != 1)) {
|
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
|
// If the user replies "Skip", we need just one file name
|
||||||
first one) */
|
// (the first one).
|
||||||
if (fop->seq.filename_list.size() > 1) {
|
if (fop->seq.filename_list.size() > 1) {
|
||||||
fop->seq.filename_list.erase(fop->seq.filename_list.begin()+1,
|
fop->seq.filename_list.erase(fop->seq.filename_list.begin()+1,
|
||||||
fop->seq.filename_list.end());
|
fop->seq.filename_list.end());
|
||||||
@ -365,10 +364,10 @@ FileOp* fop_to_save_document(Context* context, Document* document)
|
|||||||
}
|
}
|
||||||
// To save more frames
|
// To save more frames
|
||||||
else {
|
else {
|
||||||
char left[256], right[256];
|
std::string left, right;
|
||||||
int width, start_from;
|
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) {
|
if (start_from < 0) {
|
||||||
start_from = 0;
|
start_from = 0;
|
||||||
width =
|
width =
|
||||||
@ -380,7 +379,7 @@ FileOp* fop_to_save_document(Context* context, Document* document)
|
|||||||
for (FrameNumber frame(0); frame<fop->document->sprite()->totalFrames(); ++frame) {
|
for (FrameNumber frame(0); frame<fop->document->sprite()->totalFrames(); ++frame) {
|
||||||
// Get the name for this frame
|
// Get the name for this frame
|
||||||
char buf[4096];
|
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);
|
fop->seq.filename_list.push_back(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -755,9 +754,8 @@ void fop_error(FileOp *fop, const char *format, ...)
|
|||||||
{
|
{
|
||||||
char buf_error[4096];
|
char buf_error[4096];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
uvszprintf(buf_error, sizeof(buf_error), format, ap);
|
vsnprintf(buf_error, sizeof(buf_error), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
// Concatenate the new error
|
// Concatenate the new error
|
||||||
@ -850,71 +848,4 @@ static void fop_prepare_for_sequence(FileOp* fop)
|
|||||||
fop->seq.format_options.reset();
|
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
|
} // namespace app
|
||||||
|
73
src/app/file/split_filename.cpp
Normal file
73
src/app/file/split_filename.cpp
Normal 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
|
31
src/app/file/split_filename.h
Normal file
31
src/app/file/split_filename.h
Normal 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
|
44
src/app/file/split_filename_tests.cpp
Normal file
44
src/app/file/split_filename_tests.cpp
Normal 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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user