Skip to content

Commit ba928e6

Browse files
committed
Handling of sh_form_str (string containing information about the shape) was changed to be fully robust. In particular, shape files named as "%d.geom" are now correctly processed. Before, such names caused nonsence values in log file, since they were considered as format strings.
Functions rea_sprintf() and rea_vsprintf() added to io.c. Minor corrections in dyn_vsprintf(). In particular, error handling is now completely independent of LogError, calls to exit() are replaced by Stop().
1 parent 11b7d21 commit ba928e6

File tree

5 files changed

+133
-54
lines changed

5 files changed

+133
-54
lines changed

src/io.c

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,26 @@ static char warn_buf[MAX_MESSAGE2]="";
5353
* pointer to a new string is returned instead of passing it as an argument.
5454
*/
5555
static char *dyn_vsprintf(const char *format, va_list args)
56-
// same as vsprintf but allocates storage for the result
56+
/* same as vsprintf but allocates storage for the result
57+
* simple error handling is used, so it can be called from LogError, etc.
58+
*/
5759
{
5860
va_list copy;
5961
va_copy(copy,args);
6062
char *buffer=NULL; // default value to have deterministic behavior
6163
int count=vsnprintf(NULL,0,format,args);
6264
if (count>=0) {
63-
MALLOC_VECTOR(buffer,char,count+1,ALL);
64-
count=vsnprintf(buffer,count+1,format,copy);
65+
buffer=(char*)malloc(((size_t)count+1)*sizeof(char));
66+
if (buffer==NULL) {
67+
fprintf(stderr,"ERROR: malloc failed in '%s'",__func__);
68+
Stop(EXIT_FAILURE);
69+
}
70+
count=vsnprintf(buffer,(size_t)count+1,format,copy);
6571
}
66-
va_end(args);
67-
if (count<0) { // simple error handling, so it can be called from LogError, etc.
72+
va_end(copy);
73+
if (count<0) {
6874
fprintf(stderr,"ERROR: Code %d returned by vsnprintf in '%s'",count,__func__);
69-
exit(count);
75+
Stop(count);
7076
}
7177
return buffer;
7278
}
@@ -77,12 +83,51 @@ char *dyn_sprintf(const char *format, ...)
7783
// same as sprintf, but allocates storage for the result
7884
{
7985
va_list args;
80-
va_start(args, format);
86+
va_start(args,format);
8187
char *res=dyn_vsprintf(format,args);
8288
va_end(args);
8389
return res;
8490
}
8591

92+
//============================================================
93+
// The following two functions are simple modifications of the preceding two, with reallocation
94+
char *rea_vsprintf(char *str,const char *format, va_list args)
95+
/* same as vsprintf but result is added to string str, which is reallocated on the way
96+
* simple error handling is used, so it can be called from LogError, etc.
97+
*/{
98+
va_list copy;
99+
va_copy(copy,args);
100+
char *buffer=NULL; // default value to have deterministic behavior
101+
int count=vsnprintf(NULL,0,format,args);
102+
if (count>=0) {
103+
size_t len=strlen(str);
104+
buffer=(char*)realloc(str,((size_t)count+len+1)*sizeof(char));
105+
if (buffer==NULL) {
106+
fprintf(stderr,"ERROR: realloc failed in '%s'",__func__);
107+
Stop(EXIT_FAILURE);
108+
}
109+
count=vsnprintf(buffer+len,(size_t)count+1,format,copy);
110+
}
111+
va_end(copy);
112+
if (count<0) { // simple error handling, so it can be called from LogError, etc.
113+
fprintf(stderr,"ERROR: Code %d returned by vsnprintf in '%s'",count,__func__);
114+
Stop(count);
115+
}
116+
return buffer;
117+
}
118+
119+
//============================================================
120+
121+
char *rea_sprintf(char *str,const char *format, ...)
122+
// same as sprintf, but result is added to string str, which is reallocated on the way
123+
{
124+
va_list args;
125+
va_start(args,format);
126+
char *res=rea_vsprintf(str,format,args);
127+
va_end(args);
128+
return res;
129+
}
130+
86131
//============================================================
87132

88133
void WrapLines(char *restrict str)

src/io.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
}
5858

