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+ StringVector 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+ StringVector 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,130 @@ 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 inpName;
87+ QCString rest;
88+
89+ // skip leading whitespace
90+ if (*p && (c==' ' || c==' \t ' ))
91+ {
92+ while ((c=*p++) && (c==' ' || c==' \t ' )) {}
93+ }
94+ // get everything till end or endOfLine, and split into inpName (without extension) and rest
95+ enum State { InName, InExt, InRest };
96+ State state = InName;
97+ while (*p && c!=' \n ' )
98+ {
99+ switch (state)
100+ {
101+ case InName: // looking for the name part
102+ if (isId (c) || c==' -' ) inpName+=c;
103+ else if (c==' .' ) state=InExt;
104+ else rest+=c, state=InRest;
105+ break ;
106+ case InExt: // skipping over extension part
107+ if (!isId (c) && c!=' -' ) rest+=c, state=InRest;
108+ break ;
109+ case InRest: // gather rest until new line
110+ rest+=c;
111+ break ;
112+ }
113+ c = *p++;
114+ }
115+ // printf("inpName='%s' rest='%s'\n",qPrint(inpName),qPrint(rest));
116+ generatePlantUmlFileNames (inpName,format,outDir,baseName,puName,imgName);
117+
101118 // insert the image name
102119 text+=' ' ;
103120 text+=imgName;
121+
122+ if (!rest.isEmpty ())
123+ {
124+ text += ' \n ' ;
125+ text += rest;
126+ }
104127 if (c) text+=c;
105128 }
129+ else if (!insideComment && strncmp (p,(" end" +locEngine).data (), 3 +strlen (engine.data ()))==0 ) // @end...
130+ {
131+ text += " end" +locEngine+" \n " ;
132+ p+=3 +locEngine.length ();
133+ if (!inlineCode)
134+ {
135+ QCString qcOutDir (substitute (outDir," \\ " ," /" ));
136+ uint32_t pos = qcOutDir.findRev (" /" );
137+ QCString generateType (qcOutDir.right (qcOutDir.length () - (pos + 1 )) );
138+ Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
139+ PlantumlManager::instance ().insert (generateType.str (),puName.str (),outDir,format,text,srcFile,srcLine);
140+ Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
141+ baseNameVector.push_back (baseName.str ());
142+ text.clear ();
143+ }
144+ }
106145 break ;
107146 default :
108- if (!insideComment) initial=false ;
109147 break ;
110148 }
111149 }
112150 text+=' \n ' ;
113151 }
114- if (inlineCode) text +=" @end" +engine+" \n " ;
152+ if (inlineCode)
153+ {
154+ text +=" @end" +engine+" \n " ;
155+ // printf("content\n====\n%s\n=====\n->\n-----\n%s\n------\n",qPrint(content),qPrint(text));
156+ QCString qcOutDir (substitute (outDir," \\ " ," /" ));
157+ uint32_t pos = qcOutDir.findRev (" /" );
158+ QCString generateType (qcOutDir.right (qcOutDir.length () - (pos + 1 )) );
159+ Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
160+ PlantumlManager::instance ().insert (generateType.str (),puName.str (),outDir,format,text,srcFile,srcLine);
161+ Debug::print (Debug::Plantuml,0 ," *** writePlantUMLSource generateType: {}\n " ,generateType);
162+ baseNameVector.push_back (baseName.str ());
163+ }
115164
116- // printf("content\n====\n%s\n=====\n->\n-----\n%s\n------\n",qPrint(content),qPrint(text));
165+ return baseNameVector;
166+ }
117167
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);
168+ void PlantumlManager::generatePlantUmlFileNames (const QCString &fileName,OutputFormat format,const QCString &outDir,
169+ QCString &baseName,QCString &puName,QCString &imgName)
170+ {
171+ static int umlindex=1 ;
124172
125- return baseName;
173+ if (fileName.isEmpty ()) // generate name
174+ {
175+ std::lock_guard<std::mutex> lock (g_PlantUmlMutex);
176+ puName = " inline_umlgraph_" +QCString ().setNum (umlindex);
177+ baseName = outDir+" /inline_umlgraph_" +QCString ().setNum (umlindex++);
178+ }
179+ else // user specified name
180+ {
181+ baseName = fileName;
182+ int i=baseName.findRev (' .' );
183+ if (i!=-1 ) baseName = baseName.left (i);
184+ puName = baseName;
185+ baseName.prepend (outDir+" /" );
186+ }
187+
188+ switch (format)
189+ {
190+ case PUML_BITMAP:
191+ imgName =puName+" .png" ;
192+ break ;
193+ case PUML_EPS:
194+ imgName =puName+" .eps" ;
195+ break ;
196+ case PUML_SVG:
197+ imgName =puName+" .svg" ;
198+ break ;
199+ }
126200}
127201
128202void PlantumlManager::generatePlantUMLOutput (const QCString &baseName,const QCString &/* outDir */ ,OutputFormat format)
0 commit comments