Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
libcomp.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  libcomp.cpp
3  -------------
4  begin : Fri Jun 10 2005
5  copyright : (C) 2005 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 #include <QtGui>
22 #include "libcomp.h"
23 #include "qucs.h"
24 //Added by qt3to4:
25 #include <QTextStream>
26 #include "main.h"
27 #include "schematic.h"
28 
29 #include <QDir>
30 #include <QFileInfo>
31 #include <QRegExp>
32 
33 #include <math.h>
34 #include <limits.h>
35 
36 
37 
39 {
40  Type = isComponent; // both analog and digital
41  Description = QObject::tr("Component taken from Qucs library");
42 
43  Ports.append(new Port(0, 0)); // dummy port because of being device
44 
45  Model = "Lib";
46  Name = "X";
47 
48  Props.append(new Property("Lib", "", true,
49  QObject::tr("name of qucs library file")));
50  Props.append(new Property("Comp", "", true,
51  QObject::tr("name of component in library")));
52 }
53 
54 // ---------------------------------------------------------------------
56 {
57  LibComp *p = new LibComp();
58  p->Props.first()->Value = Props.first()->Value;
59  p->Props.next()->Value = Props.next()->Value;
60  p->recreate(0);
61  return p;
62 }
63 
64 // ---------------------------------------------------------------------
65 // Makes the schematic symbol subcircuit with the correct number
66 // of ports.
68 {
69  tx = INT_MIN;
70  ty = INT_MIN;
71  if(loadSymbol() > 0) {
72  if(tx == INT_MIN) tx = x1+4;
73  if(ty == INT_MIN) ty = y2+4;
74  }
75  else {
76  // only paint a rectangle
77  Lines.append(new Line(-15, -15, 15, -15, QPen(Qt::darkBlue,2)));
78  Lines.append(new Line( 15, -15, 15, 15, QPen(Qt::darkBlue,2)));
79  Lines.append(new Line(-15, 15, 15, 15, QPen(Qt::darkBlue,2)));
80  Lines.append(new Line(-15, -15,-15, 15, QPen(Qt::darkBlue,2)));
81 
82  x1 = -18; y1 = -18;
83  x2 = 18; y2 = 18;
84 
85  tx = x1+4;
86  ty = y2+4;
87  }
88 }
89 
90 // ---------------------------------------------------------------------
91 // Loads the section with name "Name" from library file into "Section".
92 int LibComp::loadSection(const QString& Name, QString& Section,
93  QStringList *Includes)
94 {
95  QDir Directory(QucsSettings.LibDir);
96  QFile file(Directory.absFilePath(Props.first()->Value + ".lib"));
97  if(!file.open(QIODevice::ReadOnly))
98  return -1;
99 
100  QTextStream ReadWhole(&file);
101  Section = ReadWhole.read();
102  file.close();
103 
104 
105  if(Section.left(14) != "<Qucs Library ") // wrong file type ?
106  return -2;
107 
108  int Start, End = Section.find(' ', 14);
109  if(End < 15) return -3;
110  QString Line = Section.mid(14, End-14);
111  if(!checkVersion(Line)) // wrong version number ?
112  return -3;
113 
114  if(Name == "Symbol") {
115  Start = Section.find("\n<", 14); // if library has default symbol, take it
116  if(Start > 0)
117  if(Section.mid(Start+2, 14) == "DefaultSymbol>") {
118  Start += 16;
119  End = Section.find("\n</DefaultSymbol>", Start);
120  if(End < 0) return -9;
121  Section = Section.mid(Start, End-Start);
122  return 0;
123  }
124  }
125 
126  // search component
127  Line = "\n<Component " + Props.next()->Value + ">";
128  Start = Section.find(Line);
129  if(Start < 0) return -4; // component not found
130  Start = Section.find('\n', Start);
131  if(Start < 0) return -5; // file corrupt
132  Start++;
133  End = Section.find("\n</Component>", Start);
134  if(End < 0) return -6; // file corrupt
135  Section = Section.mid(Start, End-Start+1);
136 
137  // search model includes
138  if(Includes) {
139  int StartI, EndI;
140  StartI = Section.find("<"+Name+"Includes");
141  if(StartI >= 0) { // includes found
142  StartI = Section.find('"', StartI);
143  if(StartI < 0) return -10; // file corrupt
144  EndI = Section.find('>', StartI);
145  if(EndI < 0) return -11; // file corrupt
146  StartI++; EndI--;
147  QString inc = Section.mid(StartI, EndI-StartI);
148  QStringList f = QStringList::split(QRegExp("\"\\s+\""), inc);
149  for(QStringList::Iterator it = f.begin(); it != f.end(); ++it ) {
150  Includes->append(*it);
151  }
152  }
153  }
154 
155  // search model
156  Start = Section.find("<"+Name+">");
157  if(Start < 0) return -7; // symbol not found
158  Start = Section.find('\n', Start);
159  if(Start < 0) return -8; // file corrupt
160  while(Section.at(++Start) == ' ') ;
161  End = Section.find("</"+Name+">", Start);
162  if(End < 0) return -9; // file corrupt
163 
164  // snip actual model
165  Section = Section.mid(Start, End-Start);
166  return 0;
167 }
168 
169 // ---------------------------------------------------------------------
170 // Loads the symbol for the subcircuit from the schematic file and
171 // returns the number of painting elements.
173 {
174  int z, Result;
175  QString FileString, Line;
176  z = loadSection("Symbol", FileString);
177  if(z < 0) {
178  if(z != -7) return z;
179 
180  // If library component not defined as subcircuit, then load
181  // new component and transfer data to this component.
182  z = loadSection("Model", Line);
183  if(z < 0) return z;
184 
185  Component *pc = getComponentFromName(Line);
186  if(pc == 0) return -20;
187 
188  copyComponent(pc);
189 
190  pc->Arcs.setAutoDelete(false);
191  pc->Lines.setAutoDelete(false);
192  pc->Rects.setAutoDelete(false);
193  pc->Ellips.setAutoDelete(false);
194  pc->Ports.setAutoDelete(false);
195  pc->Texts.setAutoDelete(false);
196  pc->Props.setAutoDelete(false);
197  delete pc;
198 
199  return 1;
200  }
201 
202 
203  z = 0;
204  x1 = y1 = INT_MAX;
205  x2 = y2 = INT_MIN;
206 
207  QTextStream stream(&FileString, QIODevice::ReadOnly);
208  while(!stream.atEnd()) {
209  Line = stream.readLine();
210  Line = Line.stripWhiteSpace();
211  if(Line.isEmpty()) continue;
212  if(Line.at(0) != '<') return -11;
213  if(Line.at(Line.length()-1) != '>') return -12;
214  Line = Line.mid(1, Line.length()-2); // cut off start and end character
215  Result = analyseLine(Line, 2);
216  if(Result < 0) return -13; // line format error
217  z += Result;
218  }
219 
220  x1 -= 4; x2 += 4; // enlarge component boundings a little
221  y1 -= 4; y2 += 4;
222  return z; // return number of ports
223 }
224 
225 // -------------------------------------------------------
227 {
228  QDir Directory(QucsSettings.LibDir);
229  QString FileName = Directory.absFilePath(Props.first()->Value);
230  return properAbsFileName(FileName);
231 }
232 
233 // -------------------------------------------------------
234 bool LibComp::createSubNetlist(QTextStream *stream, QStringList &FileList,
235  int type)
236 {
237  int r = -1;
238  QString FileString;
239  QStringList Includes;
240  if(type&1) {
241  r = loadSection("Model", FileString, &Includes);
242  } else if(type&2) {
243  r = loadSection("VHDLModel", FileString, &Includes);
244  } else if(type&4) {
245  r = loadSection("VerilogModel", FileString, &Includes);
246  }
247  if(r < 0) return false;
248 
249  // also include files
250  int error = 0;
251  for(QStringList::Iterator it = Includes.begin();
252  it != Includes.end(); ++it ) {
253  QString s = getSubcircuitFile()+"/"+*it;
254  if(FileList.findIndex(s) >= 0) continue;
255  FileList.append(s);
256 
257  // load file and stuff into stream
258  QFile file(s);
259  if(!file.open(QIODevice::ReadOnly)) {
260  error++;
261  } else {
262  QByteArray FileContent = file.readAll();
263  file.close();
264  //?stream->writeRawBytes(FileContent.data(), FileContent.size());
265  (*stream) << FileContent.data();
266  qDebug() << "hi from libcomp";
267  }
268  }
269 
270  (*stream) << "\n" << FileString << "\n";
271  return error > 0 ? false : true;
272 }
273 
274 // -------------------------------------------------------
276 {
277  QString Type = properFileName(Props.first()->Value);
278  return properName(Type + "_" + Props.next()->Value);
279 }
280 
281 // -------------------------------------------------------
283 {
284  QString s = "Sub:"+Name; // output as subcircuit
285 
286  // output all node names
287  for(Port *p1 = Ports.first(); p1 != 0; p1 = Ports.next())
288  s += " "+p1->Connection->Name; // node names
289 
290  // output property
291  s += " Type=\""+createType()+"\""; // type for subcircuit
292 
293  // output user defined parameters
294  for(Property *pp = Props.at(2); pp != 0; pp = Props.next())
295  s += " "+pp->Name+"=\""+pp->Value+"\"";
296 
297  return s + '\n';
298 }
299 
300 // -------------------------------------------------------
302 {
303  QString s = " Sub_" + createType() + " " + Name + " (";
304 
305  // output all node names
306  Port *pp = Ports.first();
307  if(pp) s += pp->Connection->Name;
308  for(pp = Ports.next(); pp != 0; pp = Ports.next())
309  s += ", "+pp->Connection->Name; // node names
310 
311  s += ");\n";
312  return s;
313 }
314 
315 // -------------------------------------------------------
316 QString LibComp::vhdlCode(int)
317 {
318  QString s = " " + Name + ": entity Sub_" + createType() + " port map (";
319 
320  // output all node names
321  Port *pp = Ports.first();
322  if(pp) s += pp->Connection->Name;
323  for(pp = Ports.next(); pp != 0; pp = Ports.next())
324  s += ", "+pp->Connection->Name; // node names
325 
326  s += ");\n";
327  return s;
328 }
Q3PtrList< Line > Lines
Definition: component.h:67
int Type
Definition: element.h:152
Node * Connection
Definition: element.h:79
QString properFileName(const QString &Name)
Definition: main.cpp:468
int y1
Definition: element.h:153
void copyComponent(Component *)
Definition: component.cpp:1216
Q3PtrList< struct Arc > Arcs
Definition: component.h:68
Q3PtrList< Area > Rects
Definition: component.h:69
tQucsSettings QucsSettings
Definition: main.cpp:52
Component * getComponentFromName(QString &Line, Schematic *p)
Definition: component.cpp:1532
int tx
Definition: component.h:78
int loadSymbol()
Definition: libcomp.cpp:172
int analyseLine(const QString &, int)
Definition: component.cpp:915
int y2
Definition: element.h:153
Definition: element.h:72
int x1
Definition: element.h:153
bool checkVersion(QString &Line)
Definition: main.cpp:602
bool createSubNetlist(QTextStream *, QStringList &, int type=1)
Definition: libcomp.cpp:234
Definitions and declarations for the main application.
int ty
Definition: component.h:78
QString properAbsFileName(const QString &Name)
Definition: main.cpp:452
Q3PtrList< Property > Props
Definition: component.h:72
SubMap FileList
Definition: element.h:48
void recreate(Schematic *)
Definition: component.cpp:1250
QString createType()
Definition: libcomp.cpp:275
Component * newOne()
Definition: libcomp.cpp:55
Q3PtrList< Port > Ports
Definition: component.h:70
QString verilogCode(int)
Definition: libcomp.cpp:301
QString Name
Definition: component.h:80
Q3PtrList< Text > Texts
Definition: component.h:71
QString Model
Definition: component.h:80
QString Name
Definition: node.h:40
QString Description
Definition: component.h:81
void createSymbol()
Definition: libcomp.cpp:67
QString vhdlCode(int)
Definition: libcomp.cpp:316
#define isComponent
Definition: element.h:110
int loadSection(const QString &, QString &, QStringList *i=0)
Definition: libcomp.cpp:92
QString properName(const QString &Name)
Definition: main.cpp:476
Q3PtrList< Area > Ellips
Definition: component.h:69
int x2
Definition: element.h:153
QString getSubcircuitFile()
Definition: libcomp.cpp:226
LibComp()
Definition: libcomp.cpp:38
QString netlist()
Definition: libcomp.cpp:282
QString LibDir
Definition: main.h:59