5959
char *dyn_sprintf(const char *format, ...) ATT_PRINTF(1,2) ATT_MALLOC;
60+
char *rea_sprintf(char *str,const char *format, ...) ATT_PRINTF(2,3) ATT_MALLOC;
6061
void WrapLines(char * restrict str);
6162
char *WrapLinesCopy(const char * restrict str);
6263
void LogError(ERR_LOC_DECL,const char * restrict fmt,...) ATT_PRINTF(4,5) ATT_NORETURN;

src/make_particle.c

Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ double gridspace; // interdipole distance (dipole size)
6969

7070
// used in param.c
7171
bool volcor_used; // volume correction was actually employed
72-
char sh_form_str[MAX_MESSAGE]; // string for log file with shape parameters
72+
const char *sh_form_str1,*sh_form_str2; // strings for log file with shape parameters
7373
size_t gr_N; // number of granules
7474
double gr_vf_real; // actual granules volume fraction
7575
size_t mat_count[MAX_NMAT+1]; // number of dipoles in each domain
@@ -1320,6 +1320,7 @@ void InitShape(void)
13201320
*/
13211321
n_boxX=n_boxY=n_boxZ=UNDEF;
13221322
n_sizeX=UNDEF;
1323+
sh_form_str2=""; // this variable can be left uninitialized by some shapes
13231324

13241325
size_given_cmd=(sizeX!=UNDEF || a_eq!=UNDEF);
13251326
if (sizeX!=UNDEF) sizename="size";
@@ -1343,9 +1344,8 @@ void InitShape(void)
13431344
* from file. Each line defines ro and z coordinates of a point, the first and the last
13441345
* points are connected automatically. Linear interpolation is used between the points.
13451346
*/
1346-
if (IFROOT) SnprintfErr(ONE_POS,sh_form_str,MAX_PARAGRAPH,
1347-
"axisymmetric, defined by a contour in ro-z plane from file %s; diameter:%s",
1348-
shape_fname,GFORM);
1347+
if (IFROOT) sh_form_str1=dyn_sprintf(
1348+
"axisymmetric, defined by a contour in ro-z plane from file %s; diameter:",shape_fname);
13491349
InitContour(shape_fname,&zx_ratio,&n_sizeX);
13501350
yx_ratio=1;
13511351
symZ=false; // input contour is assumed asymmetric over ro-axis
@@ -1363,8 +1363,12 @@ void InitShape(void)
13631363
coat_r2=0.25*coat_ratio*coat_ratio;
13641364
TestNonNegative(diskratio,"center-to-center distance to diameter ratio");
13651365
TestRangeII(coat_ratio,"inner/outer diameter ratio",0,1);
1366-
if (IFROOT) sprintf(sh_form_str,"bicoated; diameter(d):%s, center-center distance R_cc/d="
1367-
GFORM", inner diameter d_in/d="GFORM,GFORM,diskratio,coat_ratio);
1366+
if (IFROOT) {
1367+
sh_form_str1="bicoated; diameter(d):";
1368+
sh_form_str2=dyn_sprintf(", center-center distance R_cc/d="GFORM", inner diameter "
1369+
"d_in/d="GFORM,diskratio,coat_ratio);
1370+
}
1371+
13681372
coat_r2=0.25*coat_ratio*coat_ratio;
13691373
hdratio=diskratio/2.0;
13701374
if (diskratio>=1) volume_ratio = 2*PI_OVER_SIX;
@@ -1387,9 +1391,11 @@ void InitShape(void)
13871391
aspectZ2=sh_pars[4];
13881392
TestPositive(aspectZ2,"aspect ratio z2/x2");
13891393
// set descriptive string and symmetry
1390-
if (IFROOT) sprintf(sh_form_str,"biellipsoid; size along x-axis:%s; aspect ratios: y1/x1="
1391-
GFORM", z1/x1="GFORM", x2/x1="GFORM", y2/x2="GFORM", z2/x2="GFORM,
1392-
GFORM,aspectY,aspectZ,aspectXs,aspectY2,aspectZ2);
1394+
if (IFROOT) {
1395+
sh_form_str1="biellipsoid; size along x-axis:";
1396+
sh_form_str2=dyn_sprintf("; aspect ratios: y1/x1="GFORM", z1/x1="GFORM", x2/x1="GFORM
1397+
", y2/x2="GFORM", z2/x2="GFORM,aspectY,aspectZ,aspectXs,aspectY2,aspectZ2);
1398+
}
13931399
if (aspectY!=1 || aspectY2!=1) symR=false;
13941400
symZ=false; // since upper and lower ellipsoids are generally different both in size and RI
13951401
// set inverse squares of aspect ratios
@@ -1422,8 +1428,10 @@ void InitShape(void)
14221428

