pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
bdf_Reader.py
Go to the documentation of this file.
00001 ## GNU Lesser General Public License
00002 ## 
00003 ## Program pyNastran - a python interface to NASTRAN files
00004 ## Copyright (C) 2011-2012  Steven Doyle, Al Danial
00005 ## 
00006 ## Authors and copyright holders of pyNastran
00007 ## Steven Doyle <mesheb82@gmail.com>
00008 ## Al Danial    <al.danial@gmail.com>
00009 ## 
00010 ## This file is part of pyNastran.
00011 ## 
00012 ## pyNastran is free software: you can redistribute it and/or modify
00013 ## it under the terms of the GNU Lesser General Public License as published by
00014 ## the Free Software Foundation, either version 3 of the License, or
00015 ## (at your option) any later version.
00016 ## 
00017 ## pyNastran is distributed in the hope that it will be useful,
00018 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 ## GNU General Public License for more details.
00021 ## 
00022 ## You should have received a copy of the GNU Lesser General Public License
00023 ## along with pyNastran.  If not, see <http://www.gnu.org/licenses/>.
00024 ## 
00025 # pylint: disable=C0103,R0902,R0904,R0914
00026 
00027 from __future__ import division, print_function
00028 import os
00029 import sys
00030 
00031 class BDFReader(object):
00032     def __init__(self, debug, log):
00033         self.relpath = True
00034         if sys.version_info < (2, 6):
00035             #version = sys.version_info
00036             self.relpath = False
00037             #raise RuntimeError("must use python 2.6 or greater...version=%s"
00038             #                   %(str(version)))
00039 
00040         if log is None:
00041             from pyNastran.general.logger import dummyLogger
00042             if debug:
00043                 word = 'debug'
00044             else:
00045                 word = 'info'
00046             loggerObj = dummyLogger()
00047             log = loggerObj.startLog(word) # or info
00048         self.log = log
00049 
00050     def print_filename(self, filename):
00051         """
00052         Takes a path such as C:/work/fem.bdf and locates the file using
00053         relative paths.  If it's on another drive, the path is not modified.
00054         @param self the object pointer
00055         @param filename a filename string
00056         @retval filenameString a shortened representation of the filename
00057         """
00058         driveLetter = os.path.splitdrive(os.path.abspath(filename))[0]
00059         if driveLetter == os.path.splitdrive(os.curdir)[0] and self.relpath:
00060             return os.path.relpath(filename)
00061         else:
00062             return filename
00063         ###
00064 
00065     def open_file(self, infileName):
00066         """
00067         Takes a filename and opens the file.  
00068         This method is used in order to support INCLUDE files.
00069         """
00070         #print self.isOpened
00071         if self.isOpened[infileName] == False:
00072             self._active_filenames.append(infileName)
00073             #self.log.info("*openFile bdf=|%s|  pwd=|%s|" %(infileName,
00074             #                                               os.getcwd()))
00075             if not os.path.exists(infileName):
00076                 msg = "infileName=|%s| does not exist..." % (infileName)
00077                 raise IOError(msg)
00078             infile = open(infileName, 'r')
00079             self.infilesPack.append(infile)
00080             self.lineNumbers.append(0)
00081             self.isOpened[infileName] = True
00082             self.linesPack.append([])
00083         ###
00084         else:
00085             pass
00086             #print "is already open...skipping"
00087         ###
00088 
00089     def get_file_stats(self):
00090         """
00091         gets information about the active BDF file being read
00092         @param self the object pointer
00093         @retval lineNumber the active file's line number
00094         """
00095         filename   = self._active_filenames[-1]
00096         return (filename, self.get_line_number())
00097 
00098     def get_line_number(self):
00099         """
00100         Gets the line number of the active BDF (used for debugging).
00101         @param self the object pointer
00102         @retval returns the line number of the active BDF filename
00103         """
00104         lineNumber = self.lineNumbers[-1]
00105         return lineNumber
00106 
00107     def get_next_line(self, debug=False):
00108         """
00109         Gets the next line in the BDF
00110         @param self
00111           the BDF object
00112         @param debug
00113           developer debug
00114         @retval line
00115           the next line in the BDF or None if it's the end of the current file
00116         """
00117         self.lineNumbers[-1] += 1
00118         linesPack = self._make_lines_pack(debug=False)
00119         #print "len(linesPack) = ", len(linesPack)
00120         #for line in linesPack:
00121             #print("$  |%r|" %(line))
00122 
00123         if len(linesPack) == 0:
00124             self.close_file()
00125             return None
00126             #linesPack = self._make_lines_pack(debug=debug)
00127             #return lastLine
00128         #print linesPack[0]
00129         return linesPack.pop(0)
00130 
00131     def close_file(self, debug=False):
00132         """
00133         Closes the active file object.
00134         If no files are open, the function is skipped.
00135         This method is used in order to support INCLUDE files.
00136         @param self the object pointer
00137         @param debug developer debug
00138         """
00139         if len(self.infilesPack) == 0:
00140             return
00141         if debug:
00142             self.log.debug("*closing")
00143         infile = self.infilesPack.pop()
00144         infile.close()
00145 
00146         #if debug:
00147         #    print [os.path.relpath(fname) for fname in self._active_filenames]
00148         lineNumbers = self.lineNumbers.pop()
00149         active_filename = self._active_filenames.pop()
00150         linesPack = self.linesPack.pop()
00151         self.isOpened[active_filename] = False
00152         
00153         if len(self.linesPack) == 0:
00154             raise IOError('\nThe bdf closed unexpectedly...\n  an Executive '
00155                           'and Case Control Decks are required...'
00156                           'put a CEND and BEGIN BULK in the BDF')
00157         nlines = len(self.linesPack[-1])
00158 
00159         ## determines if self.activefilename should be closed at the next
00160         ## opportunity
00161         self.doneReading = False
00162         if debug:
00163             fnameA = self.print_filename(active_filename)
00164             fnameB = self.print_filename(self.bdf_filename)
00165 
00166             self.log.debug("active_filename=|%s| infilename=%s len(pack)=%s\n"
00167                          %(fnameA,fnameB,nlines))
00168         ###
00169         #print "\n\n"
00170 
00171     def _set_infile(self, bdf_filename, includeDir=None):
00172         """
00173         Sets up the basic file/lines/cardCounting operations
00174         @param self
00175           the BDF object
00176         @param bdf_filename
00177           the input BDF filename
00178         @param includeDir
00179           the location of include files if an absolute/relative path is
00180           not used (not supported in Nastran)
00181         """
00182         ## automatically rejects every parsable card (default=False)
00183         self.autoReject   = False
00184         ## is the active file done reading
00185         self.doneReading  = False
00186         ## was an ENDDATA card found
00187         self.foundEndData = False
00188 
00189         if includeDir is None:
00190             includeDir = os.path.dirname(bdf_filename)
00191         ## the active filename (string)
00192         self.bdf_filename = bdf_filename
00193         ## the directory of the 1st BDF (include BDFs are relative to this one)
00194         self.includeDir = includeDir
00195         ## list of infile objects (needed for INCLUDE files)
00196         self.infilesPack     = []
00197         ## list of lines from self.activeFilename that are stored
00198         self.linesPack       = []
00199         ## list of all open filenames
00200         self._active_filenames = []
00201         ## stores the line number of self.activefilename that the parser is on
00202         ## very helpful when debugging
00203         self.lineNumbers     = []
00204         ## dictionary that says whether self.bdf_filename is open/close
00205         ## (boolean)
00206         self.isOpened = {self.bdf_filename: False}
00207         ## list of all read in cards - useful in determining if
00208         ## entire BDF was read & really useful in debugging
00209         self.cardCount = {}
00210         ## stores the cardCount of cards that have been rejected
00211         self.rejectCount = {}
00212 
 All Classes Namespaces Files Functions Variables