mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2024-11-28 05:19:18 +08:00
Merge pull request #3368 from stweil/master
Replace remaining malloc / strdup / free
This commit is contained in:
commit
7568a3625b
@ -103,7 +103,7 @@ struct INT_CLASS_STRUCT {
|
||||
int font_set_id; // FontSet id, see above
|
||||
};
|
||||
|
||||
struct INT_TEMPLATES_STRUCT {
|
||||
struct TESS_API INT_TEMPLATES_STRUCT {
|
||||
INT_TEMPLATES_STRUCT();
|
||||
~INT_TEMPLATES_STRUCT();
|
||||
int NumClasses;
|
||||
|
@ -159,7 +159,7 @@ int main(int argc, char *argv[]) {
|
||||
printf(
|
||||
"0 significant protos for %s."
|
||||
" Retrying clustering with MinSamples = %f%%\n",
|
||||
CharSample->Label, Config.MinSamples);
|
||||
CharSample->Label.c_str(), Config.MinSamples);
|
||||
}
|
||||
}
|
||||
Config.MinSamples = SavedMinSamples;
|
||||
@ -216,11 +216,11 @@ static void WriteNormProtos(const char *Directory, LIST LabeledProtoList,
|
||||
"\nError! Not enough protos for %s: %d protos"
|
||||
" (%d significant protos"
|
||||
", %d insignificant protos)\n",
|
||||
LabeledProto->Label, N, NumberOfProtos(LabeledProto->List, true, false),
|
||||
LabeledProto->Label.c_str(), N, NumberOfProtos(LabeledProto->List, true, false),
|
||||
NumberOfProtos(LabeledProto->List, false, true));
|
||||
exit(1);
|
||||
}
|
||||
fprintf(File, "\n%s %d\n", LabeledProto->Label, N);
|
||||
fprintf(File, "\n%s %d\n", LabeledProto->Label.c_str(), N);
|
||||
WriteProtos(File, feature_desc->NumParams, LabeledProto->List, true, false);
|
||||
}
|
||||
fclose(File);
|
||||
|
@ -32,6 +32,8 @@
|
||||
#define STRING_PARAM_FLAG(name, val, comment) STRING_VAR(FLAGS_##name, val, comment)
|
||||
#define DECLARE_STRING_PARAM_FLAG(name) extern STRING_VAR_H(FLAGS_##name, "", "")
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
// Flags from commontraining.cpp
|
||||
// Command line arguments for font_properties, xheights and unicharset.
|
||||
TESS_COMMON_TRAINING_API
|
||||
@ -55,8 +57,6 @@ DECLARE_STRING_PARAM_FLAG(output_trainer);
|
||||
TESS_COMMON_TRAINING_API
|
||||
DECLARE_STRING_PARAM_FLAG(test_ch);
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
// Parse commandline flags and values. Prints the usage string and exits on
|
||||
// input of --help or --version.
|
||||
//
|
||||
|
@ -20,6 +20,8 @@
|
||||
# include "params.h"
|
||||
# include "tprintf.h"
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
INT_PARAM_FLAG(debug_level, 0, "Level of Trainer debugging");
|
||||
INT_PARAM_FLAG(load_images, 0, "Load images with tr files");
|
||||
STRING_PARAM_FLAG(configfile, "", "File to load more configs from");
|
||||
@ -35,8 +37,6 @@ STRING_PARAM_FLAG(fonts_dir, "",
|
||||
"system default font location");
|
||||
STRING_PARAM_FLAG(fontconfig_tmpdir, "/tmp", "Overrides fontconfig default temporary dir");
|
||||
|
||||
using namespace tesseract;
|
||||
|
||||
/**
|
||||
* This routine parses the command line arguments that were
|
||||
* passed to the program and uses them to set relevant
|
||||
@ -59,6 +59,8 @@ void ParseArguments(int *argc, char ***argv) {
|
||||
tesseract::ParseCommandLineFlags(usage.c_str(), argc, argv, true);
|
||||
}
|
||||
|
||||
} // namespace tesseract.
|
||||
|
||||
#else
|
||||
|
||||
# include <allheaders.h>
|
||||
@ -78,7 +80,7 @@ void ParseArguments(int *argc, char ***argv) {
|
||||
# include "tprintf.h"
|
||||
# include "unicity_table.h"
|
||||
|
||||
using namespace tesseract;
|
||||
namespace tesseract {
|
||||
|
||||
// Global Variables.
|
||||
|
||||
@ -142,7 +144,6 @@ void ParseArguments(int *argc, char ***argv) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace tesseract {
|
||||
// Helper loads shape table from the given file.
|
||||
ShapeTable *LoadShapeTable(const std::string &file_prefix) {
|
||||
ShapeTable *shape_table = nullptr;
|
||||
@ -290,8 +291,6 @@ std::unique_ptr<MasterTrainer> LoadTrainingData(int argc, const char *const *arg
|
||||
return trainer;
|
||||
}
|
||||
|
||||
} // namespace tesseract.
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* This routine returns the next command line argument. If
|
||||
@ -321,12 +320,12 @@ const char *GetNextFilename(int argc, const char *const *argv, int &tessoptind)
|
||||
* @return Labeled list with the specified label or nullptr.
|
||||
* @note Globals: none
|
||||
*/
|
||||
LABELEDLIST FindList(LIST List, char *Label) {
|
||||
LABELEDLIST FindList(LIST List, const std::string &Label) {
|
||||
LABELEDLIST LabeledList;
|
||||
|
||||
iterate(List) {
|
||||
LabeledList = reinterpret_cast<LABELEDLIST> first_node(List);
|
||||
if (strcmp(LabeledList->Label, Label) == 0) {
|
||||
if (LabeledList->Label == Label) {
|
||||
return (LabeledList);
|
||||
}
|
||||
}
|
||||
@ -334,27 +333,6 @@ LABELEDLIST FindList(LIST List, char *Label) {
|
||||
|
||||
} /* FindList */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* This routine allocates a new, empty labeled list and gives
|
||||
* it the specified label.
|
||||
* @param Label label for new list
|
||||
* @return New, empty labeled list.
|
||||
* @note Globals: none
|
||||
*/
|
||||
LABELEDLIST NewLabeledList(const char *Label) {
|
||||
LABELEDLIST LabeledList;
|
||||
|
||||
LabeledList = static_cast<LABELEDLIST>(malloc(sizeof(LABELEDLISTNODE)));
|
||||
LabeledList->Label = static_cast<char *>(malloc(strlen(Label) + 1));
|
||||
strcpy(LabeledList->Label, Label);
|
||||
LabeledList->List = NIL_LIST;
|
||||
LabeledList->SampleCount = 0;
|
||||
LabeledList->font_sample_count = 0;
|
||||
return (LabeledList);
|
||||
|
||||
} /* NewLabeledList */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// TODO(rays) This is now used only by cntraining. Convert cntraining to use
|
||||
// the new method or get rid of it entirely.
|
||||
@ -403,7 +381,7 @@ void ReadTrainingSamples(const FEATURE_DEFS_STRUCT &feature_definitions, const c
|
||||
}
|
||||
char_sample = FindList(*training_samples, unichar);
|
||||
if (char_sample == nullptr) {
|
||||
char_sample = NewLabeledList(unichar);
|
||||
char_sample = new LABELEDLISTNODE(unichar);
|
||||
*training_samples = push(*training_samples, char_sample);
|
||||
}
|
||||
auto char_desc = ReadCharDescription(feature_definitions, file);
|
||||
@ -420,7 +398,7 @@ void ReadTrainingSamples(const FEATURE_DEFS_STRUCT &feature_definitions, const c
|
||||
delete char_desc->FeatureSets[i];
|
||||
}
|
||||
}
|
||||
free(char_desc);
|
||||
delete char_desc;
|
||||
}
|
||||
} // ReadTrainingSamples
|
||||
|
||||
@ -458,8 +436,7 @@ void FreeTrainingSamples(LIST CharList) {
|
||||
*/
|
||||
void FreeLabeledList(LABELEDLIST LabeledList) {
|
||||
destroy(LabeledList->List);
|
||||
free(LabeledList->Label);
|
||||
free(LabeledList);
|
||||
delete LabeledList;
|
||||
} /* FreeLabeledList */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -477,8 +454,6 @@ void FreeLabeledList(LABELEDLIST LabeledList) {
|
||||
CLUSTERER *SetUpForClustering(const FEATURE_DEFS_STRUCT &FeatureDefs, LABELEDLIST char_sample,
|
||||
const char *program_feature_type) {
|
||||
uint16_t N;
|
||||
int i, j;
|
||||
float *Sample = nullptr;
|
||||
CLUSTERER *Clusterer;
|
||||
int32_t CharID;
|
||||
LIST FeatureList = nullptr;
|
||||
@ -490,20 +465,20 @@ CLUSTERER *SetUpForClustering(const FEATURE_DEFS_STRUCT &FeatureDefs, LABELEDLIS
|
||||
|
||||
FeatureList = char_sample->List;
|
||||
CharID = 0;
|
||||
std::vector<float> Sample;
|
||||
iterate(FeatureList) {
|
||||
FeatureSet = reinterpret_cast<FEATURE_SET> first_node(FeatureList);
|
||||
for (i = 0; i < FeatureSet->MaxNumFeatures; i++) {
|
||||
if (Sample == nullptr) {
|
||||
Sample = static_cast<float *>(malloc(N * sizeof(float)));
|
||||
for (int i = 0; i < FeatureSet->MaxNumFeatures; i++) {
|
||||
if (Sample.empty()) {
|
||||
Sample.resize(N);
|
||||
}
|
||||
for (j = 0; j < N; j++) {
|
||||
for (int j = 0; j < N; j++) {
|
||||
Sample[j] = FeatureSet->Features[i]->Params[j];
|
||||
}
|
||||
MakeSample(Clusterer, Sample, CharID);
|
||||
MakeSample(Clusterer, &Sample[0], CharID);
|
||||
}
|
||||
CharID++;
|
||||
}
|
||||
free(Sample);
|
||||
return Clusterer;
|
||||
|
||||
} /* SetUpForClustering */
|
||||
@ -638,12 +613,12 @@ LIST RemoveInsignificantProtos(LIST ProtoList, bool KeepSigProtos, bool KeepInsi
|
||||
} /* RemoveInsignificantProtos */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
MERGE_CLASS FindClass(LIST List, const char *Label) {
|
||||
MERGE_CLASS FindClass(LIST List, const std::string &Label) {
|
||||
MERGE_CLASS MergeClass;
|
||||
|
||||
iterate(List) {
|
||||
MergeClass = reinterpret_cast<MERGE_CLASS> first_node(List);
|
||||
if (strcmp(MergeClass->Label, Label) == 0) {
|
||||
if (MergeClass->Label == Label) {
|
||||
return (MergeClass);
|
||||
}
|
||||
}
|
||||
@ -651,18 +626,6 @@ MERGE_CLASS FindClass(LIST List, const char *Label) {
|
||||
|
||||
} /* FindClass */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
MERGE_CLASS NewLabeledClass(const char *Label) {
|
||||
MERGE_CLASS MergeClass;
|
||||
|
||||
MergeClass = new MERGE_CLASS_NODE;
|
||||
MergeClass->Label = static_cast<char *>(malloc(strlen(Label) + 1));
|
||||
strcpy(MergeClass->Label, Label);
|
||||
MergeClass->Class = NewClass(MAX_NUM_PROTOS, MAX_NUM_CONFIGS);
|
||||
return (MergeClass);
|
||||
|
||||
} /* NewLabeledClass */
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* This routine deallocates all of the space allocated to
|
||||
@ -676,7 +639,6 @@ void FreeLabeledClassList(LIST ClassList) {
|
||||
iterate(ClassList) /* iterate through all of the fonts */
|
||||
{
|
||||
MergeClass = reinterpret_cast<MERGE_CLASS> first_node(ClassList);
|
||||
free(MergeClass->Label);
|
||||
FreeClass(MergeClass->Class);
|
||||
delete MergeClass;
|
||||
}
|
||||
@ -704,7 +666,7 @@ CLASS_STRUCT *SetUpForFloat2Int(const UNICHARSET &unicharset, LIST LabeledClassL
|
||||
iterate(LabeledClassList) {
|
||||
UnicityTable<int> font_set;
|
||||
MergeClass = reinterpret_cast<MERGE_CLASS> first_node(LabeledClassList);
|
||||
Class = &float_classes[unicharset.unichar_to_id(MergeClass->Label)];
|
||||
Class = &float_classes[unicharset.unichar_to_id(MergeClass->Label.c_str())];
|
||||
NumProtos = MergeClass->Class->NumProtos;
|
||||
NumConfigs = MergeClass->Class->NumConfigs;
|
||||
font_set.move(&MergeClass->Class->font_set);
|
||||
@ -776,13 +738,10 @@ void FreeNormProtoList(LIST CharList)
|
||||
} // FreeNormProtoList
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void AddToNormProtosList(LIST *NormProtoList, LIST ProtoList, char *CharName) {
|
||||
PROTOTYPE *Proto;
|
||||
LABELEDLIST LabeledProtoList;
|
||||
|
||||
LabeledProtoList = NewLabeledList(CharName);
|
||||
void AddToNormProtosList(LIST *NormProtoList, LIST ProtoList, const std::string &CharName) {
|
||||
auto LabeledProtoList = new LABELEDLISTNODE(CharName.c_str());
|
||||
iterate(ProtoList) {
|
||||
Proto = reinterpret_cast<PROTOTYPE *> first_node(ProtoList);
|
||||
auto Proto = reinterpret_cast<PROTOTYPE *> first_node(ProtoList);
|
||||
LabeledProtoList->List = push(LabeledProtoList->List, Proto);
|
||||
}
|
||||
*NormProtoList = push(*NormProtoList, LabeledProtoList);
|
||||
@ -800,4 +759,6 @@ int NumberOfProtos(LIST ProtoList, bool CountSigProtos, bool CountInsigProtos) {
|
||||
return (N);
|
||||
}
|
||||
|
||||
} // namespace tesseract.
|
||||
|
||||
#endif // def DISABLED_LEGACY_ENGINE
|
||||
|
@ -26,11 +26,11 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
void ParseArguments(int *argc, char ***argv);
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
// Check whether the shared tesseract library is the right one.
|
||||
// This function must be inline because otherwise it would be part of
|
||||
// the shared library, so it could not compare the versions.
|
||||
@ -56,35 +56,43 @@ static inline void CheckSharedLibraryVersion() {
|
||||
# include "oldlist.h"
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
class Classify;
|
||||
class MasterTrainer;
|
||||
class ShapeTable;
|
||||
} // namespace tesseract
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Globals ///////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
extern tesseract::FEATURE_DEFS_STRUCT feature_defs;
|
||||
extern FEATURE_DEFS_STRUCT feature_defs;
|
||||
|
||||
// Must be defined in the file that "implements" commonTraining facilities.
|
||||
TESS_COMMON_TRAINING_API
|
||||
extern tesseract::CLUSTERCONFIG Config;
|
||||
extern CLUSTERCONFIG Config;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Structs ///////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
struct LABELEDLISTNODE {
|
||||
char *Label;
|
||||
int SampleCount;
|
||||
int font_sample_count;
|
||||
tesseract::LIST List;
|
||||
/// This constructor allocates a new, empty labeled list and gives
|
||||
/// it the specified label.
|
||||
/// @param Label label for new list
|
||||
LABELEDLISTNODE(const char *label) : Label(label) {
|
||||
}
|
||||
std::string Label;
|
||||
int SampleCount = 0;
|
||||
int font_sample_count = 0;
|
||||
LIST List = nullptr;
|
||||
};
|
||||
using LABELEDLIST = LABELEDLISTNODE *;
|
||||
|
||||
struct MERGE_CLASS_NODE {
|
||||
char *Label;
|
||||
MERGE_CLASS_NODE(const char * label) : Label(label) {
|
||||
NewClass(MAX_NUM_PROTOS, MAX_NUM_CONFIGS);
|
||||
}
|
||||
std::string Label;
|
||||
int NumMerged[MAX_NUM_PROTOS];
|
||||
tesseract::CLASS_TYPE Class;
|
||||
};
|
||||
@ -94,8 +102,6 @@ using MERGE_CLASS = MERGE_CLASS_NODE *;
|
||||
// Functions /////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
// Helper loads shape table from the given file.
|
||||
ShapeTable *LoadShapeTable(const std::string &file_prefix);
|
||||
// Helper to write the shape_table.
|
||||
@ -119,15 +125,10 @@ TESS_COMMON_TRAINING_API
|
||||
std::unique_ptr<MasterTrainer> LoadTrainingData(int argc, const char *const *argv, bool replication,
|
||||
ShapeTable **shape_table, std::string &file_prefix);
|
||||
|
||||
} // namespace tesseract.
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
const char *GetNextFilename(int argc, const char *const *argv, int &tessoptind);
|
||||
|
||||
LABELEDLIST FindList(tesseract::LIST List, char *Label);
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
LABELEDLIST NewLabeledList(const char *Label);
|
||||
LABELEDLIST FindList(tesseract::LIST List, const std::string &Label);
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
void ReadTrainingSamples(const tesseract::FEATURE_DEFS_STRUCT &feature_defs,
|
||||
@ -163,10 +164,7 @@ void MergeInsignificantProtos(tesseract::LIST ProtoList, const char *label,
|
||||
tesseract::CLUSTERER *Clusterer, tesseract::CLUSTERCONFIG *Config);
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
MERGE_CLASS FindClass(tesseract::LIST List, const char *Label);
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
MERGE_CLASS NewLabeledClass(const char *Label);
|
||||
MERGE_CLASS FindClass(tesseract::LIST List, const std::string &Label);
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
tesseract::CLASS_STRUCT *SetUpForFloat2Int(const tesseract::UNICHARSET &unicharset,
|
||||
@ -178,13 +176,15 @@ TESS_COMMON_TRAINING_API
|
||||
void FreeNormProtoList(tesseract::LIST CharList);
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
void AddToNormProtosList(tesseract::LIST *NormProtoList, tesseract::LIST ProtoList, char *CharName);
|
||||
void AddToNormProtosList(tesseract::LIST *NormProtoList, tesseract::LIST ProtoList, const std::string &CharName);
|
||||
|
||||
TESS_COMMON_TRAINING_API
|
||||
int NumberOfProtos(tesseract::LIST ProtoList, bool CountSigProtos, bool CountInsigProtos);
|
||||
|
||||
void allocNormProtos();
|
||||
|
||||
} // namespace tesseract
|
||||
|
||||
#endif // def DISABLED_LEGACY_ENGINE
|
||||
|
||||
#endif // TESSERACT_TRAINING_COMMONTRAINING_H_
|
||||
|
@ -252,8 +252,8 @@ void GeneratePerspectiveDistortion(int width, int height, TRand *randomizer, Pix
|
||||
b = new_box1.bounding_union(new_box2);
|
||||
}
|
||||
}
|
||||
free(im_coeffs);
|
||||
free(box_coeffs);
|
||||
lept_free(im_coeffs);
|
||||
lept_free(box_coeffs);
|
||||
}
|
||||
|
||||
// Computes the coefficients of a randomized projective transformation.
|
||||
|
@ -109,7 +109,7 @@ static LIST ClusterOneConfig(int shape_id, const char *class_label, LIST mf_clas
|
||||
FreeClusterer(clusterer);
|
||||
MERGE_CLASS merge_class = FindClass(mf_classes, class_label);
|
||||
if (merge_class == nullptr) {
|
||||
merge_class = NewLabeledClass(class_label);
|
||||
merge_class = new MERGE_CLASS_NODE(class_label);
|
||||
mf_classes = push(mf_classes, merge_class);
|
||||
}
|
||||
int config_id = AddConfigToClass(merge_class->Class);
|
||||
|
@ -3,7 +3,6 @@
|
||||
* Description: Class for rendering UTF-8 text to an image, and retrieving
|
||||
* bounding boxes around each grapheme cluster.
|
||||
* Author: Ranjith Unnikrishnan
|
||||
* Created: Mon Nov 18 2013
|
||||
*
|
||||
* (C) Copyright 2013, Google Inc.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -108,7 +107,6 @@ StringRenderer::StringRenderer(const std::string &font_desc, int page_width, int
|
||||
, underline_start_prob_(0)
|
||||
, underline_continuation_prob_(0)
|
||||
, underline_style_(PANGO_UNDERLINE_SINGLE)
|
||||
, features_(nullptr)
|
||||
, drop_uncovered_chars_(true)
|
||||
, strip_unrenderable_words_(false)
|
||||
, add_ligatures_(false)
|
||||
@ -147,7 +145,6 @@ void StringRenderer::set_underline_continuation_prob(const double frac) {
|
||||
}
|
||||
|
||||
StringRenderer::~StringRenderer() {
|
||||
free(features_);
|
||||
ClearBoxes();
|
||||
FreePangoCairo();
|
||||
}
|
||||
@ -204,7 +201,7 @@ void StringRenderer::SetLayoutProperties() {
|
||||
#if (PANGO_VERSION_MAJOR == 1 && PANGO_VERSION_MINOR >= 38)
|
||||
if (add_ligatures_) {
|
||||
set_features("liga, clig, dlig, hlig");
|
||||
PangoAttribute *feature_attr = pango_attr_font_features_new(features_);
|
||||
PangoAttribute *feature_attr = pango_attr_font_features_new(features_.c_str());
|
||||
pango_attr_list_change(attr_list, feature_attr);
|
||||
}
|
||||
#endif
|
||||
|
@ -41,10 +41,6 @@
|
||||
struct Boxa;
|
||||
struct Pix;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strdup(s) _strdup(s)
|
||||
#endif
|
||||
|
||||
namespace tesseract {
|
||||
|
||||
class BoxChar;
|
||||
@ -95,8 +91,7 @@ public:
|
||||
underline_style_ = style;
|
||||
}
|
||||
void set_features(const char *features) {
|
||||
free(features_);
|
||||
features_ = strdup(features);
|
||||
features_ = features;
|
||||
}
|
||||
void set_page(int page) {
|
||||
page_ = page;
|
||||
@ -196,7 +191,7 @@ protected:
|
||||
double underline_start_prob_;
|
||||
double underline_continuation_prob_;
|
||||
PangoUnderline underline_style_;
|
||||
char *features_;
|
||||
std::string features_;
|
||||
// Text filtering options
|
||||
bool drop_uncovered_chars_;
|
||||
bool strip_unrenderable_words_;
|
||||
|
@ -87,22 +87,23 @@ void SVSync::StartProcess(const char *executable, const char *args) {
|
||||
// broken socket detection seems to be useless.
|
||||
prctl(PR_SET_PDEATHSIG, 2, 0, 0, 0);
|
||||
# endif
|
||||
char *mutable_args = strdup(args);
|
||||
std::string mutable_args(args);
|
||||
int argc = 1;
|
||||
for (int i = 0; mutable_args[i]; ++i) {
|
||||
if (mutable_args[i] == ' ') {
|
||||
for (auto ch : mutable_args) {
|
||||
if (ch == ' ') {
|
||||
++argc;
|
||||
}
|
||||
}
|
||||
std::unique_ptr<char *[]> argv(new char *[argc + 2]);
|
||||
argv[0] = strdup(executable);
|
||||
argv[1] = mutable_args;
|
||||
std::string argv0(executable);
|
||||
argv[0] = &argv0[0];
|
||||
argv[1] = &mutable_args[0];
|
||||
argc = 2;
|
||||
bool inquote = false;
|
||||
for (int i = 0; mutable_args[i]; ++i) {
|
||||
if (!inquote && mutable_args[i] == ' ') {
|
||||
mutable_args[i] = '\0';
|
||||
argv[argc++] = mutable_args + i + 1;
|
||||
argv[argc++] = &mutable_args[i + 1];
|
||||
} else if (mutable_args[i] == '"') {
|
||||
inquote = !inquote;
|
||||
mutable_args[i] = ' ';
|
||||
@ -110,8 +111,6 @@ void SVSync::StartProcess(const char *executable, const char *args) {
|
||||
}
|
||||
argv[argc] = nullptr;
|
||||
execvp(executable, argv.get());
|
||||
free(argv[0]);
|
||||
free(argv[1]);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user