14231429
diskratio=sh_pars[0];
14241430
TestNonNegative(diskratio,"center-to-center distance to diameter ratio");
1425-
if (IFROOT) sprintf(sh_form_str,
1426-
"bisphere; diameter(d):%s, center-center distance R_cc/d="GFORM,GFORM,diskratio);
1431+
if (IFROOT) {
1432+
sh_form_str1="bisphere; diameter(d):";
1433+
sh_form_str2=dyn_sprintf(", center-center distance R_cc/d="GFORM,diskratio);
1434+
}
14271435
hdratio=diskratio/2.0;
14281436
if (diskratio>=1) volume_ratio = 2*PI_OVER_SIX;
14291437
else volume_ratio = PI_OVER_SIX*(2-diskratio)*(1+diskratio)*(1+diskratio)/2;
@@ -1435,16 +1443,18 @@ void InitShape(void)
14351443
double aspectY,aspectZ;
14361444

14371445
if (sh_Npars==0) {
1438-
if (IFROOT) strcpy(sh_form_str,"cube; size of edge along x-axis:"GFORM);
1446+
if (IFROOT) sh_form_str1="cube; size of edge along x-axis:";
14391447
aspectY=aspectZ=1;
14401448
}
14411449
else { // 2 parameters are given
14421450
aspectY=sh_pars[0];
14431451
TestPositive(aspectY,"aspect ratio y/x");
14441452
aspectZ=sh_pars[1];
14451453
TestPositive(aspectZ,"aspect ratio z/x");
1446-
if (IFROOT) sprintf(sh_form_str,"rectangular parallelepiped; size along x-axis:%s, "
1447-
"aspect ratio y/x="GFORM", z/x="GFORM,GFORM,aspectY,aspectZ);
1454+
if (IFROOT) {
1455+
sh_form_str1="rectangular parallelepiped; size along x-axis:";
1456+
sh_form_str2=dyn_sprintf(", aspect ratio y/x="GFORM", z/x="GFORM,aspectY,aspectZ);
1457+
}
14481458
}
14491459
if (aspectY!=1) symR=false;
14501460
// set half-aspect ratios
@@ -1460,8 +1470,10 @@ void InitShape(void)
14601470

