1313 *
1414 */
1515
16+ #include < mutex>
1617#include " plantuml.h"
1718#include " util.h"
1819#include " portable.h"
2526#include " indexlist.h"
2627#include " stringutil.h"
2728
28- QCString PlantumlManager::writePlantUMLSource (const QCString &outDirArg,const QCString &fileName,
29+ static std::mutex g_PlantUmlMutex;
30+
31+ std::vector<QCString> PlantumlManager::writePlantUMLSource (const QCString &outDirArg,const QCString &fileName,
2932 const QCString &content,OutputFormat format, const QCString &engine,
3033 const QCString &srcFile,int srcLine,bool inlineCode)
3134{
35+ std::vector<QCString> baseNameVector;
3236 QCString baseName;
3337 QCString puName;
3438 QCString imgName;
3539 QCString outDir (outDirArg);
36- static int umlindex=1 ;
3740
3841 Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource fileName: {}\n " ,fileName);
3942 Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource outDir: {}\n " ,outDir);
@@ -45,32 +48,7 @@ QCString PlantumlManager::writePlantUMLSource(const QCString &outDirArg,const QC
4548 outDir = outDir.left (l-1 );
4649 }
4750
48- if (fileName.isEmpty ()) // generate name
49- {
50- puName = " inline_umlgraph_" +QCString ().setNum (umlindex);
51- baseName = outDir+" /inline_umlgraph_" +QCString ().setNum (umlindex++);
52- }
53- else // user specified name
54- {
55- baseName = fileName;
56- int i=baseName.findRev (' .' );
57- if (i!=-1 ) baseName = baseName.left (i);
58- puName = baseName;
59- baseName.prepend (outDir+" /" );
60- }
61-
62- switch (format)
63- {
64- case PUML_BITMAP:
65- imgName =puName+" .png" ;
66- break ;
67- case PUML_EPS:
68- imgName =puName+" .eps" ;
69- break ;
70- case PUML_SVG:
71- imgName =puName+" .svg" ;
72- break ;
73- }
51+ generatePlantUmlFileNames (fileName,format,outDir,baseName,puName,imgName);
7452
7553 Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSourcebaseName: {}\n " ,baseName);
7654 Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSourcebaseName puName: {}\n " ,puName);
@@ -84,7 +62,7 @@ QCString PlantumlManager::writePlantUMLSource(const QCString &outDirArg,const QC
8462 {
8563 char c = 0 ;
8664 bool insideComment = false ;
87- bool initial = true ;
65+ QCString locEngine ;
8866 while ((c=*p++))
8967 {
9068 text+=c;
@@ -95,34 +73,153 @@ QCString PlantumlManager::writePlantUMLSource(const QCString &outDirArg,const QC
9573 case ' \t ' : break ;
9674 case ' ' : break ;
9775 case ' @' :
98- if (initial && literal_at (p," start" )) // @start...
76+ if (!insideComment && literal_at (p," start" )) // @start...
9977 {
100- while ((c=*p++) && isId (c)) text+=c;
78+ locEngine.clear ();
79+ p+=5 ;
80+ text += " start" ;
81+ while ((c=*p++) && isId (c))
82+ {
83+ locEngine += c;
84+ text+=c;
85+ }
86+ QCString line;
87+ // get everything till end or endOfLine
88+ if (c && (c!=' \n ' ))
89+ {
90+ line += c;
91+ while ((c=*p++) && (c!=' \n ' )) line+=c;
92+ line = line.stripWhiteSpace ();
93+ }
94+ QCString inpName;
95+ QCString rest;
96+ // REGEXP (<fn>)(<ext>?)(<rest>)
97+ static const reg::Ex re_new0 (R"( (([A-Za-z0-9_][A-Za-z0-9_-]*)))" );
98+ static const reg::Ex re_new1 (R"( (([A-Za-z0-9_][A-Za-z0-9_-]*)(\.[A-Za-z0-9_][A-Za-z0-9_-]*)))" );
99+ static const reg::Ex re_new2 (R"( (([A-Za-z0-9_][A-Za-z0-9_-]*)(\.[A-Za-z0-9_][A-Za-z0-9_-]*)(.*)))" );
100+ static const reg::Ex re_new3 (R"( ([A-Za-z0-9_][A-Za-z0-9_-]*)(.*))" );
101+ // std::string_view txtStr = line.view();
102+ if (!line.isEmpty ())
103+ {
104+ reg::Match match0;
105+ reg::Match match1;
106+ reg::Match match2;
107+ reg::Match match3;
108+ bool matchSet = false ;
109+ if (matchSet = reg::match (line.str (),match0,re_new0))
110+ {
111+ inpName = match0[1 ].str ();
112+ }
113+ else if (matchSet = reg::match (line.str (),match1,re_new1))
114+ {
115+ inpName = match1[1 ].str ();
116+ }
117+ else if (matchSet = reg::match (line.str (),match2,re_new2))
118+ {
119+ inpName = match2[1 ].str ();
120+ rest = match2[3 ].str ();
121+ }
122+ else if (matchSet = reg::match (line.str (),match3,re_new3))
123+ {
124+ inpName = match3[1 ].str ();
125+ rest = match3[2 ].str ();
126+ }
127+ if (matchSet)
128+ {
129+ generatePlantUmlFileNames (inpName,format,outDir,baseName,puName,imgName);
130+ }
131+ else
132+ {
133+ generatePlantUmlFileNames (QCString (),format,outDir,baseName,puName,imgName);
134+ }
135+ }
136+ else
137+ {
138+ generatePlantUmlFileNames (QCString (),format,outDir,baseName,puName,imgName);
139+ }
140+
101141 // insert the image name
102142 text+=' ' ;
103143 text+=imgName;
144+
145+ if (!rest.isEmpty ())
146+ {
147+ text += ' \n ' ;
148+ text += rest;
149+ }
104150 if (c) text+=c;
105151 }
152+ else if (!insideComment && strncmp (p,(" end" +locEngine).data (), 3 +strlen (engine.data ()))==0 ) // @end...
153+ {
154+ text += " end" +locEngine+" \n " ;
155+ p+=3 +locEngine.length ();
156+ if (!inlineCode)
157+ {
158+ QCString qcOutDir (substitute (outDir," \\ " ," /" ));
159+ uint32_t pos = qcOutDir.findRev (" /" );
160+ QCString generateType (qcOutDir.right (qcOutDir.length () - (pos + 1 )) );
161+ Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
162+ PlantumlManager::instance ().insert (generateType.str (),puName.str (),outDir,format,text,srcFile,srcLine);
163+ Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
164+ baseNameVector.emplace_back (baseName);
165+ text.clear ();
166+ }
167+ }
106168 break ;
107169 default :
108- if (!insideComment) initial=false ;
109170 break ;
110171 }
111172 }
112173 text+=' \n ' ;
113174 }
114- if (inlineCode) text +=" @end" +engine+" \n " ;
175+ if (inlineCode)
176+ {
177+ text +=" @end" +engine+" \n " ;
178+ // printf("content\n====\n%s\n=====\n->\n-----\n%s\n------\n",qPrint(content),qPrint(text));
179+ QCString qcOutDir (substitute (outDir," \\ " ," /" ));
180+ uint32_t pos = qcOutDir.findRev (" /" );
181+ QCString generateType (qcOutDir.right (qcOutDir.length () - (pos + 1 )) );
182+ Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
183+ PlantumlManager::instance ().insert (generateType.str (),puName.str (),outDir,format,text,srcFile,srcLine);
184+ Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
185+ baseNameVector.emplace_back (baseName);
186+ }
115187
116- // printf("content\n====\n%s\n=====\n->\n-----\n%s\n------\n",qPrint(content),qPrint(text));
188+ return baseNameVector;
189+ }
117190
118- QCString qcOutDir (substitute (outDir," \\ " ," /" ));
119- uint32_t pos = qcOutDir.findRev (" /" );
120- QCString generateType (qcOutDir.right (qcOutDir.length () - (pos + 1 )) );
121- Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
122- PlantumlManager::instance ().insert (generateType.str (),puName.str (),outDir,format,text,srcFile,srcLine);
123- Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
191+ void PlantumlManager::generatePlantUmlFileNames (const QCString &fileName,OutputFormat format,const QCString &outDir,
192+ QCString &baseName,QCString &puName,QCString &imgName)
193+ {
194+ static int umlindex=1 ;
195+
196+ if (fileName.isEmpty ()) // generate name
197+ {
198+ std::lock_guard<std::mutex> lock (g_PlantUmlMutex);
199+ puName = " inline_umlgraph_" +QCString ().setNum (umlindex);
200+ baseName = outDir+" /inline_umlgraph_" +QCString ().setNum (umlindex++);
201+ }
202+ else // user specified name
203+ {
204+ baseName = fileName;
205+ int i=baseName.findRev (' .' );
206+ if (i!=-1 ) baseName = baseName.left (i);
207+ puName = baseName;
208+ baseName.prepend (outDir+" /" );
209+ }
124210
125- return baseName;
211+ switch (format)
212+ {
213+ case PUML_BITMAP:
214+ imgName =puName+" .png" ;
215+ break ;
216+ case PUML_EPS:
217+ imgName =puName+" .eps" ;
218+ break ;
219+ case PUML_SVG:
220+ imgName =puName+" .svg" ;
221+ break ;
222+ }
126223}
127224
128225void PlantumlManager::generatePlantUMLOutput (const QCString &baseName,const QCString &/* outDir */ ,OutputFormat format)
0 commit comments