14611471
diskratio=sh_pars[0];
14621472
TestNonNegative(diskratio,"height to diameter ratio");
1463-
if (IFROOT) sprintf(sh_form_str,"capsule; diameter(d):%s, cylinder height h/d="GFORM,
1464-
GFORM,diskratio);
1473+
if (IFROOT) {
1474+
sh_form_str1="capsule; diameter(d):";
1475+
sh_form_str2=dyn_sprintf(", cylinder height h/d="GFORM,diskratio);
1476+
}
14651477
hdratio=diskratio/2;
14661478
volume_ratio = PI_OVER_FOUR*diskratio + PI_OVER_SIX;
14671479
yx_ratio=1;
@@ -1479,9 +1491,11 @@ void InitShape(void)
14791491
ConvertToInteger(sh_pars[1],"number of sides",&chebn);
14801492
TestPositive_i(chebn,"order n");
14811493
ChebyshevParams(chebeps,chebn,&Dx,&Dz,&sz,&volume_ratio);
1482-
if (IFROOT) sprintf(sh_form_str,"axisymmetric chebyshev particle; size along x-axis (Dx):"
1483-
"%s, amplitude eps="GFORM", order n=%d, initial radius r0/Dx="GFORM,GFORM,chebeps,
1484-
chebn,1/Dx);
1494+
if (IFROOT) {
1495+
sh_form_str1="axisymmetric chebyshev particle; size along x-axis (Dx):";
1496+
sh_form_str2=dyn_sprintf(", amplitude eps="GFORM", order n=%d, initial radius r0/Dx="
1497+
GFORM,chebeps,chebn,1/Dx);
1498+
}
14851499
yx_ratio=1;
14861500
zx_ratio=Dz/Dx;
14871501
symZ=(sz!=0);
@@ -1494,21 +1508,25 @@ void InitShape(void)
14941508
}
14951509
else if (shape==SH_COATED) {
14961510
double coat_ratio;
1511+
char *buf=NULL; // redundant initialization to remove warnings
14971512

14981513
coat_ratio=sh_pars[0];
14991514
TestRangeII(coat_ratio,"inner/outer diameter ratio",0,1);
1500-
if (IFROOT) sprintf(sh_form_str,"coated sphere; diameter(d):%s, inner diameter d_in/d="
1501-
GFORM,GFORM,coat_ratio);
1515+
if (IFROOT) {
1516+
sh_form_str1="coated sphere; diameter(d):";
1517+
buf=dyn_sprintf(", inner diameter d_in/d="GFORM,coat_ratio);
1518+
}
15021519
if (sh_Npars==4) {
15031520
coat_x=sh_pars[1];
15041521
coat_y=sh_pars[2];
15051522
coat_z=sh_pars[3];
15061523
if (coat_x*coat_x+coat_y*coat_y+coat_z*coat_z>0.25*(1-coat_ratio)*(1-coat_ratio))
15071524
PrintErrorHelp("Inner sphere is not fully inside the outer");
1508-
if (IFROOT) sprintf(sh_form_str+strlen(sh_form_str),
1509-
"\n position of inner sphere center r/d= "GFORM3V,coat_x,coat_y,coat_z);
1525+
if (IFROOT) buf=rea_sprintf(buf,"\n position of inner sphere center r/d= "GFORM3V,
1526+
coat_x,coat_y,coat_z);
15101527
}
15111528
else coat_x=coat_y=coat_z=0; // initialize default values
1529+
if (IFROOT) sh_form_str2=buf;
15121530
coat_r2=0.25*coat_ratio*coat_ratio;
15131531
volume_ratio=PI_OVER_SIX;
15141532
if (coat_x!=0) symX=symR=false;
@@ -1522,8 +1540,10 @@ void InitShape(void)
15221540

15231541
diskratio=sh_pars[0];
15241542
TestPositive(diskratio,"height to diameter ratio");
1525-
if (IFROOT) sprintf(sh_form_str,"cylinder; diameter(d):%s, height h/d="GFORM,GFORM,
1526-
diskratio);
1543+
if (IFROOT) {
1544+
sh_form_str1="cylinder; diameter(d):";
1545+
sh_form_str2=dyn_sprintf(", height h/d="GFORM,diskratio);
1546+
}
15271547
hdratio=diskratio/2;
15281548
volume_ratio=PI_OVER_FOUR*diskratio;
15291549
yx_ratio=1;
@@ -1570,8 +1590,10 @@ void InitShape(void)
15701590
*/
15711591
volume_ratio=FOUR_PI_OVER_THREE*ad2*ad*((tmp3-egnu)*tmp1+(tmp3+egnu)*tmp2)
15721592
/(egnu*egnu+2*tmp3);
1573-
if (IFROOT) sprintf(sh_form_str,"egg; diameter(d):%s, epsilon="GFORM", nu="GFORM", a/d="
1574-
GFORM,GFORM,egeps,egnu,ad);
1593+
if (IFROOT) {
1594+
sh_form_str1="egg; diameter(d):";
1595+
sh_form_str2=dyn_sprintf(", epsilon="GFORM", nu="GFORM", a/d="GFORM,egeps,egnu,ad);
1596+
}
15751597
Nmat_need=1;
15761598
yx_ratio=1;
15771599
zx_ratio=ad*(tmp1+tmp2); // (a/d)*[1/sqrt(eps+nu)+1/sqrt(eps-nu)]
@@ -1583,8 +1605,10 @@ void InitShape(void)
15831605
TestPositive(aspectY,"aspect ratio y/x");
15841606
aspectZ=sh_pars[1];
15851607
TestPositive(aspectZ,"aspect ratio z/x");
1586-
if (IFROOT) sprintf(sh_form_str,"ellipsoid; size along x-axis:%s, aspect ratios y/x="GFORM
1587-
", z/x="GFORM,GFORM,aspectY,aspectZ);
1608+
if (IFROOT) {
1609+
sh_form_str1="ellipsoid; size along x-axis:";
1610+
sh_form_str2=dyn_sprintf(", aspect ratios y/x="GFORM", z/x="GFORM,aspectY,aspectZ);
1611+
}
15881612
if (aspectY!=1) symR=false;
15891613
// set inverse squares of aspect ratios
15901614
invsqY=1/(aspectY*aspectY);
@@ -1595,7 +1619,7 @@ void InitShape(void)
15951619
Nmat_need=1;
15961620
}
15971621
else if (shape==SH_LINE) {
1598-
if (IFROOT) strcpy(sh_form_str,"line; length:"GFORM);
1622+
if (IFROOT) sh_form_str1="line; length:";
15991623
symY=symZ=symR=false;
16001624
n_boxY=n_boxZ=jagged;
16011625
yx_ratio=zx_ratio=UNDEF;
@@ -1607,8 +1631,10 @@ void InitShape(void)
16071631

16081632
diskratio=sh_pars[0];
16091633
TestRangeNI(diskratio, "height to diameter ratio",0,1);
1610-
if (IFROOT) sprintf(sh_form_str,"plate; full diameter(d):%s, height h/d="GFORM,GFORM,
1611-
diskratio);
1634+
if (IFROOT) {
1635+
sh_form_str1="plate; full diameter(d):";
1636+
sh_form_str2=dyn_sprintf(", height h/d="GFORM,diskratio);
1637+
}
16121638
volume_ratio=PI*diskratio*(6+3*(PI-4)*diskratio+(10-3*PI)*diskratio*diskratio)/24;
16131639
yx_ratio=1;
16141640
zx_ratio=diskratio;
@@ -1648,8 +1674,10 @@ void InitShape(void)
16481674
}
16491675
else Dy=Dx; // N=4k
16501676
}
1651-
if (IFROOT) sprintf(sh_form_str,"%d-sided regular prism; size along x-axis (Dx):%s, height "
1652-
"h/Dx="GFORM", base side a/Dx="GFORM,Nsides,GFORM,diskratio,1/Dx);
1677+
if (IFROOT) {
1678+
sh_form_str1=dyn_sprintf("%d-sided regular prism; size along x-axis (Dx):",Nsides);
1679+
sh_form_str2=dyn_sprintf(", height h/Dx="GFORM", base side a/Dx="GFORM,diskratio,1/Dx);
1680+
}
16531681
xcenter=sx/Dx;
16541682
yx_ratio=Dy/Dx;
16551683
zx_ratio=diskratio;
@@ -1675,8 +1703,11 @@ void InitShape(void)
16751703
if (h_d<=b_d) PrintErrorHelp("given RBC is not biconcave; maximum width is in the center");
16761704
c_d=sh_pars[2];
16771705
TestRangeII(c_d,"relative diameter of maximum width",0,1);
1678-
if (IFROOT) sprintf(sh_form_str,"red blood cell; diameter(d):%s, maximum and minimum width "
1679-
"h/d="GFORM", b/d="GFORM", diameter of maximum width c/d="GFORM,GFORM,h_d,b_d,c_d);
1706+
if (IFROOT) {
1707+
sh_form_str1="red blood cell; diameter(d):";
1708+
sh_form_str2=dyn_sprintf(", maximum and minimum width h/d="GFORM", b/d="GFORM", "
1709+
"diameter of maximum width c/d="GFORM,h_d,b_d,c_d);
1710+
}
16801711
// calculate shape parameters
16811712
h2=h_d*h_d;
16821713
b2=b_d*b_d;
@@ -1700,13 +1731,13 @@ void InitShape(void)
17001731
symX=symY=symZ=symR=false; // input file is assumed fully asymmetric
17011732
const char *rf_text;
17021733
InitDipFile(shape_fname,&n_boxX,&n_boxY,&n_boxZ,&Nmat_need,&rf_text);
1703-
if (IFROOT) SnprintfErr(ONE_POS,sh_form_str,MAX_PARAGRAPH,
1704-
"specified by file %s - %s; size along x-axis:%s",shape_fname,rf_text,GFORM);
1734+
if (IFROOT) sh_form_str1=dyn_sprintf("specified by file %s - %s; size along x-axis:",
1735+
shape_fname,rf_text);
17051736
yx_ratio=zx_ratio=UNDEF;
17061737
volume_ratio=UNDEF;
17071738
}
17081739
else if (shape==SH_SPHERE) {
1709-
if (IFROOT) strcpy(sh_form_str,"sphere; diameter:"GFORM);
1740+
if (IFROOT) sh_form_str1="sphere; diameter:";
17101741
volume_ratio=PI_OVER_SIX;
17111742
yx_ratio=zx_ratio=1;
17121743
Nmat_need=1;
@@ -1716,8 +1747,10 @@ void InitShape(void)
17161747

17171748
coat_ratio=sh_pars[0];
17181749
TestRangeII(coat_ratio,"sphere diameter/cube edge ratio",0,1);
1719-
if (IFROOT) sprintf(sh_form_str,"sphere in cube; size of cube edge(a):%s, diameter of "
1720-
"sphere d/a="GFORM,GFORM,coat_ratio);
1750+
if (IFROOT) {
1751+
sh_form_str1="sphere in cube; size of cube edge(a):";
1752+
sh_form_str2=dyn_sprintf(", diameter of sphere d/a="GFORM,coat_ratio);
1753+
}
17211754
coat_r2=0.25*coat_ratio*coat_ratio;
17221755
yx_ratio=zx_ratio=1;
17231756
volume_ratio=1;

src/memory.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ char *charVector(const size_t size,OTHER_ARGUMENTS)
203203
//============================================================
204204

205205
char *charRealloc(char *ptr,const size_t size,OTHER_ARGUMENTS)
206-
// reallocates double vector ptr to a larger size
206+
// reallocates char vector ptr to a larger size
207207
{
208208
char *v;
209209

src/param.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ extern const char avg_string[];
7676
extern const char beam_descr[];
7777
// defined and initialized in make_particle.c
7878
extern const bool volcor_used;
79-
extern const char sh_form_str[];
79+
extern const char *sh_form_str1,*sh_form_str2;
8080
extern const int gr_N;
8181
extern const double gr_vf_real;
8282
extern const size_t mat_count[];
@@ -1999,12 +1999,12 @@ void PrintInfo(void)
19991999
// log basic parameters
20002000
fprintf(logfile,"lambda: "GFORM"\n",lambda);
20012001
fprintf(logfile,"shape: ");
2002-
fprintf(logfile,sh_form_str,sizeX);
2002+
fprintf(logfile,"%s"GFORM"%s\n",sh_form_str1,sizeX,sh_form_str2);
20032003
if (sh_granul) fprintf(logfile,
2004-
"\n domain %d is filled with %d granules of diameter "GFORMDEF"\n"
2005-
" volume fraction: specified - "GFORMDEF", actual - "GFORMDEF,
2004+
" domain %d is filled with %d granules of diameter "GFORMDEF"\n"
2005+
" volume fraction: specified - "GFORMDEF", actual - "GFORMDEF"\n",
20062006
gr_mat+1,gr_N,gr_d,gr_vf,gr_vf_real);
2007-
fprintf(logfile,"\nbox dimensions: %ix%ix%i\n",boxX,boxY,boxZ);
2007+
fprintf(logfile,"box dimensions: %ix%ix%i\n",boxX,boxY,boxZ);
20082008
if (anisotropy) {
20092009
fprintf(logfile,"refractive index (diagonal elements of the tensor):\n");
20102010
if (Nmat==1) fprintf(logfile," "CFORM3V"\n",

0 commit comments

Comments
 (0)